问题
From the nginx documentation as quoted below, I understand that proxy_pass
directive will not the change the URI and will just pass the rewritten URI to the server.
When the URI is changed inside a proxied location using the rewrite directive, and this same configuration will be used to process a request (break):
location /name/ { rewrite /name/([^/]+) /users?name=$1 break; proxy_pass http://127.0.0.1/randomstring; }
In this case, the URI specified in the directive is ignored and the full changed request URI is passed to the server.
But when I set the proxy_pass
to a variable, the URI is being overwritten.
Example:
location /test_rewrite {
set $ups_addr http://upstream_server;
rewrite /test_rewrite /test_rewrite_upstream break;
proxy_pass $ups_addr/random_string;
}
The URI /test_rewrite
is being rewritten to /random_string
.
Can anyone help me understand the reason for this behavior?
回答1:
As the same documentation states below:
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 true only if resulting string contains an URI part. Some examples:
location /test_rewrite {
set $ups_addr http://upstream_server;
rewrite /test_rewrite /test_rewrite_upstream break;
proxy_pass $ups_addr;
}
Resulting string does not contain an URI part, URI passed to upstream server is /test_rewrite_upstream
.
location /test_rewrite {
set $ups_addr http://upstream_server/;
rewrite /test_rewrite /test_rewrite_upstream break;
proxy_pass $ups_addr;
}
Resulting string contains an URI part (note the trailing slash at the end of $ups_addr
variable), URI passed to upstream server is /
.
You can use an $uri
variable to combine rewrite rules with the custom URI parts in a proxy_pass
directive:
location /test_rewrite {
set $ups_addr http://upstream_server;
rewrite /test_rewrite /test_rewrite_upstream break;
proxy_pass $ups_addr/random_string$uri;
}
In this case URI passed to upstream server is /random_string/test_rewrite_upstream
.
To preserve request arguments, use the $is_args and $args variables:
location /test_rewrite {
set $ups_addr http://upstream_server;
rewrite /test_rewrite /test_rewrite_upstream break;
proxy_pass $ups_addr$uri$is_args$args;
}
来源:https://stackoverflow.com/questions/54084239/proxy-pass-overwrites-the-url-changed-by-rewrite-directive