Nginx not enforcing default client_max_body_size ?
Maxim Dounin
mdounin at mdounin.ru
Fri Dec 14 15:34:59 UTC 2018
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.
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx
mailing list