aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/controller/integration_test.rb
diff options
context:
space:
mode:
authorst0012 <stan001212@gmail.com>2019-05-08 22:28:47 +0800
committerst0012 <stan001212@gmail.com>2019-07-26 13:52:06 +0800
commit5745a3c0928ee5604ce80af19348efb42189f1d6 (patch)
tree79733d0d9b9a99c132fd0431e27c6def1b909167 /actionpack/test/controller/integration_test.rb
parent41bc4c6207147a5eeafa323d763e66c06e61cacf (diff)
downloadrails-5745a3c0928ee5604ce80af19348efb42189f1d6.tar.gz
rails-5745a3c0928ee5604ce80af19348efb42189f1d6.tar.bz2
rails-5745a3c0928ee5604ce80af19348efb42189f1d6.zip
Add `Vary: Accept` header when rendering
Problem description (quoted from @rafaelfranca's excellent explanation in https://github.com/rails/jquery-ujs/issues/318#issuecomment-88129005): > Let say that we requested /tasks/1 using Ajax, and the previous page has the same url. When we click the back button the browser tries to get the response from its cache and it gets the javascript response. With vary we "fix" this behavior because we are telling the browser that the url is the same but it is not from the same type what will skip the cache. And there's a Rails issue discussing about this problem as well https://github.com/rails/rails/issues/25842 Also, according to [RFC 7231 7.1.4](https://tools.ietf.org/html/rfc7231#section-7.1.4) > An origin server SHOULD send a Vary header field when its algorithm > for selecting a representation varies based on aspects of the request > message other than the method and request target we should add `Vary: Accept` header when determining content based on the `Accept` header. Although adding such header by default could cause unnecessary cache invalidation. But this PR only adds the header if: - The format param is not provided - The request is a `xhr` request - The request has accept headers and the headers are valid So if the user - sends request with explicit format, like `/users/1.json` - or sends a normal request (non xhr) - or doesn't specify accept headers then the header won't be added. See the discussion in https://github.com/rails/rails/issues/25842 and https://github.com/rails/rails/pull/36213 for more details.
Diffstat (limited to 'actionpack/test/controller/integration_test.rb')
-rw-r--r--actionpack/test/controller/integration_test.rb26
1 files changed, 26 insertions, 0 deletions
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index caacd66bd6..cb7c2467ac 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -543,6 +543,32 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest
end
end
+ def test_setting_vary_header_when_request_is_xhr_with_accept_header
+ with_test_route_set do
+ get "/get", headers: { "Accept" => "application/json" }, xhr: true
+ assert_equal "Accept", response.headers["Vary"]
+ end
+ end
+
+ def test_not_setting_vary_header_when_format_is_provided
+ with_test_route_set do
+ get "/get", params: { format: "json" }
+ assert_nil response.headers["Vary"]
+ end
+ end
+
+ def test_not_setting_vary_header_when_ignore_accept_header_is_set
+ original_ignore_accept_header = ActionDispatch::Request.ignore_accept_header
+ ActionDispatch::Request.ignore_accept_header = true
+
+ with_test_route_set do
+ get "/get", headers: { "Accept" => "application/json" }, xhr: true
+ assert_nil response.headers["Vary"]
+ end
+ ensure
+ ActionDispatch::Request.ignore_accept_header = original_ignore_accept_header
+ end
+
private
def with_default_headers(headers)
original = ActionDispatch::Response.default_headers