proxy_pass overwrites the URL changed by rewrite directive

Deadly 提交于 2020-01-24 00:33:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!