SpeedyCGI does not support Transfer-Encoding: chunked, while mod_perl and others does.
The test script below shows this with mod_perl:
HTTP/1.1 200 OK
Date: Wed, 04 Mar 2009 14:29:10 GMT
Server: Apache/2.2.11 [..]
Connection: close
Content-disposition: attachment; filename=data.raw
Transfer-encoding: chunked
Content-Type: application/octet-stream
But with SpeedyCGI:
HTTP/1.1 200 OK
Date: Wed, 04 Mar 2009 14:30:27 GMT
Server: Apache/2.2.11 [..]
Connection: close
Content-disposition: attachment; filename=data.raw
Transfer-encoding: chunked
Content-Length: 104857600
Content-Type: application/octet-stream
The script:
#!/usr/bin/perl -w
use CGI;
my $cgi = new CGI();
print $cgi->header(-type => 'application/octet-stream', -content_disposition => 'attachment; filename=data.raw', -connection => 'close', -transfer_encoding => 'chunked');
open (my $fh, '<', '/dev/urandom') || die "$!\n";
for (1..100) {
my $data;
read($fh, $data, 1024*1024);
print $data;
}
(Change 1..100 to 1..1000 or 1..10000 and apache2 will be oom-killed with SpeedyCGI...)
Regards,
Oskar Liljeblad (oskar@osk.mine.nu)
Here's a better test case:
my $cgi = new CGI();
print $cgi->header(
-type => 'application/octet-stream',
-content_disposition => 'attachment; filename=data.raw',
-transfer_encoding => 'chunked');
open (my $fh, '<', '/dev/urandom') || die "$!\n";
for (1..100) {
my $data;
read($fh, $data, 1024*1024);
print length($data), "\r\n", $data, "\r\n";
exit if length($data) == 0;
}
print "0\r\n\r\n"
Sorry - this does not have to do with chunked transfer encoding at all. But it seems that Apache (or SpeedyCGI) caches the output of every script, so that it can append a Content-Length header. If the script produces endless data, then the apache server process will eventually be killed by the kernel. But the main problem is that if the script takes a few minutes to run, the web browser does not receive the response until this time has passed. This is no good if you want to stream stuff to the client.
Oskar