Opened 5 years ago

Closed 5 years ago

#645 closed defect (fixed)

proxy_pass does not work as expected in if context

Reported by: Xiaochen Wang Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.7.x
Keywords: Cc:
uname -a:
nginx -V: nginx version: nginx/1.7.7
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-52)
TLS SNI support enabled
configure arguments: --with-debug --prefix=/path/to/hg-nginx-output --with-http_spdy_module --with-cc-opt=-O0 --with-http_ssl_module --with-openssl=/path/to/openssl-1.0.1h

Description

With nginx configure as following, if requesting uri '/?test=1', nginx proxy this request to 127.0.0.1:8082, not 127.0.0.1:8083.

    server {
        listen 80;
        location / {
            if ($arg_test) {
                proxy_pass http://127.0.0.1:8083;
            }
            set $p 8082;
            proxy_pass http://127.0.0.1:$p;
        }
    }

Another example as following, if requesting uri '/?test=1', nginx proxy this request with ssl enabled, which is not as expected.

    server {
        listen 80;
        location / {
            if ($arg_test) {
                proxy_pass http://127.0.0.1:8083;
            }
            proxy_pass https://127.0.0.1:8083;
        }
    }

Attachments (2)

nginx-proxy-patch-test.conf (2.2 KB ) - added by Alexey Radkov 5 years ago.
nginx-proxy.patch (1.3 KB ) - added by Alexey Radkov 5 years ago.

Download all attachments as: .zip

Change History (6)

by Alexey Radkov, 5 years ago

Attachment: nginx-proxy-patch-test.conf added

comment:1 by Alexey Radkov, 5 years ago

Hi.

Just 2 days ago i put a comprehensive article about why it happens in my blog (see http://lin-techdet.blogspot.ru/2014/10/nginx-proxypass.html) (it is written in Russian!).

I attached a patch against version 1.7.6 that solves the issue and a configuration for testing it.

Cheers, Alexey.

by Alexey Radkov, 5 years ago

Attachment: nginx-proxy.patch added

comment:2 by Alexey Radkov, 5 years ago

I updated the patch because the previous one did not respect cases when there were no new proxy_pass directive declaration in if-block. Current logic is as simple as:

  1. Try to inherit proxy_lengths and proxy_values only if upstream.upstream is NULL
  2. If both proxy_lengths/proxy_values and upstream.upstream are NULL (the case when proxy_pass is not defined again in if-block) then all must be tried to inherit (same behaviour as before the patches).
  3. If upstream.ssl is NULL then it must be inherited only if upstream.upstream is NULL (because in case of proxy_lengths it is always set).

comment:3 by Maxim Dounin <mdounin@…>, 5 years ago

In 5b9f711dc819466a023c2f7e849569987474e8d7/nginx:

Upstream: inheritance of proxy_pass and friends (ticket #645).

Instead of independant inheritance of conf->upstream.upstream (proxy_pass
without variables) and conf->proxy_lengths (proxy_pass with variables)
we now test them both and inherit only if neither is set. Additionally,
SSL context is also inherited only in this case now.

Based on the patch by Alexey Radkov.

comment:4 by Maxim Dounin, 5 years ago

Resolution: fixed
Status: newclosed

Fix committed, thanks.

Note: See TracTickets for help on using tickets.