varnish - 如何在Varnish 4.0中传递数据(标题?)

标签 varnish varnish-vcl

我正在使用devicedetect.vclX-UA-Device header 发送到我的应用程序,因此它知道要呈现的布局。 Varnish 将为此 header 设置的可能值为mobiledesktop

在出站时,此 header 将转换为Vary: User-Agent

现在,作为一个单独的隔离项目,我需要在resp对象上设置另一个 header (该 header 在发送到客户端之前先发送到我们的Golang代理)。此 header 将称为X-Analytics-Device,并将具有botmobiletabletdesktop的可能值。

后端服务器不需要来执行,而不需要执行任何操作。只有我们的Go代理会解析并删除此 header ,然后再将其发送给客户端。

问题是,我需要根据X-Analytics-Device中的子例程X-Analytics-Device的结果来设置call devicedetect; header 。我最终需要将其设置在vcl_recv中的resp上,并且我需要知道传递数据的最佳方法。

我可以想到的唯一真实的方法可能是可行的(基于我对Varnish的有限了解),我需要设置一些其他 header ,并在以后访问它。

也许是这样的(我现在暂时省略了vcl_deliver):

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";
}

之后...我不知道。我需要在bot中设置它吗?
set resp.http.X-Analytics-Device = req.http.X-Analytics-Device;

它是如何从vcl_deliver传递到resp的?如果命中或未命中怎么办?那有关系吗这是否将尝试将 header 缓存在 Varnish 中(显然,它不应该是)?

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

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

在添加上面的伪代码行之前,这是我的完整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 header 中,然后将其复制到vcl_deliver中的响应中。

他陈述了以下内容,说明了为什么不对其进行缓存:

Since the req object is not delivered to the client we need to copy the data from the req object to resp. We do this when we deliver it. If you do it in vcl_backend_response the headers will be stored in the cache and this might not be what you want.

关于varnish - 如何在Varnish 4.0中传递数据(标题?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32430811/

相关文章:

amazon-web-services - ELB 保活超时 : Varnish Configuration Assistance

virtualhost - 通过 Varnish 的多个虚拟主机,如果服务不正确的后端

php - Varnish ESI脚本可以获取原来的页面(原始页面)吗?

varnish - 如果更改了 Varnish 缓存中的缓存数据怎么办?

Varnish 不断缓存我的跟踪软件

Varnish ,用于阻止拒绝服务攻击

ruby-on-rails - Varnish 缓存 http 301 302 header 位置重定向

HTTP 验证所有 Varnish 请求

apache - Varnish绕过大文件

c - vcl_fetch 中的 if 语句不起作用