Nginx not enforcing default client_max_body_size ?

Maxim Dounin mdounin at mdounin.ru
Fri Dec 14 17:57:40 UTC 2018


Hello!

On Fri, Dec 14, 2018 at 09:24:04AM -0800, Dave Pedu wrote:

> 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.

I don't think it is documented anywhere, as this is mostly an 
implementation detail.

-- 
Maxim Dounin
http://mdounin.ru/


More information about the nginx mailing list