Originally I had a conf like this:
location /some/path/ {
proxy_pass http://other.host/foo/;
}
And requests to http://my.domain/some/path/bar
would be proxied to http://other.host/foo/bar
I started using variables in the proxy_pass to force nginx to re-resolve DNS:
location /some/path/ {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/;
}
But I found that the remainder of the uri path was no longer being appended, so now requests to http://my.domain/some/path/bar
would be proxied to simply http://other.host/foo/
.
So I changed it to a regex
location ~ ^/some/path/(.*) {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/$1;
}
But that doesn't include any query parameters, so I updated again
location ~ ^/some/path/(.*) {
resolver 1.2.3.4;
set $proxy_root "other.host/foo"
proxy_pass http://$proxy_root/$1?$args;
}
This kinda works, but it means there's a ? in every target address, when only some of the incoming requests actually have a ?query section...
I think I could do some further string manipulation, but this feels like a bit much. Is there a simpler way to proxy_pass as I did originally, but with the proxy target as a variable to force re-resolution?
Instead of working with the location matcher, another option is to use $request_uri
and match the part you want to maintain. $request_uri
contains the full URI including query parameters (http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_uri).
Since the location
block matches /some/path/
, use a regular expression to obtain the remainder:
if ($request_uri ~* "/some/path(/.*$)")
set $path_remainder $1;
}
Finally, concatenate the remainder:
location /some/path/ {
resolver 1.2.3.4;
set $proxy_root "other.host/foo";
if ($request_uri ~* "/some/path(/.*$)") {
set $path_remainder $1;
}
proxy_pass http://$proxy_root$path_remainder;
}
As for why this happens, according to http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass :
In some cases, the part of a request URI to be replaced cannot be determined
with one of those cases being
When variables are used in proxy_pass:
location /name/ { proxy_pass http://127.0.0.1$request_uri; }
In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.
This is the case here since you have $proxy_root in your proxy_pass directive parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With