问题
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