ModPerl::RegistryCooker default_handler returned status

"Pavel V." <[email protected]>
Newsgroups gmane.comp.apache.mod-perl.devel
Message-ID <[email protected]>
  Hi all.

  Can anybody explain historical reasons of ModPerl::RegistryCooker default_handler() implementation?
  We can see the following piece of code there:

    # handlers shouldn't set $r->status but return it, so we reset the
    # status after running it
    my $old_status = $self->{REQ}->status;
    my $rc = $self->run;
    my $new_status = $self->{REQ}->status($old_status);
    return ($rc == Apache2::Const::OK && $old_status != $new_status)
        ? $new_status
        : $rc;

  The goal of ModPerl modules is "Run unaltered CGI scripts under mod_perl".
  If scripts are unaltered, how they can change $r->status? I think, answer should be - 'in no way'.

  Why we need to reset status then? I see no reasons. But this solution makes us impossible to set
  status from 'altered' scripts correctly.

  Did anyone can explain, why this code appears and for which scenarios it come?

  Apache's mod_cgi.c module returns OK regardless of the r->status, which was set from script output.
  Why ModPerl handler should behave differently?

  One good example about problems, what are introduced by this solution, is 404 status.
  Let`s look into small script:

  #!/usr/bin/perl -w
  use strict;
  use CGI;

  my $q = CGI->new;
  #### Variant 1
  print $q->header(-charset => "windows-1251", -type => "text/html", -status=>'404 Not Found');
  print "SMALL RESPONSE";
  #### Variant 2
  print $q->header(-charset => "windows-1251", -type => "text/html", -status=>'404 Not Found');
  #print 'BIG RESPONSE:' . '*' x 8192;

  Under CGI it prints only "SMALL/BIG RESPONSE" string with 404 status code into browser.
  Under mod_perl, browser get status 200 instead of 404 and script response is appended by default
  Apache error-handler content (like 'Status: OK \n /path/to/script.pl was not found on this server').
  If we print 'big response', then browser get status 404 and apache error-handler appended content
  changes to 'Not Found \n The requested URL /perl/test.pl was not found on this server.'.

  The reasons for such behaviour is what scripts are using CGI.pm which handles MOD_PERL.
  So, they are practically 'altered' and can set $r-status inside of them. After script executes, we
  have r->status = 404. But ModPerl::RegistryCooker set r->status to 200 and return 404 as handler
  status - so apache ErrorDocument directive begin to work (under mod_cgi handler status is OK, so
  no error processing occurs). Also, due to r->status changed, we get 200 into browser.
  Most interesting, what we get 404 status logged into access log anyway.

  Ok, the next example - completely unaltered script:

  #!/usr/bin/perl -w
  use strict;
  print "Status: 404 Not Found\n";
  print "Content-Type: text/html; charset=windows-1251\n\n";
  #Small response
  print 'NOTFOUND:' . '*' x 81;
  #Big response
  #print 'NOTFOUND:' . '*' x 8192;

  When response is small, then 8k buffer is not filled, and r->status does not changed internally
  before cgi headers parsed on buffer flush. So, we get r->status == 200, and handler status is 200
  too. After headers are parsed, r->status become 404, but mod_perl handler returns status 200 to
  apache



-- 
Regards,,
 Pavel                          mailto:[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.