Forum: NGINX proxy_pass with variable removes uri

2974d09ac2541e892966b762aad84943?d=identicon&s=25 luckyswede (Guest)
on 2014-03-05 11:48
(Received via mailing list)
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
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2014-03-05 12:22
(Received via mailing list)
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 Dounin
http://nginx.org/
40b4c848b8fcd63b0cb60b9d170c3a77?d=identicon&s=25 Valentin V. Bartenev (Guest)
on 2014-03-05 12:23
(Received via mailing list)
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
2974d09ac2541e892966b762aad84943?d=identicon&s=25 luckyswede (Guest)
on 2014-03-05 12:29
(Received via mailing list)
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
2974d09ac2541e892966b762aad84943?d=identicon&s=25 luckyswede (Guest)
on 2014-03-05 13:23
(Received via mailing list)
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
2974d09ac2541e892966b762aad84943?d=identicon&s=25 luckyswede (Guest)
on 2014-03-05 13:26
(Received via mailing list)
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
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2014-03-05 13:34
(Received via mailing list)
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 Dounin
http://nginx.org/
36a8284995fa0fb82e6aa2bede32adac?d=identicon&s=25 Francis Daly (Guest)
on 2014-03-05 13:43
(Received via mailing list)
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 Daly        francis@daoine.org
2974d09ac2541e892966b762aad84943?d=identicon&s=25 luckyswede (Guest)
on 2014-03-05 13:46
(Received via mailing list)
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
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2014-03-05 14:42
(Received via mailing list)
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 Dounin
http://nginx.org/
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.