11

Original URL: /api/url%2Fencoded%2F/?with=queryParams

nginx:

location /api {
    client_max_body_size 2G;
    proxy_pass https://oursite;
}

With this configuration, I was able to preserve the URL encoding when passing through the proxy. If I add a "/" after "oursite", it will decode the URL.

Problem:

Now the URL after being proxied still contains "/api/". I need to remove "/api/" only while still preserving the URL encoded parts.

Sean Bollin
  • 820
  • 2
  • 9
  • 17

1 Answers1

19

Not a long time ago there was identical question without an answer. In my opinion, you should rething api to not have such weird URLs. Another way is to have api on subdomain. – Alexey Ten Mar 11 '15 at 22:58

stackoverflow.com/q/28684300/1016033 – Alexey Ten Mar 11 '15 at 23:01

Year-old challenge accepted!

    location /api/ {
        rewrite ^ $request_uri;
        rewrite ^/api/(.*) $1 break;
        return 400;
        proxy_pass http://127.0.0.1:82/$uri;
    }

That's it, folks!

More details at Nginx pass_proxy subdirectory without url decoding, but it does work even with the query string, too:

%  curl "localhost:81/api/url%2Fencoded%2F/?with=queryParams"
/url%2Fencoded%2F/?with=queryParams
%
Community
  • 1
  • 1
cnst
  • 23,936
  • 4
  • 83
  • 114
  • For anyone working without nested paths, `location / { proxy_pass http://127.0.0.1$request_uri; }` works fine – diachedelic Oct 11 '17 at 10:33
  • @diachedelic, look at the last control group in [the more details answer](//stackoverflow.com/questions/28684300/nginx-pass-proxy-subdirectory-without-url-decoding/37584637#37584637) — the `$request_uri` in your example is redundant. – cnst Oct 12 '17 at 01:31
  • by gum you're right, my mistake was adding a slash like `proxy_pass http://127.0.0.1/;` which caused nginx to normalize the path (mentioned in docs here: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) – diachedelic Oct 13 '17 at 02:10
  • Same problem here on CentOS 6.4 and nginx 1.10.2. This answer fixed it. Now I'm wondering if latest version of nginx (1.13.9) still have this behaviour. This seems like a workaround not an Nginx classic configuration... – MaX Mar 08 '18 at 17:08
  • @MaX, there is no reason to update us that the behaviour still persists, as this is not a bug in nginx, will never be "fixed". BTW, if the solution is helpful, please don't forget to upvote. – cnst Mar 08 '18 at 18:31
  • I wasn't updating to say the behaviour still persist because I do not know know if it does. I'm just really surprised I could not find an option such as "decode_uri false". – MaX Mar 08 '18 at 20:18
  • 1
    @MaX, look at the linked trac issue from the linked [full "More details…" answer](//stackoverflow.com/questions/28684300/nginx-pass-proxy-subdirectory-without-url-decoding/37584637#37584637); the option you suggest would be a security risk, hence, it's nginx classic configuration to not provide it. There's very limited use case for this, and when it does strike, then the above workaround is 100% doable and is the best choice, really. (Thanks for upvote.) BTW, also, if you don't modify `$uri`, then no decoding is done. And you can't possibly have both without it being a total mess. – cnst Mar 08 '18 at 20:52
  • @cnst Thank you it is more clear now. You said " if you don't modify $uri, then no decoding is done", is it why this "problem" does not exist with location "/" and "proxy_pass http://127.0.0.1;"? – MaX Mar 08 '18 at 21:55
  • @MaX, exactly — as per usual, nginx just always does the right thing (even if at first sight it might not look like the right thing) – cnst Mar 08 '18 at 22:31
  • @cnst Ok thanks. Maybe I did a mistake but do you know why I cannot acces root (http://domain1.com/api/)? It result in Nginx 500 error and logs say "zero length...". I thought the return 400 would avoid that... – MaX Mar 08 '18 at 22:55
  • @cnst No idea? Maybe I misunderstood the return 400 part. – MaX Mar 13 '18 at 16:54
  • One thing here I still don't get it is how can decoding %2F once be a security feature, when you can still penetrate the reverse proxy server with double encoded "/" (%252F) – Norman Xu Dec 04 '18 at 10:27