Как подавить страницу ошибки mod_perl по умолчанию в унаследованном CGI-скрипте, используя ModPerl :: Registry - PullRequest
3 голосов
/ 27 ноября 2011

У меня есть скрипт CGI на Perl, который сам генерирует страницы ошибок HTTP.Я запускаю его под mod_perl через ModPerl :: Registry , используя следующую конфигурацию Apache2:

Alias /perl "/var/www/perl"
<Directory "/var/www/perl">
    SetHandler perl-script
    PerlResponseHandler ModPerl::Registry
    PerlOptions +ParseHeaders
    Options Indexes FollowSymlinks +ExecCGI
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

Все хорошо, за исключением небольшой проблемы: когда HTTP-статус, напечатанный в заголовках, отличаетсячем 200 (например, 404), Apache добавляет документ об ошибке HTML по умолчанию к моему собственному сгенерированному ответу.

Возьмем, к примеру, следующий простой CGI-скрипт:

#!/usr/bin/perl

use strict;
use warnings;

use CGI qw(:standard :escapeHTML -nosticky);
use CGI::Carp qw(fatalsToBrowser);

use Apache2::Const qw(:http :common);

our $cgi = CGI->new();

print $cgi->header(-type=>'text/html', -charset => 'utf-8',
                   -status=> '404 Not Found');
our $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : '';
print <<"EOF";
<html>
<head>
<title>die_error_minimal$mod_perl_version 
</head>
<body>
404 error
</body>
</html>
EOF

exit;

Запуск его с настройкой Apacheупомянутые выше результаты приводят к

HTTP/1.1 404 Not Found
Date: Sun, 27 Nov 2011 13:17:59 GMT
Server: Apache/2.0.54 (Fedora)
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

<html>
<head>
<title>die_error_minimal mod_perl/2.0.1 
</head>
<body>
404 error
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /perl/die_error_minimal.cgi was not found on this server.</p>
<hr>
<address>Apache/2.0.54 (Fedora) Server at localhost Port 80</address>
</body></html>

Обратите внимание, что замена exit; в приведенном выше примере CGI-скрипта на return Apache2::Const::OK; или return Apache2::Const::DONE;, как рекомендуется в " Как подавить ошибку apache по умолчаниюdocument in mod_perl?"вопрос по SO не помогает - результат остается прежним.

Что я должен исправить в своей конфигурации Apache, или что я должен добавить в свой CGI-скрипт, чтобы подавить добавлениестраница ошибки mod_perl / Apache для сгенерированного ответа?

Ответы [ 3 ]

5 голосов
/ 28 ноября 2011

FAQ работает для меня, после того, как ваш CGI сделан, после того, как заголовки отправлены, скажите apache, что статус в порядке, поэтому он не отправляет ErrorDocument http://search.cpan.org/~gozer/mod_perl-1.31/faq/mod_perl_faq.pod#So_how_do_I_use_mod_perl_in_conjunction_with_ErrorDocument%3F

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

Main( @ARGV );
exit( 0 );

sub Main { 
    my404();
#~ my $r = CGI::Simple->new->_mod_perl_request;
    my $r = CGI->new->r;
    $r->status(200);
    return;
}
sub my404 {
    my $cgi = CGI->new;
    print $cgi->header(  -status => 404 );
    print "<html><title>print404 says tough noogies</title>
<body><h1>tough noogies</h1></body></html>";
}
__END__

GET http://localhost/perl/print404
User-Agent: lwp-request/6.03 libwww-perl/6.03

404 Not Found
Connection: close
Date: Sun, 27 Nov 2011 20:55:39 GMT
Server: Apache/2.0.54 (Win32) mod_ssl/2.0.54 OpenSSL/0.9.7g PHP/4.3.11 mod_perl/2.0.1 Perl/v5.8.9
Content-Type: text/html; charset=ISO-8859-1
Client-Date: Sun, 27 Nov 2011 20:55:39 GMT
Client-Peer: 127.0.0.1:80
Client-Response-Num: 1
Client-Transfer-Encoding: chunked
Title: print404 says tough noogies

<html><title>print404 says tough noogies</title>
<body><h1>tough noogies</h1></body></html>
3 голосов
/ 06 февраля 2013

Мне кажется, что я сталкиваюсь с той же проблемой: я устанавливаю статус заголовка на 400 в случае ошибки и возвращаю массив JSON для описания фактической ошибки.

Когда я делаю:

print $main::cgi->header(@ret), $html;

С переменными:

@ret: {'-type' => 'application/json','-charset' => 'utf-8','-status' => '400 Bad Request'}
$html: '{"errors":{"short_name":["Missing!"]}}'

Я получу следующее:

Status Code: 200 OK
Content-Type: application/json; charset=utf-8
Response: {"errors":{"short_name":["Missing!"]}<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  <html><head>
  <title>400 Bad Request</title>
  </head><body>
  <h1>Bad Request</h1>
  <p>Your browser sent a request that this server could not understand.<br />
  </p>
  <hr>
  <address>Apache/2.2.3 (CentOS) Server at localhost Port 80</address>
  </body></html>

Использование метода, описанного faquer, в действительности подавит документ об ошибке, но все равно вернет статус 200 OKКак отмечает Якуб Наребский.


НО!Я нашел обходной путь, где $ r является Apache2 :: RequestRec, используя это: http://perl.apache.org/docs/2.0/user/coding/coding.html#Forcing_HTTP_Response_Headers_Out (в противном случае вы бы использовали $ r-> send_http_header (), я думаю)

print $main::cgi->header(@ret), $html;
my $r = $main::cgi->r;
$r->rflush; # force sending headers (with headers set by CGI)
$r->status(200); # tell Apache that everything was ok, dont send error doc.

HTTP-ответ:

Status Code: 400 Bad Request
Content-Type: application/json; charset=utf-8
Response: {"errors":{"short_name":["Missing!"]}}

Конфигурация Apache:

PerlModule ModPerl::PerlRun
PerlModule CGI
PerlModule Apache::DBI
PerlRequire /var/www/html/startup.pl
PerlSendHeader On

.htaccess:

<Files *.cgi>
 SetHandler  perl-script
 PerlHandler ModPerl::PerlRun
 Options ExecCGI
</Files>
2 голосов
/ 06 февраля 2013

Моя версия кода, но работает стабильнее:

#!/usr/bin/perl

use CGI qw/:standard/ ;

my $Content_of_webpage = 'Oops. 404 error ...' ;
my $status_code = 404 ;


  if( $ENV{MOD_PERL} ) { # mod_perl ON

    my $r = CGI->new->r ;
    $r->status($status_code) ;
    $r->content_type("text/html; charset=UTF-8") ;
    $r->rflush ; # send the headers out << it is the trick :)
    $r->status(200) ;      

  }
  else { # mod_perl OFF

   my $cgi = CGI->new ;
   print $cgi->header( 

     -type    => "text/html",
     -status  => $status_code,
     -charset => 'UTF-8'

   );    

  }

 print $Content_of_webpage ;
...