Nginx – Apply client_max_body_size for a single URL only

nginx

I want to allow client to upload files on our system, and I want them to be able to upload files larger than the default body set in nginx.

So I've set the following in our site configuration:

client_max_body_size 10m;

So far, so good, but I really only need this larger body size on a single URL; the one users POST to.

So I've tried the following configuration:

location /api/files/ {
  client_max_body_size 10m;
}

But this doesn't work at all, I get the following error in the log:

2016/04/24 13:52:51 [error] 17853#0: *1569513 client intended to send too large body: 1083334 bytes, client: 203.0.113.7, server: example.com, request: "POST /api/files HTTP/1.1", host: "example.com"

So I tried the following change:

location = /api/files {
  client_max_body_size 10m;
}

But this just results in a different error:

2016/04/24 14:25:50 [error] 19500#0: *171 open() "/usr/share/nginx/html/api/files" failed (2: No such file or directory), client: 203.0.113.7, server: example.com, request: "POST /api/files HTTP/1.1", host: "example.com"

This makes me assume that location actually refers to locations on the local file system, even though the documentation says:

Sets configuration depending on a request URI.

So, how do I apply this configuration change for this single request location only?

Best Answer

I think the solution lies in a nested location. So "location /api/files "should be inside your php location block. Your fastcgi config should be inherited to the "files" location.

http://nginx.org/en/docs/http/ngx_http_core_module.html#location

location ~* \.php$ {
     try_files $uri =404;
     fastcgi_pass backend; 
     # [...]

     location /api/files { 
          client_max_body_size 10m;
     }
}

If you have location /api/files outside your php location nginx would find 'api/files' and remember it. But before using it, it would check whether there is a location with a matching regular expression, which would be the php location for php file requests. It would then use the php location and discard 'location api/files'.

Related Topic