Browse Source

Merge pull request #2322 from nnja/dont_overwrite_vary_header

Don't overwrite Vary header when setting for cookie access
pull/2338/head
David Lord 7 years ago committed by GitHub
parent
commit
cb94f4c5d3
  1. 14
      flask/helpers.py
  2. 16
      flask/sessions.py
  3. 26
      tests/test_basic.py

14
flask/helpers.py

@ -1004,3 +1004,17 @@ def is_ip(value):
return True return True
return False return False
def patch_vary_header(response, value):
"""Add a value to the ``Vary`` header if it is not already present."""
header = response.headers.get('Vary', '')
headers = [h for h in (h.strip() for h in header.split(',')) if h]
lower_value = value.lower()
if not any(h.lower() == lower_value for h in headers):
headers.append(value)
updated_header = ', '.join(headers)
response.headers['Vary'] = updated_header

16
flask/sessions.py

@ -9,18 +9,20 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import uuid
import hashlib import hashlib
import uuid
import warnings import warnings
from base64 import b64encode, b64decode from base64 import b64decode, b64encode
from datetime import datetime from datetime import datetime
from werkzeug.http import http_date, parse_date
from itsdangerous import BadSignature, URLSafeTimedSerializer
from werkzeug.datastructures import CallbackDict from werkzeug.datastructures import CallbackDict
from werkzeug.http import http_date, parse_date
from flask.helpers import patch_vary_header
from . import Markup, json from . import Markup, json
from ._compat import iteritems, text_type from ._compat import iteritems, text_type
from .helpers import total_seconds, is_ip from .helpers import is_ip, total_seconds
from itsdangerous import URLSafeTimedSerializer, BadSignature
class SessionMixin(object): class SessionMixin(object):
@ -405,7 +407,7 @@ class SecureCookieSessionInterface(SessionInterface):
# Add a "Vary: Cookie" header if the session was accessed at all. # Add a "Vary: Cookie" header if the session was accessed at all.
if session.accessed: if session.accessed:
response.headers.add('Vary', 'Cookie') patch_vary_header(response, 'Cookie')
if not self.should_set_cookie(app, session): if not self.should_set_cookie(app, session):
return return

26
tests/test_basic.py

@ -520,15 +520,31 @@ def test_session_vary_cookie(app, client):
def setdefault(): def setdefault():
return flask.session.setdefault('test', 'default') return flask.session.setdefault('test', 'default')
@app.route('/vary-cookie-header-set')
def vary_cookie_header_set():
response = flask.Response()
response.headers['Vary'] = 'Cookie'
flask.session['test'] = 'test'
return response
@app.route('/vary-header-set')
def vary_header_set():
response = flask.Response()
response.headers['Vary'] = 'Accept-Encoding, Accept-Language'
flask.session['test'] = 'test'
return response
@app.route('/no-vary-header') @app.route('/no-vary-header')
def no_vary_header(): def no_vary_header():
return '' return ''
def expect(path, header=True): def expect(path, header_value='Cookie'):
rv = client.get(path) rv = client.get(path)
if header: if header_value:
assert rv.headers['Vary'] == 'Cookie' # The 'Vary' key should exist in the headers only once.
assert len(rv.headers.get_all('Vary')) == 1
assert rv.headers['Vary'] == header_value
else: else:
assert 'Vary' not in rv.headers assert 'Vary' not in rv.headers
@ -536,7 +552,9 @@ def test_session_vary_cookie(app, client):
expect('/get') expect('/get')
expect('/getitem') expect('/getitem')
expect('/setdefault') expect('/setdefault')
expect('/no-vary-header', False) expect('/vary-cookie-header-set')
expect('/vary-header-set', 'Accept-Encoding, Accept-Language, Cookie')
expect('/no-vary-header', None)
def test_flashes(app, req_ctx): def test_flashes(app, req_ctx):

Loading…
Cancel
Save