简体   繁体   中英

In Varnish, how can I read the Set-Cookie response header?

I am trying to detect if my application has set a cookie that holds an "alert message" for the user on the next page, where the Javascript displays it if detected.

In my vcl_fetch(), I need to detect if the specific cookie value "alert_message" appears anywhere in the Set-Cookie header (presumably in the VCL variable beresp.http.Set-Cookie ). If detected, then I do not want to cache that next page (since Varnish strips the Set-Cookie header by default, which would obliterate the alert message before it makes it back to the browser).

So here is my simple test:

if(beresp.http.Set-Cookie ~ "alert_message") {
    set req.http.no_cache = 1;
}

Strangely, it fails to evaluate to true.

So I throw the variable into the Server header to see what it looks like:

set beresp.http.Server = " MyApp Varnish implementation - test reading set-cookie: "+beresp.http.Set-Cookie;

But for some reason this only displays the FIRST Set-Cookie line in the response headers.

Here are the relevant response headers:

Server: MyApp Varnish implementation - test reading cookie: elstats_session=7d7279kjmsnkel31lre3s0vu24; expires=Wed, 10-Oct-2012 00:03:32 GMT; path=/; HttpOnly
Set-Cookie:app_session=7d7279kjmsnkel31lre3s0vu24; expires=Wed, 10-Oct-2012 00:03:32 GMT; path=/; HttpOnly
Set-Cookie:alert_message=Too+many+results.; expires=Tue, 09-Oct-2012 20:13:32 GMT; path=/; domain=.my.app.com
Set-Cookie:alert_key=flash_error; expires=Tue, 09-Oct-2012 20:13:32 GMT; path=/; domain=.my.app.com
Vary:Accept-Encoding

How do I read and run string detection on ALL Set-Cookie header lines?

You can resolve it with header.get function from vmod header (Varnish version >= 3)

For example, I have simple PHP script and more than one Set-Cookie in it:

 <?php
 setcookie ("Foo", "test", time() + 3600);
 setcookie ("Bar", "test", time() + 3600);
 setcookie ("TestCookie", "test", time() + 3600);
 ?>

By default, only first Set-Cookie header will be parsed with ' if(beresp.http.Set-Cookie ~ "somedata" '. Of course, we can use std.collect procedure from vmod std (already comes with Varnish 3 and not requires compilation) to collapse all our Set-Cookie headers to one, but it will break cookies - Bar and TestCookie will not set.

header.get avoids this defect: it will check all headers for regex match:

 if (header.get(beresp.http.set-cookie,"TestCookie=") ~ "TestCookie")
 {
     set beresp.http.cookie-test = 1;
     return(hit_for_pass);
 }

So, with it I got in response headers on first and next requests:

cookie-test:1
Set-Cookie:Foo=test; expires=Tue, 09-Oct-2012 22:33:37 GMT
Set-Cookie:Bar=test; expires=Tue, 09-Oct-2012 22:33:37 GMT
Set-Cookie:TestCookie=test; expires=Tue, 09-Oct-2012 22:33:37 GMT
X-Cache:MISS

If I comment out setcookie for cookie TestCookie, then I will got HITs on next requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM