shahyar7 has asked for the wisdom of the Perl Monks concerning the following question:

Hello all

I used the code below to turn off the buffering but it doesn't work. When I call the code from the browser it supposed to show START at first and then wait for 5 seconds and then show END. But the browser doesn't display anything for 5 seconds and then show START and END at the same time. When I tested the code on a Windows based system it works great but it works as I said on Apache server. Also the code works great at the command line. Does any body knows what the problem is?

#!/usr/bin/perl use strict; $| = 1; print "Content-type: text/html\n\n"; print "<html><head></head><body>"; print "START\n"; sleep 5; print "End\n"; print "</body></html>\n";


My Perl version is: 5.8.0
My Apache version is: 1.3.37 (Unix)

Thank you all.

Replies are listed 'Best First'.
Re: Turning off buffering ($|=1) doesn't work on Apache server
by osunderdog (Deacon) on Feb 27, 2007 at 13:04 UTC

    You are correct. Turning off buffering does not directly affect what you see in the browser. When apache receives your request from a browser, it invokes your perl script. Once that perl script has completed, the output is sent back to the browser.

    You can't compare the behavior of you program on STDOUT to the behavior of your program on apache.

    Hazah! I'm Employed!

Re: Turning off buffering ($|=1) doesn't work on Apache server
by almut (Canon) on Feb 27, 2007 at 13:16 UTC

    You forgot to specify which browser you're using :)   Also, do you have some proxy in between (e.g. squid)? (it might be doing its own buffering...)

    As of Apache-1.3.x, this is supposed to work, and in fact, it does work for me, when I test it with Firefox, or simply with telnet from the command line:

    $ telnet localhost 80 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET /cgi-bin/buffering-test.pl HTTP/1.0 HTTP/1.1 200 OK Date: Tue, 27 Feb 2007 13:03:09 GMT Server: Apache/1.3.37 (Unix) Connection: close Content-Type: text/html <html><head></head><body>START End </body></html> Connection closed by foreign host.

    (5 secs pause in between "...START" and "End...")

Re: Turning off buffering ($|=1) doesn't work on Apache server
by fenLisesi (Priest) on Feb 27, 2007 at 13:17 UTC
Re: Turning off buffering ($|=1) doesn't work on Apache server
by Moron (Curate) on Feb 27, 2007 at 13:10 UTC
    There are two types of buffered I/O in question. One is caused by not closing the output channel under *NIX and the other happens within the browser itself. The former was not being turned off because it can't be from the browser. I haven't tried it, but maybe closing and reopening STDOUT would flush it?

    -M

    Free your mind

Re: Turning off buffering ($|=1) doesn't work on Apache server
by Rhandom (Curate) on Feb 27, 2007 at 16:30 UTC
    In early 1.3 versions of Apache - it was enough to simply do $| = 1. In later versions - and especially in Apache 2 versions you must flush the buffer your self. Your example above would turn into the following:
    #!/usr/bin/perl use strict; my $r = Apache->request; # mod_perl 1 print "Content-type: text/html\n\n"; print "<html><head></head><body>"; print "START\n"; $r->rflush; sleep 5; print "End\n"; print "</body></html>\n";


    If you want everything to be buffered I would make a sub like the following:
    my $my_print = sub { print @_; $r->rflush; }; # call it like this $my_print->("<html><head>....");

    If your script is going to be migrating from CGI to mod_perl 1 to mod_perl 2 I would recommend using the CGI::Ex module which lets you handle all three without modifying your script.
    #!/usr/bin/perl use strict; use warnings; use CGI::Ex; my $cgix = CGI::Ex->new; my $my_flush; if (! $cgix->mod_perl_version) { $| = 1; $my_flush = sub {}; # no op } else { $my_flush = sub { # works on most apache versions $cgix->apache_request->rflush; }; } $cgix->print_content_type; print "<html>...\n"; $my_flush->(); sleep 5; print "The rest...\n";


    my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re: Turning off buffering ($|=1) doesn't work on Apache server
by scorpio17 (Canon) on Feb 27, 2007 at 15:10 UTC
    I tested your script, and it works for me with both Firefox 1.5 and IE 6. My server is Apache 2.2.2 running on Fedora Core 4 linux. Perl version 5.8.8. I guess this doesn't really answer your question, but at least you can be sure that the problem is not due to an error in your perl code.