11

I would like to be able to allow a user to view the output of a long-running GCI script as it is generated rather than after the script is complete. However even when I explicitly flush STDOUT the server seems to wait for the script to complete before sending the response to the client. This is on a Linux server running Apache 2.2.9.

Example python CGI:

#!/usr/bin/python

import time
import sys


print "Content-type: text/plain"
print
for i in range(1, 10):
        print i
        sys.stdout.flush()
        time.sleep(1)

print "Done."

Similar example in perl:

#!/usr/bin/perl

print "Content-type: text/plain\n\n";

for ($i = 1; $i <= 10 ; $i++) {
        print "$i\n";
        sleep(1);
}

print "Done.";

This link says as of Apache 1.3 CGI output should be unbuffered (but this might apply only to Apache 1.x): http://httpd.apache.org/docs/1.3/misc/FAQ-F.html#nph-scripts

Any ideas?

Dave Forgac
  • 3,146
  • 7
  • 39
  • 54

4 Answers4

4

Randal Schwartz's article Watching long processes through CGI explains a different (and IMHO, better) way of watching a long running process.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • I ended up using a similar method for my application but I'm still curious as to why the original method isn't working in my setup. Oh well. – Dave Forgac Sep 22 '09 at 14:48
2

Flushing STDOUT can help. For example, the following Perl program should work as intended:

#!/usr/bin/perl

use strict;
use warnings;

local $| = 1;

print "Content-type: text/plain\n\n";

for ( my $i = 1 ; $i <= 10 ; $i++ ) {
    print "$i\n";
    sleep(1);
}

print "Done.";
Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
2

You must put your push script into a special directory wich contain a special .htaccess with this environnment specs:

Options +ExecCGI
AddHandler cgi-script .cgi .sh .pl .py
SetEnvIfNoCase Content-Type \
"^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"
SetEnv no-gzip dont-vary
F. Hauri
  • 21
  • 1
1

According to CGI::Push,

Apache web server from version 1.3b2 on does not need server push scripts installed as NPH scripts: the -nph parameter to do_push() may be set to a false value to disable the extra headers needed by an NPH script.

You just have to find do_push equivalent in python.

Edit: Take a look at CherryPy: Streaming the response body.

When you set the config entry "response.stream" to True (and use "yield") CherryPy manages the conversation between the HTTP server and your code like this:

alt text
(source: cherrypy.org)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319