File Coverage

blib/lib/Apache2/Controller/PerChildInit.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Apache2::Controller::PerChildInit;
2              
3             =head1 NAME
4              
5             Apache2::Controller::PerChildInit -
6             C handler for child process setup in A2C.
7              
8             =head1 VERSION
9              
10             Version 1.001.001
11              
12             =cut
13              
14 1     1   1671 use version;
  1         2  
  1         6  
15             our $VERSION = version->new('1.001.001');
16              
17             =head1 SYNOPSIS
18              
19            
20            
21             PerlLoadModule Apache2::Controller::PerChildInit
22             PerChildInitHandler Apache2::Controller::PerChildInit
23              
24            
25             # normal Apache2::Controller::Dispatch setup
26            
27              
28            
29              
30             =head1 DESCRIPTION
31              
32             This is a SERVER init handler that runs once when an
33             Apache2 child process is spawned.
34              
35             =head1 INITIALIZATION ITEMS
36              
37             These are the items initialized once per Apache2 child
38             when the C runs.
39              
40             =head2 LOGGING
41              
42             Replaces the L appender for loggers
43             in the L namespace with one that
44             sends the errors to the Apache2 error log facility
45             with the appropriate log level.
46              
47             This factors out the common parts of handlers in the C
48             framework other than the main response handler. These non-response
49             handlers like Dispatch and Session do not need to create the
50             Apache2::Request object (I think...), so that is put off until
51             the Response phase.
52              
53             You should not use this module for anything that you're doing.
54              
55             Pre-response phase handlers do not handle errors in the same way
56             that Apache2::Controller does. If you get an error in a pre-response
57             phase, A2C cannot call your render class error() method, because
58             that stuff is not set up yet. Instead, it spits the error to
59             the error log, logs the reason for the response code, and
60             returns the response code. This should get Apache to quit
61             processing the chain of handlers... we'll see.
62              
63             =head1 METHODS
64              
65             =cut
66              
67 1     1   94 use strict;
  1         2  
  1         33  
68 1     1   5 use warnings FATAL => 'all';
  1         2  
  1         71  
69 1     1   5 use English '-no_match_vars';
  1         2  
  1         6  
70              
71 1     1   410 use Log::Log4perl qw(:easy);
  1         7  
  1         9  
72 1     1   611 use YAML::Syck;
  1         2  
  1         72  
73              
74 1     1   346 use Apache2::RequestRec ();
  0            
  0            
75             use Apache2::RequestUtil ();
76             use Apache2::Log;
77             use Apache2::Const -compile => qw( :common :http :methods );
78              
79             use Apache2::Controller::X;
80             use Apache2::Controller::Const qw( @RANDCHARS $NOT_GOOD_CHARS );
81             use Apache2::Controller::Funk qw( log_bad_request_reason );
82              
83             =head2 handler
84              
85             handler() takes the request, creates an object using the
86             child class name, runs the process() method, and handles errors.
87              
88             =cut
89              
90             sub handler : method {
91             my ($class, $r) = @_;
92              
93             DEBUG("begin $class ->handler()");
94              
95             my ($handler, $status, $X) = ( );
96              
97             eval {
98             $handler = $class->new($r);
99             $status = $handler->process();
100             };
101             if ($X = Exception::Class->caught('Apache2::Controller::X')) {
102             $status = $X->status || Apache2::Const::SERVER_ERROR;
103             WARN("Caught an Apache2::Controller::X: $status");
104             WARN(ref($X).": $X\n".($X->dump ? Dump($X->dump) : '').$X->trace());
105             }
106             elsif ($X = $EVAL_ERROR) {
107             WARN("Caught an unknown error: $X");
108             $status = Apache2::Const::SERVER_ERROR;
109             }
110              
111             if ($status) {
112             DEBUG("Setting http-status to '$status'");
113             $r->status($status);
114             }
115              
116             if ($status && $status >= Apache2::Const::HTTP_BAD_REQUEST) {
117             DEBUG("logging bad request");
118             eval { log_bad_request_reason($r, $X); };
119             if (my $X = Exception::Class->caught('Apache2::Controller::X')) {
120             FATAL("Bad error logging bad request! '$X'\n".$X->trace);
121             }
122             elsif ($EVAL_ERROR) {
123             FATAL("Weird error logging bad request! '$EVAL_ERROR'");
124             }
125             }
126              
127             # Exception objects with non-error status were already WARN'ed.
128            
129             $status = Apache2::Const::OK if !defined $status;
130             DEBUG("returning '$status'");
131             return $status;
132             }
133              
134             =head2 new
135              
136             C creates an object of the child class and assigns the
137             C<< Apache2::RequestRec >> object to
138             C<< $self->{r} >>.
139              
140             If the parent class defines a method C, this will
141             be called at the end of object creation.
142              
143             Unlike L, the handler object of other handlers
144             that use this package as a base do not create, delegate to and subclass
145             the L object. They just keep the original
146             L object in
147             C<< $self->{r} >>.
148              
149             =cut
150              
151             my %can_init;
152              
153             sub new {
154             my ($class, $r) = @_;
155              
156             DEBUG("handler class is '$class', reqrec is '$r'");
157              
158             my $self = {
159             r => $r,
160             class => $class,
161             };
162             bless $self, $class;
163              
164             $can_init{$class} = $self->can('init') if !exists $can_init{$class};
165             $self->init() if $can_init{$class};
166              
167             return $self;
168             }
169              
170             1;
171              
172             =head1 SEE ALSO
173              
174             L
175              
176             L
177              
178             L
179              
180             L
181              
182             =head1 AUTHOR
183              
184             Mark Hedges, C<< >>
185              
186             =head1 COPYRIGHT & LICENSE
187              
188             Copyright 2008-2010 Mark Hedges, all rights reserved.
189              
190             This program is free software; you can redistribute it and/or modify it
191             under the same terms as Perl itself.
192              
193             This software is provided as-is, with no warranty
194             and no guarantee of fitness
195             for any particular purpose.
196