Opened 2 years ago

Closed 2 years ago

#645 closed defect (fixed)

proxy_pass does not work as expected in if context

Reported by: wangxiaochen0@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.7.x
Keywords: Cc:
Sensitive: no
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@… 2 years ago.
nginx-proxy.patch (1.3 KB) - added by alexey.radkov@… 2 years ago.

Download all attachments as: .zip

Change History (6)

Changed 2 years ago by alexey.radkov@…

comment:1 Changed 2 years ago by alexey.radkov@…

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.

Changed 2 years ago by alexey.radkov@…

comment:2 Changed 2 years ago by alexey.radkov@…

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 Changed 2 years ago by Maxim Dounin <mdounin@…>

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 Changed 2 years ago by mdounin

  • Resolution set to fixed
  • Status changed from new to closed

Fix committed, thanks.

Note: See TracTickets for help on using tickets.