Proxy_pass with variable removes uri

Hi,
I have a conf with two virtual hosts and a proxy-pass that is dependent
on
which host the request arrived to, like this:

server {
    listen 80;
    server_name x.com y.com;
    resolver 8.8.8.8;
    root /var/www/html;

    location / {
  # whatever
    }

    location /api/ {
        proxy_pass http://api.$host/;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
    }
}

Note the trailing “/” on proxy_pass which should forward the uri
untouched,
stripping out “/api”. However, the uri is not forwarded at all, e.g. GET
http://x.com/api/somehing is forwarded to api.x.com without the
“/something”
part.
But, if I hard code the proxy_pass url, like this:
proxy_pass http://api.x.com/;
it works, the uri is properly forwarded.

Doesn’t proxy_pass have proper support for variables or have I done
something wrong?

Many thanks / Jonas

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,248124,248124#msg-248124

Hello!

On Wed, Mar 05, 2014 at 05:47:58AM -0500, luckyswede wrote:

    location / {

Note the trailing “/” on proxy_pass which should forward the uri untouched,
stripping out “/api”. However, the uri is not forwarded at all, e.g. GET
http://x.com/api/somehing is forwarded to api.x.com without the “/something”
part.
But, if I hard code the proxy_pass url, like this:
proxy_pass http://api.x.com/;
it works, the uri is properly forwarded.

Doesn’t proxy_pass have proper support for variables or have I done
something wrong?

The “proxy_pass” directive, if used with variables, specifies
full URI to request, see http://nginx.org/r/proxy_pass:

: A server name, its port and the passed URI can also be specified
: using variables:
:
: proxy_pass http://$host$uri;
:
: or even like this:
:
: proxy_pass $request;


Maxim D.
http://nginx.org/

On Wednesday 05 March 2014 05:47:58 luckyswede wrote:

    location / {

Note the trailing “/” on proxy_pass which should forward the uri untouched,
stripping out “/api”. However, the uri is not forwarded at all, e.g. GET
http://x.com/api/somehing is forwarded to api.x.com without the “/something”
part.
But, if I hard code the proxy_pass url, like this:
proxy_pass http://api.x.com/;
it works, the uri is properly forwarded.

Doesn’t proxy_pass have proper support for variables or have I done
something wrong?
[…]

If variables are used in proxy_pass, then a full path should be
specified.

For example: proxy_pass http://api.$host$uri;

wbr, Valentin V. Bartenev

Hi,
I’ve had troubles with url-decoding using this kind configuration, e.g.
get
variables with values containing spaces have been decoded before proxied
which is resulting in an error.
For example I’ve tried:
location ~ ^/api/(.*) {
proxy_pass http://api.$host/$1$is_args$args;
}
but that gives an error if the uri is urlencoded.

Any ideas?

BR / Jonas

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,248124,248129#msg-248129

Thanks,
But I want to automatically remove the “/api” part, just as it does if I
don’t use variables.
So that isn’t possible?

BR / Jonas

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,248124,248128#msg-248128

Also, I want to make use of a resolver, which requires variables in the
proxy_pass directive. Does this mean that it is not possible to
automatically “strip” out the leading “/api” (which seems to not work
with
variables) and using resolvers (which requires variables)?

BR / Jonas

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,248124,248130#msg-248130

Hello!

On Wed, Mar 05, 2014 at 07:23:23AM -0500, luckyswede wrote:

Any ideas?
When using variables you are responsible for proper encoding of
URIs used.

If you really want to use proxy_pass with variables, try this
instead:

location /api/ {
    rewrite ^/api(/.*) $1 break;
    proxy_pass http://api.$host;
}

It relies on the fact that if there is no URI at all, original
request uri will be used.

Though I would recommend using hardcoded name instead. Note that
using proxy_pass with variables implies various other side
effects, notably use of resolver for dynamic name resolution, and
generally less effective than using names in a configuration.


Maxim D.
http://nginx.org/

On Wed, Mar 05, 2014 at 07:23:23AM -0500, luckyswede wrote:

Hi there,

I’ve had troubles with url-decoding using this kind configuration, e.g. get
variables with values containing spaces have been decoded before proxied
which is resulting in an error.

Untested, but I’d suggest to use a map (http://nginx.org/r/map) to save
the part of $request_uri that you want to use in the proxy_pass url.

It may become complicated if you want to handle people requesting things
like /ap%69/stuff, but otherwise should probably work.

(The alternative is probably to use a url encoder on the appropriate
parts of your url; I don’t know of one that drop-in works.)

f

Francis D. [email protected]

Cool, that works!
I don’t understand why though, why is the uri urldecoded in my example
but
not in your example?

Also, I actually want the dns resolution to take place because I’m
running
in an AWS environment…

Thanks / Jonas

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,248124,248134#msg-248134

Hello!

On Wed, Mar 05, 2014 at 07:46:38AM -0500, luckyswede wrote:

Cool, that works!
I don’t understand why though, why is the uri urldecoded in my example but
not in your example?

In your config, URI is defined using variables, and your are
responsible for proper urlencoding. Config suggested by me uses
proxy_pass without URI component (which uses request URI, even with
variables), and a rewrite to change request URI - hence nginx does
appropriate urlencoding.


Maxim D.
http://nginx.org/

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs