undoing rewrite (for proxy_pass)
Thorben Thuermer
thuermer at veeseo.com
Mon Feb 27 17:45:16 UTC 2012
Hello,
i recently tried to set up nginx as reverse-proxy in front of apache
to offload serving of cached static versions of pages,
where i needed to apply a rewrite to construct the local path of the
cache files:
* receive incoming requests
* apply a rewrite-rule, use try_files to serve files if they exist
* otherwise proxy_pass the original request to apache
the problem i ran into was, that i needed to pass the original unprocessed
request to apache, as it may contain script parameters that get broken by
processing.
(the best reference to this issue that i found is this:
http://mailman.nginx.org/pipermail/nginx/2010-April/019905.html )
as i do not even need to forward a rewritten version,
this solution should apply:
"If it is necessary to transmit URI in the unprocessed form then directive
proxy_pass should be used without URI part:"
-- http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass
but this does not work anymore after a rewrite was applied, as the
rewritten version will be transmitted.
the natural method to undo a rewrite would appear to be:
rewrite .* $request_uri break;
but this replaces the request with a processed version!
i found the code for constructing the request in:
src/http/modules/ngx_http_proxy_module.c:ngx_http_proxy_create_request
the if-block starting at line ~910 appears to pick the request-uri
to be used in the request.
there the problem appears to be that r->valid_unparsed_uri is no longer
set after rewrites were applied, so it will never choose to use the
unparsed uri!
i simply ignored r->valid_unparsed_uri, and replaced the whole block with:
unparsed_uri = 1;
uri_len = r->unparsed_uri.len;
and now my reverse-proxying works as required.
(ofcourse i broke the other cases by hardcoding this, but that's not an
issue for me.)
i am wondering if there might be interest in including a proper solution
for this situation in nginx.
(or maybe there is one already and i missed it?)
Greetings,
Thorben Thuermer
VSEO GmbH
PS1:
when working on this, i spent most time on finding out how to get nginx
running in gdb - is there some introduction to development documentation
where such information might be found/useful?
PS2:
before anybody asks, the configuration:
server {
listen 1.2.3.4:80;
server_name ...;
root /var/www/...;
location / {
rewrite "^(lots of stuff here)$" /cache/(lots of submatches) break;
try_files $uri $uri/ @apache;
}
location @apache {
rewrite ^(.*)$ $request_uri break; # useless
proxy_pass http://localhost;
}
}
More information about the nginx
mailing list