1

我很好奇如果响应是 404,在 Varnish 2.1.5 中是否有办法重写 URL?

例如。我想提取一个 URL,它可能存在也可能不存在。如果 URL 不存在,我想重写 URL 并尝试使用新的 URL。

我是 Varnish 的新手,并不完全了解请求的生命周期(如果有人知道有文章解释这一点,请分享)。

我已经尝试设置一些变量和请求标头,并进行检查,res.status但它们似乎在生命周期中的某个地方丢失了,并且无论如何页面 404:

if (req.http.cookie ~ "lang_pref"
      && resp.status == 404
      && req.url ~ "^\/(en|fr|de)(\/.*)?$"
      ) {
    set resp.http.Location = "https://" req.http.host regsub(req.url, "^\/(en|fr|de)\/","/");
  }

该用例用于翻译网站。例子

Website.com/french/page 可能存在也可能不存在 如果 /French/page 以 404 响应然后尝试 /page 如果 /page 不存在 那么 404

4

2 回答 2

2

我正在写这个作为答案,否则作为评论它看起来很愚蠢。请记住,301 是永久移动的,而 302 是临时移动的。

您还可以调整以使用正则表达式,就像您在帖子中所做的那样。

sub vcl_recv {
    if (req.url ~ “^/old/page”) {
        return (synth(301, “/new/page”));
    }
    if (req.url ~ “^/this/oldPage”) {
        return (synth(302, “/this/newPage”));
    }
}

sub vcl_synth {
    if (resp.status == 301 || resp.status == 302) {
        set resp.http.location = resp.reason;
        set resp.reason = "Moved";
        return (deliver);
    }
}

更新:解决评论。

sub vcl_error { 
  if (obj.status == 404) { 
  set obj.status = 301; 
  set obj.http.Location = obj.response; 
  return (deliver);
于 2017-06-20T03:00:01.810 回答
2

这是最终适用于我的用例的内容:

sub vcl_fetch {
...
  if (beresp.status == 404 && req.url ~ "^\/(en|fr|de)(\/.*)?$") {
    error 494;
  }

  return(deliver);
}

sub vcl_error {
  # Double check i18n pages for English before 404
  if (obj.status == 494) {
      set obj.http.Location = "https://" req.http.host regsub(req.url, "^\/(en|fr|de)\/","/") "?notranslation";
      set obj.status = 302;
      return(restart);
  }
...
}
于 2017-06-20T22:46:53.913 回答