aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Nogueira Neves <arthurnn@gmail.com>2015-02-15 12:17:19 -0500
committerArthur Nogueira Neves <arthurnn@gmail.com>2015-02-15 12:17:19 -0500
commite825042c981e0f1cec0f45b09c2da0c1e30e607a (patch)
tree0bdcac3de0ed72f7f69b4fe46cd1cadcfecfc960
parent66a30dc3225589d8aba6c10fee7bfa68da444e49 (diff)
parent2ed39424dbecf1d040b15d1450f0265b35b78022 (diff)
downloadrails-e825042c981e0f1cec0f45b09c2da0c1e30e607a.tar.gz
rails-e825042c981e0f1cec0f45b09c2da0c1e30e607a.tar.bz2
rails-e825042c981e0f1cec0f45b09c2da0c1e30e607a.zip
Merge pull request #18394 from arthurnn/http_cache_forever
Implement http_cache_forever to ActionController
-rw-r--r--actionpack/CHANGELOG.md4
-rw-r--r--actionpack/lib/action_controller/metal/conditional_get.rb18
-rw-r--r--actionpack/test/controller/render_test.rb53
3 files changed, 75 insertions, 0 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 3b115a7bf7..268f037bfe 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Add http_cache_forever to Action Controller, so we can cache a response that never gets expired.
+
+ *arthurnn*
+
* ActionController#translate supports symbols as shortcuts.
When shortcut is given it also lookups without action name.
diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb
index 28f0b6e349..bc6d336e19 100644
--- a/actionpack/lib/action_controller/metal/conditional_get.rb
+++ b/actionpack/lib/action_controller/metal/conditional_get.rb
@@ -215,6 +215,24 @@ module ActionController
response.cache_control.replace(:no_cache => true)
end
+ # Cache or yield the block. The cache is suppose to never expire.
+ #
+ # You can use this method when you have a HTTP response that never changes,
+ # and the browser and proxies should cache it indefinitely.
+ #
+ # <tt>public</tt> By default, HTTP responses are private, cached only on the
+ # user's web browser. To allow proxies to cache the response, set +true+ to
+ # indicate that they can serve the cached response to all users.
+ #
+ # <tt>version</tt> is the version passed as a key for the cache.
+ def http_cache_forever(public: false, version: 'v1')
+ expires_in 100.years, public: public
+
+ yield if stale?(etag: "#{version}-#{request.fullpath}",
+ last_modified: Time.parse('2011-01-01').utc,
+ public: public)
+ end
+
private
def combine_etags(options)
etags = etaggers.map { |etagger| instance_exec(options, &etagger) }.compact
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 8d6b62f2bf..488585c7a4 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -561,3 +561,56 @@ class HeadRenderTest < ActionController::TestCase
assert_response :forbidden
end
end
+
+class HttpCacheForeverTest < ActionController::TestCase
+ class HttpCacheForeverController < ActionController::Base
+ def cache_me_forever
+ http_cache_forever(public: params[:public], version: params[:version] || 'v1') do
+ render text: 'hello'
+ end
+ end
+ end
+
+ tests HttpCacheForeverController
+
+ def test_cache_with_public
+ get :cache_me_forever, params: {public: true}
+ assert_equal "max-age=#{100.years.to_i}, public", @response.headers["Cache-Control"]
+ assert_not_nil @response.etag
+ end
+
+ def test_cache_with_private
+ get :cache_me_forever
+ assert_equal "max-age=#{100.years.to_i}, private", @response.headers["Cache-Control"]
+ assert_not_nil @response.etag
+ assert_response :success
+ end
+
+ def test_cache_response_code_with_if_modified_since
+ get :cache_me_forever
+ assert_response :success
+ @request.if_modified_since = @response.headers['Last-Modified']
+ get :cache_me_forever
+ assert_response :not_modified
+ end
+
+ def test_cache_response_code_with_etag
+ get :cache_me_forever
+ assert_response :success
+ @request.if_modified_since = @response.headers['Last-Modified']
+ @request.if_none_match = @response.etag
+
+ get :cache_me_forever
+ assert_response :not_modified
+ @request.if_modified_since = @response.headers['Last-Modified']
+ @request.if_none_match = @response.etag
+
+ get :cache_me_forever, params: {version: 'v2'}
+ assert_response :success
+ @request.if_modified_since = @response.headers['Last-Modified']
+ @request.if_none_match = @response.etag
+
+ get :cache_me_forever, params: {version: 'v2'}
+ assert_response :not_modified
+ end
+end