disable request body buffering for file upload

Maxim Dounin mdounin at mdounin.ru
Wed Jul 19 14:59:51 UTC 2017


Hello!

On Wed, Jul 19, 2017 at 10:33:01AM -0400, garyc wrote:

> Hello, hopefully someone can tell me if i am attempting the impossible. 
> 
> We use nginx and php5-fpm to handle the upload of test files used by our web
> app that may be several gigabytes in size. 
> 
> To achieve this we use a location block for the upload url and define the
> fastcgi_pass directive to provide the location of the fastcgi socket i.e.
> 
> location /api/filter/analysis/upload {
>    fastcgi_pass unix:/tmp/php5-fpm.sock;
>    include fastcgi_params;
>    fastcgi_params SCRIPTFILENAME $document_root/PHP/uploadFile.php;
> }
> 
> The above configuration functions however we have observed that nginx will
> cache the entire request body before calling the php script which
> effectively copies the uploaded temporary file to a different location. 
> 
> Under certain circumstances this can be a major issue for us as our host
> environment is within an instrument that is designed to capture data
> continuously and will fill the hard drive close to 100% capacity before
> stopping. If a user instigates the upload of a 1gb file that is cached first
> by nginx and then copied elsewhere by the php script we can find ourselves
> out of disk space at which point nginx (and other processes) understandably
> stops functioning leaving the instrument in a state that is difficult to
> recover from.
> 
> If we can prevent nginx from caching the entire request body and have it
> pass it straight to our php script we should be able to take preventative
> steps in the script and reject the upload attempt if disk space is too low.
> 
> I have looked at the directives 'proxy_request_buffering off;' and
> 'fastcgi_request_buffering off;' however i have not been successful in
> stopping the initial nginx upload before our php script is called.

With "fastcgi_request_buffering off;" nginx will send the request 
body to the FastCGI application immediately, without trying to 
buffer it anywhere.

An example configuration:

    location / {
        fastcgi_pass 127.0.0.1:10002;
        fastcgi_request_buffering off;
    }

It is up to your FastCGI application to handle this though, 
and PHP as well as PHP-FPM may impose additional limitations 
and/or require additional configuration for this to work.

> If this is the wrong approach can anyone suggest a different one? basically
> we need to intercept the file upload request and reject it if we are too low
> on disk space the current setup effectively uploads the file before we can
> perform such a check.

Doing such checks in nginx (for example, you can use embedded perl 
to do such checks) and/or keeping client_max_body_size low enough might 
be a better solution.  Nevertheless, fastcgi_request_buffering is 
expected to work as well.

-- 
Maxim Dounin
http://nginx.org/


More information about the nginx mailing list