perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pavel V." <pavel2...@ngs.ru>
Subject ModPerl::RegistryCooker default_handler returned status
Date Sun, 31 Aug 2014 08:43:37 GMT

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


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


Mime
View raw message