File Coverage

blib/lib/Plack/App/FakeApache/Request.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Plack::App::FakeApache::Request;
2             $Plack::App::FakeApache::Request::VERSION = '0.08'; # TRIAL
3 1     1   2760 use Moo;
  1         8749  
  1         10  
4 1     1   1444 use MooX::HandlesVia;
  1         8536  
  1         7  
5 1     1   767 use Types::Standard qw/HashRef Any InstanceOf Bool Str Maybe/;
  1         71438  
  1         18  
6 1     1   2312 use APR::Pool;
  0            
  0            
7             use APR::Table;
8              
9             use HTTP::Status qw(:is);
10              
11             use Plack::Request;
12             use Plack::Response;
13             use Plack::App::File;
14              
15             use Plack::App::FakeApache::Connection;
16             use Plack::App::FakeApache::Log;
17             use Plack::App::FakeApache::Server;
18             use Cwd qw(cwd);
19             use URI;
20              
21             my $NS = "plack.app.fakeapache";
22              
23             # Plack related attributes:
24             has env => (
25             is => 'ro',
26             isa => HashRef,
27             required => 1,
28             );
29              
30             has plack_request => (
31             is => 'lazy',
32             isa => InstanceOf['Plack::Request'],
33             handles => {
34             method => 'method',
35             unparsed_uri => 'request_uri',
36             user => 'user',
37             },
38             );
39              
40             has plack_response => (
41             is => 'lazy',
42             isa => InstanceOf['Plack::Response'],
43             handles => {
44             set_content_length => 'content_length',
45             content_type => 'content_type',
46             content_encoding => 'content_encoding',
47             status => 'status',
48             },
49             );
50              
51             has log => (
52             is => 'rw',
53             default => sub { Plack::App::FakeApache::Log->new() },
54             handles => [ qw(log_error log_reason warn) ],
55             );
56              
57             has server => (
58             is => 'rw',
59             default => sub { Plack::App::FakeApache::Server->new() },
60             );
61              
62             # Apache related attributes
63             has _apr_pool => (
64             is => 'lazy',
65             isa => InstanceOf['APR::Pool'],
66             );
67              
68             has headers_in => (
69             is => 'lazy',
70             isa => InstanceOf['APR::Table'],
71             );
72              
73             has headers_out => (
74             is => 'lazy',
75             isa => InstanceOf['APR::Table'],
76             );
77              
78             has err_headers_out => (
79             is => 'lazy',
80             isa => InstanceOf['APR::Table'],
81             );
82              
83             has _subprocess_env => (
84             is => 'lazy',
85             isa => InstanceOf['APR::Table'],
86             );
87              
88              
89             has dir_config => (
90             is => 'bare',
91             isa => HashRef,
92             default => sub { {} },
93             handles_via => 'Hash',
94             handles => { dir_config => 'accessor' },
95             );
96              
97              
98             has location => (
99             is => 'rw',
100             isa => Str,
101             default => '/',
102             );
103              
104             has filename => (
105             is => 'rw',
106             isa => Maybe[Str],
107             );
108              
109             has root => (
110             is => 'rw',
111             isa => Str,
112             default => cwd(),
113             );
114              
115             has is_initial_req => (
116             is => 'lazy',
117             isa => Bool,
118             default => 1,
119             );
120              
121             has auth_type => (
122             is => 'ro',
123             isa => Str,
124             );
125              
126             has auth_name => (
127             is => 'ro',
128             isa => Str,
129             );
130              
131             # builders
132             sub _build_plack_request { return Plack::Request->new( shift->env ) }
133             sub _build_plack_response { return Plack::Response->new( 200, {}, [] ) }
134             sub _build__apr_pool { return APR::Pool->new() }
135             sub _build_headers_out { return APR::Table::make( shift->_apr_pool, 64 ) }
136             sub _build_err_headers_out{ return APR::Table::make( shift->_apr_pool, 64 ) }
137              
138             sub _build__subprocess_env {
139             my $self = shift;
140             my $env = $self->env;
141             my $table = APR::Table::make( $self->_apr_pool, 64 );
142              
143             $table->add( $_ => $env->{$_} ) for grep { /^[_A-Z]+$/ } keys %$env;
144              
145             return $table;
146             }
147              
148             sub _build_headers_in {
149             my $self = shift;
150             my $table = APR::Table::make( $self->_apr_pool, 64 );
151              
152             $self->plack_request->headers->scan( sub {
153             $table->add( @_ );
154             } );
155              
156             return $table;
157             }
158              
159             sub _build_filename {
160             my $self = shift;
161              
162             my $paf = Plack::App::File->new(
163             root => $self->root
164             );
165             my ($file, $path) = $paf->locate_file( $self->env );
166              
167             return undef if ref $file; # some sort of error
168             return $file;
169             }
170              
171             # Plack methods
172             sub finalize {
173             my $self = shift;
174             my $response = $self->plack_response;
175              
176             $self->headers_out->do( sub { $response->header( @_ ); 1 } ) if is_success( $self->status() );
177             $self->err_headers_out->do( sub { $response->header( @_ ); 1 } );
178              
179             return $response->finalize;
180             };
181              
182             # Apache methods
183              
184             sub args {
185             my $self = shift;
186             return $self->plack_request->env->{QUERY_STRING};
187             }
188              
189             sub hostname {
190             my $self = shift;
191              
192             return $self->env->{SERVER_NAME};
193             }
194              
195             sub subprocess_env {
196             my $self = shift;
197              
198             if (@_ == 1) {
199             return $self->_subprocess_env->get( @_ );
200             }
201              
202             if (@_ == 2) {
203             return $self->_subprocess_env->set( @_ );
204             }
205              
206             if (defined wantarray) {
207             return $self->_subprocess_env;
208             }
209              
210             $self->_subprocess_env->do( sub { $ENV{ $_[0] } = $_[1]; 1 } );
211             return;
212             }
213              
214             sub document_root {
215             my $self = shift;
216             return $self->root;
217             }
218              
219             sub pnotes {
220             my $self = shift;
221             my $key = shift;
222             my $old = $self->env->{$NS.'.pnotes'}->{$key};
223              
224             if (@_) {
225             $self->env->{$NS.'.pnotes'}->{$key} = shift;
226             }
227              
228             return $old;
229             }
230              
231             sub notes {
232             my $self = shift;
233             my $key = shift;
234             my $old = $self->env->{$NS.'.notes'}->{$key};
235              
236             if (@_) {
237             $self->env->{$NS.'.notes'}->{$key} = "".shift;
238             }
239              
240             return $old;
241             }
242              
243             # this is strictly mocking Apache::Connection, and only partially
244             sub connection {
245             my $self = shift;
246              
247             return Plack::App::FakeApache::Connection->new(
248             remote_ip => $self->plack_request->address,
249             log => $self->log,
250             );
251             }
252              
253             sub read {
254             my $self = shift;
255             my ($buffer, $length, $offset) = @_; # ... but use $_[0] for buffer
256              
257             my $request = $self->plack_request;
258              
259             # Is this needed? Intrudes on a Plack::Request private methodf...
260             unless ($request->env->{'psgix.input.buffered'}) {
261             $request->_parse_request_body;
262              
263             # Sets psgix.input.buffered and rewinds.
264             }
265              
266             my $fh = $request->input
267             or return 0;
268              
269             return $fh->read($_[0], $length, $offset);
270             }
271              
272             sub print {
273             my $self = shift;
274              
275             my $length = 0;
276             for (@_) {
277             $self->_add_content($_);
278             $length += length;
279             }
280              
281             return $length;
282             }
283              
284             sub write {
285             my ($self, $buffer, $length, $offset) = @_;
286              
287             if (defined $length && $length == -1) {
288             $self->_add_content($buffer);
289             return length $buffer;
290             }
291              
292             my $output = substr $buffer, $offset // 0, $length // length $buffer;
293              
294             $self->_add_content($output);
295            
296             return length $output;
297             }
298              
299             sub _add_content {
300             my $self = shift;
301              
302             push @{ $self->plack_response->body }, @_;
303             }
304              
305             sub rflush {
306             1;
307             }
308              
309             sub uri
310             {
311             my $self = shift;
312             return $self->plack_request->uri->path;
313             }
314              
315             sub construct_url
316             {
317             my $self = shift;
318             my $path = shift;
319             my $uri = URI->new($self->plack_request->uri);
320             $uri->path($path) if $path;
321             return $uri->as_string;
322             }
323              
324             no Moose;
325             __PACKAGE__->meta->make_immutable;
326              
327             1;