Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Vary: Cookie header to the response if cookie is set #8

Closed
simonw opened this issue Jun 5, 2020 · 1 comment
Closed

Add Vary: Cookie header to the response if cookie is set #8

simonw opened this issue Jun 5, 2020 · 1 comment
Labels
enhancement New feature or request

Comments

@simonw
Copy link
Owner

simonw commented Jun 5, 2020

Follow up from #7. This should ensure the middleware works correctly in conjunction with caching such as Cloudflare.

Also refs simonw/datasette#798

@simonw simonw added the enhancement New feature or request label Jun 5, 2020
@simonw
Copy link
Owner Author

simonw commented Jun 5, 2020

Here's how Django does it:

https://github.com/django/django/blob/f283ffaa84ef0a558eb466b8fc3fae7e6fbb547c/django/middleware/csrf.py#L185-L197

            # Set the Vary header since content varies with the CSRF cookie.
            patch_vary_headers(response, ('Cookie',))

https://github.com/django/django/blob/f283ffaa84ef0a558eb466b8fc3fae7e6fbb547c/django/utils/cache.py#L276-L298

cc_delim_re = _lazy_re_compile(r'\s*,\s*')
# ...
def patch_vary_headers(response, newheaders):
    """
    Add (or update) the "Vary" header in the given HttpResponse object.
    newheaders is a list of header names that should be in "Vary". If headers
    contains an asterisk, then "Vary" header will consist of a single asterisk
    '*'. Otherwise, existing headers in "Vary" aren't removed.
    """
    # Note that we need to keep the original order intact, because cache
    # implementations may rely on the order of the Vary contents in, say,
    # computing an MD5 hash.
    if response.has_header('Vary'):
        vary_headers = cc_delim_re.split(response['Vary'])
    else:
        vary_headers = []
    # Use .lower() here so we treat headers as case-insensitive.
    existing_headers = {header.lower() for header in vary_headers}
    additional_headers = [newheader for newheader in newheaders
                          if newheader.lower() not in existing_headers]
    vary_headers += additional_headers
    if '*' in vary_headers:
        response['Vary'] = '*'
    else:
        response['Vary'] = ', '.join(vary_headers)

@simonw simonw closed this as completed in 67edabe Jun 5, 2020
simonw added a commit that referenced this issue Jun 5, 2020
simonw added a commit to simonw/datasette that referenced this issue Jun 5, 2020
- Use new csrftoken() function, refs simonw/asgi-csrf#7
- Check for Vary: Cookie hedaer, refs simonw/asgi-csrf#8

Refs #793 and #798
simonw added a commit to simonw/datasette that referenced this issue Jun 5, 2020
Closes #793.

* Rename RequestParameters to MultiParams, refs #799
* Allow tuples as well as lists in MultiParams, refs #799
* Use csrftokens when running tests, refs #799
* Use new csrftoken() function, refs simonw/asgi-csrf#7
* Check for Vary: Cookie hedaer, refs simonw/asgi-csrf#8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant