如何通过光油4.0传递数据(标题?)

问题描述:

我使用devicedetect.vclX-UA-Device标题发送到我的应用程序,因此它知道要渲染哪个布局。 varnish将为此标题设置的可能值为mobiledesktop如何通过光油4.0传递数据(标题?)

在出路中,此标题被转换为Vary: User-Agent

现在,作为一个单独的独立项目,我需要在resp对象(在发送到客户端之前发送到我们的Golang代理)设置另一个标头。该标题将被称为X-Analytics-Device并且将具有可能的值botmobile,tabletdesktop

后台服务器确实不是需要用X-Analytics-Device做任何事情。只有我们的Go代理将解析并在将其发送到客户端之前将其删除。

问题是,我需要根据vcl_recv子程序call devicedetect;的结果设置X-Analytics-Device标头。我需要最终将其设置为resp这是vcl_deliver,我需要知道传递数据的最佳方式。

我能想到的唯一真正的方法可能工作(基于我对Varnish的有限理解),我需要设置一些其他标题并稍后访问它。

也许这样的事情(我现在离开了bot):

if (req.http.X-UA-Device ~ "^mobile") { 
    set req.http.X-UA-Device  = "mobile"; 
    set req.http.X-Analytics-Device = "mobile"; 

} elseif (req.http.X-UA-Device ~ "^tablet") { 
    set req.http.X-UA-Device  = "desktop"; 
    set req.http.X-Analytics-Device = "tablet"; 

} else { 
    set req.http.X-UA-Device  = "desktop"; 
    set req.http.X-Analytics-Device = "desktop"; 
} 

在此之后......我不知道。我需要在vcl_deliver这样设置吗?

set resp.http.X-Analytics-Device = req.http.X-Analytics-Device; 

它是怎样到达从resp传递给req?如果它是一个打击或一个小姐会发生什么?这很重要吗?这是否会试图缓存清漆头(这显然不应该)?

我这样做的主要担心是,有太多动人的东西我只是不知道最好的方式。

最终的结果是...每个请求都需要检查设备,并且在出路时需要设置标题,而不需要将该值与清漆中的数据一起缓存,并且它不会伤害到将它发送到后端,它不需要。

这是我的完整VCL,在添加上面的伪代码行之前。

vcl 4.0; 

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

import std; 

include "purge.vcl"; 
include "devicedetect.vcl"; 

acl purge { 
    "localhost"; 
    "127.0.0.1"; 
    "10.0.0.0"/8; 
} 

sub vcl_recv { 
    call devicedetect; 
    if (req.http.X-UA-Device ~ "^mobile") { 
    set req.http.X-UA-Device = "mobile"; 
    } else { 
    set req.http.X-UA-Device = "desktop"; 
    } 

    if (req.restarts == 0) { 
    if (req.http.X-Forwarded-For) { 
     set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; 
    } else { 
     set req.http.X-Forwarded-For = client.ip; 
    } 
    } 

    if (req.method !~ "^(GET|HEAD|PUT|POST|OPTIONS|DELETE)$") { 
    return (synth(405)); 
    } 

    # never cache anything except GET/HEAD 
    if (req.method != "GET" && req.method != "HEAD") { 
    return (pass); 
    } 

    # don't cache images or assets 
    if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|ico|tiff|tif|bmp|svg)$") { 
    return (pass); 
    } 

    # fix up the request 
    unset req.http.cookie; 
    return (hash); 
} 

sub vcl_backend_response { 
    set beresp.do_stream = false; 

    # device detect 
    if (bereq.http.X-UA-Device) { 
    if (!beresp.http.Vary) { # no Vary at all 
     set beresp.http.Vary = "X-UA-Device"; 
    } elseif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary 
     set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device"; 
    } 
    } 

    # bypass cache for files > 5 MB 
    if (std.integer(beresp.http.Content-Length, 0) > 5242880) { 
    set beresp.uncacheable = true; 
    set beresp.ttl = 120s; 
    return (deliver); 
    } 

    # catch obvious reasons we can't cache 
    if (beresp.http.Set-Cookie) { 
    set beresp.ttl = 0s; 
    } 

    # avoid caching error responses (1m grace period) 
    if (beresp.status >= 500) { 
    set beresp.ttl = 1m; 
    return (deliver); 
    } 

    # set times 
    set beresp.ttl = 24h; 
    set beresp.grace = 4h; 
    return (deliver); 
} 

sub vcl_deliver { 
    # device detect 
    if ((req.http.X-UA-Device) && (resp.http.Vary)) { 
    set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent"); 
    } 

    # remove junk headers 
    unset resp.http.Server; 
    unset resp.http.Via; 
    unset resp.http.X-Powered-By; 
    unset resp.http.X-Runtime; 
    unset resp.http.X-Varnish; 

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

该链接实际上完全澄清和解答一切我无法表述的事情... https://info.varnish-software.com/blog/adding-headers-gain-insight-vcl

答案是铲,你需要进入req头在vcl_recv数据的所有位,然后将它们复制到vcl_deliver中的响应中。

他指出以下,为什么它不会得到缓存:由于REQ对象不传递到我们需要将数据从REQ对象复制到RESP客户

。我们在交付时会这样做。如果你在vcl_backend_response中执行它,头文件将被存储在缓存中,这可能不是你想要的。

@Tallboy的回答挽救了我的一天。总结一下你想要做的是:

# set the value in vcl_recv 
sub vcl_recv { 
    set req.http.X-NAVO-AY = "AYAYAYAYAYAYYYYY"; 
} 
# copy the value from req to resp (because it is not done automatically) 
sub vcl_deliver { 
    set resp.http.X-NAVO-AY = req.http.X-NAVO-AY; 
}