Skipping the proxy cache based on a cookie?

Hi everyone,
I’m looking into setting up nginx as a proxy cache. I was wondering if
someone can elaborate a bit about ways to bypass the cache
in certain requests. For example, I’d like every new user to go to the
backend server once in order for some cookies to be written.
On further requests I’d like to serve the user with a cached copy of the
site.
How can I set a mechanism that bypasses the cache if a cookie with a
certain name does/does not exist?

Thanks!

Posted at Nginx Forum:

I’ve dug a bit deeper into the documentation and it seems like
proxy_no_cache and proxy_cache_bypass should somehow do the trick, but I
can get things to work with my exact scenario.
Here’s the flow I’d like to create:

  1. when a new user reaches the site, it is forwarded to the backend and
    receives a few cookies back.
    A “new user” is identified by a lack of a certain cookie, which
    is something I couldn’t figure out how to implement (seems like it only
    supports bypassing/no caching if a cookie exists, but not if it
    doesn’t).

This request should not be taken from the cache, but the response can be
stored in cache as long as further requests will not be sent the cookies
this request produced.

  1. Returning visitors can be served from the cache, unless they are
    logged in (in which case they should be sent to the backend and the
    response should not be stored). This is simple enough to do with the
    regular bypass/no_cache combination based on a cookie that is created
    when a user logs in.

It doesn’t seem like a complicated scenario, but I can’t get it to work
just right.
Any help would be appreciated :slight_smile:

Posted at Nginx Forum:

Hmmm…
Is there any chance that such functionality will ever make it into
production?

Posted at Nginx Forum:

Just came back to this as I have hit this wall and it would be very
useful if the roxy no cache and proxy bypass could be triggered based on
the absence of a cookie.

I need to pass first time visitors to the backend and I need to make
sure the content they get is not cached. As they are first time
visitors, I can’t rely on the presence of a cookie to tell this and the
only way I can think off is to check for the absence of a cookie.

Any chance of implementing …

proxy_cache_bypass_empty $cookie_COOKIE;
proxy_no_cache_empty $cookie_COOKIE;

… which would do the same as the standard modes except that they would
be triggered if the cookie or header is absent or empty.

Thanks

Posted at Nginx Forum:

On 18 Jan 2011 21h34 WET, [email protected] wrote:

Any chance of implementing …

proxy_cache_bypass_empty $cookie_COOKIE;
> proxy_no_cache_empty $cookie_COOKIE;

If I understand your question, wouldn’t this do the trick?

if ($cookie_COOKIE = “”) {
set $cookie_no_cache true;
}

Now it works as “usual”.
— appa

Hmmm. That might work. I’ll give it a shot.

Posted at Nginx Forum:

Hi all

I doesn’t seem that “if ($cookie_COOKIE = “”) {” is a valid test for the
presence of a cookie as the code in the if statement does not seem to be
run.

I am using …

if ($cookie_COOKIE = "") {
add_header Set-Cookie: "hits = 1";
}

… but no joy. (I tried the original suggestion first)

Open to further suggestions

Thanks

Posted at Nginx Forum:

ps I did change “$cookie_COOKIE” to match my cookie name.

Thanks

Posted at Nginx Forum:

Dayo Wrote:

if ($cookie_COOKIE = “”) {
add_header Set-Cookie: “hits = 1”;
}

… but no joy. (I tried the original suggestion
first)

Open to further suggestions

Thanks

OK managed to find out that it should be along the lines of …

if ($http_cookie ~* 'COOKIE = ""') {

… but will not appreciate some advice on why my add header is not
working

Thanks

Posted at Nginx Forum:

Dayo Wrote:

… but will not appreciate some advice on why my
add header is not working
“Will now …” that is!

Posted at Nginx Forum:

I think I am getting closer and hope someone can nudge me across the
line.

My set up is now …

if ($http_cookie !~* "mycookie=0") {
  add_header Cookie: "mycookie=1";
}

The idea being that if mycookie is not 0 (which should cover it not
being set), it is set to 1. I then added cookie_MYCOOKIE to the bypass
and no cache parameters so that if it is set to 1, they are triggered.

The backend sets mycookie to 0 if it is 1 so that on subsequent
requests, the resource is served from the cache.

However unfortunately, the “add_header Cookie: “mycookie=1”;” line does
not seem to be called at all.

Thanks

Posted at Nginx Forum:

On 19 Jan 2011 19h58 WET, [email protected] wrote:

I think I am getting closer and hope someone can nudge me across the
line.

My set up is now …

if ($http_cookie !~* "mycookie=0") {
>   add_header Cookie: "mycookie=1";
> }

IIRC you want to bust the proxy cache. Right? So,
http://wiki.nginx.org/HttpProxyModule#proxy_no_cache

If you want a header do as describe, this if you don’t want to cache
the response. If not use a cache busting variable, to force a refresh.

— appa

António P. P. Almeida Wrote:

if ($http_cookie !~* “mycookie=0”) {
don’t want to cache
the response. If not use a cache busting variable,
to force a refresh.

— appa


nginx mailing list
[email protected]
nginx Info Page

Hi

Thanks for the stopping by.

i am already using proxy_cache_bypass and proxy_no_cache.

What I am trying to do is as follows

  1. User requests page and Nginx checks for cookie and if not present,
    sets cookie value to 1. Default cookie value is 0.
  2. Cookie is evaluated against proxy_cache_bypass and proxy_no_cache so
    that if value is 1, user gets passed to backend and response is not
    cached
  3. Backend checks for cookie and if value is 1, sets value to 0 and
    serves specific additional content
  4. User requests another page and this time cookie is present with 0
    value so Step 1 is skipped
  5. Cookie is evaluated against proxy_cache_bypass and proxy_no_cache and
    since value is 0, user gets served from cache or if cache is stale, from
    backend
  6. If user is passed to backend, backend checks for cookie and since
    value is 0, serves normal content

I have Steps 2 onwards basically setup but Step 1 is where it is falling
down. I can’t get Nginx to set that cookie.

Thanks again

Posted at Nginx Forum:

On 19 Jan 2011 20h43 WET, [email protected] wrote:

add_header Cookie “mycookie=1”;

should do the trick.

Don’t use the colon when specifying the header name.

— appa

I have actually already tried that with no success.

Taking a look at the 3rd party headers more module to see if it will
help.

Posted at Nginx Forum:

Hi,

On 19/01/2011 23:22, Dayo wrote:

I have actually already tried that with no success.
Do you have multiple if blocks and have you read the if-is-evil stuff?

It sounds like a different block is being processed.

Marcus.

On 19 Jan 2011 21h22 WET, [email protected] wrote:

I have actually already tried that with no success.

Taking a look at the 3rd party headers more module to see if it will
help.

There’s no need for that the Headers module does what is needed.

It works for me. So I guess that you’ve got something in your
setup/config that breaks it.

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 19 Jan 2011 21:27:05 GMT
Content-Type: application/octet-stream
Content-Length: 0
Connection: keep-alive
Keep-Alive: timeout=10
Cookie: mycookie=1

— appa

I throw my hands up in surrender as I just can’t get it to return the
cookie.

I have tried a plain vanilla build with no joy.

v0.8.54

The relevant location code is …

  location /folder/ {
    if ($http_cookie !~* "COOKIEX=0") {
      add_header Cookie "COOKIEX=1; domain=domain.com; path=/folder/";
    }

    # BEGIN Url Rewrites
                   ...
    # END Url Rewrites

    try_files $uri $uri/ @proxy;
  }

Posted at Nginx Forum:

Probably … headers more isn’t working as well.

Maybe a third party module is breaking it…

Posted at Nginx Forum:

On 19 Jan 2011 22h19 WET, [email protected] wrote:

I throw my hands up in surrender as I just can’t get it to return
the cookie.

I have tried a plain vanilla build with no joy.

v0.8.54

The relevant location code is …

Like Marcus said before. You’re likely to have some implicit location
(if) that it isn’t working.

location /folder/ {
if ($http_cookie !~* “COOKIEX=0”) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
have you checked using the debug flag in the error log
that this if (implicit location) is entered?

Read this explanation by Maxim in another thread:

  add_header Cookie "COOKIEX=1;
  domain=domain.com; path=/folder/";
}

# BEGIN Url Rewrites


# END Url Rewrites

try_files $uri $uri/ @proxy;

}

— appa