Varnish如何将含/site路径的请求重定向到其他网站或Web服务器
配置问题诊断
你给出的原有配置存在多处错误,完全不符合重定向需求:
- 逻辑偏差:你需要实现的是用户端重定向(返回3xx响应让浏览器跳转至新地址),但原配置是修改请求参数后透传给后端,属于反向代理透传逻辑,和重定向需求完全不匹配
- 变量错误:VCL标准中修改请求URL需要操作
req.url变量,你写的set url是无效语法,服务启动时会直接编译报错 - 正则匹配&替换不严谨:匹配规则
req.url ~ "/site.*$"没有锚定匹配位置,只要URL任意位置出现/site就会触发规则,很容易误拦截其他正常请求;替换规则regsub(req.url, "site", "")只会替换第一个出现的site字符串,若URL其他位置包含site字符会导致路径异常 - 语法错误:
return (pass)后缺少分号,不符合VCL语法规范,编译无法通过
正确实现方案
以下方案适配Varnish 4.0及以上版本,根据你的重定向需求分为两种常用场景:
场景1:重定向到http://ip:port根路径,丢弃原路径所有参数
如果需要永久重定向就把302改为301即可
# 匹配所有以/site开头的请求 if (req.url ~ "^/site(/.*)?$") { return (synth(302, "Moved Temporarily")); } sub vcl_synth { if (resp.status == 302 && req.url ~ "^/site(/.*)?$") { set resp.http.Location = "http://ip:port"; set resp.http.Content-Type = "text/html; charset=utf-8"; return (deliver); } }
如果你需要匹配URL任意位置出现的/site路径,删除正则规则里的开头锚定符^即可。
场景2:重定向时保留/site后面的路径参数
比如访问https://website.com/site/abc?id=1自动跳转到http://ip:port/abc?id=1
if (req.url ~ "^/site(/.*)?$") { return (synth(302, "Moved Temporarily")); } sub vcl_synth { if (resp.status == 302 && req.url ~ "^/site(/.*)?$") { set resp.http.Location = "http://ip:port" + regsub(req.url, "^/site", ""); set resp.http.Content-Type = "text/html; charset=utf-8"; return (deliver); } }
内容的提问来源于stack exchange,提问作者Oliver Wood
相关产品推荐
相关产品推荐

