description
We configure nginx in a proxy mode,
upstream backend-test { server 127.0.0.1:80; } server { listen 8080; location = /nginx/hwwc/ { proxy_pass http://backend-test; proxy_redirect off; } location / { return 500; } }
Visit http: // t103: 8080 / nginx / hwwc / 80 can access the service port access curl http:. // t103: 8080 / nginx / hwwc time, will return 301 redirect their difference is whether there is the end. One"/"
┬─[tong@T7:~/Src/thirdparty/nginx.git]─[07:13:29 PM] ╰─>$ curl http://t103:8080/nginx/hwwc <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.12.2</center> </body> </html>
Conclusion front: The reason for this is that triggers auto_rediect function when accessing hwwc nginx redirects the request to the hwwc /.
Analysis process is as follows:
Debug Log
First, open the nginx debugging using the --with-debug option compiled nginx can open the following configurations:
Reference: https://nginx.org/en/docs/ngx_core_module.html#debug_connection
events { debug_connection 192.168.7.1; }
In error.log can see in the log as follows: (excerpt key content)
... ... 2019/09/02 18:37:49 [debug] 23137#0: *70 test location: "/" 2019/09/02 18:37:49 [debug] 23137#0: *70 test location: "nginx/hwwc/" 2019/09/02 18:37:49 [debug] 23137#0: *70 using configuration "=/nginx/hwwc/" 2019/09/02 18:37:49 [debug] 23137#0: *70 http cl:-1 max:1048576 2019/09/02 18:37:49 [debug] 23137#0: *70 http finalize request: 301, "/nginx/hwwc?" a:1, c:1 2019/09/02 18:37:49 [debug] 23137#0: *70 http special response: 301, "/nginx/hwwc?" 2019/09/02 18:37:49 [debug] 23137#0: *70 http set discard body 2019/09/02 18:37:49 [debug] 23137#0: *70 xslt filter header 2019/09/02 18:37:49 [debug] 23137#0: *70 posix_memalign: 000055830C085F80:4096 @16 2019/09/02 18:37:49 [debug] 23137#0: *70 HTTP/1.1 301 Moved Permanently Server: nginx/1.12.2 Date: Mon, 02 Sep 2019 10:37:49 GMT Content-Type: text/html Content-Length: 185 Location: http://t103:8080/nginx/hwwc/ Connection: keep-alive
We can see through the top of the log, nginx in the location "/" and "nginx / hwwc /" is selected, the final choice "nginx / hwwc /", then triggered 301.
Code Analysis
One
According to the top of the log, we locate the following code through the main keyword "test location" and "using configuration":
nginx/src/http/ngx_http_core_module.c::ngx_http_core_find_static_location():1443
if (len + 1 == (size_t) node->len && node->auto_redirect) { r->loc_conf = (node->exact) ? node->exact->loc_conf: node->inclusive->loc_conf; rv = NGX_DONE; }
When the selected location, if a URI string more than a location character string (i.e., "/"), and in front of the characters are the same, while the variable node structure is also true of auto_redirect. He considers the current hit location.
That URI "hwwc" will match an exact match in the inspection of the location to location "hwwc /"
two
nginx/src/http/ngx_http.c::ngx_http_create_locations_tree():1093
node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
|| (lq->inclusive && lq->inclusive->auto_redirect));
Nginx global code in two auto_redirect, a node structure is (a) the other is the structure of the config.
Experience in the node structure by the assignment of the config. As described in that section of code.
three
nginx/src/http/modules/ngx_http_proxy_module.c::ngx_http_proxy_pass():3594
if (clcf->name.len && clcf->name.data[clcf->name.len - 1] == '/') { clcf->auto_redirect = 1; }
config in auto_redirect, upon detection of the location in time "/" at the end, will be automatically assigned auto_redirect is true, and passed to run through (b).
This code is assigned, in addition to the proxy module, and also the presence of fastcgi, grpc, memcached, scgi, uwsgi module.
four
nginx/src/http/ngx_http_core_module.h
struct ngx_http_core_loc_conf_s { ... ... unsigned auto_redirect:1; ngx_flag_t absolute_redirect; /* absolute_redirect */ ngx_flag_t server_name_in_redirect; /* server_name_in_redirect */ ngx_flag_t port_in_redirect; /* port_in_redirect */ ... ... }
nginx/src/http/ngx_http_core_module.c
static ngx_command_t ngx_http_core_commands[] = { { ngx_string("absolute_redirect"), ... ... { ngx_string("server_name_in_redirect"), ... ... { ngx_string("port_in_redirect"), ... ... }
Analysis of code flow configuration. LOCATION associated with the redirect disposed about a total of four, wherein auto_redirect is not configurable. The other three may be provided by the configuration file. However, none of the logical coupling and auto_redirect.
In conclusion. Auto_redirect not be modified through the configuration. Whether the end of the URI of "/" is automatically set.
Confirmed by official documents
View, ngnix official documents, there is the following description for the problem, and has been recommended to keep solving and analysis carried out by our source:
https://nginx.org/en/docs/http/ngx_http_core_module.html#location
If you want to block this redirect issue should be clear on without location "/" is specified.
In addition,
Several configuration mentioned above, there is a configuration in addition to proxy_redirect.
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
By simple tests, we found that under the current scenario, the configuration is not effective. It should be the next scene because we use proxy redirect hair. And this configuration item
Is modified for the backend sent redirect messages.
After reading the code can be confirmed now to do so judged by the black box testing.
other
On serverfault also raised the same question. Unanimous conclusion of our analysis.