php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #34429 [PATCH] Output buffering cannot be turned off with FastCGI
Submitted: 2005-09-08 16:12 UTC Modified: 2005-12-18 01:37 UTC
Votes:6
Avg. Score:4.3 ± 0.7
Reproduced:6 of 6 (100.0%)
Same Version:3 (50.0%)
Same OS:4 (66.7%)
From: zimage at icdsoft dot com Assigned: mike (profile)
Status: Closed Package: CGI/CLI related
PHP Version: 5CVS, 4CVS (2005-09-12) OS: *
Private report: No CVE-ID: None
 [2005-09-08 16:12 UTC] zimage at icdsoft dot com
Description:
------------
Output comes in chunks of about 8k and cannot be forced by using flush(), ob_flush() or output_buffering = Off

I've tested with netcat to avoid browser buffering issues:

echo -ne 'GET /buf.php HTTP/1.0\n\n' |nc 10.0.0.1 80

Reproduce code:
---------------
<?php
        for ($i=0; $i<4; $i++){
                echo "$i\n";
                ob_flush();
                flush();
                sleep (1);
        }
?>


Expected result:
----------------
When run under mod_php, cgi version or lighttpd+php/fastcgi there is one digit printed per second.

Actual result:
--------------
When run under apache 1.3.33 + php/fastcgi the entire output is printed at once.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-09-08 21:23 UTC] zimage at icdsoft dot com
Just tried with php5-200509081630:

PHP 5.1.0-dev (cgi-fcgi) (built: Sep  8 2005 15:09:53)

No luck either. Output still comes at once.

Tried with apache2 + php-4.3.11 - the problem is present there too.
 [2005-09-09 11:25 UTC] zimage at icdsoft dot com
And strace of php process looks like:

read(4, "<?php\n\tfor ($i=0; $i<4; $i++){\n\t"..., 8192) = 65
read(4, "", 4096)                       = 0
read(4, "", 8192)                       = 0
close(4)                                = 0
munmap(0x4056b000, 4096)                = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, {1, 0})               = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, {1, 0})               = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, {1, 0})               = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, {1, 0})               = 0
setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
write(3, "\1\6\0\1\0@\0\0Content-type: text/html\r"..., 96) = 96

I.e. there are 4 calls to sleep and the script output is writen at once. Any
pointers to documentation or further tests that I should perform are welcome.
 [2005-09-10 22:56 UTC] sniper@php.net
How would it be useful to be able to turn it off?

 [2005-09-12 15:47 UTC] zimage at icdsoft dot com
This is how you could write a chat client for example. Connection is kept open for the duration of chat session and php script is looping over the client and server messages.
 [2005-09-12 15:49 UTC] sniper@php.net
Writing such things using PHP is pretty useless IMO, but if it works with other SAPIs..

 [2005-09-12 16:08 UTC] zimage at icdsoft dot com
It could be also used for writing progress bars. On a random shared hosting server:

locate .php |wc -l
  25147
locate .php |xargs -n1 -i grep -H -e "flush *(" {}
    641

So people are using it for some reason... I can see flush() used in Moveable Type, Word Press, MediaWiki and so on.
 [2005-10-10 15:06 UTC] pdxtechie at gmail dot com
This would also be useful for Ajax (using, for example, the RicoAjaxEngine.) If you are unable to disable buffering, there is no way to stream XML for progress updates through Ajax.
 [2005-11-19 03:50 UTC] fabwash at hotmail dot com
I have the same problem.. What I did was to send a lot of blank space to fill up the buffer:

add_message($id, str_pad('',4096));

That fixed the problem but increases the bandwidth.
 [2005-11-30 06:26 UTC] ilya at cs dot msu dot su
I've the same problem... At the newest php, on Debian and FreeBSD, doesn't matter, using fastcgi compiled in... Any suggestions about this problem?!

It is a very important bug for me, because I'd like to give webpages to users by parts, compiling them on fly!-)
 [2005-12-06 23:29 UTC] ilya at cs dot msu dot su
So, here is a trivial patch, that works... Sent it to internals@lists.php.net
Hope, this will close this bug.

? khext.patch
Index: sapi/cgi/cgi_main.c
===================================================================
RCS file: /repository/php-src/sapi/cgi/cgi_main.c,v
retrieving revision 1.271
diff -u -r1.271 cgi_main.c
--- sapi/cgi/cgi_main.c 3 Dec 2005 01:27:37 -0000       1.271
+++ sapi/cgi/cgi_main.c 6 Dec 2005 21:58:18 -0000
@@ -264,13 +264,15 @@

 static void sapi_cgibin_flush(void *server_context)
 {
-       if (!FCGX_IsCGI()) {
+       int flush_result;
+    if (!FCGX_IsCGI()) {
                FCGX_Request *request = (FCGX_Request *) server_context;
-               if (
+               flush_result = FCGX_FFlush(request->out);
+        if (
 #ifndef PHP_WIN32
                !parent &&
 #endif
-               (!request || FCGX_FFlush(request->out) == -1)) {
+               (!request || flush_result == -1)) {
                        php_handle_aborted_connection();
                }
                return;
 [2005-12-09 18:06 UTC] dmitry@php.net
Fixed in CVS HEAD, PHP_5_1 and PHP_5_0.
 [2005-12-18 01:37 UTC] zimage at icdsoft dot com
I've just tested it and can confirm that flush() now works as expected. Thank you.
 [2010-03-17 21:49 UTC] m dot ghadam at gmail dot com
This problem exist on php v5.3.13 or php v5.3.2 stable.
Please fix it.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 03 06:01:29 2024 UTC