cookies - Varnish 4 vcl_deliver 从 backend_response 中删除 set-cookie

标签 cookies varnish setcookie varnish-vcl

我有 vcl_deliver 的这种行为,它会从后端删除每个 http.set-cookie。

这是我的 Varnish 日志:

-   VCL_call       DELIVER
-   RespUnset      Set-Cookie: JSESSIONID=20E1512F59F3BA8A7BAE6AC2C10B0F66; Path=/; HttpOnly
-   RespUnset      Set-Cookie: OpenCmsOuFqn=/; Expires=Wed, 03-Feb-2016 13:18:41 GMT; Path=/
-   RespUnset      Set-Cookie: OpenCmsUserName=Admin; Expires=Wed, 03-Feb-2016 13:18:41 GMT; Path=/
-   RespHeader     Set-Cookie: LB=fep001; path=/;
-   RespHeader     X-Cache: MISS
-   VCL_return     deliver

我可能看不到我也发布的配置错误。 这是我的 default.vcl 配置文件:

vcl 4.0;

import std;
import directors;

backend fep001 {
    .host = "fe1";
    .port = "82";
    .probe = {
        .url = "/ping";
        .interval = 10s;
        .timeout = 1s;
        .window = 1;
        .threshold = 1;
        .expected_response = 200;
    }
}
backend fep002 {
    .host = "fe2";
    .port = "82";
    .probe = {
        .url = "/ping";
        .interval = 10s;
        .timeout = 1s;
        .window = 1;
        .threshold = 1;
        .expected_response = 200;
    }
}

sub vcl_init {
    new cluster = directors.round_robin();
    new clusterhash = directors.hash();
    cluster.add_backend(fep001);
    clusterhash.add_backend(fep001, 1.0);
    cluster.add_backend(fep002);
    clusterhash.add_backend(fep002, 1.0);
}

sub vcl_recv {
    if (req.http.Cookie ~ "LB=fep[0-9]+") {
        set req.backend_hint = clusterhash.backend(req.http.Cookie.LB);
    } else {
        set req.backend_hint = cluster.backend();
    }
    if (! std.healthy(req.backend_hint)) {
        std.log("not healthy");
        set req.backend_hint = cluster.backend();
    }

    if (req.http.Cookie) {
        set req.http.Cookie = regsuball(req.http.Cookie, "(^|; ) *LB=[^;]+;? *", "\1");
    }

    if (req.method != "GET" && req.method != "HEAD") {
        return(pass);
    }
    if (req.url ~ "^/export/.*$") {
        return(hash);
    }
    return(pass);
}

sub vcl_backend_response {
    set beresp.http.X-node = beresp.backend.name;
    set beresp.http.Vary = "Accept-Encoding";
    if (bereq.url ~ "^/export/.*$" && beresp.status < 400) {
        set beresp.ttl = 30m;
    } else {
        set beresp.ttl = 0s;
    }
    return(deliver);
}

sub vcl_deliver {
    if (obj.hits == 0 && req.http.Cookie !~ "LB=fep[0-9]+") {
        set resp.http.Set-Cookie = "LB=" + resp.http.X-node + "; path=/;";
    }

    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT:" + obj.hits;
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

我怎样才能保留这些http header ?

谢谢

戴维德

最佳答案

我终于找到了从文章Proper sticky session load balancing in Varnish中推导出来的一个解决方案

看来 Varnish 4 没有添加其他 Set-Cookie 而是覆盖它,并且不会以这样的方式添加这样的 Varnish 3:

set resp.http.Set-Cookie = "LB=" + req.http.X-node + "; path=/;" + resp.http.Cookie;

这意味着你必须使用一些VMOD。

我添加了 cookie 和 header 导入:

vcl 4.0;

import std;
import directors;
import cookie;
import header;

我稍微改变了后端选择:

cookie.parse(req.http.cookie);
if (cookie.get("LB")) {
    set req.backend_hint = clusterhash.backend(cookie.get("LB"));
} else {
    set req.backend_hint = cluster.backend();
}
if (! std.healthy(req.backend_hint)) {
    std.log("not healthy");
    set req.backend_hint = cluster.backend();
}

最后,这是添加这些 VMOD 的主要原因:

if (obj.hits == 0 && req.http.Cookie !~ "LB=fep[0-9]+") {
    header.remove(resp.http.Set-Cookie,"^LB=.*$");
    header.append(resp.http.Set-Cookie,"LB=" + resp.http.X-node + "; Expires=" + cookie.format_rfc1123(now, 60m) + "; path=/;");
}

希望这个答案能对某人有所帮助。

关于cookies - Varnish 4 vcl_deliver 从 backend_response 中删除 set-cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31787670/

相关文章:

javascript - GC 期间会删除什么类型的 cookie?

apache - 配置后 Varnish 失败

caching - Varnish :即使请求或响应 header 中存在某些 cookie 也会缓存

magento - 使用 Varnish -松节油组合排除结帐和客户模块/magento 部分

javascript - 使用javascript设置跨子域cookie

PHP 或 JavaScript 或 jQuery cookie 5 分钟后过期

python - flask_login 有时会混合登录;我以其他人身份登录

security - 在启用 SSL 的网站上使用 JWT 代替 Cookie

javascript - 如果 self.location.href!=top.location.href 设置 cookie

即使所有 CORS 允许,Firefox 也不会保留跨域发送的 cookie