line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- cperl-indent-level: 4; cperl-continued-brace-offset: -4; cperl-continued-statement-offset: 4 -*- |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Copyright (c) 1998-2005 by Jonathan Swartz. All rights reserved. |
4
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify it |
5
|
|
|
|
|
|
|
# under the same terms as Perl itself. |
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
873
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
40
|
|
8
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
68
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
package HTML::MasonX::ApacheLikePlackHandler; |
11
|
|
|
|
|
|
|
$HTML::MasonX::ApacheLikePlackHandler::VERSION = '0.02'; |
12
|
|
|
|
|
|
|
#---------------------------------------------------------------------- |
13
|
|
|
|
|
|
|
# |
14
|
|
|
|
|
|
|
# APACHE-SPECIFIC REQUEST OBJECT |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
package HTML::MasonX::Request::ApacheLikePlackHandler; |
17
|
|
|
|
|
|
|
$HTML::MasonX::Request::ApacheLikePlackHandler::VERSION = '0.02'; |
18
|
1
|
|
|
1
|
|
1300
|
use HTML::Mason::Request; |
|
1
|
|
|
|
|
141898
|
|
|
1
|
|
|
|
|
45
|
|
19
|
1
|
|
|
1
|
|
13
|
use Class::Container; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
21
|
|
20
|
1
|
|
|
1
|
|
5
|
use Params::Validate qw(BOOLEAN); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
101
|
|
21
|
|
|
|
|
|
|
Params::Validate::validation_options( on_fail => sub { param_error( join '', @_ ) } ); |
22
|
|
|
|
|
|
|
|
23
|
1
|
|
|
1
|
|
5
|
use base qw(HTML::Mason::Request); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
95
|
|
24
|
|
|
|
|
|
|
|
25
|
1
|
|
|
1
|
|
5
|
use HTML::Mason::Exceptions( abbr => [qw(param_error error)] ); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
9
|
|
26
|
|
|
|
|
|
|
|
27
|
1
|
|
|
1
|
|
59
|
use constant OK => 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
56
|
|
28
|
1
|
|
|
1
|
|
6
|
use constant HTTP_OK => 200; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
39
|
|
29
|
1
|
|
|
1
|
|
5
|
use constant DECLINED => -1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
30
|
1
|
|
|
1
|
|
4
|
use constant NOT_FOUND => 404; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
32
|
|
31
|
1
|
|
|
1
|
|
5
|
use constant REDIRECT => 302; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
140
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $APACHE2_REQUEST_CLASS; |
34
|
|
|
|
|
|
|
my $APACHE2_REQUEST_INSTANCE_CLASS; |
35
|
|
|
|
|
|
|
my $APACHE2_STATUS_CLASS; |
36
|
|
|
|
|
|
|
my $APACHE2_SERVERUTIL_CLASS; |
37
|
|
|
|
|
|
|
BEGIN { |
38
|
1
|
|
|
1
|
|
5
|
my %_name_to_var = ( |
39
|
|
|
|
|
|
|
APACHE2_REQUEST => \$APACHE2_REQUEST_CLASS, |
40
|
|
|
|
|
|
|
APACHE2_REQUEST_INSTANCE => \$APACHE2_REQUEST_INSTANCE_CLASS, |
41
|
|
|
|
|
|
|
APACHE2_STATUS => \$APACHE2_STATUS_CLASS, |
42
|
|
|
|
|
|
|
APACHE2_SERVERUTIL => \$APACHE2_SERVERUTIL_CLASS, |
43
|
|
|
|
|
|
|
); |
44
|
|
|
|
|
|
|
|
45
|
1
|
|
|
|
|
3
|
for my $key (keys %_name_to_var) { |
46
|
4
|
|
|
|
|
20
|
my $env_name = sprintf 'HTML_MASONX_APACHELIKEPLACKHANDLER_MOCK_%s_CLASS', $key; |
47
|
4
|
|
50
|
|
|
15
|
${$_name_to_var{$key}} = $ENV{$env_name} || die "You need to set \$ENV{$env_name} to a mock class"; |
|
4
|
|
|
|
|
80
|
|
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
BEGIN |
52
|
|
|
|
|
|
|
{ |
53
|
1
|
|
|
1
|
|
19
|
__PACKAGE__->valid_params |
54
|
|
|
|
|
|
|
( ah => { isa => 'HTML::MasonX::ApacheLikePlackHandler', |
55
|
|
|
|
|
|
|
descr => 'An ApacheHandler to handle web requests', |
56
|
|
|
|
|
|
|
public => 0 }, |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
apache_req => { isa => $APACHE2_REQUEST_INSTANCE_CLASS, default => undef, |
59
|
|
|
|
|
|
|
descr => "An Apache request object", |
60
|
|
|
|
|
|
|
public => 0 }, |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
cgi_object => { isa => 'CGI', default => undef, |
63
|
|
|
|
|
|
|
descr => "A CGI.pm request object", |
64
|
|
|
|
|
|
|
public => 0 }, |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
auto_send_headers => { parse => 'boolean', type => BOOLEAN, default => 1, |
67
|
|
|
|
|
|
|
descr => "Whether HTTP headers should be auto-generated" }, |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
use HTML::Mason::MethodMaker |
72
|
1
|
|
|
|
|
2
|
( read_write => [ map { [ $_ => __PACKAGE__->validation_spec->{$_} ] } |
|
3
|
|
|
|
|
120
|
|
73
|
1
|
|
|
1
|
|
73
|
qw( ah apache_req auto_send_headers ) ] ); |
|
1
|
|
|
|
|
2
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# A hack for subrequests |
76
|
0
|
|
|
0
|
|
0
|
sub _properties { qw(ah apache_req), shift->SUPER::_properties } |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub new |
79
|
|
|
|
|
|
|
{ |
80
|
0
|
|
|
0
|
|
0
|
my $class = shift; |
81
|
0
|
|
|
|
|
0
|
my $self = $class->SUPER::new(@_); # Magic! |
82
|
|
|
|
|
|
|
|
83
|
0
|
0
|
0
|
|
|
0
|
unless ($self->apache_req or $self->cgi_object) |
84
|
|
|
|
|
|
|
{ |
85
|
0
|
|
|
|
|
0
|
param_error __PACKAGE__ . "->new: must specify 'apache_req' or 'cgi_object' parameter"; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# Record a flag indicating whether the user passed a custom out_method |
89
|
0
|
|
|
|
|
0
|
my %params = @_; |
90
|
0
|
|
|
|
|
0
|
$self->ah->{has_custom_out_method} = exists $params{out_method}; |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
0
|
return $self; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub cgi_object |
96
|
|
|
|
|
|
|
{ |
97
|
0
|
|
|
0
|
|
0
|
my ($self) = @_; |
98
|
|
|
|
|
|
|
|
99
|
0
|
0
|
|
|
|
0
|
error "Can't call cgi_object() unless 'args_method' is set to CGI.\n" |
100
|
|
|
|
|
|
|
unless $self->ah->args_method eq 'CGI'; |
101
|
|
|
|
|
|
|
|
102
|
0
|
0
|
|
|
|
0
|
if (defined($_[1])) { |
103
|
0
|
|
|
|
|
0
|
$self->{cgi_object} = $_[1]; |
104
|
|
|
|
|
|
|
} else { |
105
|
|
|
|
|
|
|
# We may not have created a CGI object if, say, request was a |
106
|
|
|
|
|
|
|
# GET with no query string. Create one on the fly if necessary. |
107
|
0
|
|
0
|
|
|
0
|
$self->{cgi_object} ||= CGI->new(''); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
0
|
return $self->{cgi_object}; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# |
114
|
|
|
|
|
|
|
# Override this method to return NOT_FOUND when we get a |
115
|
|
|
|
|
|
|
# TopLevelNotFound exception. In case of POST we must trick |
116
|
|
|
|
|
|
|
# Apache into not reading POST content again. Wish there were |
117
|
|
|
|
|
|
|
# a more standardized way to do this... |
118
|
|
|
|
|
|
|
# |
119
|
|
|
|
|
|
|
sub exec |
120
|
|
|
|
|
|
|
{ |
121
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
122
|
0
|
|
|
|
|
0
|
my $r = $self->apache_req; |
123
|
0
|
|
|
|
|
0
|
my $retval; |
124
|
|
|
|
|
|
|
|
125
|
0
|
0
|
|
|
|
0
|
if ( $self->is_subrequest ) |
126
|
|
|
|
|
|
|
{ |
127
|
|
|
|
|
|
|
# no need to go through all the rigamorale below for |
128
|
|
|
|
|
|
|
# subrequests, and it may even break things to do so, since |
129
|
|
|
|
|
|
|
# $r's print should only be redefined once. |
130
|
0
|
|
|
|
|
0
|
$retval = $self->SUPER::exec(@_); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
else |
133
|
|
|
|
|
|
|
{ |
134
|
|
|
|
|
|
|
# ack, this has to be done at runtime to account for the fact |
135
|
|
|
|
|
|
|
# that Apache::Filter changes $r's class and implements its |
136
|
|
|
|
|
|
|
# own print() method. |
137
|
0
|
|
|
|
|
0
|
my $real_apache_print = $r->can('print'); |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# Remap $r->print to Mason's $m->print while executing |
140
|
|
|
|
|
|
|
# request, but just for this $r, in case user does an internal |
141
|
|
|
|
|
|
|
# redirect or apache subrequest. |
142
|
0
|
|
|
|
|
0
|
local $^W = 0; |
143
|
1
|
|
|
1
|
|
369
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
44
|
|
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
0
|
my $req_class = ref $r; |
146
|
1
|
|
|
1
|
|
10
|
no warnings 'redefine'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
310
|
|
147
|
0
|
|
|
|
|
0
|
local *{"$req_class\::print"} = sub { |
148
|
0
|
|
|
0
|
|
0
|
my $local_r = shift; |
149
|
0
|
0
|
|
|
|
0
|
return $self->print(@_) if $local_r eq $r; |
150
|
0
|
|
|
|
|
0
|
return $local_r->$real_apache_print(@_); |
151
|
0
|
|
|
|
|
0
|
}; |
152
|
0
|
|
|
|
|
0
|
$retval = $self->SUPER::exec(@_); |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# mod_perl 1 treats HTTP_OK and OK the same, but mod_perl-2 does not. |
156
|
0
|
0
|
0
|
|
|
0
|
return defined $retval && $retval ne HTTP_OK ? $retval : OK; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# |
160
|
|
|
|
|
|
|
# Override this method to always die when top level component is not found, |
161
|
|
|
|
|
|
|
# so we can return NOT_FOUND. |
162
|
|
|
|
|
|
|
# |
163
|
|
|
|
|
|
|
sub _handle_error |
164
|
|
|
|
|
|
|
{ |
165
|
0
|
|
|
0
|
|
0
|
my ($self, $err) = @_; |
166
|
|
|
|
|
|
|
|
167
|
0
|
0
|
|
|
|
0
|
if (isa_mason_exception($err, 'TopLevelNotFound')) { |
168
|
0
|
|
|
|
|
0
|
rethrow_exception $err; |
169
|
|
|
|
|
|
|
} else { |
170
|
0
|
0
|
|
|
|
0
|
if ( $self->error_format eq 'html' ) { |
171
|
0
|
|
|
|
|
0
|
$self->apache_req->content_type('text/html'); |
172
|
|
|
|
|
|
|
} |
173
|
0
|
|
|
|
|
0
|
$self->SUPER::_handle_error($err); |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub redirect |
178
|
|
|
|
|
|
|
{ |
179
|
0
|
|
|
0
|
|
0
|
my ($self, $url, $status) = @_; |
180
|
0
|
|
|
|
|
0
|
my $r = $self->apache_req; |
181
|
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
0
|
$r->method('GET'); |
183
|
0
|
|
|
|
|
0
|
$r->headers_in->unset('Content-length'); |
184
|
0
|
|
|
|
|
0
|
$r->err_headers_out->{Location} = $url; |
185
|
0
|
|
0
|
|
|
0
|
$self->clear_and_abort($status || REDIRECT); |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
#---------------------------------------------------------------------- |
189
|
|
|
|
|
|
|
# |
190
|
|
|
|
|
|
|
# APACHEHANDLER OBJECT |
191
|
|
|
|
|
|
|
# |
192
|
|
|
|
|
|
|
package HTML::MasonX::ApacheLikePlackHandler; |
193
|
|
|
|
|
|
|
|
194
|
1
|
|
|
1
|
|
5
|
use File::Path; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
65
|
|
195
|
1
|
|
|
1
|
|
6
|
use File::Spec; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
29
|
|
196
|
1
|
|
|
1
|
|
4
|
use HTML::Mason::Exceptions( abbr => [qw(param_error system_error error)] ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
197
|
1
|
|
|
1
|
|
1322
|
use HTML::Mason::Interp; |
|
1
|
|
|
|
|
82874
|
|
|
1
|
|
|
|
|
95
|
|
198
|
1
|
|
|
1
|
|
25
|
use HTML::Mason::Tools qw( load_pkg ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
114
|
|
199
|
1
|
|
|
1
|
|
6
|
use HTML::Mason::Utils; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
48
|
|
200
|
1
|
|
|
1
|
|
41
|
use Params::Validate qw(:all); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
428
|
|
201
|
|
|
|
|
|
|
Params::Validate::validation_options( on_fail => sub { param_error( join '', @_ ) } ); |
202
|
|
|
|
|
|
|
|
203
|
1
|
|
|
1
|
|
6
|
use constant OK => 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
99
|
|
204
|
1
|
|
|
1
|
|
5
|
use constant HTTP_OK => 200; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
51
|
|
205
|
1
|
|
|
1
|
|
6
|
use constant DECLINED => -1; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
42
|
|
206
|
1
|
|
|
1
|
|
5
|
use constant NOT_FOUND => 404; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
56
|
|
207
|
1
|
|
|
1
|
|
5
|
use constant REDIRECT => 302; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
40
|
|
208
|
|
|
|
|
|
|
|
209
|
1
|
|
|
1
|
|
6
|
use base qw(HTML::Mason::Handler); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1335
|
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
BEGIN |
212
|
|
|
|
|
|
|
{ |
213
|
1
|
|
|
1
|
|
691
|
__PACKAGE__->valid_params |
214
|
|
|
|
|
|
|
( |
215
|
|
|
|
|
|
|
apache_status_title => |
216
|
|
|
|
|
|
|
{ parse => 'string', type => SCALAR, default => 'HTML::Mason status', |
217
|
|
|
|
|
|
|
descr => "The title of the Apache::Status page" }, |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
args_method => |
220
|
|
|
|
|
|
|
{ parse => 'string', type => SCALAR, |
221
|
|
|
|
|
|
|
default => 'CGI', |
222
|
|
|
|
|
|
|
regex => qr/^(?:CGI|mod_perl)$/, |
223
|
|
|
|
|
|
|
descr => "Whether to use CGI.pm or Apache::Request for parsing the incoming HTTP request", |
224
|
|
|
|
|
|
|
}, |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
decline_dirs => |
227
|
|
|
|
|
|
|
{ parse => 'boolean', type => BOOLEAN, default => 1, |
228
|
|
|
|
|
|
|
descr => "Whether Mason should decline to handle requests for directories" }, |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# the only required param |
231
|
|
|
|
|
|
|
interp => |
232
|
|
|
|
|
|
|
{ isa => 'HTML::Mason::Interp', |
233
|
|
|
|
|
|
|
descr => "A Mason interpreter for processing components" }, |
234
|
|
|
|
|
|
|
); |
235
|
|
|
|
|
|
|
|
236
|
1
|
|
|
|
|
50
|
__PACKAGE__->contained_objects |
237
|
|
|
|
|
|
|
( |
238
|
|
|
|
|
|
|
interp => |
239
|
|
|
|
|
|
|
{ class => 'HTML::Mason::Interp', |
240
|
|
|
|
|
|
|
descr => 'The interp class coordinates multiple objects to handle request execution' |
241
|
|
|
|
|
|
|
}, |
242
|
|
|
|
|
|
|
); |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
use HTML::Mason::MethodMaker |
246
|
3
|
|
|
|
|
127
|
( read_only => [ 'args_method' ], |
247
|
1
|
|
|
|
|
4
|
read_write => [ map { [ $_ => __PACKAGE__->validation_spec->{$_} ] } |
248
|
|
|
|
|
|
|
qw( apache_status_title |
249
|
|
|
|
|
|
|
decline_dirs |
250
|
|
|
|
|
|
|
interp ) ] |
251
|
1
|
|
|
1
|
|
75
|
); |
|
1
|
|
|
|
|
2
|
|
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
sub _get_apache_server |
254
|
|
|
|
|
|
|
{ |
255
|
1
|
|
|
1
|
|
23
|
return $APACHE2_SERVERUTIL_CLASS->server(); |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
my ($STARTED); |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
# The "if _get_apache_server" bit is a hack to let this module load |
261
|
|
|
|
|
|
|
# when not under mod_perl, which is needed to generate Params.pod |
262
|
|
|
|
|
|
|
__PACKAGE__->_startup() if eval { _get_apache_server }; |
263
|
|
|
|
|
|
|
sub _startup |
264
|
|
|
|
|
|
|
{ |
265
|
0
|
|
|
0
|
|
|
my $pack = shift; |
266
|
0
|
0
|
|
|
|
|
return if $STARTED++; # Allows a subclass to call this method without running it twice |
267
|
|
|
|
|
|
|
|
268
|
0
|
0
|
|
|
|
|
if ( my $args_method = $pack->_get_string_param('MasonArgsMethod') ) |
269
|
|
|
|
|
|
|
{ |
270
|
0
|
0
|
|
|
|
|
if ($args_method eq 'CGI') |
|
|
0
|
|
|
|
|
|
271
|
|
|
|
|
|
|
{ |
272
|
0
|
0
|
|
|
|
|
eval { require CGI unless defined CGI->VERSION; }; |
|
0
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# mod_perl2 does not warn about this, so somebody should |
274
|
0
|
0
|
|
|
|
|
if (CGI->VERSION < 3.08) { |
275
|
0
|
|
|
|
|
|
die "CGI version 3.08 is required to support mod_perl2 API"; |
276
|
|
|
|
|
|
|
} |
277
|
0
|
0
|
|
|
|
|
die $@ if $@; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
elsif ( $args_method eq 'mod_perl' ) |
280
|
|
|
|
|
|
|
{ |
281
|
0
|
0
|
|
|
|
|
eval "require $APACHE2_REQUEST_CLASS" unless defined $APACHE2_REQUEST_CLASS->VERSION; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# Register with Apache::Status at module startup. Will get replaced |
287
|
|
|
|
|
|
|
# with a more informative status once an interpreter has been created. |
288
|
|
|
|
|
|
|
my $status_name = 'mason0001'; |
289
|
|
|
|
|
|
|
if ( load_pkg($APACHE2_STATUS_CLASS) ) |
290
|
|
|
|
|
|
|
{ |
291
|
|
|
|
|
|
|
$APACHE2_STATUS_CLASS->menu_item |
292
|
|
|
|
|
|
|
($status_name => __PACKAGE__->allowed_params->{apache_status_title}{default}, |
293
|
|
|
|
|
|
|
sub { ["(no interpreters created in this child yet)"] }); |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
my %AH_BY_CONFIG; |
298
|
|
|
|
|
|
|
sub make_ah |
299
|
|
|
|
|
|
|
{ |
300
|
0
|
|
|
0
|
0
|
|
my ($package, $r) = @_; |
301
|
|
|
|
|
|
|
|
302
|
0
|
|
|
|
|
|
my $config = $r->dir_config; |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# |
305
|
|
|
|
|
|
|
# If the user has virtual hosts, each with a different document |
306
|
|
|
|
|
|
|
# root, then we will have to be called from the handler method. |
307
|
|
|
|
|
|
|
# This means we have an active request. In order to distinguish |
308
|
|
|
|
|
|
|
# between virtual hosts with identical config directives that have |
309
|
|
|
|
|
|
|
# no comp root defined (meaning they expect to use the default |
310
|
|
|
|
|
|
|
# comp root), we append the document root for the current request |
311
|
|
|
|
|
|
|
# to the key. |
312
|
|
|
|
|
|
|
# |
313
|
0
|
|
|
|
|
|
my $key = |
314
|
|
|
|
|
|
|
( join $;, |
315
|
|
|
|
|
|
|
$r->document_root, |
316
|
0
|
|
|
|
|
|
map { $_, sort $config->get($_) } |
317
|
0
|
|
|
|
|
|
grep { /^Mason/ } |
318
|
|
|
|
|
|
|
keys %$config |
319
|
|
|
|
|
|
|
); |
320
|
|
|
|
|
|
|
|
321
|
0
|
0
|
|
|
|
|
return $AH_BY_CONFIG{$key} if exists $AH_BY_CONFIG{$key}; |
322
|
|
|
|
|
|
|
|
323
|
0
|
|
|
|
|
|
my %p = $package->_get_mason_params($r); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# can't use hash_list for this one because it's _either_ a string |
326
|
|
|
|
|
|
|
# or a hash_list |
327
|
0
|
0
|
|
|
|
|
if (exists $p{comp_root}) { |
328
|
0
|
0
|
0
|
|
|
|
if (@{$p{comp_root}} == 1 && $p{comp_root}->[0] !~ /=>/) { |
|
0
|
|
|
|
|
|
|
329
|
0
|
|
|
|
|
|
$p{comp_root} = $p{comp_root}[0]; # Convert to a simple string |
330
|
|
|
|
|
|
|
} else { |
331
|
0
|
|
|
|
|
|
my @roots; |
332
|
0
|
|
|
|
|
|
foreach my $root (@{$p{comp_root}}) { |
|
0
|
|
|
|
|
|
|
333
|
0
|
|
|
|
|
|
$root = [ split /\s*=>\s*/, $root, 2 ]; |
334
|
0
|
0
|
|
|
|
|
param_error "Configuration parameter MasonCompRoot must be either ". |
335
|
|
|
|
|
|
|
"a single string value or multiple key/value pairs ". |
336
|
|
|
|
|
|
|
"like 'foo => /home/mason/foo'. Invalid parameter:\n$root" |
337
|
|
|
|
|
|
|
unless defined $root->[1]; |
338
|
|
|
|
|
|
|
|
339
|
0
|
|
|
|
|
|
push @roots, $root; |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
$p{comp_root} = \@roots; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
|
346
|
0
|
|
|
|
|
|
my $ah = $package->new(%p, $r); |
347
|
0
|
0
|
|
|
|
|
$AH_BY_CONFIG{$key} = $ah if $key; |
348
|
|
|
|
|
|
|
|
349
|
0
|
|
|
|
|
|
return $ah; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# The following routines handle getting information from $r->dir_config |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
sub calm_form { |
355
|
|
|
|
|
|
|
# Transform from StudlyCaps to name_like_this |
356
|
0
|
|
|
0
|
0
|
|
my ($self, $string) = @_; |
357
|
0
|
|
|
|
|
|
$string =~ s/^Mason//; |
358
|
0
|
0
|
|
|
|
|
$string =~ s/(^|.)([A-Z])/$1 ? "$1\L_$2" : "\L$2"/ge; |
|
0
|
|
|
|
|
|
|
359
|
0
|
|
|
|
|
|
return $string; |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
sub studly_form { |
363
|
|
|
|
|
|
|
# Transform from name_like_this to StudlyCaps |
364
|
0
|
|
|
0
|
0
|
|
my ($self, $string) = @_; |
365
|
0
|
|
|
|
|
|
$string =~ s/(?:^|_)(\w)/\U$1/g; |
366
|
0
|
|
|
|
|
|
return $string; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub _get_mason_params |
370
|
|
|
|
|
|
|
{ |
371
|
0
|
|
|
0
|
|
|
my $self = shift; |
372
|
0
|
|
|
|
|
|
my $r = shift; |
373
|
|
|
|
|
|
|
|
374
|
0
|
0
|
|
|
|
|
my $config = $r ? $r->dir_config : _get_apache_server->dir_config; |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
# Get all params starting with 'Mason' |
377
|
0
|
|
|
|
|
|
my %candidates; |
378
|
|
|
|
|
|
|
|
379
|
0
|
|
|
|
|
|
foreach my $studly ( keys %$config ) |
380
|
|
|
|
|
|
|
{ |
381
|
0
|
0
|
|
|
|
|
(my $calm = $studly) =~ s/^Mason// or next; |
382
|
0
|
|
|
|
|
|
$calm = $self->calm_form($calm); |
383
|
|
|
|
|
|
|
|
384
|
0
|
|
|
|
|
|
$candidates{$calm} = $config->{$studly}; |
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
|
387
|
0
|
0
|
|
|
|
|
return unless %candidates; |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# |
390
|
|
|
|
|
|
|
# We will accumulate all the string versions of the keys and |
391
|
|
|
|
|
|
|
# values here for later use. |
392
|
|
|
|
|
|
|
# |
393
|
0
|
|
|
|
|
|
return ( map { $_ => |
|
0
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
scalar $self->_get_param( $_, \%candidates, $config, $r ) |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
keys %candidates ); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub _get_param { |
400
|
|
|
|
|
|
|
# Gets a single config item from dir_config. |
401
|
|
|
|
|
|
|
|
402
|
0
|
|
|
0
|
|
|
my ($self, $key, $candidates, $config, $r) = @_; |
403
|
|
|
|
|
|
|
|
404
|
0
|
|
|
|
|
|
$key = $self->calm_form($key); |
405
|
|
|
|
|
|
|
|
406
|
0
|
0
|
0
|
|
|
|
my $spec = $self->allowed_params( $candidates || {} )->{$key} |
407
|
|
|
|
|
|
|
or error "Unknown config item '$key'"; |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
# Guess the default parse type from the Params::Validate validation spec |
410
|
0
|
0
|
0
|
|
|
|
my $type = ($spec->{parse} or |
411
|
|
|
|
|
|
|
$spec->{type} & ARRAYREF ? 'list' : |
412
|
|
|
|
|
|
|
$spec->{type} & SCALAR ? 'string' : |
413
|
|
|
|
|
|
|
$spec->{type} & CODEREF ? 'code' : |
414
|
|
|
|
|
|
|
undef) |
415
|
|
|
|
|
|
|
or error "Unknown parse type for config item '$key'"; |
416
|
|
|
|
|
|
|
|
417
|
0
|
|
|
|
|
|
my $method = "_get_${type}_param"; |
418
|
0
|
|
|
|
|
|
return $self->$method('Mason'.$self->studly_form($key), $config, $r); |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub _get_string_param |
422
|
|
|
|
|
|
|
{ |
423
|
0
|
|
|
0
|
|
|
my $self = shift; |
424
|
0
|
|
|
|
|
|
return scalar $self->_get_val(@_); |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
sub _get_boolean_param |
428
|
|
|
|
|
|
|
{ |
429
|
0
|
|
|
0
|
|
|
my $self = shift; |
430
|
0
|
|
|
|
|
|
return scalar $self->_get_val(@_); |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub _get_code_param |
434
|
|
|
|
|
|
|
{ |
435
|
0
|
|
|
0
|
|
|
my $self = shift; |
436
|
0
|
|
|
|
|
|
my $p = $_[0]; |
437
|
0
|
|
|
|
|
|
my $val = $self->_get_val(@_); |
438
|
|
|
|
|
|
|
|
439
|
0
|
0
|
|
|
|
|
return unless $val; |
440
|
|
|
|
|
|
|
|
441
|
0
|
|
|
|
|
|
my $sub_ref = eval $val; |
442
|
|
|
|
|
|
|
|
443
|
0
|
0
|
|
|
|
|
param_error "Configuration parameter '$p' is not valid perl:\n$@\n" |
444
|
|
|
|
|
|
|
if $@; |
445
|
|
|
|
|
|
|
|
446
|
0
|
|
|
|
|
|
return $sub_ref; |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
sub _get_list_param |
450
|
|
|
|
|
|
|
{ |
451
|
0
|
|
|
0
|
|
|
my $self = shift; |
452
|
0
|
|
|
|
|
|
my @val = $self->_get_val(@_); |
453
|
0
|
0
|
0
|
|
|
|
if (@val == 1 && ! defined $val[0]) |
454
|
|
|
|
|
|
|
{ |
455
|
0
|
|
|
|
|
|
@val = (); |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
0
|
|
|
|
|
|
return \@val; |
459
|
|
|
|
|
|
|
} |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
sub _get_hash_list_param |
462
|
|
|
|
|
|
|
{ |
463
|
0
|
|
|
0
|
|
|
my $self = shift; |
464
|
0
|
|
|
|
|
|
my @val = $self->_get_val(@_); |
465
|
0
|
0
|
0
|
|
|
|
if (@val == 1 && ! defined $val[0]) |
466
|
|
|
|
|
|
|
{ |
467
|
0
|
|
|
|
|
|
return {}; |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
|
470
|
0
|
|
|
|
|
|
my %hash; |
471
|
0
|
|
|
|
|
|
foreach my $pair (@val) |
472
|
|
|
|
|
|
|
{ |
473
|
0
|
|
|
|
|
|
my ($key, $val) = split /\s*=>\s*/, $pair, 2; |
474
|
0
|
0
|
0
|
|
|
|
param_error "Configuration parameter $_[0] must be a key/value pair ". |
475
|
|
|
|
|
|
|
qq|like "foo => bar". Invalid parameter:\n$pair| |
476
|
|
|
|
|
|
|
unless defined $key && defined $val; |
477
|
|
|
|
|
|
|
|
478
|
0
|
|
|
|
|
|
$hash{$key} = $val; |
479
|
|
|
|
|
|
|
} |
480
|
|
|
|
|
|
|
|
481
|
0
|
|
|
|
|
|
return \%hash; |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
sub _get_val |
485
|
|
|
|
|
|
|
{ |
486
|
0
|
|
|
0
|
|
|
my ($self, $p, $config, $r) = @_; |
487
|
|
|
|
|
|
|
|
488
|
0
|
|
|
|
|
|
my @val; |
489
|
0
|
0
|
0
|
|
|
|
if (wantarray || !$config) |
490
|
|
|
|
|
|
|
{ |
491
|
0
|
0
|
|
|
|
|
if ($config) |
492
|
|
|
|
|
|
|
{ |
493
|
0
|
|
|
|
|
|
@val = $config->get($p); |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
else |
496
|
|
|
|
|
|
|
{ |
497
|
0
|
0
|
|
|
|
|
my $c = $r ? $r : _get_apache_server; |
498
|
0
|
|
|
|
|
|
@val = $c->dir_config->get($p); |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
} |
501
|
|
|
|
|
|
|
else |
502
|
|
|
|
|
|
|
{ |
503
|
0
|
0
|
|
|
|
|
@val = exists $config->{$p} ? $config->{$p} : (); |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
0
|
0
|
0
|
|
|
|
param_error "Only a single value is allowed for configuration parameter '$p'\n" |
507
|
|
|
|
|
|
|
if @val > 1 && ! wantarray; |
508
|
|
|
|
|
|
|
|
509
|
0
|
0
|
|
|
|
|
return wantarray ? @val : $val[0]; |
510
|
|
|
|
|
|
|
} |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
sub new |
513
|
|
|
|
|
|
|
{ |
514
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
# Get $r off end of params if its there |
517
|
0
|
|
|
|
|
|
my $r; |
518
|
0
|
0
|
|
|
|
|
$r = pop() if @_ % 2; |
519
|
0
|
|
|
|
|
|
my %params = @_; |
520
|
|
|
|
|
|
|
|
521
|
0
|
|
|
|
|
|
my %defaults; |
522
|
0
|
0
|
|
|
|
|
$defaults{request_class} = 'HTML::MasonX::Request::ApacheLikePlackHandler' |
523
|
|
|
|
|
|
|
unless exists $params{request}; |
524
|
|
|
|
|
|
|
|
525
|
0
|
|
|
|
|
|
my $allowed_params = $class->allowed_params(%defaults, %params); |
526
|
|
|
|
|
|
|
|
527
|
0
|
0
|
0
|
|
|
|
if ( exists $allowed_params->{comp_root} and |
528
|
|
|
|
|
|
|
my $req = $r ) # DocumentRoot is only available inside requests |
529
|
|
|
|
|
|
|
{ |
530
|
0
|
|
|
|
|
|
$defaults{comp_root} = $req->document_root; |
531
|
|
|
|
|
|
|
} |
532
|
|
|
|
|
|
|
|
533
|
0
|
0
|
0
|
|
|
|
if (exists $allowed_params->{data_dir} and not exists $params{data_dir}) |
534
|
|
|
|
|
|
|
{ |
535
|
|
|
|
|
|
|
# constructs path to /mason |
536
|
0
|
0
|
|
|
|
|
if (UNIVERSAL::can($APACHE2_SERVERUTIL_CLASS,'server_root')) { |
537
|
1
|
|
|
1
|
|
2016
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2552
|
|
538
|
0
|
|
|
|
|
|
$defaults{data_dir} = File::Spec->catdir(&{"$APACHE2_SERVERUTIL_CLASS\::server_root"}(),'mason'); |
|
0
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
} else { |
540
|
0
|
|
|
|
|
|
$defaults{data_dir} = Apache->server_root_relative('mason'); |
541
|
|
|
|
|
|
|
} |
542
|
0
|
|
|
|
|
|
my $def = $defaults{data_dir}; |
543
|
0
|
0
|
|
|
|
|
param_error "Default data_dir (MasonDataDir) '$def' must be an absolute path" |
544
|
|
|
|
|
|
|
unless File::Spec->file_name_is_absolute($def); |
545
|
|
|
|
|
|
|
|
546
|
0
|
|
|
|
|
|
my @levels = File::Spec->splitdir($def); |
547
|
0
|
0
|
|
|
|
|
param_error "Default data_dir (MasonDataDir) '$def' must be more than two levels deep (or must be set explicitly)" |
548
|
|
|
|
|
|
|
if @levels <= 3; |
549
|
|
|
|
|
|
|
} |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
# Set default error_format based on error_mode |
552
|
0
|
0
|
0
|
|
|
|
if (exists($params{error_mode}) and $params{error_mode} eq 'fatal') { |
553
|
0
|
|
|
|
|
|
$defaults{error_format} = 'line'; |
554
|
|
|
|
|
|
|
} else { |
555
|
0
|
|
|
|
|
|
$defaults{error_mode} = 'output'; |
556
|
0
|
|
|
|
|
|
$defaults{error_format} = 'html'; |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
# Push $r onto default allow_globals |
560
|
0
|
0
|
|
|
|
|
if (exists $allowed_params->{allow_globals}) { |
561
|
0
|
0
|
|
|
|
|
if ( $params{allow_globals} ) { |
562
|
0
|
|
|
|
|
|
push @{ $params{allow_globals} }, '$r'; |
|
0
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
} else { |
564
|
0
|
|
|
|
|
|
$defaults{allow_globals} = ['$r']; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
|
568
|
0
|
|
|
|
|
|
my $self = eval { $class->SUPER::new(%defaults, %params) }; |
|
0
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
# We catch this exception just to provide a better error message |
571
|
0
|
0
|
0
|
|
|
|
if ( $@ && isa_mason_exception( $@, 'Params' ) && $@->message =~ /comp_root/ ) |
|
|
|
0
|
|
|
|
|
572
|
|
|
|
|
|
|
{ |
573
|
0
|
|
|
|
|
|
param_error "No comp_root specified and cannot determine DocumentRoot." . |
574
|
|
|
|
|
|
|
" Please provide comp_root explicitly."; |
575
|
|
|
|
|
|
|
} |
576
|
0
|
|
|
|
|
|
rethrow_exception $@; |
577
|
|
|
|
|
|
|
|
578
|
0
|
0
|
|
|
|
|
unless ( $self->interp->resolver->can('apache_request_to_comp_path') ) |
579
|
|
|
|
|
|
|
{ |
580
|
0
|
|
|
|
|
|
error "The resolver class your Interp object uses does not implement " . |
581
|
|
|
|
|
|
|
"the 'apache_request_to_comp_path' method. This means that ApacheHandler " . |
582
|
|
|
|
|
|
|
"cannot resolve requests. Are you using a handler.pl file created ". |
583
|
|
|
|
|
|
|
"before version 1.10? Please see the handler.pl sample " . |
584
|
|
|
|
|
|
|
"that comes with the latest version of Mason."; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
# If we're running as superuser, change file ownership to http user & group |
588
|
0
|
0
|
0
|
|
|
|
if (!($> || $<) && $self->interp->files_written) |
|
|
|
0
|
|
|
|
|
589
|
|
|
|
|
|
|
{ |
590
|
0
|
0
|
|
|
|
|
chown $self->get_uid_gid, $self->interp->files_written |
591
|
|
|
|
|
|
|
or system_error( "Can't change ownership of files written by interp object: $!\n" ); |
592
|
|
|
|
|
|
|
} |
593
|
|
|
|
|
|
|
|
594
|
0
|
|
|
|
|
|
$self->_initialize; |
595
|
0
|
|
|
|
|
|
return $self; |
596
|
|
|
|
|
|
|
} |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
sub get_uid_gid |
599
|
|
|
|
|
|
|
{ |
600
|
|
|
|
|
|
|
# Apache2 lacks $s->uid. |
601
|
|
|
|
|
|
|
# Workaround by searching the config tree. |
602
|
0
|
|
|
0
|
0
|
|
die "The wrapper layer using the Apache2::Directive class is unimplemented"; |
603
|
|
|
|
|
|
|
|
604
|
0
|
|
|
|
|
|
my $conftree = Apache2::Directive::conftree(); |
605
|
0
|
|
|
|
|
|
my $user = $conftree->lookup('User'); |
606
|
0
|
|
|
|
|
|
my $group = $conftree->lookup('Group'); |
607
|
|
|
|
|
|
|
|
608
|
0
|
|
|
|
|
|
$user =~ s/^["'](.*)["']$/$1/; |
609
|
0
|
|
|
|
|
|
$group =~ s/^["'](.*)["']$/$1/; |
610
|
|
|
|
|
|
|
|
611
|
0
|
0
|
|
|
|
|
my $uid = $user ? getpwnam($user) : $>; |
612
|
0
|
0
|
|
|
|
|
my $gid = $group ? getgrnam($group) : $); |
613
|
|
|
|
|
|
|
|
614
|
0
|
|
|
|
|
|
return ($uid, $gid); |
615
|
|
|
|
|
|
|
} |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
sub _initialize { |
618
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
619
|
|
|
|
|
|
|
|
620
|
0
|
0
|
|
|
|
|
if ($self->args_method eq 'mod_perl') { |
621
|
0
|
0
|
|
|
|
|
unless (defined $APACHE2_REQUEST_CLASS->VERSION) { |
622
|
0
|
|
|
|
|
|
warn "Loading $APACHE2_REQUEST_CLASS at runtime. You could " . |
623
|
|
|
|
|
|
|
"increase shared memory between Apache processes by ". |
624
|
|
|
|
|
|
|
"preloading it in your httpd.conf or handler.pl file\n"; |
625
|
0
|
|
|
|
|
|
eval "require $APACHE2_REQUEST_CLASS"; |
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
} else { |
628
|
0
|
0
|
|
|
|
|
unless (defined CGI->VERSION) { |
629
|
0
|
|
|
|
|
|
warn "Loading CGI at runtime. You could increase shared ". |
630
|
|
|
|
|
|
|
"memory between Apache processes by preloading it in ". |
631
|
|
|
|
|
|
|
"your httpd.conf or handler.pl file\n"; |
632
|
|
|
|
|
|
|
|
633
|
0
|
|
|
|
|
|
require CGI; |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
# Add an HTML::Mason menu item to the /perl-status page. |
638
|
0
|
0
|
|
|
|
|
if (defined $APACHE2_STATUS_CLASS->VERSION) { |
639
|
|
|
|
|
|
|
# A closure, carries a reference to $self |
640
|
|
|
|
|
|
|
my $statsub = sub { |
641
|
0
|
|
|
0
|
|
|
my ($r,$q) = @_; # request and CGI objects |
642
|
0
|
0
|
|
|
|
|
return [] if !defined($r); |
643
|
|
|
|
|
|
|
|
644
|
0
|
0
|
0
|
|
|
|
if ($r->path_info and $r->path_info =~ /expire_code_cache=(.*)/) { |
645
|
0
|
|
|
|
|
|
$self->interp->delete_from_code_cache($1); |
646
|
|
|
|
|
|
|
} |
647
|
|
|
|
|
|
|
|
648
|
0
|
|
|
|
|
|
return ["" . $self->apache_status_title . "" , |
649
|
|
|
|
|
|
|
$self->status_as_html(apache_req => $r), |
650
|
|
|
|
|
|
|
$self->interp->status_as_html(ah => $self, apache_req => $r)]; |
651
|
0
|
|
|
|
|
|
}; |
652
|
0
|
|
|
|
|
|
local $^W = 0; # to avoid subroutine redefined warnings |
653
|
0
|
|
|
|
|
|
$APACHE2_STATUS_CLASS->menu_item($status_name, $self->apache_status_title, $statsub); |
654
|
|
|
|
|
|
|
} |
655
|
|
|
|
|
|
|
|
656
|
0
|
|
|
|
|
|
my $interp = $self->interp; |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
# |
659
|
|
|
|
|
|
|
# Allow global $r in components |
660
|
|
|
|
|
|
|
# |
661
|
|
|
|
|
|
|
# This is somewhat redundant with code in new, but seems to be |
662
|
|
|
|
|
|
|
# needed since the user may simply create their own interp. |
663
|
|
|
|
|
|
|
# |
664
|
0
|
0
|
|
|
|
|
$interp->compiler->add_allowed_globals('$r') |
665
|
|
|
|
|
|
|
if $interp->compiler->can('add_allowed_globals'); |
666
|
|
|
|
|
|
|
} |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
# Generate HTML that describes ApacheHandler's current status. |
669
|
|
|
|
|
|
|
# This is used in things like Apache::Status reports. |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
sub status_as_html { |
672
|
0
|
|
|
0
|
0
|
|
my ($self, %p) = @_; |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
# Should I be scared about this? =) |
675
|
|
|
|
|
|
|
|
676
|
0
|
|
|
|
|
|
my $comp_source = <<'EOF'; |
677
|
|
|
|
|
|
|
ApacheHandler properties: |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
<%perl> |
682
|
|
|
|
|
|
|
foreach my $property (sort keys %$ah) { |
683
|
|
|
|
|
|
|
my $val = $ah->{$property}; |
684
|
|
|
|
|
|
|
my $default = ( defined $val && defined $valid{$property}{default} && $val eq $valid{$property}{default} ) || ( ! defined $val && exists $valid{$property}{default} && ! defined $valid{$property}{default} ); |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
my $display = $val; |
687
|
|
|
|
|
|
|
if (ref $val) { |
688
|
|
|
|
|
|
|
$display = ''; |
689
|
|
|
|
|
|
|
# only object can ->can, others die |
690
|
|
|
|
|
|
|
my $is_object = eval { $val->can('anything'); 1 }; |
691
|
|
|
|
|
|
|
if ($is_object) { |
692
|
|
|
|
|
|
|
$display .= ref $val . ' object'; |
693
|
|
|
|
|
|
|
} else { |
694
|
|
|
|
|
|
|
if (UNIVERSAL::isa($val, 'ARRAY')) { |
695
|
|
|
|
|
|
|
$display .= 'ARRAY reference - [ '; |
696
|
|
|
|
|
|
|
$display .= join ', ', @$val; |
697
|
|
|
|
|
|
|
$display .= '] '; |
698
|
|
|
|
|
|
|
} elsif (UNIVERSAL::isa($val, 'HASH')) { |
699
|
|
|
|
|
|
|
$display .= 'HASH reference - { '; |
700
|
|
|
|
|
|
|
my @pairs; |
701
|
|
|
|
|
|
|
while (my ($k, $v) = each %$val) { |
702
|
|
|
|
|
|
|
push @pairs, "$k => $v"; |
703
|
|
|
|
|
|
|
} |
704
|
|
|
|
|
|
|
$display .= join ', ', @pairs; |
705
|
|
|
|
|
|
|
$display .= ' }'; |
706
|
|
|
|
|
|
|
} else { |
707
|
|
|
|
|
|
|
$display = ref $val . ' reference'; |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
} |
710
|
|
|
|
|
|
|
$display .= ''; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
defined $display && $display =~ s,([\x00-\x1F]),'control-' . chr( ord('A') + ord($1) - 1 ) . '',eg; # does this work for non-ASCII? |
714
|
|
|
|
|
|
|
%perl> |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
| |
717
|
|
|
|
|
|
|
<% $property | h %> |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
| |
720
|
|
|
|
|
|
|
<% defined $display ? $display : 'undef' %> |
721
|
|
|
|
|
|
|
<% $default ? '(default)' : '' %> |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
% } |
725
|
|
|
|
|
|
|
| |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
<%args> |
730
|
|
|
|
|
|
|
$ah # The ApacheHandler we'll elucidate |
731
|
|
|
|
|
|
|
%valid # Contains default values for member data |
732
|
|
|
|
|
|
|
%args> |
733
|
|
|
|
|
|
|
EOF |
734
|
|
|
|
|
|
|
|
735
|
0
|
|
|
|
|
|
my $interp = $self->interp; |
736
|
0
|
|
|
|
|
|
my $comp = $interp->make_component(comp_source => $comp_source); |
737
|
0
|
|
|
|
|
|
my $out; |
738
|
|
|
|
|
|
|
|
739
|
0
|
|
|
|
|
|
$self->interp->make_request |
740
|
|
|
|
|
|
|
( comp => $comp, |
741
|
|
|
|
|
|
|
args => [ah => $self, valid => $interp->allowed_params], |
742
|
|
|
|
|
|
|
ah => $self, |
743
|
|
|
|
|
|
|
apache_req => $p{apache_req}, |
744
|
|
|
|
|
|
|
out_method => \$out, |
745
|
|
|
|
|
|
|
)->exec; |
746
|
|
|
|
|
|
|
|
747
|
0
|
|
|
|
|
|
return $out; |
748
|
|
|
|
|
|
|
} |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
sub handle_request |
751
|
|
|
|
|
|
|
{ |
752
|
0
|
|
|
0
|
0
|
|
my ($self, $r) = @_; |
753
|
|
|
|
|
|
|
|
754
|
0
|
|
|
|
|
|
my $req = $self->prepare_request($r); |
755
|
0
|
0
|
|
|
|
|
return $req unless ref($req); |
756
|
|
|
|
|
|
|
|
757
|
0
|
|
|
|
|
|
return $req->exec; |
758
|
|
|
|
|
|
|
} |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
sub prepare_request |
761
|
|
|
|
|
|
|
{ |
762
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
763
|
|
|
|
|
|
|
|
764
|
0
|
|
|
|
|
|
my $r = $self->_apache_request_object(@_); |
765
|
|
|
|
|
|
|
|
766
|
0
|
|
|
|
|
|
my $interp = $self->interp; |
767
|
|
|
|
|
|
|
|
768
|
0
|
|
|
|
|
|
my $fs_type = $self->_request_fs_type($r); |
769
|
|
|
|
|
|
|
|
770
|
0
|
0
|
0
|
|
|
|
return DECLINED if $fs_type eq 'dir' && $self->decline_dirs; |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
# |
773
|
|
|
|
|
|
|
# Compute the component path via the resolver. Return NOT_FOUND on failure. |
774
|
|
|
|
|
|
|
# |
775
|
0
|
|
|
|
|
|
my $comp_path = $interp->resolver->apache_request_to_comp_path($r, $interp->comp_root_array); |
776
|
0
|
0
|
|
|
|
|
unless ($comp_path) { |
777
|
|
|
|
|
|
|
# |
778
|
|
|
|
|
|
|
# Append path_info if filename does not represent an existing file |
779
|
|
|
|
|
|
|
# (mainly for dhandlers). |
780
|
|
|
|
|
|
|
# |
781
|
0
|
|
|
|
|
|
my $pathname = $r->filename; |
782
|
0
|
0
|
|
|
|
|
$pathname .= $r->path_info unless $fs_type eq 'file'; |
783
|
|
|
|
|
|
|
|
784
|
0
|
|
|
|
|
|
warn "[Mason] Cannot resolve file to component: " . |
785
|
|
|
|
|
|
|
"$pathname (is file outside component root?)"; |
786
|
0
|
|
|
|
|
|
return $self->return_not_found($r); |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
|
789
|
0
|
|
|
|
|
|
my ($args, undef, $cgi_object) = $self->request_args($r); |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
# |
792
|
|
|
|
|
|
|
# Set up interpreter global variables. |
793
|
|
|
|
|
|
|
# |
794
|
0
|
|
|
|
|
|
$interp->set_global( r => $r ); |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
# If someone is using a custom request class that doesn't accept |
797
|
|
|
|
|
|
|
# 'ah' and 'apache_req' that's their problem. |
798
|
|
|
|
|
|
|
# |
799
|
0
|
|
|
|
|
|
my $m = eval { |
800
|
0
|
|
|
|
|
|
$interp->make_request( comp => $comp_path, |
801
|
|
|
|
|
|
|
args => [%$args], |
802
|
|
|
|
|
|
|
ah => $self, |
803
|
|
|
|
|
|
|
apache_req => $r, |
804
|
|
|
|
|
|
|
); |
805
|
|
|
|
|
|
|
}; |
806
|
|
|
|
|
|
|
|
807
|
0
|
0
|
|
|
|
|
if (my $err = $@) { |
808
|
|
|
|
|
|
|
# We rethrow everything but TopLevelNotFound, Abort, and Decline errors. |
809
|
|
|
|
|
|
|
|
810
|
0
|
0
|
|
|
|
|
if ( isa_mason_exception($@, 'TopLevelNotFound') ) { |
811
|
0
|
|
0
|
|
|
|
$r->log_error("[Mason] File does not exist: ", $r->filename . ($r->path_info || "")); |
812
|
0
|
|
|
|
|
|
return $self->return_not_found($r); |
813
|
|
|
|
|
|
|
} |
814
|
0
|
0
|
|
|
|
|
my $retval = ( isa_mason_exception($err, 'Abort') ? $err->aborted_value : |
|
|
0
|
|
|
|
|
|
815
|
|
|
|
|
|
|
isa_mason_exception($err, 'Decline') ? $err->declined_value : |
816
|
|
|
|
|
|
|
rethrow_exception $err ); |
817
|
0
|
0
|
0
|
|
|
|
$retval = OK if defined $retval && $retval eq HTTP_OK; |
818
|
0
|
0
|
|
|
|
|
unless ($retval) { |
819
|
0
|
0
|
|
|
|
|
unless ($r->notes('mason-sent-headers')) { |
820
|
0
|
|
|
|
|
|
$r->send_http_header(); |
821
|
|
|
|
|
|
|
} |
822
|
|
|
|
|
|
|
} |
823
|
0
|
|
|
|
|
|
return $retval; |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
|
826
|
0
|
0
|
|
|
|
|
$self->_set_mason_req_out_method($m, $r) unless $self->{has_custom_out_method}; |
827
|
|
|
|
|
|
|
|
828
|
0
|
0
|
0
|
|
|
|
$m->cgi_object($cgi_object) if $m->can('cgi_object') && $cgi_object; |
829
|
|
|
|
|
|
|
|
830
|
0
|
|
|
|
|
|
return $m; |
831
|
|
|
|
|
|
|
} |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
my $do_filter = sub { $_[0]->filter_register }; |
834
|
|
|
|
|
|
|
my $no_filter = sub { $_[0] }; |
835
|
|
|
|
|
|
|
sub _apache_request_object |
836
|
|
|
|
|
|
|
{ |
837
|
0
|
|
|
0
|
|
|
my $self = shift; |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
# We need to be careful to never assign a new apache (subclass) |
840
|
|
|
|
|
|
|
# object to $r or we will leak memory, at least with mp1. |
841
|
0
|
|
|
|
|
|
my $new_r = $_[0]; |
842
|
|
|
|
|
|
|
|
843
|
0
|
|
|
|
|
|
my $r_sub; |
844
|
0
|
|
|
|
|
|
my $filter = $_[0]->dir_config('Filter'); |
845
|
0
|
0
|
0
|
|
|
|
if ( defined $filter && lc $filter eq 'on' ) |
846
|
|
|
|
|
|
|
{ |
847
|
0
|
0
|
|
|
|
|
die "To use Apache::Filter with Mason you must have at least version 1.021 of Apache::Filter\n" |
848
|
|
|
|
|
|
|
unless Apache::Filter->VERSION >= 1.021; |
849
|
|
|
|
|
|
|
|
850
|
0
|
|
|
|
|
|
$r_sub = $do_filter; |
851
|
|
|
|
|
|
|
} |
852
|
|
|
|
|
|
|
else |
853
|
|
|
|
|
|
|
{ |
854
|
0
|
|
|
|
|
|
$r_sub = $no_filter; |
855
|
|
|
|
|
|
|
} |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
my $apreq_instance = |
858
|
0
|
|
|
0
|
|
|
sub { $APACHE2_REQUEST_CLASS->new( $_[0] ) }; |
|
0
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
return |
861
|
0
|
0
|
|
|
|
|
$r_sub->( $self->args_method eq 'mod_perl' ? |
862
|
|
|
|
|
|
|
$apreq_instance->( $new_r ) : |
863
|
|
|
|
|
|
|
$new_r |
864
|
|
|
|
|
|
|
); |
865
|
|
|
|
|
|
|
} |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
sub _request_fs_type |
868
|
|
|
|
|
|
|
{ |
869
|
0
|
|
|
0
|
|
|
my ($self, $r) = @_; |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
# |
872
|
|
|
|
|
|
|
# If filename is a directory, then either decline or simply reset |
873
|
|
|
|
|
|
|
# the content type, depending on the value of decline_dirs. |
874
|
|
|
|
|
|
|
# |
875
|
|
|
|
|
|
|
# ** We should be able to use $r->finfo here, but finfo is broken |
876
|
|
|
|
|
|
|
# in some versions of mod_perl (e.g. see Shane Adams message on |
877
|
|
|
|
|
|
|
# mod_perl list on 9/10/00) |
878
|
|
|
|
|
|
|
# |
879
|
0
|
|
|
|
|
|
my $is_dir = -d $r->filename; |
880
|
|
|
|
|
|
|
|
881
|
0
|
0
|
|
|
|
|
return $is_dir ? 'dir' : -f _ ? 'file' : 'other'; |
|
|
0
|
|
|
|
|
|
882
|
|
|
|
|
|
|
} |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
sub request_args |
885
|
|
|
|
|
|
|
{ |
886
|
0
|
|
|
0
|
0
|
|
my ($self, $r) = @_; |
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
# |
889
|
|
|
|
|
|
|
# Get arguments from Apache::Request or CGI. |
890
|
|
|
|
|
|
|
# |
891
|
0
|
|
|
|
|
|
my ($args, $cgi_object); |
892
|
0
|
0
|
|
|
|
|
if ($self->args_method eq 'mod_perl') { |
893
|
0
|
|
|
|
|
|
$args = $self->_mod_perl_args($r); |
894
|
|
|
|
|
|
|
} else { |
895
|
0
|
|
|
|
|
|
$cgi_object = CGI->new; |
896
|
0
|
|
|
|
|
|
$args = $self->_cgi_args($r, $cgi_object); |
897
|
|
|
|
|
|
|
} |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
# we return $r solely for backwards compatibility |
900
|
0
|
|
|
|
|
|
return ($args, $r, $cgi_object); |
901
|
|
|
|
|
|
|
} |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
# |
904
|
|
|
|
|
|
|
# Get $args hashref via CGI package |
905
|
|
|
|
|
|
|
# |
906
|
|
|
|
|
|
|
sub _cgi_args |
907
|
|
|
|
|
|
|
{ |
908
|
0
|
|
|
0
|
|
|
my ($self, $r, $q) = @_; |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
# For optimization, don't bother creating a CGI object if request |
911
|
|
|
|
|
|
|
# is a GET with no query string |
912
|
0
|
0
|
0
|
|
|
|
return {} if $r->method eq 'GET' && !scalar($r->args); |
913
|
|
|
|
|
|
|
|
914
|
0
|
|
|
|
|
|
return HTML::Mason::Utils::cgi_request_args($q, $r->method); |
915
|
|
|
|
|
|
|
} |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
# |
918
|
|
|
|
|
|
|
# Get $args hashref via Apache::Request package. |
919
|
|
|
|
|
|
|
# |
920
|
|
|
|
|
|
|
sub _mod_perl_args |
921
|
|
|
|
|
|
|
{ |
922
|
0
|
|
|
0
|
|
|
my ($self, $apr) = @_; |
923
|
|
|
|
|
|
|
|
924
|
0
|
|
|
|
|
|
my %args; |
925
|
0
|
|
|
|
|
|
foreach my $key ( $apr->param ) { |
926
|
0
|
|
|
|
|
|
my @values = $apr->param($key); |
927
|
0
|
0
|
|
|
|
|
$args{$key} = @values == 1 ? $values[0] : \@values; |
928
|
|
|
|
|
|
|
} |
929
|
|
|
|
|
|
|
|
930
|
0
|
|
|
|
|
|
return \%args; |
931
|
|
|
|
|
|
|
} |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
sub _set_mason_req_out_method |
934
|
|
|
|
|
|
|
{ |
935
|
0
|
|
|
0
|
|
|
my ($self, $m, $r) = @_; |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
my $final_output_method = ($r->method eq 'HEAD' ? |
938
|
0
|
|
|
0
|
|
|
sub {} : |
939
|
0
|
0
|
|
|
|
|
$r->can('print')); |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
# Craft the request's out method to handle http headers, content |
942
|
|
|
|
|
|
|
# length, and HEAD requests. |
943
|
0
|
|
|
|
|
|
my $out_method; |
944
|
|
|
|
|
|
|
{ |
945
|
|
|
|
|
|
|
# mod_perl-2 does not need to call $r->send_http_headers |
946
|
0
|
|
|
|
|
|
$out_method = sub { |
947
|
0
|
|
|
0
|
|
|
$r->$final_output_method( grep { defined } @_ ); |
|
0
|
|
|
|
|
|
|
948
|
0
|
|
|
|
|
|
$r->rflush; |
949
|
0
|
|
|
|
|
|
}; |
950
|
|
|
|
|
|
|
} |
951
|
|
|
|
|
|
|
|
952
|
0
|
|
|
|
|
|
$m->out_method($out_method); |
953
|
|
|
|
|
|
|
} |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
# Utility function to prepare $r before returning NOT_FOUND. |
956
|
|
|
|
|
|
|
sub return_not_found |
957
|
|
|
|
|
|
|
{ |
958
|
0
|
|
|
0
|
0
|
|
my ($self, $r) = @_; |
959
|
|
|
|
|
|
|
|
960
|
0
|
0
|
|
|
|
|
if ($r->method eq 'POST') { |
961
|
0
|
|
|
|
|
|
$r->method('GET'); |
962
|
0
|
|
|
|
|
|
$r->headers_in->unset('Content-length'); |
963
|
|
|
|
|
|
|
} |
964
|
0
|
|
|
|
|
|
return NOT_FOUND; |
965
|
|
|
|
|
|
|
} |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
# |
968
|
|
|
|
|
|
|
# PerlHandler HTML::MasonX::ApacheLikePlackHandler |
969
|
|
|
|
|
|
|
# |
970
|
|
|
|
|
|
|
sub handler |
971
|
|
|
|
|
|
|
{ |
972
|
0
|
|
|
0
|
0
|
|
my ($package, $r) = @_; |
973
|
|
|
|
|
|
|
|
974
|
0
|
|
|
|
|
|
my $ah; |
975
|
0
|
|
0
|
|
|
|
$ah ||= $package->make_ah($r); |
976
|
|
|
|
|
|
|
|
977
|
0
|
|
|
|
|
|
return $ah->handle_request($r); |
978
|
|
|
|
|
|
|
} |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
1; |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
__END__ |