7

I need to pass some requests to proxy (running GlassFish) with removing one section of url. For example:

https://xxx.net/jazz/MobileApi?id=2&make_id=4

Should be passed to proxy as:

http://X.X.X.X:8080/MobileApi?id=2&make_id=4

I have following Nginx configuration:

upstream vito_api {
    server 178.63.X.X:8080;
}

server {
    listen 80;
    listen 443 ssl;
    ....

    location ~ /jazz/(?<section>.*) {
       proxy_pass http://vito_api/$section/;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

But, unfortunately, request passing without parameters. So, in GlassFish access logs, I can see only:

"148.251.X.X" "NULL-AUTH-USER" "05/Jan/2015:15:18:40 +0100" "GET /MobileApi/ HTTP/1.0" 200 21

What I did wrong? How to pass URL parameters too?

Thank you.

Xavier Lucas
  • 12,815
  • 2
  • 44
  • 50
Andrey
  • 173
  • 1
  • 1
  • 6

4 Answers4

8

From nginx's documentation (context : prefixed location)

If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive.

So it can be simplified with the following :

location /jazz/ {
    proxy_pass http://vito_api/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Xavier Lucas
  • 12,815
  • 2
  • 44
  • 50
  • 1
    This did it for me, however, maybe you can give a clarification to help with this case: `https://example.net/jazz/asdf` redirects to `https://example.net/asdf/` instead of `https://example.net/jazz/asdf/`. I assume that I may have to tweak the proxied application to not redirect non-trailing-slashed URLs to append a `/`. – Kevin Apr 11 '16 at 19:58
  • 1
    In case anyone else is stumped by this, it's important to note that this only works if your `proxy_pass` value contains no variables. – Wes Cossick Aug 24 '20 at 20:26
  • Thanks @WesCossick I wasted hours trying to understand why it wasn't working, turns out because of variables!!! (which I had to use to another problems). – th3n3rd Jul 19 '22 at 12:00
7

I know this is an old question but I was looking for this and found another and I belive the easiest solution. While using proxy_pass you can't use uri however you can use it as variable. Like here:

location  ~ ^/app/(.*)$ {
# proxy_pass   http://127.0.0.1/some_dir;       # error
proxy_pass   http://127.0.0.1/some_dir/$1;      # ok
}
Donm
  • 71
  • 1
  • 2
2

For your question, this will work for you. Use regex.

location ^~ /jazz/ {
    rewrite ^/jazz/(.*)$ /$1? break;
    proxy_pass http://vito_api;
}
georgexsh
  • 133
  • 5
-1

Andrey, this will not work. Keep it simple :)

According to nginx docs:

In some cases, the part of a request URI to be replaced cannot be determined:

When location is specified using a regular expression. In this case, the directive should be specified without a URI.

So, please,

proxy_pass http://vito_api;
yagmoth555
  • 16,300
  • 4
  • 26
  • 48
  • 1
    The issue is not the URI in the proxy_pass directive. He misses $is_args$args at the end of the URI and has a trailing slash to be removed. But it can be simplified by using a standard prefixed location, see my answer. – Xavier Lucas Jan 05 '15 at 20:20