1 |
|
2 |
=head1 NAME |
3 |
|
4 |
SuikaWiki::Output::CGICarp --- SuikaWiki : CGI::Carp modification to |
5 |
return 500 status code |
6 |
|
7 |
=head1 DESCRIPTION |
8 |
|
9 |
At the time of writing, latest version of CGI::Carp (1.27) |
10 |
does not output error dying message with 500 (Internal Server Error) |
11 |
HTTP status code unless it is working on mod_perl. |
12 |
|
13 |
This module overrides some of CGI::Carp functions to return 500 status |
14 |
code. Users of this module should take attention whether later revision |
15 |
of CGI::Carp provides improved version of CGI outputing methods. |
16 |
|
17 |
This module is part of SuikaWiki. |
18 |
|
19 |
=cut |
20 |
|
21 |
package SuikaWiki::Output::CGICarp; |
22 |
require CGI::Carp; # 1.27 |
23 |
use strict; |
24 |
our $VERSION = do{my @r=(q$Revision: 1.4 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
25 |
our $CUSTOM_REASON_TEXT = 'Internal CGI Script Error'; |
26 |
our $CUSTOM_STATUS_CODE = 500; |
27 |
|
28 |
=head1 OPTIONS |
29 |
|
30 |
=over 4 |
31 |
|
32 |
=item $SuikaWiki::Output::CGICarp::CUSTOM_REASON_TEXT (Default : Internal CGI Script Error) |
33 |
|
34 |
Short description of error status. This string should contains only |
35 |
printable ASCII characters (including SPACE) for interoperability |
36 |
and line break characters (CR and LF) MUST NOT be used. |
37 |
|
38 |
=item $SuikaWiki::Output::CGICarp::CUSTOM_STATUS_CODE (Default : 500) |
39 |
|
40 |
Three digit status code defined by HTTP specifications. |
41 |
|
42 |
=back |
43 |
|
44 |
=cut |
45 |
|
46 |
package CGI::Carp; |
47 |
our $CUSTOM_MSG; |
48 |
sub fatalsToBrowser { |
49 |
my($msg) = @_; |
50 |
$msg=~s/&/&/g; |
51 |
$msg=~s/>/>/g; |
52 |
$msg=~s/</</g; |
53 |
$msg=~s/\"/"/g; |
54 |
my($wm) = $main::ENV{SERVER_ADMIN} ? |
55 |
qq[the webmaster <<a href="mailto:$main::ENV{SERVER_ADMIN}">$main::ENV{SERVER_ADMIN}</a>>] : |
56 |
"this site's webmaster"; |
57 |
my ($outer_message) = <<END; |
58 |
For help, please send mail to $wm, giving this error message |
59 |
and the time and date of the error. |
60 |
END |
61 |
; |
62 |
my $mod_perl = exists $main::ENV{MOD_PERL}; |
63 |
|
64 |
warningsToBrowser(1); # emit warnings before dying |
65 |
|
66 |
if ($CUSTOM_MSG) { |
67 |
if (ref($CUSTOM_MSG) eq 'CODE') { |
68 |
my $bytes_written = eval{tell STDOUT}; |
69 |
unless (defined $bytes_written && $bytes_written > 0) { |
70 |
print STDOUT "Status: @{[$SuikaWiki::Output::CGICarp::CUSTOM_STATUS_CODE+0]} $SuikaWiki::Output::CGICarp::CUSTOM_REASON_TEXT\n"; |
71 |
print STDOUT "Content-type: text/html; charset=iso-8859-1\n\n"; |
72 |
} |
73 |
&$CUSTOM_MSG($msg); # nicer to perl 5.003 users |
74 |
return; |
75 |
} else { |
76 |
$outer_message = $CUSTOM_MSG; |
77 |
} |
78 |
} |
79 |
|
80 |
my $mess = <<END; |
81 |
<h1>Software error:</h1> |
82 |
<pre>$msg</pre> |
83 |
<p> |
84 |
$outer_message |
85 |
</p> |
86 |
END |
87 |
; |
88 |
|
89 |
if ($mod_perl) { |
90 |
require mod_perl; |
91 |
if ($mod_perl::VERSION >= 1.99) { |
92 |
$mod_perl = 2; |
93 |
require Apache::RequestRec; |
94 |
require Apache::RequestIO; |
95 |
require Apache::RequestUtil; |
96 |
require APR::Pool; |
97 |
require ModPerl::Util; |
98 |
require Apache::Response; |
99 |
} |
100 |
my $r = Apache->request; |
101 |
# If bytes have already been sent, then |
102 |
# we print the message out directly. |
103 |
# Otherwise we make a custom error |
104 |
# handler to produce the doc for us. |
105 |
if ($r->bytes_sent) { |
106 |
$r->print($mess); |
107 |
$mod_perl == 2 ? ModPerl::Util::exit(0) : $r->exit; |
108 |
} else { |
109 |
# MSIE won't display a custom 500 response unless it is >512 bytes! |
110 |
if ($main::ENV{HTTP_USER_AGENT} =~ /MSIE/) { |
111 |
$mess = "<!-- " . (' ' x 513) . " -->\n$mess"; |
112 |
} |
113 |
$r->custom_response($SuikaWiki::Output::CGICarp::CUSTOM_STATUS_CODE+0,$mess); |
114 |
} |
115 |
} else { |
116 |
my $bytes_written = eval{tell STDOUT}; |
117 |
if (defined $bytes_written && $bytes_written > 0) { |
118 |
print STDOUT $mess; |
119 |
} else { |
120 |
print STDOUT "Status: @{[$SuikaWiki::Output::CGICarp::CUSTOM_STATUS_CODE+0]} $SuikaWiki::Output::CGICarp::CUSTOM_REASON_TEXT\n"; |
121 |
print STDOUT "Content-type: text/html; charset=iso-8859-1\n\n"; |
122 |
print STDOUT $mess; |
123 |
} |
124 |
} |
125 |
} |
126 |
|
127 |
=head1 EXAMPLE |
128 |
|
129 |
use CGI::Carp qw/fatalsToBrowser/; |
130 |
require SuikaWiki::Output::CGICarp; |
131 |
|
132 |
die 'Something wrong'; |
133 |
|
134 |
=head1 LICENSE |
135 |
|
136 |
Copyright 2003-2004 Wakaba <w@suika.fam.cx> |
137 |
|
138 |
This program is free software; you can redistribute it and/or |
139 |
modify it under the same terms as Perl itself. |
140 |
|
141 |
=cut |
142 |
|
143 |
1; # $Date: 2004/01/17 09:18:38 $ |