如何使用 ModPerl::Registry 抑制旧版 CGI 脚本中的默认 mod_perl 错误页面
我有一个 Perl 语言的 CGI 脚本,它可以自行生成 HTTP 错误页面。我通过 ModPerl::Registry 在 mod_perl 下运行它,使用以下 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>
,将上面示例 CGI 脚本中的 exit;
替换为 return Apache2::Const::OK;
或 return Apache2::Const::DONE;
,如“如何抑制默认值mod_perl 中的 apache 错误文档?”关于 SO 的问题没有帮助——结果保持不变。
我应该在 Apache 配置中修复什么,或者应该在 CGI 脚本中添加什么以抑制 mod_perl / Apache 将错误页面附加到生成的响应?
I have a CGI script in Perl that generates HTTP error pages by itself. I am running it under mod_perl via ModPerl::Registry, using the following Apache2 configuration:
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>
Everything is fine, except a little problem: when HTTP status printed in headers is different than 200 (for instance 404), Apache appends a default HTML error document to my own generated response.
Take for example the following simple CGI script:
#!/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;
Running it with Apache configuration mentioned above results in
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>
Note that replacing exit;
in the example CGI script above with either return Apache2::Const::OK;
or return Apache2::Const::DONE;
, as recommended in "How do I suppress the default apache error document in mod_perl?" question on SO doesn't help -- the result stays the same.
What should I fix in my Apache configuration, or what should I add to my CGI script to suppress appending error page by mod_perl / Apache to generated response?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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
The FAQ works for me , after your CGI is done, after headers are sent, tell apache the status is ok, so it doesn't send 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
我的代码版本,但工作更稳定:
My version of the code, but working more stable:
我似乎面临着同样的问题:我将标头状态设置为 400,以防发生错误并返回 JSON 数组来描述实际错误。
当我这样做时:
使用变量:
我最终会得到这样的结果:
使用 faquer 描述的方法确实会抑制错误文档,但仍然返回状态 200 OK,就像 Jakub Narębski 指出的那样。
但!我找到了一个解决方法,其中 $r 是 Apache2::RequestRec,使用以下命令:
http://perl.apache.org/docs/2.0/user /coding/coding.html#Forcing_HTTP_Response_Headers_Out
(否则你会使用 $r->send_http_header(),我猜)
HTTP 响应:
Apache config:
.htaccess:
I seem to be facing the same problem: I set header status to 400 in case of an error and return JSON array to describe the actual error.
When I do:
With variables:
I will end up with this:
Using the method described by faquer will in deed suppress the error document, but still returns status 200 OK, like Jakub Narębski points out.
BUT! I have found a workaround, where $r is a Apache2::RequestRec, using this:
http://perl.apache.org/docs/2.0/user/coding/coding.html#Forcing_HTTP_Response_Headers_Out
(otherwise you would use $r->send_http_header(), I guess)
HTTP response:
Apache config:
.htaccess: