0

我正在尝试检测我的应用程序是否设置了一个 cookie,该 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 标题行上读取和运行字符串检测?

4

1 回答 1

2

您可以使用vmod 标头中的 header.get 函数解决它(清漆版本> = 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

如果我为 cookie TestCookie 注释掉 setcookie,那么我将在下一个请求中获得 HIT。

于 2012-10-09T21:35:36.653 回答