Score:0

How to Avoid Crazy Caching with "Vary: Cookie" Header in NGINX

ke flag

I know Vary: Cookie is not well liked, since it causes caching of every variation of cookies a user might report. On the other hand, without it, I've had to use Cache-Control: no-cache to tell my NGINX caching server to skip caching content entirely that might have a user logged in (every page of my site, incidentally, since there's an account box at the top of the page).

I only send cookies if the user logs in, so most page views would benefit from caching. I would like to narrow it down so that there are only two variations: a cached version for users whose "variance" is that they have no cookies and a non-cached version for those who have cookies (e.g. the user is logged in and has authentication cookies).

If I add "Vary: Cookie" to my Perl program, is there a way for me to tell NGINX that in this case it should only pay attention to whether a sessionId cookie exists or not? Something along the lines of -- to make a pseudo-header -- Vary: Cookie('sessionId')? If there is a way to implement this in the header produced by the script that NGINX would then respect, I think I'd prefer that over putting it in the NGINX configuration, but any solution would be appreciated.

I'm not entirely sure how to test if I'll cause NGINX to go crazy with caching, but I wonder if something along these lines could work: on a viewer who is not logged in, the script sends Vary: Cookie, but on a viewer who is logged in, it sends both that header and Cache-Control: no-cache. Would NGINX understand this to be telling it to cache the first response but not the variant? Or would I mess something up in ways I'm not catching just now?

Update: Here's a sample of one of my server blocks:

server {
    server_name myservername.tld
    listen 80;

    location / {
        proxy_cache $PROXY_CACHE;

        proxy_cache_valid 200 302 60m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout http_429 http_500 http_502 http_503 http_504;
        proxy_cache_background_update on;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 1;
        proxy_cache_lock on;

        proxy_pass $scheme://$APACHE_PROXY_REQ_IP:$APACHE_PROXY_REQ_PORT;
    }

}
Michael Hampton avatar
cz flag
Please post your nginx `server` block.
ke flag
I added the `server` block. Thanks!
Score:1
cz flag

You should look at the directives proxy_no_cache and proxy_cache_bypass.

proxy_no_cache tells nginx the conditions under which it should not cache the response from your app. You can define this to be just about whatever you wish, e.g.:

proxy_no_cache $cookie_sessionid;

proxy_cache_bypass operates in the other direction: it tells nginx when a request should not be served from cache but instead passed on to your app, even if a cached entry exists.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.