Opened 7 days ago

Closed 7 days ago

Last modified 4 days ago

#2021 closed defect (invalid)

try_files not always sending full $uri to proxy_pass and upstream

Reported by: bengalih@… Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.17.x
Keywords: Cc:
uname -a: Linux router-asus 2.6.36.4brcmarm #1 SMP PREEMPT Sat Feb 8 13:46:29 EST 2020 armv7l ASUSWRT-Merlin
nginx -V: nginx version: nginx/1.17.7
built by gcc 8.3.0 (OpenWrt GCC 8.3.0 r1148-dbf3d603)
built with OpenSSL 1.1.1d 10 Sep 2019
TLS SNI support enabled
configure arguments: --crossbuild=Linux::arm --with-cc=arm-openwrt-linux-gnueabi-gcc --with-cc-opt='-I/media/ware3/Entware.2020.01/staging_dir/target-arm_cortex-a9_glibc-2.23_eabi/opt/include -I/media/ware3/Entware.2020.01/staging_dir/toolchain-arm_cortex-a9_gcc-8.3.0_glibc-2.23_eabi/include -O2 -pipe -mtune=cortex-a9 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -mfloat-abi=soft -I/media/ware3/Entware.2020.01/staging_dir/target-arm_cortex-a9_glibc-2.23_eabi/opt/include/libxml2 -Wno-error=parentheses -Wno-error=implicit-fallthrough -Wno-error=cast-function-type' --with-ld-opt='-L/media/ware3/Entware.2020.01/staging_dir/target-arm_cortex-a9_glibc-2.23_eabi/opt/lib -Wl,-rpath,/opt/lib -Wl,-rpath-link=/media/ware3/Entware.2020.01/staging_dir/target-arm_cortex-a9_glibc-2.23_eabi/opt/lib -Wl,--dynamic-linker=/opt/lib/ld-linux.so.3 -L/media/ware3/Entware.2020.01/staging_dir/toolchain-arm_cortex-a9_gcc-8.3.0_glibc-2.23_eabi/lib -lxml2' --prefix=/opt --conf-path=/opt/etc/nginx/nginx.conf --http-log-path=/opt/var/log/nginx/access.log --error-log-path=/opt/var/log/nginx/error.log --lock-path=/opt/var/lock/nginx.lock --pid-path=/opt/var/run/nginx.pid --modules-path=/opt/lib/nginx --http-client-body-temp-path=/opt/var/lib/nginx/body --http-fastcgi-temp-path=/opt/var/lib/nginx/fastcgi --http-proxy-temp-path=/opt/var/lib/nginx/proxy --http-scgi-temp-path=/opt/var/lib/nginx/scgi --http-uwsgi-temp-path=/opt/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --without-http_upstream_zone_module --without-stream_upstream_zone_module --with-http_addition_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_random_index_module --with-http_secure_link_module --with-http_sub_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-stream=dynamic --with-stream_ssl_module --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-headers-more-filter --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-auth-pam --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-cache-purge --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-dav-ext --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-ndk --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-echo --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-fancyindex --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/nchan --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-lua --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/rtmp --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-uploadprogress --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-upstream-fair --add-dynamic-module=/media/ware3/Entware.2020.01/build_dir/target-arm_cortex-a9_glibc-2.23_eabi/nginx-1.17.7/modules/http-subs-filter

Description

So I'm dealing with an app that states it needs a configuration block like so (removed tuning settings I believe irrelevant to issue):

server {
    listen 80;
    server_name app1.mydomain.com;
}

location / {
        proxy_pass http://10.10.10.102:8096/;
    }

location /socket {
        proxy_pass http://10.10.102:8096/socket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

When using this configuration, the app functions properly, or specifically in the console logs of the app I see no errors and the sockets that need to be created/accessed are apparently done so. However, my overall nginx config is a bit more complex and I try to standardize and modularize things in a certain way. I have a configuration which looks more like this, using proxy_pass and upstream blocks:

upstream app1_backend {
        server 10.10.10.102:8096;
}

server {
        listen 443 ssl http2;

        server_name app1.mydomain.com;

        location @proxy {
                proxy_pass http://app1_backend;
        }

        location / {
                try_files $uri @proxy;
        }

        location /api {
                try_files $uri @proxy;
        }

        location /socket {
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                try_files $uri @proxy;
        }
}

The above does not work. Namely the application complains that it can't access /socket. If however I change it to the below block, it works:


  location /socket {
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                try_files $uri @proxy/sockets;
        }

I don't believe I should have to append /sockets onto the @proxy statment.
I don't need to do this with the /api location for it to work properly.

Is there something undocumented here, perhaps with setting the http_version or any other explanation of why the entire /socket $uri is not being sent on through the proxy_pass and upstream?

Change History (2)

comment:1 by Maxim Dounin, 7 days ago

Resolution: invalid
Status: newclosed

An obvious problem with your second configuration is that proxy_set_header and proxy_http_version directives are used in the wrong location (not in the location where proxying configured), hence they won't do anything. Most likely your application won't work without these directives used when proxying, so complaints from the application are expected.

No idea why the third configuration works for you, as it is expected to return 500 (Internal Server Error) error when requesting non-existent files within /socket, since there is no "@proxy/sockets" named location in your configuration.

Note well that your original configuration is actually expected to be much more robust and effective than your attempts to "modularize" things. Check out Igor Sysoev's talk Scaleable NGINX Configuration if you are interested.

If you have further questions on how to configure nginx, consider using support options available.

comment:2 by bengalih@…, 4 days ago

Maxim,

Thanks for your comments. I will definitely watch the Scaleable video to see how I might improve my configurations.

I just wanted to add closure that I am not actually sure the third configuration was working, as I got the same feedback from the app logs as if I had an empty socket location like this:

 location /socket {
        }

When viewing the NGINX logs, I could still see 404 errors when hitting the empty location, but the app apparently didn't log/complain which is why I thought it was functioning properly.

Also thanks for pointing out the wrong location of the proxy commands, I had overlooked that when I did some refactoring.

Note: See TracTickets for help on using tickets.