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