How to disable output buffering with PHP and nginx

Ben Johnson ben at indietorrent.org
Thu Oct 10 15:13:40 UTC 2013



On 10/8/2013 11:48 AM, Maxim Dounin wrote:
> Hello!
> 
> On Mon, Oct 07, 2013 at 10:57:14PM -0400, B.R. wrote:
> 
> [...]
> 
>> I then noticed on the capture that PHP was rightfully sending the content
>> in 2 parts as expected but somehow nginx was still waiting for the last
>> parto to arrive before sending content to the client.
> 
> What makes you think that nginx was waiting for the last part 
> without sending data to the client?
> 
> Please note that checking by a browser as in your check list isn't 
> something meaningful as browsers may (and likely will) wait for a 
> complete response from a server.  In my limited testing on 
> Windows, IE needs a complete response, while Chrome shows data on 
> arrival.
> 
> Just in case, it works fine here with the following minimal 
> config:
> 
>     events {}
>     http {
>         server {
>             listen 8080;
>             location / {
>                 fastcgi_pass backend:9000;
>                 fastcgi_param SCRIPT_FILENAME /path/to/flush.php;
>                 fastcgi_keep_conn on;
>             }
>         }
>     }
> 
> But, again, testing with fastcgi_keep_conn is mostly useless now, 
> it's an abuse of the unrelated directive.  The fastcgi_buffering 
> directive is already here in 1.5.6, use
> 
>     fastcgi_buffering off;
> 
> instead if you need to turn off buffering for fastcgi responses.  
> Just in case, documentation can be found here:
> 
> http://nginx.org/r/fastcgi_buffering
> 

Hi, everyone, so sorry for the delayed reply.

Thank you to ittp2012, Francis, Maxim, and B.R.

Well, after all of the configuration changes, both to nginx and PHP, the
solution was to add the following header to the response:

header('Content-Encoding: none;');

With this header in-place (sent as the first output in the PHP test
script), I see the timing intervals from the test script printed to the
browser in real-time. This works even in nginx-1.5.2, with my existing
configuration. (This seems to work in Chrome and Firefox, but not IE,
which corroborates Maxim's above observations re: individual browser
behavior.)

The whole reason for which I was seeking to disable output buffering is
that I need to test nginx's ability to handle multiple requests
simultaneously. This need is inspired by yet another problem, about
which I asked on this list in late August: "504 Gateway Time-out when
calling curl_exec() in PHP with SSL peer verification
(CURLOPT_SSL_VERIFYPEER) off".

Some folks suggested that the cURL problem could result from nginx not
being able to serve more than one request for a PHP file at a time. So,
that's why I cooked up this test with sleep() and so forth.

Now that output buffering is disabled, I am able to test concurrency.
Sure enough, if I request my concurrency test script in two different
browser tabs, the second tab will not begin producing output until the
first tab has finished. I set the test time to 120 seconds and at
exactly 120 seconds, the second script begins producing output.

Also, while one of these tests is running, I am unable to request a
"normal PHP web page" from the same server (localhost). The request
"hangs" until the concurrency test in the other tab is finished.

I even tried requesting the test script from two different browsers, and
the second browser always hangs until the first completes.

These observations lend credence to the notion that my cURL script is
failing due to dead-locking of some kind. (I'll refrain from discussing
this other problem here, as it has its own thread.)

Is this inability to handle concurrent requests a limitation of nginx on
Windows? Do others on Windows observe this same behavior?

I did see the Windows limitation, "Although several workers can be
started, only one of them actually does any work", but that isn't the
problem here, right? One nginx worker does not mean that only one PHP
request can be satisfied at a time, correct?

Thanks again for all the help, everyone!

-Ben



More information about the nginx mailing list