My mirroring works just fine, and I am correctly getting the original request body in the mirror server.
However I need to access a response header called Location
from the original upstream and forward it to my mirror. Typically the response header from upstream will be accessed using this variable: $upstream_http_<*header name*>
, in my case $upstream_http_location
.
However I want to access this in my mirror so I can forward the response header from my upstream to my mirror.
How do I do this? Here’s my current configuration, but it doesn’t work and I don’t see the header DAV-response
in my mirror. Is there another way to access all $upstream_http
headers in the mirror block?
I have the following request mirroring setup in 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!
}
Update
Open to alternative solutions to achieve this using nginx. I am aware of other non-nginx workarounds and in-fact using those as fallbacks at the moment. Ideally we would want this to be nginx solution.
Update
This question seems to suggest that nginx is actually waiting on upstream response before resolving mirror?
Update
Verified that upstream does actually include a ‘Location’ Header:
Here’s all the headers I receive in the mirror. Note that DAV-response
is missing
2
Answers
if you’re having trouble accessing the
Location
header in the mirror block, it could be because the header isn’t included in the response from your upstream server,to check, you can use tools likecurl
or browser developer tools to look at the response headers, but if theLocation
header is there, then there might be an issue with how you’re setting up the mirror block.also, instead of using
$upstream_http_
, you can try using$sent_http_
which also has the response headers from the upstream server.something like this :
update
So you can use the
proxy_set_header
directive with the$upstream_http_
variable like this :or if still not working just try to use the
proxy_pass_header
directive along with theproxy_hide_header
directive to achieve the desired result and please don’t forget to restart or reload your Nginx service !if still not working, you need to use the
proxy_intercept_errors
directive, because it tells Nginx to pass all error responses from the upstream server to the mirror server!Alright, so the issue here is a bit of head-scratcher. You see, Nginx’s
mirror
is a bit limited when it comes to waiting for original request to complete. This is probably why$upstream_http_location
ain’t wokring in you’r mirror block.But hey, there’s a workaround you can try, though its not super clean. Have you heard of the
post_action
directive? It’s not well documented. But it letys you do stuff after your originalproxy_pass
is done and the response headers are revievd.Here’s how you could tweak your config:
So,
@davmirror
will only kick in after the originalproxy_pass
gets its response. That way,$upstream_http_location
should be populated and you can forward it to your mirror.Again, it’s not the most elegant solution. If you’re looking for something more robust, you might have to go for app-level logic or some custom module.