我的镜像工作得很好,并且我在镜像服务器中正确获取了原始请求正文。
但是,我需要从原始上游访问名为
Location
的响应标头并将其转发到我的镜像。通常,将使用以下变量访问来自上游的响应标头:$upstream_http_<*header name*>
,在我的例子中为$upstream_http_location
。
但是我想在我的镜像中访问它,以便我可以将响应标头从上游转发到我的镜像。
我该怎么做?这是我当前的配置,但它不起作用,而且我在镜子中看不到标题
DAV-response
。是否有另一种方法可以访问镜像块中的所有 $upstream_http
标头?
我在 nginx 中有以下请求镜像设置:
location /ops/opendata/DataAccessViewer/ {
mirror /davmirror;
proxy_pass https://<upstream>/;
proxy_redirect https://<upstream>/ /;
}
location /davmirror {
internal;
proxy_pass https://<mirror>;
proxy_set_header DAV-Original-URI $request_uri; # <<<<-- works!
proxy_set_header DAV-tier internals; # <<<<-- works!
proxy_set_header DAV-response $upstream_http_location; # <<<-- DOESNT WORK!
}
更新
欢迎使用 nginx 实现这一目标的替代解决方案。我知道其他非 nginx 解决方法,事实上目前正在使用它们作为后备。理想情况下,我们希望这是 nginx 解决方案。
更新 这个问题似乎表明nginx在解析镜像之前实际上正在等待上游响应?
更新
验证上游确实包含“位置”标头:
这是我在镜像中收到的所有标题。请注意,缺少
DAV-response
好吧,这里的问题有点令人头疼。你看,Nginx 的
mirror
在等待原始请求完成时有点有限。这可能就是为什么 $upstream_http_location
在你的镜子块中不起作用。
但是,嘿,您可以尝试一个解决方法,尽管它不是超级干净。您听说过
post_action
指令吗?这没有很好的记录。但它允许您在原始 proxy_pass
完成并且响应标头已审核后执行操作。
以下是调整配置的方法:
location /ops/opendata/DataAccessViewer/ {
proxy_pass https://<upstream>/;
proxy_redirect https://<upstream>/ /;
post_action @davmirror;
}
location @davmirror {
proxy_pass https://<mirror>;
proxy_set_header DAV-Original-URI $request_uri;
proxy_set_header DAV-tier internals;
proxy_set_header DAV-response $upstream_http_location;
}
因此,
@davmirror
只会在原始 proxy_pass
得到响应后才会启动。这样,$upstream_http_location
就应该被填充,您可以将其转发到您的镜子。
再次强调,这不是最优雅的解决方案。如果您正在寻找更强大的东西,您可能必须选择应用程序级逻辑或某些自定义模块。
基于 Krishan 的回答,另一种方法是您可以尝试使用
proxy_next_upstream
指令,因此在这种情况下,我将从上游服务器捕获响应标头,并且 proxy_next_upstream
指令指定哪些响应应触发重试下一个上游服务器,因此通过包含 invalid_header
,我将确保捕获响应标头!然后,在 mirror
位置块中,我将使用 $http_dav_response
变量来使用存储的响应标头!
location /ops/opendata/DataAccessViewer/ {
proxy_pass https://<upstream>/;
proxy_redirect https://<upstream>/ /;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_set_header DAV-Response $upstream_http_location; # Store the response header in a variable
}
location /davmirror {
internal;
proxy_pass https://<mirror>;
proxy_set_header DAV-Original-URI $request_uri;
proxy_set_header DAV-tier internals;
proxy_set_header DAV-Response $http_dav_response; #just use the stored response header in the mirror block
}