File Coverage

blib/lib/HTTP/Engine/Request.pm
Criterion Covered Total %
statement 126 126 100.0
branch 66 66 100.0
condition 2 2 100.0
subroutine 28 28 100.0
pod 7 10 70.0
total 229 232 98.7


line stmt bran cond sub pod time code
1             package HTTP::Engine::Request;
2 62     62   71484 use Any::Moose;
  62         910385  
  62         384  
3 62     62   100242 use HTTP::Headers::Fast;
  62         269506  
  62         2659  
4 62     62   40483 use HTTP::Engine::Types::Core qw( Uri Header );
  62         226  
  62         489  
5 62     62   26474 use URI::QueryParam;
  62         147  
  62         165573  
6             require Carp; # Carp->import is too heavy =(
7              
8             # Mouse, Moose role merging is borked with attributes
9             #with qw(HTTP::Engine::Request);
10              
11             # this object constructs all our lazy fields for us
12             has request_builder => (
13             does => "HTTP::Engine::Role::RequestBuilder",
14             is => "rw",
15             required => 1,
16             );
17              
18             sub BUILD {
19 116     116 1 425 my ( $self, $param ) = @_;
20              
21 116         292 foreach my $field (qw/base path/) {
22 232 100       3880 if ( my $val = $param->{$field} ) {
23 48         732 $self->$field($val);
24             }
25             }
26             }
27              
28             has _connection => (
29             is => "ro",
30             isa => 'HashRef',
31             required => 1,
32             );
33              
34             has "_read_state" => (
35             is => "rw",
36             lazy_build => 1,
37             );
38              
39             sub _build__read_state {
40 19     19   59 my $self = shift;
41 19         121 $self->request_builder->_build_read_state($self);
42             }
43              
44             has connection_info => (
45             is => "rw",
46             isa => "HashRef",
47             lazy_build => 1,
48             );
49              
50             sub _build_connection_info {
51 35     35   85 my $self = shift;
52 35         6790 $self->request_builder->_build_connection_info($self);
53             }
54              
55             has cookies => (
56             is => 'rw',
57             isa => 'HashRef',
58             lazy_build => 1,
59             );
60              
61             sub _build_cookies {
62 2     2   14 my $self = shift;
63 2         18 $self->request_builder->_build_cookies($self);
64             }
65              
66             foreach my $attr (qw/address method protocol user port _https_info request_uri/) {
67             has $attr => (
68             is => 'rw',
69             # isa => "Str",
70             lazy => 1,
71             default => sub { shift->connection_info->{$attr} },
72             );
73             }
74             has query_parameters => (
75             is => 'rw',
76             isa => 'HashRef',
77             lazy_build => 1,
78             );
79              
80             sub _build_query_parameters {
81 31     31   181 my $self = shift;
82 31         295 $self->uri->query_form_hash;
83             }
84              
85             # https or not?
86             has secure => (
87             is => 'rw',
88             isa => 'Bool',
89             lazy_build => 1,
90             );
91              
92             sub _build_secure {
93 27     27   108 my $self = shift;
94              
95 27 100       158 if ( my $https = $self->_https_info ) {
96 3 100       30 return 1 if uc($https) eq 'ON';
97             }
98              
99 25 100       158 if ( my $port = $self->port ) {
100 3 100       14 return 1 if $port == 443;
101             }
102              
103 24         172 return 0;
104             }
105              
106             # proxy request?
107             has proxy_request => (
108             is => 'rw',
109             isa => 'Str', # TODO: union(Uri, Undef) type
110             # coerce => 1,
111             lazy_build => 1,
112             );
113              
114             sub _build_proxy_request {
115 27     27   48 my $self = shift;
116 27 100       165 return '' unless $self->request_uri; # TODO: return undef
117 3 100       35 return '' unless $self->request_uri =~ m!^https?://!i; # TODO: return undef
118 2         22 return $self->request_uri; # TODO: return URI->new($self->request_uri);
119             }
120              
121             has uri => (
122             is => 'rw',
123             isa => Uri,
124             coerce => 1,
125             lazy_build => 1,
126             handles => [qw(base path)],
127             );
128              
129             sub _build_uri {
130 28     28   505 my $self = shift;
131 28         221 $self->request_builder->_build_uri($self);
132             }
133              
134             has builder_options => (
135             is => 'rw',
136             isa => 'HashRef',
137             default => sub {
138             +{
139             disable_raw_body => 0,
140             upload_tmp => undef,
141             },
142             },
143             );
144              
145             has raw_body => (
146             is => 'rw',
147             isa => 'Str',
148             lazy_build => 1,
149             );
150              
151             sub _build_raw_body {
152 5     5   69 my $self = shift;
153 5         50 $self->request_builder->_build_raw_body($self);
154             }
155              
156             has headers => (
157             is => 'rw',
158             isa => Header,
159             coerce => 1,
160             lazy_build => 1,
161             handles => [ qw(content_encoding content_length content_type header referer user_agent) ],
162             );
163              
164             sub _build_headers {
165 10     10   134 my $self = shift;
166 10         83 $self->request_builder->_build_headers($self);
167             }
168              
169             # Contains the URI base. This will always have a trailing slash.
170             # If your application was queried with the URI C then C is C.
171              
172             has hostname => (
173             is => 'rw',
174             isa => 'Str',
175             lazy_build => 1,
176             );
177              
178             sub _build_hostname {
179 2     2   3 my $self = shift;
180 2         12 $self->request_builder->_build_hostname($self);
181             }
182              
183             has http_body => (
184             is => 'rw',
185             isa => 'HTTP::Body',
186             lazy_build => 1,
187             handles => {
188             body_parameters => 'param',
189             body => 'body',
190             },
191             );
192              
193             sub _build_http_body {
194 14     14   86 my $self = shift;
195 14         106 $self->request_builder->_build_http_body($self);
196             }
197              
198             # contains body_params and query_params
199             has parameters => (
200             is => 'rw',
201             isa => 'HashRef',
202             lazy_build => 1,
203             );
204              
205             sub _build_parameters {
206 11     11   34 my $self = shift;
207              
208 11         72 my $query = $self->query_parameters;
209 11         572 my $body = $self->body_parameters;
210              
211 11         135 my %merged;
212              
213 11         23 foreach my $hash ( $query, $body ) {
214 22         75 foreach my $name ( keys %$hash ) {
215 12         20 my $param = $hash->{$name};
216 12 100 100     19 push( @{ $merged{$name} ||= [] }, ( ref $param ? @$param : $param ) );
  12         94  
217             }
218             }
219              
220 11         31 foreach my $param ( values %merged ) {
221 10 100       33 $param = $param->[0] if @$param == 1;
222             }
223              
224 11         106 return \%merged;
225             }
226              
227             has uploads => (
228             is => 'rw',
229             isa => 'HashRef',
230             lazy_build => 1,
231             );
232              
233             sub _build_uploads {
234 8     8   35 my $self = shift;
235 8         69 $self->request_builder->_prepare_uploads($self);
236             }
237              
238             # aliases
239             *body_params = \&body_parameters;
240             *input = \&body;
241             *params = \¶meters;
242             *query_params = \&query_parameters;
243             *path_info = \&path;
244              
245             sub cookie {
246 5     5 1 24 my $self = shift;
247              
248 5 100       15 return keys %{ $self->cookies } if @_ == 0;
  1         9  
249              
250 4 100       12 if (@_ == 1) {
251 3         5 my $name = shift;
252 3 100       25 return undef unless exists $self->cookies->{$name}; ## no critic.
253 2         19 return $self->cookies->{$name};
254             }
255 1         4 return;
256             }
257              
258             sub param {
259 13     13 1 41 my $self = shift;
260              
261 13 100       29 return keys %{ $self->parameters } if @_ == 0;
  5         25  
262              
263 8 100       17 if (@_ == 1) {
264 6         10 my $param = shift;
265 6 100       30 return wantarray ? () : undef unless exists $self->parameters->{$param};
    100          
266              
267 4 100       16 if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
268             return (wantarray)
269 2 100       11 ? @{ $self->parameters->{$param} }
  1         6  
270             : $self->parameters->{$param}->[0];
271             } else {
272             return (wantarray)
273 2 100       12 ? ( $self->parameters->{$param} )
274             : $self->parameters->{$param};
275             }
276             } else {
277 2         5 my $field = shift;
278 2         13 $self->parameters->{$field} = [@_];
279             }
280             }
281              
282             sub upload {
283 27     27 1 811 my $self = shift;
284              
285 27 100       81 return keys %{ $self->uploads } if @_ == 0;
  2         17  
286              
287 25 100       65 if (@_ == 1) {
288 21         32 my $upload = shift;
289 21 100       148 return wantarray ? () : undef unless exists $self->uploads->{$upload};
    100          
290              
291 19 100       109 if (ref $self->uploads->{$upload} eq 'ARRAY') {
292             return (wantarray)
293 9 100       64 ? @{ $self->uploads->{$upload} }
  3         19  
294             : $self->uploads->{$upload}->[0];
295             } else {
296             return (wantarray)
297 10 100       69 ? ( $self->uploads->{$upload} )
298             : $self->uploads->{$upload};
299             }
300             } else {
301 4         20 while ( my($field, $upload) = splice(@_, 0, 2) ) {
302 4 100       20 if ( exists $self->uploads->{$field} ) {
303 2         8 for ( $self->uploads->{$field} ) {
304 2 100       8 $_ = [$_] unless ref($_) eq "ARRAY";
305 2         2 push(@{ $_ }, $upload);
  2         13  
306             }
307             } else {
308 2         14 $self->uploads->{$field} = $upload;
309             }
310             }
311             }
312             }
313              
314             sub uri_with {
315 44     44 1 1609 my($self, $args) = @_;
316            
317 44 100       4323 Carp::carp( 'No arguments passed to uri_with()' ) unless $args;
318              
319 44         1155 for my $value (values %{ $args }) {
  44         188  
320 9 100       24 next unless defined $value;
321 8 100       29 for ( ref $value eq 'ARRAY' ? @{ $value } : $value ) {
  4         13  
322 12         24 $_ = "$_";
323 12         43 utf8::encode( $_ );
324             }
325             };
326            
327 44         321 my $uri = $self->uri->clone;
328            
329 44         295 $uri->query_form( {
330 44         2414 %{ $uri->query_form_hash },
331 44         1014 %{ $args },
332             } );
333 44         2865 return $uri;
334             }
335              
336             sub as_http_request {
337 2     2 1 33 my $self = shift;
338 2         2200 require 'HTTP/Request.pm'; ## no critic
339 2         1968 HTTP::Request->new( $self->method, $self->uri, $self->headers, $self->raw_body );
340             }
341              
342             sub absolute_url {
343 5     5 1 10 my ($self, $location) = @_;
344              
345 5 100       25 unless ($location =~ m!^https?://!) {
346 4         16 return URI->new( $location )->abs( $self->base );
347             } else {
348 1         6 return $location;
349             }
350             }
351              
352             sub content {
353 2     2 0 12 my ( $self, @args ) = @_;
354              
355 2 100       8 if ( @args ) {
356 1         217 Carp::croak "The HTTP::Request method 'content' is unsupported when used as a writer, use HTTP::Engine::RequestBuilder";
357             } else {
358 1         12 return $self->raw_body;
359             }
360             }
361              
362             sub as_string {
363 1     1 0 44 my $self = shift;
364 1         5 $self->as_http_request->as_string; # FIXME not efficient
365             }
366              
367             sub parse {
368 1     1 0 293 Carp::croak "The HTTP::Request method 'parse' is unsupported, use HTTP::Engine::RequestBuilder";
369             }
370              
371 62     62   541 no Any::Moose;
  62         135  
  62         598  
372             __PACKAGE__->meta->make_immutable(inline_destructor => 1);
373             1;
374             __END__