Opened 9 years ago
Closed 9 years ago
#874 closed defect (wontfix)
Incorrect $upstream_http_location value
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | 1.9.x |
Keywords: | Cc: | ||
uname -a: | Linux node.airee.ru 2.6.32-504.23.4.el6.centos.plus.x86_64 #1 SMP Wed Jun 10 13:09:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.9.5
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --add-module=/root/ngx_pagespeed-release-1.7.30.2-beta --add-module=/root/ngx_devel_kit --add-module=/root/set-misc-nginx-module --add-module=/root/nginx-length-hiding-filter-module --add-module=/root/nginx-http-rdns --add-module=/root/ngx_http_substitutions_filter_module --with-cc-opt='-DNGX_HAVE_ACCEPT4=0 -DTCP_FASTOPEN=23 -O2 -fomit-frame-pointer' --with-ipv6 --with-http_gunzip_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_sub_module --without-http_geo_module --without-http_access_module --without-http_auth_basic_module --without-http_autoindex_module --without-http_empty_gif_module --without-http_memcached_module --without-http_referer_module --without-http_scgi_module --without-http_split_clients_module --without-http_uwsgi_module |
Description
While accessing $upstream_http_location after proxied request it contains \x00AB at the end (it seems AB are the last 2 symbols of actual $upstream_http_location).
Example (response headers):
< HTTP/1.1 302 Moved Temporarily
< Date: Wed, 06 Jan 2016 13:32:43 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Location: http://xn--80aqc2a.xn--p1ai/loop.redirects.php
< Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval' < UpstreamHTTPLocation: http://xn--80aqc2a.xn--p1ai/loop.redirects.phphp
\x00hp are added to current upstream Location HTTP header
Change History (7)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
Yes, it seems proxy_redirect breaks the variable $upstream_http_location. Without this directive Location is modified accordingly to actual port requested:
http://xn--80aqc2a.xn--p1ai:81/loop.redirects.php
So proxy_redirect fixes the port (:81 -> ""), but breaks the variable. Can you please fix this?
comment:3 by , 9 years ago
As previously explained, this is an optimization to avoid an extra memory allocation. If it's the problem in your use case, please provide more details on how you use $upstream_http_location. We can consider removing the optimization if causes more harm than good.
comment:4 by , 9 years ago
Can you please just fix the length of variable (it's incorrect after optimization)? You shouldn't remove the optimization itself.
Use case: set cookie with Location header value to prevent loop redirects or fix them somehow (with client cookie with previous Location sent). Now the previous Location (from cookie) doesn't concide with current Location (from upstream variable).
comment:5 by , 9 years ago
Correct changed value is available via the $sent_http_location variable, consider using it instead.
comment:6 by , 9 years ago
Good idea. But suddenly access to $sent_http_location breaks (nulls) it.
I.e.
add_header X-Location $sent_http_location;
OK
set $stored_http_location $sent_http_location;
add_header X-Location $sent_http_location;
Nothing
add_header X-Location $sent_http_location;
if ($sent_http_location = 'redirect.value')
{
return 503;
}
Nothing
This happens both with upstream_ and sent_ variables. So it's not the initial topic (Initial topic solution - to use sent_ variables instead of upstream_) but another question (or issue?).
comment:7 by , 9 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
The "set" and "if" directives cannot be used to modify variables not yet available when these directives are executred. The directives are executed when nginx selects a location to handle the request, see docs. The $sent_*
variables are only available when the response is actually being sent, and this happens later. Using not-yet-available variables will result in an empty value being cached, and this is what breaks things for you.
The $sent_*
variables, however, can be used in the add_header
when response is being returned and response headers are already known. If needed, it can be modified using variable-based processing, e.g., map or perl_set.
When the proxy_redirect directive is used to rewrite returned Location headers, it does the replacement in place if possible, overwriting original value of the header as available via the $upstream_http_location variable. This is an optimization to avoid an extra memory allocation.
If it's the problem in your use case, please provide more details on how you use $upstream_http_location. We can consider removing the optimization if causes more harm than good.