我想在所有带有清漆的网址上添加一个尾部斜杠(通过301重定向)。
然而,我很惊讶我无法在任何地方找到任何关于网络的信息。这是我得到的最接近的,但显然已被破坏,因为它没有考虑查询字符串或任何带有。在它。
if (req.url !~ "/$") {
return (synth (751, ""));
}
...
sub vcl_synth {
if (resp.status == 750) {
set resp.status = 301;
set resp.http.Location = "http://www.example.com" + req.url;
return(deliver);
}
}
我想要考虑的测试用例
example.com/xyz?query=string
- > www.example.com/xyz/?query=string
(添加www,添加/)
example.com/api/latest.json
- > www.example.com/api/latest.json
(添加www,不要添加/)
答案 0 :(得分:1)
以下是Varnish 3的解决方案,您可以将其翻译成Varnish 4.我自己也不会使用Varnish 4:
sub vcl_recv {
if (req.http.Host !~ "^www\." || (
req.url !~ {"(?x)
(?:/$) # last character isn't a slash
| # or
(?:/\?) # query string isn't immediately preceded by a slash
"} &&
req.url ~ {"(?x)
(?:/[^./]+$) # last path segment doesn't contain a . no query string
| # or
(?:/[^.?]+\?) # last path segment doesn't contain a . with a query string
"})
) {
error 720;
}
}
sub vcl_error {
if (obj.status == 720) {
set obj.status = 301;
set obj.http.Location = "http://";
set obj.http.Host = req.http.Host;
if (obj.http.Host !~ "^www\.") {
// for www. prefix
set obj.http.Host = "www." + obj.http.Host;
}
set obj.http.Location = obj.http.Location + obj.http.Host;
if (req.url ~ "(?:/[^./]+$)|(?:/[^.?]+\?)") {
// no . in last path segment before optional query string
if (req.url !~ "/$" && req.url !~ "\?") {
// no trailing slash and no query string
set obj.http.Location = obj.http.Location + req.url + "/";
} else if (req.url ~ "[^/]\?") {
// no trailing slash and with query string, preserve it
set obj.http.Location = obj.http.Location +
regsub(req.url, "([^?]+)\?.*", "\1") +
"/" +
regsub(req.url, "[^?]+(\?.*)", "\1");
} else if (obj.http.Host != req.http.Host) {
// trailing slash rule met, handle missing www. scenario
set obj.http.Location = obj.http.Location + req.url;
}
} else if (obj.http.Host != req.http.Host) {
// last path segment contains a . so handle missing www. scenario
set obj.http.Location = obj.http.Location + req.url;
}
set obj.response = "Moved Permanently";
}
}
我有一个Varnish测试用例文件,用于练习您感兴趣的各种URL:
varnishtest "Testing adding trailing slash"
server s1 {
rxreq
txresp -body "hello world"
} -repeat 4 -start
varnish v1 -vcl+backend {
include "${pwd}/26921577.vcl";
} -start
client c1 {
txreq -url "/document/" -hdr "Host: www.example.com"
rxresp
expect resp.status == 200
expect resp.body == "hello world"
} -run
client c2 {
txreq -url "/document" -hdr "Host: www.example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/document/"
} -run
client c3 {
txreq -url "/document/" -hdr "Host: example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/document/"
} -run
client c4 {
txreq -url "/document" -hdr "Host: example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/document/"
} -run
client c5 {
txreq -url "/xyz/?query=string" -hdr "Host: www.example.com"
rxresp
expect resp.status == 200
expect resp.body == "hello world"
} -run
client c6 {
txreq -url "/xyz?query=string" -hdr "Host: www.example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/xyz/?query=string"
} -run
client c7 {
txreq -url "/xyz/?query=string" -hdr "Host: example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/xyz/?query=string"
} -run
client c8 {
txreq -url "/xyz?query=string" -hdr "Host: example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/xyz/?query=string"
} -run
client c9 {
txreq -url "/api/latest.json" -hdr "Host: www.example.com"
rxresp
expect resp.status == 200
expect resp.body == "hello world"
} -run
client c10 {
txreq -url "/api/latest.json" -hdr "Host: example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/api/latest.json"
} -run
client c11 {
txreq -url "/api/latest.json?query=string" -hdr "Host: www.example.com"
rxresp
expect resp.status == 200
expect resp.body == "hello world"
} -run
client c12 {
txreq -url "/api/latest.json?query=string" -hdr "Host: example.com"
rxresp
expect resp.status == 301
expect resp.http.Location == "http://www.example.com/api/latest.json?query=string"
} -run
varnish v1 -expect client_req == 12
答案 1 :(得分:1)
基于上述varnish 3
的解决方案,以下是varnish 4
的解决方案,用于处理超时问题而不会出现斜杠。我只是对在清漆请求中添加尾部斜杠而没有其他任何花哨的东西而感到惊讶。
因为没有斜杠,我注意到/wp-admin
上的超时问题。 /wp-admin/
工作正常。但是现在在default.vcl
中进行以下更新之后,一切正常。
如果您遇到超时问题并且进行了更改,但仍然遇到相同的问题,请考虑刷新浏览器的缓存,并在浏览器的私有窗口中打开URL,然后尝试使用其他您不喜欢的浏览器不用。
sub vcl_recv {
if (req.url ~ "(?:/[^./]+$)|(?:/[^.?]+\?)") {
// no . in last path segment before optional query string
//add trailing slash to directory URL for instance wp-admin will be replaced with wp-admin/
if (req.url !~ "/$" && req.url !~ "\?") {
// no trailing slash and no query string
set req.url = req.url + "/";
} else if (req.url ~ "[^/]\?") {
// no trailing slash and with query string, preserve it
set req.url = regsub(req.url, "([^?]+)\?.*", "\1") +
"/" + regsub(req.url, "[^?]+(\?.*)", "\1");
}
}
}
这对我来说绝对不错,我希望它也可以对其他人有所帮助。