Missing $uri when performing proxy_pass?


#1

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


#2

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 D.


#3

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 :slight_smile:

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