Item12835: http status code not properly set under certain conditions
Priority: Normal
Current State: Closed
Released In: 2.0.0
Target Release: major
Applies To: Engine
Component: Foswiki/Response.pm
Branches: trunk
In
FosWiki.pm, in line 954, if the engine decides on a 304 reply, it sets the status code:
# finally decide on a 304 reply
if ( $etagFlag && $lastModified ) {
$hopts->{'Status'} = '304 Not Modified';
$text = '';
Later, Foswiki/Response.pm line 247 will use the Status header to set the return status in the reply object:
unless ( exists $this->{headers}->{$hdr} ) {
if ( $hdr eq 'Status' ) {
$this->status($hdr); # <---- Bug here!
}
This passes the header name, "Status", instead of the status, 304, to $this->status(). Which will make the status undefined:
sub status {
my ( $this, $status ) = @_;
if ($status) {
ASSERT( !$this->{outputHasStarted}, 'Too late to change status' )
if DEBUG;
$this->{status} = $status =~ /^\d{3}/ ? $status : undef; # <--- status will be undef because the parameter, "Status", does not begin with 3 digits
}
return $this->{status};
}
}
In the cgi version, this doesn't hurt much, because the engine will still pass the header -
Status: 304
- to apache, and the web server will turn this into a
HTTP/1.1 304 not modified
header. However, in the mod_perl version, the engine will convert the undefined status to 200, and send out
HTTP/1.1 200 OK
, with an extra
Status: 304
header and an empty document body, resulting in an empty page.
The following patch fixes the problem:
diff -rC4 /home/webadmin/wiki-test.islap003/lib/Foswiki/Response.pm lib/Foswiki/Response.pm
*** /home/webadmin/wiki-test.islap003/lib/Foswiki/Response.pm Wed Nov 10 01:29:12 2010
--- lib/Foswiki/Response.pm Mon Mar 31 15:59:49 2014
***************
*** 243,251 ****
while ( my ( $hdr, $value ) = each %$hopt ) {
$hdr =~ s/(?:^|(?<=-))(.)([^-]*)/\u$1\L$2\E/g;
unless ( exists $this->{headers}->{$hdr} ) {
if ( $hdr eq 'Status' ) {
! $this->status($hdr);
}
elsif ( $hdr eq 'Expires' ) {
$value = CGI::Util::expires( $value, 'http' );
}
--- 243,251 ----
while ( my ( $hdr, $value ) = each %$hopt ) {
$hdr =~ s/(?:^|(?<=-))(.)([^-]*)/\u$1\L$2\E/g;
unless ( exists $this->{headers}->{$hdr} ) {
if ( $hdr eq 'Status' ) {
! $this->status($value);
}
elsif ( $hdr eq 'Expires' ) {
$value = CGI::Util::expires( $value, 'http' );
}
--
GuntramBlohm - 31 Mar 2014
Thanks a lot for the fix. Same error happens on trunk. I don't think the error is related to mod_perl.
--
MichaelDaum - 01 Apr 2014