| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Plack::App::FakeApache; | 
| 2 |  |  |  |  |  |  | $Plack::App::FakeApache::VERSION = '0.08'; # TRIAL | 
| 3 | 3 |  |  | 3 |  | 131269 | use Try::Tiny; | 
|  | 3 |  |  |  |  | 9056 |  | 
|  | 3 |  |  |  |  | 232 |  | 
| 4 | 3 |  |  | 3 |  | 29 | use strict; | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 87 |  | 
| 5 | 3 |  |  | 3 |  | 23 | use warnings; | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 114 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 3 |  |  | 3 |  | 2010 | use Plack::Util; | 
|  | 3 |  |  |  |  | 35585 |  | 
|  | 3 |  |  |  |  | 144 |  | 
| 8 | 3 |  |  | 3 |  | 1149 | use Plack::Util::Accessor qw( authen_handler authz_handler response_handler handler dir_config root logger request_args request_class without_cgi); | 
|  | 3 |  |  |  |  | 910 |  | 
|  | 3 |  |  |  |  | 26 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 3 |  |  | 3 |  | 429 | use parent qw( Plack::Component ); | 
|  | 3 |  |  |  |  | 8 |  | 
|  | 3 |  |  |  |  | 16 |  | 
| 11 | 3 |  |  | 3 |  | 3526 | use attributes; | 
|  | 3 |  |  |  |  | 2331 |  | 
|  | 3 |  |  |  |  | 23 |  | 
| 12 |  |  |  |  |  |  |  | 
| 13 | 3 |  |  | 3 |  | 211 | use Carp; | 
|  | 3 |  |  |  |  | 10 |  | 
|  | 3 |  |  |  |  | 228 |  | 
| 14 | 3 |  |  | 3 |  | 1050 | use Module::Load; | 
|  | 3 |  |  |  |  | 3244 |  | 
|  | 3 |  |  |  |  | 19 |  | 
| 15 | 3 |  |  | 3 |  | 191 | use Scalar::Util qw( blessed ); | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 173 |  | 
| 16 | 3 |  |  | 3 |  | 1942 | use Apache2::Const qw(OK DECLINED HTTP_OK HTTP_UNAUTHORIZED HTTP_NOT_FOUND); | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | sub _get_phase_handlers | 
| 19 |  |  |  |  |  |  | { | 
| 20 |  |  |  |  |  |  | my $self = shift; | 
| 21 |  |  |  |  |  |  | my $phase = shift; | 
| 22 |  |  |  |  |  |  | my $accessor = $phase.'_handler'; | 
| 23 |  |  |  |  |  |  | my $handlers = $self->$accessor or return; | 
| 24 |  |  |  |  |  |  | return @{$handlers}; | 
| 25 |  |  |  |  |  |  | } | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | # RUN_FIRST | 
| 28 |  |  |  |  |  |  | # Run until a handler returns something other than DECLINED... | 
| 29 |  |  |  |  |  |  | sub _run_first | 
| 30 |  |  |  |  |  |  | { | 
| 31 |  |  |  |  |  |  | my $self = shift; | 
| 32 |  |  |  |  |  |  | my $phase = shift; | 
| 33 |  |  |  |  |  |  | my $fake_req = shift; | 
| 34 |  |  |  |  |  |  | my $fallback_status = shift; | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | # Mangle env to cope with certain kinds of CGI brain damage. | 
| 38 |  |  |  |  |  |  | unless ($self->without_cgi) { | 
| 39 |  |  |  |  |  |  | require CGI::Emulate::PSGI; | 
| 40 |  |  |  |  |  |  | my $env = $fake_req->plack_request->env; | 
| 41 |  |  |  |  |  |  | local %ENV = (%ENV, CGI::Emulate::PSGI->emulate_environment($env)); | 
| 42 |  |  |  |  |  |  | # and stdin! | 
| 43 |  |  |  |  |  |  | local *STDIN  = $env->{'psgi.input'}; | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | my $status = OK; | 
| 47 |  |  |  |  |  |  | foreach my $handler ($self->_get_phase_handlers($phase)) | 
| 48 |  |  |  |  |  |  | { | 
| 49 |  |  |  |  |  |  | try { | 
| 50 |  |  |  |  |  |  | $status = $handler->($fake_req); | 
| 51 |  |  |  |  |  |  | } | 
| 52 |  |  |  |  |  |  | catch { | 
| 53 |  |  |  |  |  |  | die $_ unless $_ =~ /^EXIT 0$/; | 
| 54 |  |  |  |  |  |  | }; | 
| 55 |  |  |  |  |  |  | last if $status != DECLINED; | 
| 56 |  |  |  |  |  |  | } | 
| 57 |  |  |  |  |  |  | return (defined($status) and $status != DECLINED) ? $status : $fallback_status; # mod_perl seems to do this if all handlers decline | 
| 58 |  |  |  |  |  |  | } | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | sub call { | 
| 61 |  |  |  |  |  |  | my ($self, $env) = @_; | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | my %args = ( | 
| 64 |  |  |  |  |  |  | env => $env, | 
| 65 |  |  |  |  |  |  | dir_config => $self->dir_config || {}, | 
| 66 |  |  |  |  |  |  | request_class => $self->request_class || 'Plack::App::FakeApache::Request', | 
| 67 |  |  |  |  |  |  | %{$self->request_args || {}} | 
| 68 |  |  |  |  |  |  | ); | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | $args{root} = $self->root if defined $self->root; | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | if ( $self->logger ) { | 
| 73 |  |  |  |  |  |  | my $logger  = $self->logger; | 
| 74 |  |  |  |  |  |  | $args{log} = $logger if blessed($logger) and !$logger->isa('IO::Handle'); | 
| 75 |  |  |  |  |  |  | $args{log} ||= Plack::FakeApache::Log->new( logger => sub { print $logger @_ } ); | 
| 76 |  |  |  |  |  |  | } | 
| 77 |  |  |  |  |  |  | my $request_class = $args{request_class}; | 
| 78 |  |  |  |  |  |  | my $fake_req = $request_class->new(%args); | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | my $status = $self->_run_handlers($fake_req); | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | $fake_req->status($status == OK ? HTTP_OK : $status); | 
| 83 |  |  |  |  |  |  | return $fake_req->finalize; | 
| 84 |  |  |  |  |  |  | } | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | sub _run_handlers | 
| 87 |  |  |  |  |  |  | { | 
| 88 |  |  |  |  |  |  | my $self = shift; | 
| 89 |  |  |  |  |  |  | my $fake_req = shift; | 
| 90 |  |  |  |  |  |  | my $status; | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | # TODO: More request phases here... | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | $status = $self->_run_first('authen', $fake_req, HTTP_UNAUTHORIZED); | 
| 95 |  |  |  |  |  |  | return $status if $status != OK; | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | $status = $self->_run_first('authz', $fake_req, HTTP_UNAUTHORIZED); | 
| 98 |  |  |  |  |  |  | return $status if $status != OK; | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | # we wrap the call to $handler->( ... ) in tie statements so | 
| 101 |  |  |  |  |  |  | # prints, etc are caught and sent to the right place | 
| 102 |  |  |  |  |  |  | tie *STDOUT, "Plack::App::FakeApache::Tie", $fake_req; | 
| 103 |  |  |  |  |  |  | $status = $self->_run_first('response', $fake_req, HTTP_NOT_FOUND); | 
| 104 |  |  |  |  |  |  | untie *STDOUT; | 
| 105 |  |  |  |  |  |  | return $status if $status != OK; | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | # TODO: More request phases here... | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | return OK; | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | sub prepare_app { | 
| 113 |  |  |  |  |  |  | my $self = shift; | 
| 114 |  |  |  |  |  |  | my $request_class = $self->request_class || 'Plack::App::FakeApache::Request'; | 
| 115 |  |  |  |  |  |  | load $request_class; | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | $self->response_handler($self->response_handler || $self->handler); | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | foreach my $accessor ( qw(authen_handler authz_handler response_handler) ) | 
| 120 |  |  |  |  |  |  | { | 
| 121 |  |  |  |  |  |  | my $handlers = $self->$accessor or next; | 
| 122 |  |  |  |  |  |  | my @handlers = ref($handlers) eq 'ARRAY' ? @{$handlers} : ($handlers); | 
| 123 |  |  |  |  |  |  | @handlers = map({ $self->_massage_handler($_) } @handlers); | 
| 124 |  |  |  |  |  |  | $self->$accessor([ @handlers ]); | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  | carp "handler or response_handler not defined" unless $self->response_handler; | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | # Workaround for mod_perl handlers doing CGI->new($r). CGI doesn't | 
| 130 |  |  |  |  |  |  | # know our fake request class, so we hijack CGI->new() and explicitly | 
| 131 |  |  |  |  |  |  | # pass the request query string instead... | 
| 132 |  |  |  |  |  |  | unless ($self->without_cgi) { | 
| 133 |  |  |  |  |  |  | my $new = CGI->can('new'); | 
| 134 |  |  |  |  |  |  | no warnings qw(redefine); | 
| 135 |  |  |  |  |  |  | *CGI::new = sub { | 
| 136 |  |  |  |  |  |  | my $request_class = $self->request_class || 'Plack::App::FakeApache::Request'; | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | if (blessed($_[1]) and $_[1]->isa($request_class)) { | 
| 139 |  |  |  |  |  |  | return $new->(CGI => $_[1]->env->{QUERY_STRING} || $_[1]->plack_request->content); | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  | return $new->(@_); | 
| 142 |  |  |  |  |  |  | }; | 
| 143 |  |  |  |  |  |  | } | 
| 144 |  |  |  |  |  |  | else { | 
| 145 |  |  |  |  |  |  | my $new = CGI->can('new'); | 
| 146 |  |  |  |  |  |  | no warnings qw/redefine/; | 
| 147 |  |  |  |  |  |  | *CGI::new = sub { | 
| 148 |  |  |  |  |  |  | warn "CALLING CGI->new\n"; | 
| 149 |  |  |  |  |  |  | return $new(@_); | 
| 150 |  |  |  |  |  |  | }; | 
| 151 |  |  |  |  |  |  | } | 
| 152 |  |  |  |  |  |  | return; | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | sub _massage_handler | 
| 156 |  |  |  |  |  |  | { | 
| 157 |  |  |  |  |  |  | my $self = shift; | 
| 158 |  |  |  |  |  |  | my $handler = shift; | 
| 159 |  |  |  |  |  |  | my ($class, $method); | 
| 160 |  |  |  |  |  |  | if ( blessed $handler ) { | 
| 161 |  |  |  |  |  |  | $handler = sub { $handler->handler( @_ ) }; | 
| 162 |  |  |  |  |  |  | } elsif ( my ($class, $method) = $handler =~ m/(.+)->(.+)/ ) { | 
| 163 |  |  |  |  |  |  | Plack::Util::load_class( $class ); | 
| 164 |  |  |  |  |  |  | $handler = sub { $class->$method( @_ ) }; | 
| 165 |  |  |  |  |  |  | } else { | 
| 166 |  |  |  |  |  |  | my $class  = $handler; | 
| 167 |  |  |  |  |  |  | Plack::Util::load_class( $class ); | 
| 168 |  |  |  |  |  |  | my $method = eval { $class->can("handler") }; | 
| 169 |  |  |  |  |  |  | if ( grep { $_ eq 'method' } attributes::get($method) ) { | 
| 170 |  |  |  |  |  |  | $handler = sub { $class->handler( @_ ) }; | 
| 171 |  |  |  |  |  |  | } else { | 
| 172 |  |  |  |  |  |  | $handler = $method; | 
| 173 |  |  |  |  |  |  | } | 
| 174 |  |  |  |  |  |  | } | 
| 175 |  |  |  |  |  |  | return $handler; | 
| 176 |  |  |  |  |  |  | } | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | package Plack::App::FakeApache::Tie; | 
| 179 |  |  |  |  |  |  | $Plack::App::FakeApache::Tie::VERSION = '0.08'; # TRIAL | 
| 180 |  |  |  |  |  |  | sub TIEHANDLE { | 
| 181 |  |  |  |  |  |  | my $class = shift; | 
| 182 |  |  |  |  |  |  | my $r = shift; | 
| 183 |  |  |  |  |  |  | return bless \$r, $class; | 
| 184 |  |  |  |  |  |  | } | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | sub PRINT  { my $r = ${ shift() }; $r->print(@_) } | 
| 187 |  |  |  |  |  |  | sub WRITE  { my $r = ${ shift() }; $r->write(@_) } | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | 1; | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | __END__ |