Hello,

On 2018-12-14 07:34, Maxim Dounin wrote:
Hello!

On Thu, Dec 13, 2018 at 09:16:12PM -0800, Dave Pedu wrote:

Hello,

I came across some nginx behavior that seems odd to me. In my config, I
have this server block:


     server {
       server_name subdomain.somehostname.com
       listen 443 ssl;
       ssl_certificate     "/some/file.crt";
       ssl_certificate_key "/some/other/file.key";
       ssl_protocols       <redacted>
       ssl_ciphers         <redacted>
return 307 https://anothersubdomain.somehostname.com$request_uri;
     }


I'm using a 307 redirect to cause clients to retry their original
request at the redirected destination, particularly for file uploads.
With the above configuration, client requests regardless of post size - even larger than the default client_max_body_size - are redirected. For
example, a 6MB file upload:


     $ curl -v --data-binary "@5mbRandomData.bin"
'https://subdomain.somehostname.com/upload'
     ...
     > POST /upload HTTP/1.1
     ...
     > User-Agent: curl/7.54.0
     > Content-Length: 6161400
     > Content-Type: application/x-www-form-urlencoded
     > Expect: 100-continue
     >
     < HTTP/1.1 100 Continue
     < HTTP/1.1 307 Temporary Redirect
     < Server: nginx/1.12.2
     < Location: https://anothersubdomain.somehostname.com/upload
     ...


However, when I place the "return" line within a location block as shown
here:


     server {
       server_name subdomain.somehostname.com
       listen 443 ssl;
       ssl_certificate     "/some/file.crt";
       ssl_certificate_key "/some/other/file.key";
       ssl_protocols       <redacted>
       ssl_ciphers         <redacted>
       location / {
           return 307
https://anothersubdomain.somehostname.com$request_uri;
       }
     }


...then clients posting larger than the default client_max_body_size are
sent an error instead. Again, with a 6MB upload:


     $ curl -v --data-binary "@5mbRandomData.bin"
'https://subdomain.somehostname.com/upload'
     > POST /upload HTTP/1.1
     ...
     > User-Agent: curl/7.54.0
     > Content-Length: 6161400
     > Content-Type: application/x-www-form-urlencoded
     > Expect: 100-continue
     >
     < HTTP/1.1 413 Request Entity Too Large
     < Server: nginx/1.12.2


Which seems like correct behavior in contrast to the first example since client_max_body_size must be set to 0 to allow unlimited sized uploads, and the default value is 1m. I didn't see anything in the documentation
about selective application of the body size limit. Is this a bug?

The client_max_body_size limit is only enforced when nginx selects
a location (or when reading the body if Content-Length is not
known in advance).  This is because different limits can be
configured in different locations, so a configuration like

    location / {
        client_max_body_size 1m;
        ...
    }

    location = /upload.cgi {
        client_max_body_size 100m;
        ...
    }

will properly allow uploading of large files via "/upload.cgi",
but will restrict maximum request body size on other requests.

As such, client_max_body_size is only enforced when nginx chooses
some location configuration to work with.  And in your first
configuration the request is answered during processing server
rewrites, before nginx has a chance to select a location.

This is not really important though, since nginx does not try
read a request body in such a case.  Rather, it will discard
anything - much like it will do when returning an error anyway.


That makes sense - I appreciate your reply, Maxim. Is there an area of the documentation that describes this selective enforcement when a location block is not selected? I would like to determine what other options are handled similarly.

Looking at the description of client_max_body_size here [1], the language is quite clear that the setting's value is compared to Content-Length, a header that's present in both situations above, hence my confusion.

Thanks!
Dave

[1] http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size



_______________________________________________
nginx mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx

Reply via email to