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:pavel2...@ngs.ru


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org
For additional commands, e-mail: dev-h...@perl.apache.org

Reply via email to