Forum: NGINX missing $uri when performing proxy_pass ??

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Aadb127e483a6e92716c510c77745880?d=identicon&s=25 Thomas Mangin (Guest)
on 2009-02-06 02:17
(Received via mailing list)
Hello,

I think I hit a bug (and found a workaround) however as I may be
mistaken, I would appreciate if someone could review this and let me
know if the behaviour observed is normal or not.

I am going to use NGINX to perform per cookie load distribution. The
first request hit a backend using an upstream list, which then set a
cookie used to re-route the following requests to the same machine.

When testing the configuration below, the server correctly set the
cookie. From that point on all the request for subsequent pages are
passing via the name stored in the cookie which cause NGINX to create
invalid proxy_pass requests !

Here is the initial request :

GET /roundcube/ HTTP/1.1.
Host: webmail.domain.com.
[....]

which cause NGNIX to generate the following request :

GET  HTTP/1.0.
Host: webmail.domain.com.
[...]

For some reason the URI is not set between the GET and the HTTP/1.0 !
(tested with 0.6.35)

Here is the configuration causing this behaviour

http {
   upstream roundcube {
     server 127.0.0.0.1;
     .......
   }

   proxy_set_header    Host      $host;
   proxy_set_header    X-Real-IP    $remote_addr;
   proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;

   proxy_redirect  off;

   server {
     listen 1.2.3.4:80;

     server_name   webmail.domain.com;

     # Attempt to cluster roundcube, each webserver running it set a
cookie once auth.
     # This allow to get following connection to the same machine
     location / {
         set $backend "";

         if ($http_cookie ~* "cluster_id=([^;]+)(?:;|$)" )
         {
             set $backend $1;
         }
         if ($backend ~* "backend[0-9]+.domain.com")
         {
             proxy_pass http://$backend;
             break;
         }
         proxy_pass http://roundcube;
         break;
     }
   }
}

I got around the problem by changing the proxy_pass for http://
$backend/$uri but it was my impression that this should not be needed
as without trailing / the uri would be appended.

Not to help, I have been unable to access the english wiki for the
last two days.

Regards,

Thomas Mangin
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2009-02-06 02:59
(Received via mailing list)
Hello!

On Fri, Feb 06, 2009 at 01:06:37AM +0000, Thomas Mangin wrote:

> I think I hit a bug (and found a workaround) however as I may be
> mistaken, I would appreciate if someone could review this and let me
> know if the behaviour observed is normal or not.

[...]

> I got around the problem by changing the proxy_pass for http://
> $backend/$uri but it was my impression that this should not be needed as
> without trailing / the uri would be appended.

No.  There are 3 forms of proxy_pass currently:

    proxy_pass http://backend;
    proxy_pass http://backend/path/;
    proxy_pass http://$variables;

First two forms will append uri automatically (without or with
modifications of part matching current location).  In the third
form, i.e. if variables used, it's you responsibility to construct
full valid uri.

BTW, http://$backend/$uri is actually wrong (extra '/', no query string,
and $uri is unescaped - this sometimes matters).  Better use
something like

    proxy_pass http://$backend$request_uri;

Maxim Dounin
Aadb127e483a6e92716c510c77745880?d=identicon&s=25 Thomas Mangin (Guest)
on 2009-02-06 10:21
(Received via mailing list)
Hello Maxim,

>
> BTW, http://$backend/$uri is actually wrong (extra '/', no query
> string,
> and $uri is unescaped - this sometimes matters).  Better use
> something like
>
>    proxy_pass http://$backend$request_uri;

Thank you for the clarification and the fix, it confused the hell out
of me :)

For some reason I expected the $request_uri to be appended if no
path / uri was passed and I can still not see why it should be as
otherwise nginx is sending an invalid request anyway (GET HTTP/1.0),
so it can not break existing configuration and would make the
behaviour more consistent and predictable.

Could you share some light on the reason for this special case please
(if you know of one) ?

Thomas
This topic is locked and can not be replied to.