[web] set Vary response header to "Accept-Language" when using content negotiation
This is slightly annoying because the response actually only varies
based on the language we decide to send, which has much fewer possible
values than Accept-Language, but that's not in the request, so we can't
easily use it. Deployments using varnish or similar and controlling the
set of available languages will likely want to override this to allow
reasonable amounts of caching.
Closes #2105812
--- a/web/request.py Tue Jul 29 16:27:11 2014 +0200
+++ b/web/request.py Tue Jul 29 15:45:04 2014 +0200
@@ -139,6 +139,11 @@
self.setup_params(form)
#: received body
self.content = StringIO()
+ # prepare output header
+ #: Header used for the final response
+ self.headers_out = Headers()
+ #: HTTP status use by the final response
+ self.status_out = 200
# set up language based on request headers or site default (we don't
# have a user yet, and might not get one)
self.set_user_language(None)
@@ -152,11 +157,6 @@
#: page id, set by htmlheader template
self.pageid = None
self._set_pageid()
- # prepare output header
- #: Header used for the final response
- self.headers_out = Headers()
- #: HTTP status use by the final response
- self.status_out = 200
def _set_pageid(self):
"""initialize self.pageid
@@ -1001,6 +1001,7 @@
pass
if vreg.config.get('language-negociation', False):
# 2. http accept-language
+ self.headers_out.addHeader('Vary', 'Accept-Language')
for lang in self.header_accept_language():
if lang in self.translations:
self.set_language(lang)
--- a/web/test/unittest_web.py Tue Jul 29 16:27:11 2014 +0200
+++ b/web/test/unittest_web.py Tue Jul 29 15:45:04 2014 +0200
@@ -101,9 +101,13 @@
headers = {'Accept-Language': 'fr'}
webreq = self.web_request(headers=headers)
self.assertIn('lang="fr"', webreq.read())
+ vary = [h.lower().strip() for h in webreq.getheader('Vary').split(',')]
+ self.assertIn('accept-language', vary)
headers = {'Accept-Language': 'en'}
webreq = self.web_request(headers=headers)
self.assertIn('lang="en"', webreq.read())
+ vary = [h.lower().strip() for h in webreq.getheader('Vary').split(',')]
+ self.assertIn('accept-language', vary)
def test_response_codes(self):
with self.admin_access.client_cnx() as cnx: