Opened 11 years ago

Closed 11 years ago

Last modified 8 years ago

#388 closed defect (duplicate)

nginx proxy pass and CROS(cross-origin resource sharing)

Reported by: peng yuehui Owned by:
Priority: minor Milestone: 1.5
Component: nginx-module Version: 1.2.x
Keywords: CROS proxy pass Cc:
uname -a: 2.6.32-220.13.1.el6.x86_64 #1 SMP Tue Apr 17 23:56:34 BST 2012 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.2.1
built by gcc 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/home/work/nginx/ --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_sub_module --add-module=../extra_modules/ngx_consistent_hash --add-module=../extra_modules/ngx_devel_kit --add-module=../extra_modules/set-misc-nginx-module --add-module=../extra_modules/ngx_healcheck

Description

I configed nginx to combine the CROS config and the proxy pass.

When I use 'if' statement to judge whether the domain is allowed to CROS, the proxy pass worked badly, It added another suffix to the origin url. Details see the following config snippet and explanation. I think the 'if' statement has some defects, hope you can fix it.

The config1 will get the right results, the config2 will add another "resource" path to the end of /sync/resource, like /sync/resource/resource, this leading to backend not response it. The if statement is true, I direct return 200 will see the origin headers existing, but why when I added the 'if' statement , the behavior of proxy pass changed.

config1
<snippet>

location /resource {

add_header 'Access-Control-Allow-Methods' 'GET,POST,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Headers' 'WD-Since,WD-Start,WD-Direction,WD-Length,WD-Ids,Content-Type,WD-Client-Id';
add_header 'Access-Control-Expose-Headers' 'WD-Total-Length,WD-Phone-Modal,WD-Client-Id,WD-Udid,WD-Need-More';
proxy_cache off;
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_pass http://sync-nodes/sync/resource;

}

</snippet>

config2
<snippet>

location /resource {

if ($http_origin ~* "https?:.*\.XXXX\.com") {

add_header 'Access-Control-Allow-Methods' 'GET,POST,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Headers' 'WD-Since,WD-Start,WD-Direction,WD-Length,WD-Ids,Content-Type,WD-Client-Id';
add_header 'Access-Control-Expose-Headers' 'WD-Total-Length,WD-Phone-Modal,WD-Client-Id,WD-Udid,WD-Need-More';

}
proxy_cache off;
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_pass http://sync-nodes/sync/resource;

}

</snippet>

Change History (2)

comment:1 by Maxim Dounin, 11 years ago

Resolution: duplicate
Status: newclosed

This is one of the known problems with the "if" directive used in a location context, see ​http://wiki.nginx.org/IfIsEvil. Reduced test case is as follows (copied from the wiki page in question):

        # request will be sent to backend without uri changed
        # to '/' due to if
 
        location /proxy-pass-uri {
            proxy_pass http://127.0.0.1:8080/;
 
            set $true 1;
 
            if ($true) {
                # nothing
            }
        }

Closing this ticket as duplicate as we already have a ticket in track about various "if" directive problems, see #86.

comment:2 by Maxim Dounin, 8 years ago

sensitive: 10
Note: See TracTickets for help on using tickets.