Varnish: Rewrite a URL if response is 404

一曲冷凌霜 提交于 2020-02-08 04:44:45

问题


I'm curious if there is a way rewrite a URL if response is a 404, in Varnish 2.1.5?

For example. I'd like to pull up a URL, which may or may not exist. If the URL doesn't exist, I'd like to do a URL rewrite and try the new URL instead.

I'm new to Varnish and don't completely understand the lifecycle of a request (if anyone knows a guy of article explaining this, please share).

I've tried setting some variables and request headers, and checking res.status but they seem to get lost someplace in the lifecycle and the page 404s anyways:

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)\/","/");
  }

The use case is for a translated site. Example

Website.com/french/page may or may not exist If /French/page responds with a 404 Then try /page instead If /page doesn't exist Then 404


回答1:


I am writing this as an answer or it will look goofy as a comment. Keep in mind that 301 is permanently moved and 302 is temporarily moved.

You can also adjust to use regex as you did in your post.

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

UPDATE: To address comments.

sub vcl_error { 
  if (obj.status == 404) { 
  set obj.status = 301; 
  set obj.http.Location = obj.response; 
  return (deliver);



回答2:


Here is what ended up working for my use case:

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);
  }
...
}


来源:https://stackoverflow.com/questions/44642621/varnish-rewrite-a-url-if-response-is-404

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!