I have nginx location directive which purpose is to "remove" localization prefix from the URI for the proxy_pass directive.
For example, to make URI http://example.com/en/lalala use proxy_pass http://example.com/lalala
location ~ '^/(?<locale>[\w]{2})(/(?<rest>.*))?$' {
        ...
        proxy_pass http://example/$rest;
        ...
}
This way the rest variable will be decoded when passed to proxy_pass directeve. It seems to be an expected behavior.
The problem is when my URI contains encoded space %20 passed from client
http://example.com/lala%20lala
nginx decodes URI to
http://example.com/lala lala
I can see it in my error.log.
The question is - is it possible do use encoded rest variable somehow as it is passed from client?
If I am doing something completely wrong, please, suggest the right way.
Thank you.
I have had some success using the following with Confluence and other Atlassian applications behind nginx where special characters such as ( ) < > [ ] were causing issues.
location /path {
  # [... other proxy options ...]
  # set proxy path with regex
  if ($request_uri ~* "/path(/.*)") { 
    proxy_pass http://server:port/path$1;
    break;
  }
  # fallback (probably not needed)
  proxy_pass http://server:port/path;
}
                        Yes, this behaviour is expected although docs also say:
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI:
location /some/path/ {
    proxy_pass http://127.0.0.1;
}
Nginx engineers say the same: https://serverfault.com/questions/459369/disabling-url-decoding-in-nginx-proxy
However if you append $request_uri to proxy_pass (and strip locale beforehand it may work as said by Nginx engineer):
set $modified_uri $request_uri;
if ($modified_uri ~ "^/([\w]{2})(/.*)") {
set $modified_uri $1;
}
proxy_pass http://example$modified_uri;
                        The set directive can do the trick. It keeps the encoding intact or rather encodes decoded string.
location ~ '^/(?<locale>[\w]{2})(/(?<rest>.*))?$' {
        ...
        set $encoded_rest $rest
        proxy_pass http://example/$encoded_rest;
        ...
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With