File Coverage

blib/lib/HTTP/Engine/Request.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package HTTP::Engine::Request;
2 52     52   11358 use Any::Moose;
  52         316541  
  52         217  
3 52     52   40063 use HTTP::Headers::Fast;
  52         187035  
  52         1615  
4 52     52   17591 use HTTP::Engine::Types::Core qw( Uri Header );
  52         115  
  52         171  
5 52     52   13058 use URI::QueryParam;
  52         80  
  52         94815  
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             my ( $self, $param ) = @_;
20              
21             foreach my $field qw(base path) {
22             if ( my $val = $param->{$field} ) {
23             $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             my $self = shift;
41             $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             my $self = shift;
52             $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             my $self = shift;
63             $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             my $self = shift;
82             $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             my $self = shift;
94              
95             if ( my $https = $self->_https_info ) {
96             return 1 if uc($https) eq 'ON';
97             }
98              
99             if ( my $port = $self->port ) {
100             return 1 if $port == 443;
101             }
102              
103             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             my $self = shift;
116             return '' unless $self->request_uri; # TODO: return undef
117             return '' unless $self->request_uri =~ m!^https?://!i; # TODO: return undef
118             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             my $self = shift;
131             $self->request_builder->_build_uri($self);
132             }
133              
134             has raw_body => (
135             is => 'rw',
136             isa => 'Str',
137             lazy_build => 1,
138             );
139              
140             sub _build_raw_body {
141             my $self = shift;
142             $self->request_builder->_build_raw_body($self);
143             }
144              
145             has headers => (
146             is => 'rw',
147             isa => Header,
148             coerce => 1,
149             lazy_build => 1,
150             handles => [ qw(content_encoding content_length content_type header referer user_agent) ],
151             );
152              
153             sub _build_headers {
154             my $self = shift;
155             $self->request_builder->_build_headers($self);
156             }
157              
158             # Contains the URI base. This will always have a trailing slash.
159             # If your application was queried with the URI C then C is C.
160              
161             has hostname => (
162             is => 'rw',
163             isa => 'Str',
164             lazy_build => 1,
165             );
166              
167             sub _build_hostname {
168             my $self = shift;
169             $self->request_builder->_build_hostname($self);
170             }
171              
172             has http_body => (
173             is => 'rw',
174             isa => 'HTTP::Body',
175             lazy_build => 1,
176             handles => {
177             body_parameters => 'param',
178             body => 'body',
179             },
180             );
181              
182             sub _build_http_body {
183             my $self = shift;
184             $self->request_builder->_build_http_body($self);
185             }
186              
187             # contains body_params and query_params
188             has parameters => (
189             is => 'rw',
190             isa => 'HashRef',
191             lazy_build => 1,
192             );
193              
194             sub _build_parameters {
195             my $self = shift;
196              
197             my $query = $self->query_parameters;
198             my $body = $self->body_parameters;
199              
200             my %merged;
201              
202             foreach my $hash ( $query, $body ) {
203             foreach my $name ( keys %$hash ) {
204             my $param = $hash->{$name};
205             push( @{ $merged{$name} ||= [] }, ( ref $param ? @$param : $param ) );
206             }
207             }
208              
209             foreach my $param ( values %merged ) {
210             $param = $param->[0] if @$param == 1;
211             }
212              
213             return \%merged;
214             }
215              
216             has uploads => (
217             is => 'rw',
218             isa => 'HashRef',
219             lazy_build => 1,
220             );
221              
222             sub _build_uploads {
223             my $self = shift;
224             $self->request_builder->_prepare_uploads($self);
225             }
226              
227             # aliases
228             *body_params = \&body_parameters;
229             *input = \&body;
230             *params = \¶meters;
231             *query_params = \&query_parameters;
232             *path_info = \&path;
233              
234             sub cookie {
235             my $self = shift;
236              
237             return keys %{ $self->cookies } if @_ == 0;
238              
239             if (@_ == 1) {
240             my $name = shift;
241             return undef unless exists $self->cookies->{$name}; ## no critic.
242             return $self->cookies->{$name};
243             }
244             return;
245             }
246              
247             sub param {
248             my $self = shift;
249              
250             return keys %{ $self->parameters } if @_ == 0;
251              
252             if (@_ == 1) {
253             my $param = shift;
254             return wantarray ? () : undef unless exists $self->parameters->{$param};
255              
256             if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
257             return (wantarray)
258             ? @{ $self->parameters->{$param} }
259             : $self->parameters->{$param}->[0];
260             } else {
261             return (wantarray)
262             ? ( $self->parameters->{$param} )
263             : $self->parameters->{$param};
264             }
265             } else {
266             my $field = shift;
267             $self->parameters->{$field} = [@_];
268             }
269             }
270              
271             sub upload {
272             my $self = shift;
273              
274             return keys %{ $self->uploads } if @_ == 0;
275              
276             if (@_ == 1) {
277             my $upload = shift;
278             return wantarray ? () : undef unless exists $self->uploads->{$upload};
279              
280             if (ref $self->uploads->{$upload} eq 'ARRAY') {
281             return (wantarray)
282             ? @{ $self->uploads->{$upload} }
283             : $self->uploads->{$upload}->[0];
284             } else {
285             return (wantarray)
286             ? ( $self->uploads->{$upload} )
287             : $self->uploads->{$upload};
288             }
289             } else {
290             while ( my($field, $upload) = splice(@_, 0, 2) ) {
291             if ( exists $self->uploads->{$field} ) {
292             for ( $self->uploads->{$field} ) {
293             $_ = [$_] unless ref($_) eq "ARRAY";
294             push(@{ $_ }, $upload);
295             }
296             } else {
297             $self->uploads->{$field} = $upload;
298             }
299             }
300             }
301             }
302              
303             sub uri_with {
304             my($self, $args) = @_;
305            
306             Carp::carp( 'No arguments passed to uri_with()' ) unless $args;
307              
308             for my $value (values %{ $args }) {
309             next unless defined $value;
310             for ( ref $value eq 'ARRAY' ? @{ $value } : $value ) {
311             $_ = "$_";
312             utf8::encode( $_ );
313             }
314             };
315            
316             my $uri = $self->uri->clone;
317            
318             $uri->query_form( {
319             %{ $uri->query_form_hash },
320             %{ $args },
321             } );
322             return $uri;
323             }
324              
325             sub as_http_request {
326             my $self = shift;
327             require 'HTTP/Request.pm'; ## no critic
328             HTTP::Request->new( $self->method, $self->uri, $self->headers, $self->raw_body );
329             }
330              
331             sub absolute_url {
332             my ($self, $location) = @_;
333              
334             unless ($location =~ m!^https?://!) {
335             return URI->new( $location )->abs( $self->base );
336             } else {
337             return $location;
338             }
339             }
340              
341             sub content {
342             my ( $self, @args ) = @_;
343              
344             if ( @args ) {
345             Carp::croak "The HTTP::Request method 'content' is unsupported when used as a writer, use HTTP::Engine::RequestBuilder";
346             } else {
347             return $self->raw_body;
348             }
349             }
350              
351             sub as_string {
352             my $self = shift;
353             $self->as_http_request->as_string; # FIXME not efficient
354             }
355              
356             sub parse {
357             Carp::croak "The HTTP::Request method 'parse' is unsupported, use HTTP::Engine::RequestBuilder";
358             }
359              
360             no Any::Moose;
361             __PACKAGE__->meta->make_immutable(inline_destructor => 1);
362             1;
363             __END__