Opened 9 years ago

Last modified 4 years ago

#712 accepted defect

limit_conn and internal redirects

Reported by: Alex Habarov Owned by:
Priority: trivial Milestone:
Component: documentation Version:
Keywords: limit_conn index x-accel-redirect Cc:
uname -a: Linux alex-home 3.13.0-44-generic #73-Ubuntu SMP Tue Dec 16 00:23:46 UTC 2014 i686 i686 i686 GNU/Linux
nginx -V: nginx version: nginx/1.4.6 (Ubuntu)
built by gcc 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/ --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_spdy_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --add-module=/build/buildd/nginx-1.4.6/debian/modules/nginx-auth-pam --add-module=/build/buildd/nginx-1.4.6/debian/modules/nginx-dav-ext-module --add-module=/build/buildd/nginx-1.4.6/debian/modules/nginx-echo --add-module=/build/buildd/nginx-1.4.6/debian/modules/nginx-upstream-fair --add-module=/build/buildd/nginx-1.4.6/debian/modules/ngx_http_substitutions_filter_module


It seems that limit_conn is only checked at the beginning of the request processing and is ignored in other processing stages. This sometimes results in somewhat unanticipated behaviour when dealing with internal redirects.

Consider an example:

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    listen       80;

    index index.html;

    limit_conn addr 20; # first rule

    location / {
        limit_conn addr 10; # second rule
        root /var/www;

Since any request ends up in the only defined location, one would expect that the second rule would always be used. However, only the first rule is applied if we try to request (that is, without relative reference part). If we move index directive inside the location though, the second rule will be used without exception.

This may not be exactly a bug, but if this behaviour is "by design" some additional explanation might be worth mentioning in the documentation.

Change History (2)

comment:1 by Maxim Dounin, 9 years ago

In the configuration provided the limit_conn addr 10; rule will be used, as request to is actually a request to "/" on the port 80 of the server.

In general you are right though, limit_conn (and limit_req) limits won't be re-applied if they were already
checked for a request, e.g.:

location = / {
    # this limit will be used for a request to '/'
    limit_conn foo 10;

location = /index.html {
    # the request will be redirected to /index.html, 
    # but this limit won't be used

    limit_conn bar 20;

This behaviour is by design, though in some configurations this may be a bit confusing. Probably this deserves an additional note in the documentation.

comment:2 by Maxim Dounin, 9 years ago

Component: nginx-moduledocumentation
Status: newaccepted
Note: See TracTickets for help on using tickets.