2

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?

1

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

  • Indeed, it seems it's not working for me for the same reason. So, what's the solution? Duplicate the complete content of my main location block? – Der Hochstapler Apr 25 '16 at 10:13
  • Sorry for lots of edits. – JosefScript Apr 25 '16 at 14:42
  • From what I can tell (and what my tests seemed to confirm), nested location blocks don't inherit (all) settings from their "parent". The only real solution seems to be duplication, which can be abstracted with includes. Either way, you were correct. What I found particularly helpful in debugging this was to use add_header X-Location foo to mark which location was picked. – Der Hochstapler Apr 25 '16 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.