清漆-将req.url与动态Cookie值进行比较

时间:2018-09-22 17:52:55

标签: varnish varnish-vcl

我正在尝试构建一个系统,其中CMS(在本例中为Drupal)可以设置cookie值(取决于用户角色等),该值将在cookie中存储动态数量的路径,该路径应由Varnish而非传递给Drupal CMS。

这是我的Cookie标头外观的一个示例

cookie: SESS25dJds8sdkjhas324c0352a47f7fd=k16ZxR_095akCmg889utcGSw8ryz2vrG7zzIuQvDCFA; Drupal.visitor.varnish_enabled=1; Drupal.visitor.varnish_mode=exclude; Drupal.visitor.varnish_pages=%2Fuser%0D%0A%2Fuser%2F%2A%0D%0A%2Fnode%2F3

因此在Drupal.visitor.varnish_pages cookie中设置的路径为:

/user
/user/*
/node/3

我需要查看req.url是否等于那些值。

从上面可以看出,为了使事情稍微复杂一点,Drupal cookie中的某些路径也包含一个星号通配符。例如,如果我希望Varnish提供/node/[node-id]之类的所有路径,则将cookie值设置为/node/*。我尝试根据cookie中的值构建一个正则表达式,以将其与req.uri进行比较,并且我的正则表达式有效-因为我已经使用regex101.com和一些示例cookie数据进行了验证,但是清漆不喜欢变量中的正则表达式。这是我所拥有的:

# Check the cookie for the custom data. This way we can control whether
# to serve up static caches of the page, or bypass the varnish cache and let
# Drupal serve up the content.
if (req.http.Cookie ~ "(^|;\s*)(Drupal.visitor.varnish_enabled=1)(;|$)") {
  set req.http.custom_paths = regsub(req.http.Cookie, "(?:^|.*;\s*)(?:Drupal\.visitor\.varnish_pages=)(.*?)(?:;.*|$)", "\1");

  set req.http.varnish_paths_pattern = regsuball(req.http.as_paths, "%0D%0A", "|");
  set req.http.varnish_paths_pattern = regsuball(req.http.varnish_paths_pattern, "%2A", "[.*]");
  set req.http.varnish_paths_pattern = regsuball(req.http.varnish_paths_pattern, "%2F", "/");
  set req.http.varnish_paths_pattern = "(?i)(" + req.http.varnish_paths_pattern + ")";

  # We are in include mode, so varnish should only trigger for the
  # specified paths.
  if (req.http.Cookie ~ "(^|;\s*)Drupal\.visitor\.varnish_mode=include(;|$)") {
    if (req.url ~ req.http.varnish_paths_pattern) {
      set req.http.X-Custom-Varnish = true;
      unset req.http.Cookie;
    }
  }

  # We are in exclude mode, so varnish should trigger for all paths except
  # the specified paths.
  if (req.http.Cookie ~ "(^|;\s*)Drupal\.visitor\.varnish_mode=exclude(;|$)") {
    if (req.url !~ req.http.varnish_paths_pattern) {
      set req.http.X-Custom-Varnish = true;
      unset req.http.Cookie;
    }
  }

  unset req.http.varnish_paths_pattern;
  unset req.http.varnish_paths;
}

从阅读开始,我知道清漆中的正则表达式不会在运行时进行编译,因此将正则表达式与存储在变量中的模式一起使用不起作用-我已经对其进行了测试,并且不起作用。

那么我该如何解决这个问题?我需要能够检测当前路径是否是cookie值中的一个,但是这些cookie值是完全动态的并由CMS控制。

1 个答案:

答案 0 :(得分:0)

因此,首先警告:让用户决定(或至少告诉您)是否应缓存哪种清漆是非常危险的。

第二个警告:让用户给您执行正则表达式就像超级危险。

您应该真正拥有角色列表以及可能在CMS上存储在服务器端的相应路径,并使用重新启动,vmod_curl或vmod_http来询问是否应提供这些服务(显然将答案缓存了一段时间)。

现在,要回答最初的问题,您可以看一下UPLEX的re2 vmod:https://code.uplex.de/uplex-varnish/libvmod-re2/,它将使您可以使用正则表达式作为变量,但是再次:这将是一条曲折的危险道路。