使用Cookie标头使Varnish忽略请求

时间:2014-04-08 16:55:34

标签: http cookies browser-cache varnish varnish-vcl

清漆默​​认行为是永远不会查找包含Cookie标头的请求。换句话说,永远不会缓存包含Cookie标头的请求。我需要覆盖此行为以忽略带有Cookie标头的请求。

考虑我的应用程序中的下一个用户行为:

  1. 用户进入应用程序主页(/),页面应缓存,后端返回public缓存控件,一切正常,页面被Varnish缓存。
  2. 用户导航到不可缓存的自定义页面(/not-cacheable),后端返回private缓存控件。还会在响应中返回Set-Cookie标头。 Varnish忽略了这个请求,用户最终得到了一个cookie。到目前为止一切顺利。
  3. 用户导航回主页(/),记住,该主页已被缓存。问题是,用户请求现在带有Cookie标头。这会导致Varnish忽略该请求并委托给后端。
  4. 删除Cookie 无法使用,因为当用户返回/not-cacheable路线时,他将看不到他的个性化页面,{{1}标头已经条纹化了。相反,后端会返回一个新生成的会话,并在Cookie中添加一个新ID。

    此外,在Varnish中查找每个Set-Cookie请求都会导致每个请求(有关方法或后端响应)被缓存。

    如果有某种方式告诉Varnish忽略Cookie标头,这样我就可以通过让后端决定请求是否可以缓存来缓存带有该标头的请求。

    有什么想法吗?

2 个答案:

答案 0 :(得分:1)

为了记录,我终于想出了一个VCL脚本,它使用自定义标头解决了这个问题并重新启动了请求:

backend default
{
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_recv
{
    if(req.http.X-Force-Backend)
    {
        return(pass);
    }

    if(req.http.Cookie && req.request ~ "(GET|HEAD)")
    {
        set req.http.X-Cookie = req.http.Cookie;
        remove req.http.Cookie;

        return(lookup);
    }
}

sub vcl_deliver
{
    if(resp.http.Cache-control ~ "(private|no-cache|no-store)" 
        && !req.http.X-Force-Backend
        && req.request ~ "(GET|HEAD)"
    )
    {
        set req.http.X-Force-Backend = "YES";
        set req.http.Cookie = req.http.X-Cookie;

        remove req.http.X-Cookie;

        return(restart);
    }
}

正如您所看到的,通过始终删除Cookie标头并在我们从后端获得不可缓存的响应时重新启动请求,我们可以实现所需的效果。我不知道可能的性能缺陷,但我在生产中使用它并且效果很好。

我还写了一篇关于这个特定问题的博客文章,如果有人使用Symfony和Varnish,它可能会很有趣:http://albertofem.com/post/symfony-varnish-and-http-practical-considerations.html

答案 1 :(得分:-1)

我认为删除vcl_recv中的cookie标题应该可以解决问题,这是我在wordpress上用来忽略前端而不是后端的东西,你可以轻松删除if条件使其超过整个服务器

sub vcl_recv {
  if (req.url !~ "^/wp-"){
    unset req.http.cookie;
  }
}
相关问题