File Coverage

blib/lib/Prancer/Request.pm
Criterion Covered Total %
statement 106 110 96.3
branch 19 20 95.0
condition 2 3 66.6
subroutine 30 32 93.7
pod 18 22 81.8
total 175 187 93.5


line stmt bran cond sub pod time code
1             package Prancer::Request;
2              
3 3     3   86948 use strict;
  3         4  
  3         115  
4 3     3   13 use warnings FATAL => 'all';
  3         6  
  3         200  
5              
6 3     3   907 use version;
  3         3495  
  3         17  
7             our $VERSION = '1.04';
8              
9 3     3   1739 use Plack::Request;
  3         129750  
  3         157  
10 3     3   26 use Hash::MultiValue;
  3         4  
  3         48  
11 3     3   11 use URI::Escape ();
  3         2  
  3         53  
12 3     3   12 use Carp;
  3         4  
  3         169  
13              
14 3     3   1167 use Prancer::Request::Upload;
  3         6  
  3         3284  
15              
16             # even though this *should* work automatically, it was not
17             our @CARP_NOT = qw(Prancer Try::Tiny);
18              
19             sub new {
20 8     8 0 64892 my ($class, $env) = @_;
21 8         65 my $self = bless({
22             '_env' => $env,
23             '_request' => Plack::Request->new($env),
24             }, $class);
25              
26             # make instances of these and return those. these calls create new URI objects
27             # with every invocation so this should avoid creating unnecessary objects later
28 8         138 $self->{'_uri'} = $self->{'_request'}->uri();
29 8         8335 $self->{'_base'} = $self->{'_request'}->base();
30              
31             # other manipulation routines
32 8         908 $self->{'_uploads'} = $self->_parse_uploads();
33 8         27 $self->{'_cookies'} = $self->_parse_cookies();
34              
35 8         28 return $self;
36             }
37              
38             sub _parse_uploads {
39 8     8   9 my $self = shift;
40              
41             # turn all uploads into Prancer::Upload objects
42 8         46 my $result = Hash::MultiValue->new();
43 8         267 my $uploads = $self->{'_request'}->uploads();
44 8         4345 for my $key (keys %{$uploads}) {
  8         34  
45 2         39 $result->add($key, map { Prancer::Request::Upload->new($_) } $uploads->get_all($key));
  3         43  
46             }
47              
48 8         50 return $result;
49             }
50              
51             sub _parse_cookies {
52 8     8   15 my $self = shift;
53              
54 8         23 my $result = Hash::MultiValue->new();
55 8 100       265 return $result unless defined($self->{'_env'}->{'HTTP_COOKIE'});
56              
57             # translate all cookies
58 1         6 my @pairs = grep { m/=/x } split(/[;,]\s?/x, $self->{'_env'}->{'HTTP_COOKIE'});
  1         4  
59 1         2 for my $pair (@pairs) {
60             # trim leading and trailing whitespace
61 1         5 $pair =~ s/^\s+|\s+$//xg;
62              
63 1         3 my ($key, $value) = map { URI::Escape::uri_unescape($_) } split(/=/x, $pair, 2);
  2         8  
64 1         9 $result->add($key, $value);
65             }
66              
67 1         30 return $result;
68             }
69              
70             sub env {
71 0     0 0 0 my $self = shift;
72 0         0 return $self->{'_env'};
73             }
74              
75             sub uri {
76 1     1 1 432 my $self = shift;
77 1         8 return $self->{'_uri'};
78             }
79              
80             sub base {
81 4     4 1 8 my $self = shift;
82 4         25 return $self->{'_base'};
83             }
84              
85             sub method {
86 1     1 1 3 my $self = shift;
87 1         8 return $self->{'_request'}->method();
88             }
89              
90             sub protocol {
91 1     1 1 367 my $self = shift;
92 1         9 return $self->{'_request'}->protocol();
93             }
94              
95             sub scheme {
96 1     1 1 416 my $self = shift;
97 1         9 return $self->{'_request'}->scheme();
98             }
99              
100             sub port {
101 1     1 0 392 my $self = shift;
102 1         10 return $self->{'_request'}->port();
103             }
104              
105             sub secure {
106 1     1 1 402 my $self = shift;
107 1 50       8 return ($self->{'_request'}->secure() ? 1 : 0);
108             }
109              
110             sub path {
111 1     1 1 4 my $self = shift;
112 1         8 return $self->{'_request'}->path();
113             }
114              
115             sub body {
116 1     1 1 402 my $self = shift;
117 1         7 return $self->{'_request'}->body();
118             }
119              
120             sub content {
121 1     1 0 697 my $self = shift;
122 1         9 return $self->{'_request'}->raw_body();
123             }
124              
125             sub address {
126 1     1 1 311 my $self = shift;
127 1         9 return $self->{'_request'}->address();
128             }
129              
130             sub user {
131 1     1 1 405 my $self = shift;
132 1         7 return $self->{'_request'}->user();
133             }
134              
135             sub headers {
136 0     0 1 0 my $self = shift;
137 0         0 return $self->{'_request'}->headers();
138             }
139              
140             sub param {
141 7     7 1 2276 my $self = shift;
142              
143             # return the keys if nothing is asked for
144 7 100       22 return keys %{$self->params()} unless @_;
  2         6  
145              
146 5         11 my $key = shift;
147 5 100       33 return $self->params->get($key) unless wantarray;
148 1         5 return $self->params->get_all($key);
149             }
150              
151             sub params {
152 7     7 1 8 my $self = shift;
153 7         30 return $self->{'_request'}->parameters();
154             }
155              
156             sub cookie {
157 5     5 1 2069 my $self = shift;
158              
159             # return the keys if nothing is asked for
160 5 100       19 return keys %{$self->cookies()} unless @_;
  2         7  
161              
162 3         7 my $key = shift;
163 3 100       12 return $self->cookies->get($key) unless wantarray;
164 1         5 return $self->cookies->get_all($key);
165             }
166              
167             sub cookies {
168 5     5 1 11 my $self = shift;
169 5         27 return $self->{'_cookies'};
170             }
171              
172             sub upload {
173 4     4 1 1590 my $self = shift;
174              
175             # return the keys if nothing is asked for
176 4 100       23 return keys %{$self->uploads()} unless @_;
  2         7  
177              
178 2         4 my $key = shift;
179 2 100       9 return $self->uploads->get($key) unless wantarray;
180 1         4 return $self->uploads->get_all($key);
181             }
182              
183             sub uploads {
184 4     4 1 6 my $self = shift;
185 4         24 return $self->{'_uploads'};
186             }
187              
188             sub uri_for {
189 3     3 1 377 my ($self, $path, $args) = @_;
190 3         12 my $uri = URI->new($self->base());
191              
192             # don't want multiple slashes clouding things up
193 3 100 66     368 if ($uri->path() =~ /\/$/x && $path =~ /^\//x) {
194 2         42 $path = substr($path, 1);
195             }
196              
197 3         44 $uri->path($uri->path() . $path);
198 3 100       180 $uri->query_form(@{$args}) if $args;
  1         16  
199 3         116 return $uri;
200             }
201              
202             1;
203              
204             =head1 NAME
205              
206             Prancer::Request
207              
208             =head1 SYNOPSIS
209              
210             sub handler {
211             my ($self, $env, $request, $response, $session) = @_;
212              
213             sub (GET) {
214             my $path = $request->path();
215             my $cookie = $request->cookie("foo");
216             my $param = $request->param("bar");
217             my $cookie_names = $request->cookie();
218             my $user_agent = $request->headers->header("user-agent");
219              
220             ...
221              
222             return $response->finalize(200);
223             }
224             }
225              
226             =head1 METHODS
227              
228             =over
229              
230             =item uri
231              
232             Returns an URI object for the current request. The URI is constructed using
233             various environment values such as C, C,
234             C, C, C and C.
235              
236             =item base
237              
238             Returns a URI object for the base path of current request. This is like C
239             but only contains up to C where your application is hosted at.
240              
241             =item method
242              
243             Contains the request method (C, C, C, etc).
244              
245             =item protocol
246              
247             Returns the protocol (C or C) used for the current request.
248              
249             =item scheme
250              
251             Returns the scheme (C or C) of the request.
252              
253             =item secure
254              
255             Returns true or false, indicating whether the connection is secure (C).
256              
257             =item path
258              
259             Returns B in the environment but returns / in case it is empty.
260              
261             =item body
262              
263             Returns a handle to the input stream.
264              
265             =item address
266              
267             Returns the IP address of the client (C).
268              
269             =item user
270              
271             Returns C if it's set.
272              
273             =item headers
274              
275             Returns an L object containing the headers for the current
276             request.
277              
278             =item param
279              
280             When called with no arguments this will return a list of all parameter names.
281             When called in scalar context this will return the last value for the given
282             key. When called in list context this will return all values for the given key
283             in a list.
284              
285             =item params
286              
287             Returns a L hash reference containing the merged GET and POST
288             parameters.
289              
290             =item cookie
291              
292             When called with no arguments this will return a list of all cookie names.
293             When called in scalar context this will return the last cookie for the given
294             key. When called in list context this will return all cookies for the given
295             key in a list.
296              
297             =item cookies
298              
299             Returns an L containing all cookies.
300              
301             =item upload
302              
303             When called with no arguments this will return a list of all upload names.
304             When called in scalar context this will return the last
305             L object for the given key. When called in list
306             context this will return all L objects for the given
307             key.
308              
309             =item uploads
310              
311             Returns an L containing all uploads.
312              
313             =item uri_for
314              
315             Generates a URL to a new location in an easy to use manner. For example:
316              
317             my $link = $request->uri_for("/logout", [ signoff => 1 ]);
318              
319             =back
320              
321             =cut