This is an issue I've seen occasionally on our own WAMP server as well as LAMP hosting environments. The later releases of Apache 1.3 and 2.0 seemed to limit the issue, but it's regularly a problem with 2.2.
The issue is pronounced mainly when NPH scripts are combined with a rewrite. The issue is further compounded if you handle your own gzip compression, which is pretty much a requirement when using NPH scrips. If you aren't using URL rewriting, the issue pretty much disappears.
This is NOT documented anywhere, and I've had to determine the possible causes and solutions on my own. I've been able to (MOSTLY) resolve the issue in the following way: Adding a Content-Length header. This will ONLY work if you accumulate the page output prior to sending to the client, so that you can calculate the byte size for the header.
For example, as you build up your page, if you use Perl you would accumulate them into a variable such as $HTML
and then when you've handled all the page processing, you would send that to a subroutine which handles the final output. What I also do is accumulate headers separately into a variable as needed prior to the final output and that effectively saves me the hassle of handling the output more than once, which helps a lot with debugging.
Here's a code snippet without gzip output support:
sub finish {
my ($STATUS, $HEADER, $TYPE, $HTML, $ISNPH) = @_;
my $HTTP_PROTOCOL = $ENV{'SERVER_PROTOCOL'}
if ($ENV{'SERVER_PROTOCOL'}
&& $ENV{'SERVER_PROTOCOL'} =~ m/^HTTP\/\d\.\d\$/);
$HTTP_PROTOCOL ||= 'HTTP/1.1';
$STATUS ||= 200;
$TYPE ||= 'text/html';
if ($STATUS =~ m/^30[123]$/) {
$HEADER .= "Content-Length: 0\n";
print "$HTTP_PROTOCOL $STATUS\n";
print $HEADER;
print "Content-type: $TYPE\n";
print "Location: $HTML\n\n";
exit;
}
print "$HTTP_PROTOCOL $STATUS\n" if ($ISNPH);
print $HEADER;
print "Content-type: $TYPE\n";
print 'Content-Length: ' . length($HTML) . "\n" if ($ISNPH);
print "\n";
print $HTML;
exit;
}
It would be called like this:
&finish('200', $HEADER, 'text/html', $HTML, 1);
If you're testing your script before making it support NPH, just pass a 0
as the last parameter. Simply don't print to the client at all prior to this function call and build up your headers into $HEADER
and HTML into $HTML
.
If you're doing a redirect, pass the URL you're redirecting to in the $HTML
parameter. There's no need for actual HTML output in a redirect scenario.
To further resolve issues if you still see them, test your script with output buffering on
& off
.
There are still situations where this may not resolve the issue, and I've yet to pinpoint a solution, it should be brought up to the Apache Group. I only know CGI programming so I wouldn't have the capacity to research Apache source or submit patches, but hopefully someone takes this up.
~Jay