在Varnish中,如何读取Set-Cookie响应头?

时间:2012-10-09 20:09:07

标签: cookies http-headers varnish varnish-vcl

我正在尝试检测我的应用程序是否在下一页上为用户设置了一个包含“警报消息”的cookie,如果检测到,则Javascript会显示该消息。

在我的vcl_fetch()中,我需要检测特定cookie值“alert_message”是否出现在Set-Cookie标头中的任何位置(可能是在VCL变量 beresp.http.Set-Cookie 中) 。如果检测到,那么我不想缓存下一页(因为Varnish默认剥离了Set-Cookie标头,这会在它返回浏览器之前消除警报消息)。

所以这是我的简单测试:

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

奇怪的是,它无法评估为真。

因此,我将变量放入Server标头,看看它是什么样的:

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

但由于某种原因,这只会在响应标题中显示FIRST Set-Cookie行。

以下是相关的回复标题:

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

如何在所有Set-Cookie标题行上读取和运行字符串检测?

1 个答案:

答案 0 :(得分:2)

您可以使用vmod header中的header.get函数解决此问题(Varnish版本> = 3)

例如,我有简单的PHP脚本和多个Set-Cookie:

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

默认情况下,只有第一个Set-Cookie标头将使用'if(beresp.http.Set-Cookie~“somedata”')进行解析。 当然,我们可以使用来自vmod std的std.collect程序(已经附带Varnish 3而不需要编译)将我们所有的Set-Cookie标头折叠为一个,但它会破坏cookie - Bar和TestCookie不会设置

header.get避免了这个缺陷:它将检查正则表达式匹配的所有标题:

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

所以,有了它,我在第一次和下一次请求时得到了响应标题:

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

如果我将setcookie评论为Cookie TestCookie,那么我将在下次请求时获得HIT。