File Coverage

blib/lib/Dancer2/Core/Request.pm
Criterion Covered Total %
statement 300 318 94.3
branch 107 128 83.5
condition 40 56 71.4
subroutine 79 85 92.9
pod 46 53 86.7
total 572 640 89.3


line stmt bran cond sub pod time code
1             # ABSTRACT: Interface for accessing incoming requests
2             $Dancer2::Core::Request::VERSION = '0.400000';
3             use strict;
4 145     145   220057 use warnings;
  145         308  
  145         4166  
5 145     145   662 use parent 'Plack::Request';
  145         282  
  145         3638  
6 145     145   2785  
  145         1886  
  145         1148  
7             use Carp;
8 145     145   8295197 use Encode;
  145         423  
  145         8527  
9 145     145   887 use URI;
  145         355  
  145         8202  
10 145     145   830 use URI::Escape;
  145         319  
  145         2977  
11 145     145   672 use Safe::Isa;
  145         325  
  145         6178  
12 145     145   4087 use Hash::MultiValue;
  145         3562  
  145         16355  
13 145     145   948 use Module::Runtime 'require_module';
  145         306  
  145         3734  
14 145     145   2441 use Ref::Util qw< is_ref is_arrayref is_hashref >;
  145         6359  
  145         1260  
15 145     145   11512  
  145         6422  
  145         7797  
16             use Dancer2::Core::Types;
17 145     145   2219 use Dancer2::Core::Request::Upload;
  145         358  
  145         2476  
18 145     145   1298912 use Dancer2::Core::Cookie;
  145         503  
  145         5272  
19 145     145   3980  
  145         322  
  145         541351  
20             # add an attribute for each HTTP_* variables
21             # (HOST is managed manually)
22             my @http_env_keys = (qw/
23             accept_charset
24             accept_encoding
25             accept_language
26             connection
27             keep_alive
28             x_requested_with
29             /);
30              
31             # apparently you can't eval core functions
32              
33 1     1 1 1767 eval << "_EVAL" or die $@ for @http_env_keys; ## no critic
34             sub $_ { \$_[0]->env->{ 'HTTP_' . ( uc "$_" ) } }
35 1     1 1 404 1;
  1     1 1 413  
  1     1 1 388  
  1     1 1 404  
  1     1 1 406  
  1     1 1 1336  
36             _EVAL
37              
38             # check presence of XS module to speedup request
39             our $XS_URL_DECODE = eval { require_module('URL::Encode::XS'); 1; };
40             our $XS_PARSE_QUERY_STRING = eval { require_module('CGI::Deurl::XS'); 1; };
41             our $XS_HTTP_COOKIES = eval { require_module('HTTP::XSCookies'); 1; };
42              
43             our $_id = 0;
44              
45             # self->new( env => {}, serializer => $s, is_behind_proxy => 0|1 )
46             my ( $class, @args ) = @_;
47              
48             # even sized list
49 735     735 1 200818 @args % 2 == 0
50             or croak 'Must provide even sized list';
51              
52 735 50       2978 my %opts = @args;
53             my $env = $opts{'env'};
54              
55 735         2630 my $self = $class->SUPER::new($env);
56 735         1553  
57             if ( my $s = $opts{'serializer'} ) {
58 735         4159 $s->$_does('Dancer2::Core::Role::Serializer')
59             or croak 'Serializer provided not a Serializer object';
60 735 100       8253  
61 84 100       308 $self->{'serializer'} = $s;
62             }
63              
64 83         4064 # additionally supported attributes
65             $self->{'id'} = ++$_id;
66             $self->{'vars'} = {};
67             $self->{'is_behind_proxy'} = !!$opts{'is_behind_proxy'};
68 734         2218  
69 734         1794 $opts{'body_params'}
70 734         1992 and $self->{'_body_params'} = $opts{'body_params'};
71              
72             # Deserialize/parse body for HMV
73 734 100       2209 $self->data;
74             $self->_build_uploads();
75              
76 734         2548 return $self;
77 731         2760 }
78              
79 730         2624 # a buffer for per-request variables
80              
81             my $self = shift;
82             @_ == 2
83 87     87 1 263 ? $self->vars->{ $_[0] } = $_[1]
84             : $self->vars->{ $_[0] };
85             }
86 12     12 1 581  
87             # I don't like this. I know send_file uses this and I wonder
88             # if we can remove it.
89 12 100       61 # -- Sawyer
90              
91             # XXX: incompatible with Plack::Request
92              
93              
94             # Private 'read-only' attributes for request params. See the params()
95 0     0 0 0 # method for the public interface.
96             #
97             # _body_params, _query_params and _route_params have setter methods that
98 32     32 1 160 # decode byte string to characters before setting; If you know you have
99             # decoded (character) params, such as output from a deserializer, you can
100 16     16 1 2576 # set these directly in the request object hash to avoid the decode op.
101              
102              
103              
104              
105             my ( $self, $params ) = @_;
106             $self->{_query_params} = _decode( $params );
107             }
108              
109 284   66 284   1327  
110             my ( $self, $params ) = @_;
111 574     574   2010 $self->{_route_params} = _decode( $params );
112             $self->_build_params();
113 1316   66 1316   5729 }
114              
115 79     79   194 # XXX: incompatible with Plack::Request
116              
117              
118 31     31   74 my ($self) = @_;
119 31         77  
120             if ( $self->is_behind_proxy and exists $self->env->{'HTTP_X_FORWARDED_HOST'} ) {
121             my @hosts = split /\s*,\s*/, $self->env->{'HTTP_X_FORWARDED_HOST'}, 2;
122 575   100 575   2377 return $hosts[0];
123             } else {
124             return $self->env->{'HTTP_HOST'};
125 547     547   1301 }
126 547         1313 }
127 547         1865  
128             # aliases, kept for backward compat
129              
130             # there are two options
131 5     5 1 19 $_[0]->env->{'HTTP_X_FORWARDED_PROTO'} ||
132             $_[0]->env->{'HTTP_X_FORWARDED_PROTOCOL'} ||
133 295 100   295 0 1274 $_[0]->env->{'HTTP_FORWARDED_PROTO'}
134             }
135              
136 141     141 1 1860 my ($self) = @_;
137             my $scheme = $self->is_behind_proxy
138 141 100 100     318 ? $self->forwarded_protocol
139 3         20 : '';
140 3         28  
141             return $scheme || $self->env->{'psgi.url_scheme'};
142 138         319 }
143              
144              
145              
146             my $self = shift;
147 12     12 1 1651  
148 4     4 1 5524 my $serializer = $self->serializer
149 3     3 1 3205 or return;
150 0     0 1 0  
151             # The latest draft of the RFC does not forbid DELETE to have content,
152             # rather the behaviour is undefined. Take the most lenient route and
153             # deserialize any content on delete as well.
154             return
155             unless grep { $self->method eq $_ } qw/ PUT POST PATCH DELETE /;
156 14 100 100 14 1 40  
157             # try to deserialize
158             my $body = $self->body;
159              
160 153     153 1 9429 $body && length $body > 0
161 153 100       329 or return;
162              
163             # Catch serializer fails - which is tricky as Role::Serializer
164             # wraps the deserializaion in an eval and returns undef.
165 153   66     699 # We want to generate a 500 error on serialization fail (Ref #794)
166             # to achieve that, override the log callback so we can catch a signal
167             # that it failed. This is messy (messes with serializer internals), but
168 798     798 1 4629 # "works".
169             my $serializer_fail;
170 784   100 784 1 3643 my $serializer_log_cb = $serializer->log_cb;
171             local $serializer->{log_cb} = sub {
172             $serializer_fail = $_[1];
173 734     734 0 1321 $serializer_log_cb->(@_);
174             };
175 734 100       1840 # work-around to resolve a chicken-and-egg issue when instantiating a
176             # request object; the serializer needs that request object to deserialize
177             # the body params.
178             Scalar::Util::weaken( my $request = $self );
179             $self->serializer->has_request || $self->serializer->set_request($request);
180             my $data = $serializer->deserialize($body);
181             die $serializer_fail if $serializer_fail;
182 83 100       173  
  332         1563  
183             # Set _body_params directly rather than using the setter. Deserializiation
184             # returns characters and skipping the decode op in the setter ensures
185 31         237 # that numerical data "stays" numerical; decoding an SV that is an IV
186             # converts that to a PVIV. Some serializers are picky (JSON)..
187 31 100 66     9432 $self->{_body_params} = $data;
188              
189             # Set body parameters (decoded HMV)
190             $self->{'body_parameters'} =
191             Hash::MultiValue->from_mixed( is_hashref($data) ? %$data : () );
192              
193             return $data;
194             }
195              
196 30         71  
197 30         115  
198             # public interface compat with CGI.pm objects
199 3     3   6  
200 3         13 my ($self) = @_;
201 30         157 return "[#" . $self->id . "] " . $self->method . " " . $self->path;
202             }
203              
204             my $self = shift;
205 30         114 my $uri = $self->_common_uri;
206 30 100       77  
207 30         3221 return $uri->canonical;
208 30 100       113 }
209              
210             my $self = shift;
211              
212             my $path = $self->env->{SCRIPT_NAME};
213             my $port = $self->env->{SERVER_PORT};
214 27         86 my $server = $self->env->{SERVER_NAME};
215             my $host = $self->host;
216             my $scheme = $self->scheme;
217 27 100       201  
218             my $uri = URI->new;
219             $uri->scheme($scheme);
220 27         1322 $uri->authority( $host || "$server:$port" );
221             $uri->path( $path || '/' );
222              
223 3     3 1 7925 return $uri;
224             }
225 4     4 1 1009  
226 7     7 1 4349 my $self = shift;
227 7     7 1 5463 my $uri = $self->_common_uri;
228 4     4 1 1031 my $canon = $uri->canonical;
229 4     4 1 1012  
230 4     4 0 984 if ( $uri->path eq '/' ) {
231 0     0 1 0 $canon =~ s{/$}{};
232             }
233              
234 3     3 1 2563 return $canon;
235 0     0 1 0 }
236              
237             warn q{DEPRECATED: request->dispatch_path. Please use request->path instead};
238 7     7 1 4364 return shift->path;
239 7         22 }
240              
241             my ( $self, $part, $params, $dont_escape ) = @_;
242              
243 24     24 1 9103 $part ||= '';
244 24         53 my $uri = $self->base;
245              
246 24         65 # Make sure there's exactly one slash between the base and the new part
247             my $base = $uri->path;
248             $base =~ s|/$||;
249             $part =~ s|^/||;
250 135     135   201 $uri->path("$base/$part");
251              
252 135         427 $uri->query_form($params) if $params;
253 135         627  
254 135         462 return $dont_escape
255 135         556 ? uri_unescape( ${ $uri->canonical } )
256 135         615 : ${ $uri->canonical };
257             }
258 135         925  
259 135         16947 my ( $self, $source ) = @_;
260 135   66     15630  
261 135   100     4301 return %{ $self->_params } if wantarray && @_ == 1;
262             return $self->_params if @_ == 1;
263 135         3860  
264             if ( $source eq 'query' ) {
265             return %{ $self->_query_params || {} } if wantarray;
266             return $self->_query_params;
267 111     111 1 6981 }
268 111         276 elsif ( $source eq 'body' ) {
269 111         355 return %{ $self->_body_params || {} } if wantarray;
270             return $self->_body_params;
271 111 100       9742 }
272 104         1142 if ( $source eq 'route' ) {
273             return %{ $self->_route_params } if wantarray;
274             return $self->_route_params;
275 111         1456 }
276             else {
277             croak "Unknown source params \"$source\".";
278             }
279 0     0 1 0 }
280 0         0  
281             my $self = shift;
282             $self->{'query_parameters'} ||= do {
283             if ($XS_PARSE_QUERY_STRING) {
284 15     15 1 10941 my $query = _decode(CGI::Deurl::XS::parse_query_string(
285             $self->env->{'QUERY_STRING'}
286 15   50     37 ));
287 15         36  
288             Hash::MultiValue->new(
289             map {;
290 15         1244 my $key = $_;
291 15         127 is_arrayref( $query->{$key} )
292 15         41 ? ( map +( $key => $_ ), @{ $query->{$key} } )
293 15         48 : ( $key => $query->{$key} )
294             } keys %{$query}
295 15 100       354 );
296             } else {
297             # defer to Plack::Request
298 3         9 _decode($self->SUPER::query_parameters);
299 15 100       295 }
  12         27  
300             };
301             }
302              
303 252     252 1 20801 # this will be filled once the route is matched
304              
305 252 100 66     813 my ( $self, $params ) = @_;
  31         75  
306 221 100       814 # remove reserved splat parameter name
307             # you should access splat parameters using splat() keyword
308 16 100       66 delete @{$params}{qw<splat captures>};
    100          
309 5 0       14 $self->{'route_parameters'} = Hash::MultiValue->from_mixed( %{_decode($params)} );
  0 50       0  
310 5         12 }
311              
312             my $self = shift;
313 10 0       27 # defer to (the overridden) Plack::Request->body_parameters
  0 50       0  
314 10         27 $self->{'body_parameters'} ||= _decode($self->SUPER::body_parameters());
315             }
316 1 50       4  
317 1 50       4 my ( $self, $type ) = @_;
  0         0  
318 1         3  
319             # handle a specific case
320             if ($type) {
321 0         0 my $attr = "${type}_parameters";
322             return $self->$attr;
323             }
324              
325             # merge together the *decoded* parameters
326 59     59 1 97 $self->{'merged_parameters'} ||= do {
327 59   66     222 my $query = $self->query_parameters;
328 47 100       135 my $body = $self->body_parameters;
329             my $route = $self->route_parameters; # not in Plack::Request
330 43         117 Hash::MultiValue->new( map $_->flatten, $query, $body, $route );
331             };
332             }
333              
334              
335 10         19  
336             # XXX: incompatible with Plack::Request
337 2         23  
338 10 100       50 my ($h) = @_;
339 43         100 return if not defined $h;
  43         168  
340              
341             if ( !is_ref($h) && !utf8::is_utf8($h) ) {
342             return decode( 'UTF-8', $h );
343 4         22 }
344             elsif ( ref($h) eq 'Hash::MultiValue' ) {
345             return Hash::MultiValue->from_mixed(_decode($h->as_hashref_mixed));
346             }
347             elsif ( is_hashref($h) ) {
348             return { map {my $t = _decode($_); $t} (%$h) };
349 17   33 17 0 64 }
350             elsif ( is_arrayref($h) ) {
351             return [ map _decode($_), @$h ];
352 547     547   1295 }
353              
354             return $h;
355 547         952 }
  547         1385  
356 547         933  
  547         1094  
357             my $self = shift;
358              
359             return 0 unless defined $self->headers;
360 712     712 1 1339 return 0 unless defined $self->header('X-Requested-With');
361             return 0 if $self->header('X-Requested-With') ne 'XMLHttpRequest';
362 712   66     3975 return 1;
363             }
364              
365             # XXX incompatible with Plack::Request
366 3     3 1 9 # context-aware accessor for uploads
367             my ( $self, $name ) = @_;
368             my $res = $self->{uploads}{$name};
369 3 50       8  
370 0         0 return $res unless wantarray;
371 0         0 return () unless defined $res;
372             return ( is_arrayref($res) ) ? @$res : $res;
373             }
374              
375 3   33     16 my ($self) = @_;
376 3         8  
377 3         9 # params may have been populated by before filters
378 3         9 # _before_ we get there, so we have to save it first
379 3         12 my $previous = $self->_has_params ? $self->_params : {};
380              
381             # now parse environment params...
382             my $get_params = $self->_parse_get_params();
383 2 100   2 0 5  
384             # and merge everything
385 31 100   31 0 54 $self->{_params} = {
  31         130  
386             map +( is_hashref($_) ? %{$_} : () ),
387             $previous,
388 10     10 1 1354 $get_params,
389             $self->_body_params,
390             $self->_route_params,
391 24114     24114   212972 };
392 24114 100       37713  
393             }
394 24071 100 66     66456  
    100          
    100          
    50          
395 21551         49076 my ( $self, $encoded ) = @_;
396             return URL::Encode::XS::url_decode($encoded) if $XS_URL_DECODE;
397             my $clean = $encoded;
398 654         2643 $clean =~ tr/\+/ /;
399             $clean =~ s/%([a-fA-F0-9]{2})/pack "H2", $1/eg;
400             return $clean;
401 1788         9068 }
  21490         29004  
  21490         553265  
402              
403             my ($self) = @_;
404 78         242 return $self->_query_params if defined $self->{_query_params};
405              
406             my $query_params = {};
407 0         0  
408             my $source = $self->env->{QUERY_STRING};
409             return if !defined $source || $source eq '';
410              
411 0     0 1 0 if ($XS_PARSE_QUERY_STRING) {
412             $self->_set_query_params(
413 0 0       0 CGI::Deurl::XS::parse_query_string($source) || {}
414 0 0       0 );
415 0 0       0 return $self->_query_params;
416 0         0 }
417              
418             foreach my $token ( split /[&;]/, $source ) {
419             my ( $key, $val ) = split( /=/, $token );
420             next unless defined $key;
421             $val = ( defined $val ) ? $val : '';
422 21     21 1 2445 $key = $self->_url_decode($key);
423 21         42 $val = $self->_url_decode($val);
424              
425 21 100       57 # looking for multi-value params
426 9 100       21 if ( exists $query_params->{$key} ) {
427 6 100       21 my $prev_val = $query_params->{$key};
428             if ( is_arrayref($prev_val) ) {
429             push @{ $query_params->{$key} }, $val;
430             }
431 574     574   1185 else {
432             $query_params->{$key} = [ $prev_val, $val ];
433             }
434             }
435 574 100       1644  
436             # simple value param (first time we see it)
437             else {
438 574         1824 $query_params->{$key} = $val;
439             }
440             }
441             $self->_set_query_params( $query_params );
442 574 100       1592 return $self->_query_params;
  1794         5375  
443             }
444              
445             my ($self) = @_;
446              
447             # parse body and build body params
448             my $body_params = $self->_body_params;
449              
450             my $uploads = $self->SUPER::uploads;
451             my %uploads;
452 64     64   93  
453 64 100       133 for my $name ( keys %$uploads ) {
454 32         37 my @uploads = map Dancer2::Core::Request::Upload->new(
455 32         46 # For back-compatibility, we use a HashRef of headers
456 32         64 headers => {@{$_->{headers}->psgi_flatten_without_sort}},
  7         32  
457 32         52 tempname => $_->{tempname},
458             size => $_->{size},
459             filename => _decode( $_->{filename} ),
460             ), $uploads->get_all($name);
461 574     574   1176  
462 574 100       1656 $uploads{$name} = @uploads > 1 ? \@uploads : $uploads[0];
463              
464 531         1017 # support access to the filename as a normal param
465             my @filenames = map $_->{'filename'}, @uploads;
466 531         1628 $self->{_body_params}{$name} =
467 531 100 100     4099 @filenames > 1 ? \@filenames : $filenames[0];
468             }
469 31 100       95  
470 21   50     243 $self->{uploads} = \%uploads;
471             }
472              
473 21         88 # XXX: incompatible with Plack::Request
474              
475             my $self = shift;
476 10         62 my $cookies = {};
477 32         90  
478 32 50       65 my $http_cookie = $self->header('Cookie');
479 32 50       55 return $cookies unless defined $http_cookie; # nothing to do
480 32         65  
481 32         54 if ( $XS_HTTP_COOKIES ) {
482             $cookies = HTTP::XSCookies::crush_cookie($http_cookie);
483             }
484 32 100       66 else {
485 6         11 # handle via Plack::Request
486 6 100       21 $cookies = $self->SUPER::cookies();
487 2         5 }
  2         9  
488              
489             # convert to objects
490 4         12 while (my ($name, $value) = each %{$cookies}) {
491             $cookies->{$name} = Dancer2::Core::Cookie->new(
492             name => $name,
493             # HTTP::XSCookies v0.17+ will do the split and return an arrayref
494             value => (is_arrayref($value) ? $value : [split(/[&;]/, $value)])
495             );
496 26         59 }
497             return $cookies;
498             }
499 10         39  
500 10         30 # poor man's clone
501             my ($self, $params, $options) = @_;
502              
503             # shallow clone $env; we don't want to alter the existing one
504 731     731   1510 # in $self, then merge any overridden values
505             my $env = { %{ $self->env }, %{ $options || {} } };
506              
507 731         2151 my $new_request = __PACKAGE__->new(
508             env => $env,
509 730         30549 body_params => {},
510 730         6830 );
511              
512 730         2057 # Clone and merge query params
513             my $new_params = $self->params;
514             $new_request->{_query_params} = { %{ $self->{_query_params} || {} } };
515 20         3704 $new_request->{query_parameters} = $self->query_parameters->clone;
516             for my $key ( keys %{ $params || {} } ) {
517             my $value = $params->{$key};
518 14         39 $new_params->{$key} = $value;
519             $new_request->{_query_params}->{$key} = $value;
520             $new_request->{query_parameters}->add( $key => $value );
521 14 100       4491 }
522              
523             # Copy params (these are already decoded)
524 14         41 $new_request->{_params} = $new_params;
525 14 100       41 $new_request->{_body_params} = $self->{_body_params};
526             $new_request->{_route_params} = $self->{_route_params};
527             $new_request->{headers} = $self->headers;
528              
529 730         2115 # Copy remaining settings
530             $new_request->{is_behind_proxy} = $self->{is_behind_proxy};
531             $new_request->{vars} = $self->{vars};
532              
533 566   66 566 1 5226 # Clone any existing decoded & cached body params. (GH#1116 GH#1269)
534             $new_request->{'body_parameters'} = $self->body_parameters->clone;
535              
536 479     479   1055 # Delete merged HMV parameters, allowing them to be reconstructed on first use.
537 479         1015 delete $new_request->{'merged_parameters'};
538              
539 479         2249 return $new_request;
540 479 100       74711 }
541              
542 64 100       233  
543 63         568 my ( $self, $route ) = @_;
544             $self->{'route'} = $route;
545             }
546              
547 1         10  
548             my $self = shift;
549             return $self->data if $self->serializer;
550             $self->_body_params;
551 64         227 return $self->{_body_params} if keys %{ $self->{_body_params} };
  131         2281  
552 67 100       1903 return $self->body;
553             }
554              
555             1;
556              
557              
558 64         468 =pod
559              
560             =encoding UTF-8
561              
562             =head1 NAME
563 53     53   122  
564             Dancer2::Core::Request - Interface for accessing incoming requests
565              
566             =head1 VERSION
567 53 50       76  
  53         183  
  53         980  
568             version 0.400000
569 53         350  
570             =head1 SYNOPSIS
571              
572             In a route handler, the current request object can be accessed by the
573             C<request> keyword:
574              
575 53         155 get '/foo' => sub {
576 53 100       81 request->params; # request, params parsed as a hash ref
  53         305  
577 53         180 request->body; # returns the request body, unparsed
578 53 100       3538 request->path; # the path requested by the client
  53         238  
579 9         16 # ...
580 9         20 };
581 9         18  
582 9         37 =head1 DESCRIPTION
583              
584             An object representing a Dancer2 request. It aims to provide a proper
585             interface to anything you might need from a web request.
586 53         365  
587 53         111 =head1 METHODS
588 53         140  
589 53         205 =head2 address
590              
591             Return the IP address of the client.
592 53         4741  
593 53         99 =head2 base
594              
595             Returns an absolute URI for the base of the application. Returns a L<URI>
596 53         128 object (which stringifies to the URL, as you'd expect).
597              
598             =head2 body_parameters
599 53         1839  
600             Returns a L<Hash::MultiValue> object representing the POST parameters.
601 53         124  
602             =head2 body
603              
604             Return the raw body of the request, unparsed.
605              
606 547     547   1268 If you need to access the body of the request, you have to use this accessor and
607 547         1336 should not try to read C<psgi.input> by hand. C<Dancer2::Core::Request>
608             already did it for you and kept the raw body untouched in there.
609              
610 6     6 1 79 =head2 body_data
611              
612             Returns the body of the request in data form, making it possible to distinguish
613 2     2 1 4 between C<body_parameters>, a representation of the request parameters
614 2 100       5 (L<Hash::MultiValue>) and other forms of content.
615 1         4  
616 1 50       2 If a serializer is set, this is the deserialized request body. Otherwise this is
  1         4  
617 1         3 the decoded body parameters (if any), or the body content itself.
618              
619             =head2 content
620              
621             Returns the undecoded byte string POST body.
622              
623             =head2 cookies
624              
625             Returns a reference to a hash containing cookies, where the keys are the names of the
626             cookies and values are L<Dancer2::Core::Cookie> objects.
627              
628             =head2 data
629              
630             If the application has a serializer and if the request has serialized
631             content, returns the deserialized structure as a hashref.
632              
633             =head2 dispatch_path
634              
635             Alias for L<path>. Deprecated.
636              
637             =head2 env
638              
639             Return the current PSGI environment hash reference.
640              
641             =head2 header($name)
642              
643             Return the value of the given header, if present. If the header has multiple
644             values, returns an the list of values if called in list context, the first one
645             in scalar.
646              
647             =head2 headers
648              
649             Returns either an L<HTTP::Headers> or an L<HTTP::Headers::Fast> object
650             representing the headers.
651              
652             =head2 id
653              
654             The ID of the request. This allows you to trace a specific request in loggers,
655             per the string created using C<to_string>.
656              
657             The ID of the request is essentially the number of requests run in the current
658             class.
659              
660             =head2 input
661              
662             Alias to C<input_handle> method below.
663              
664             =head2 input_handle
665              
666             Alias to the PSGI input handle (C<< <request->env->{psgi.input}> >>)
667              
668             =head2 is_ajax
669              
670             Return true if the value of the header C<X-Requested-With> is
671             C<XMLHttpRequest>.
672              
673             =head2 is_delete
674              
675             Return true if the method requested by the client is 'DELETE'
676              
677             =head2 is_get
678              
679             Return true if the method requested by the client is 'GET'
680              
681             =head2 is_head
682              
683             Return true if the method requested by the client is 'HEAD'
684              
685             =head2 is_post
686              
687             Return true if the method requested by the client is 'POST'
688              
689             =head2 is_put
690              
691             Return true if the method requested by the client is 'PUT'
692              
693             =head2 is_options
694              
695             Return true if the method requested by the client is 'OPTIONS'
696              
697             =head2 logger
698              
699             Returns the C<psgix.logger> code reference, if exists.
700              
701             =head2 method
702              
703             Return the HTTP method used by the client to access the application.
704              
705             While this method returns the method string as provided by the environment, it's
706             better to use one of the following boolean accessors if you want to inspect the
707             requested method.
708              
709             =head2 new
710              
711             The constructor of the class, used internally by Dancer2's core to create request
712             objects.
713              
714             It uses the environment hash table given to build the request object:
715              
716             Dancer2::Core::Request->new( env => $env );
717              
718             There are two additional parameters for instantiation:
719              
720             =over 4
721              
722             =item * serializer
723              
724             A serializer object to work with when reading the request body.
725              
726             =item * body_params
727              
728             Provide body parameters.
729              
730             Used internally when we need to avoid parsing the body again.
731              
732             =back
733              
734             =head2 param($key)
735              
736             Calls the C<params> method below and fetches the key provided.
737              
738             =head2 params($source)
739              
740             Called in scalar context, returns a hashref of params, either from the specified
741             source (see below for more info on that) or merging all sources.
742              
743             So, you can use, for instance:
744              
745             my $foo = params->{foo}
746              
747             If called in list context, returns a list of key and value pairs, so you could use:
748              
749             my %allparams = params;
750              
751             Parameters are merged in the following order: query, body, route - i.e. route
752             parameters have the highest priority:
753              
754             POST /hello/Ruth?name=Quentin
755              
756             name=Bobbie
757              
758             post '/hello/:name' => sub {
759             return "Hello, " . route_parameters->get('name') . "!"; # returns Ruth
760             return "Hello, " . query_parameters->get('name') . "!"; # returns Quentin
761             return "Hello, " . body_parameters->get('name') . "!"; # returns Bobbie
762             return "Hello, " . param('name') . "!"; # returns Ruth
763             };
764              
765             The L</query_parameters>, L</route_parameters>, and L</body_parameters> keywords
766             provide a L<Hash::MultiValue> result from the three different parameters.
767             We recommend using these rather than C<params>, because of the potential for
768             unintentional behaviour - consider the following request and route handler:
769              
770             POST /artist/104/new-song
771              
772             name=Careless Dancing
773              
774             post '/artist/:id/new-song' => sub {
775             find_artist(param('id'))->create_song(params);
776             # oops! we just passed id into create_song,
777             # but we probably only intended to pass name
778             find_artist(param('id'))->create_song(body_parameters);
779             };
780              
781             POST /artist/104/join-band
782              
783             id=4
784             name=Dancing Misfits
785              
786             post '/artist/:id/new-song' => sub {
787             find_artist(param('id'))->join_band(params);
788             # oops! we just passed an id of 104 into join_band,
789             # but we probably should have passed an id of 4
790             };
791              
792             =head2 parameters
793              
794             Returns a L<Hash::MultiValue> object with merged GET and POST parameters.
795              
796             Parameters are merged in the following order: query, body, route - i.e. route
797             parameters have the highest priority - see L</params> for how this works, and
798             associated risks and alternatives.
799              
800             =head2 path
801              
802             The path requested by the client, normalized. This is effectively
803             C<path_info> or a single forward C</>.
804              
805             =head2 path_info
806              
807             The raw requested path. This could be empty. Use C<path> instead.
808              
809             =head2 port
810              
811             Return the port of the server.
812              
813             =head2 protocol
814              
815             Return the protocol (I<HTTP/1.0> or I<HTTP/1.1>) used for the request.
816              
817             =head2 query_parameters
818              
819             Returns a L<Hash::MultiValue> parameters object.
820              
821             =head2 query_string
822              
823             Returns the portion of the request defining the query itself - this is
824             what comes after the C<?> in a URI.
825              
826             =head2 raw_body
827              
828             Alias to C<content> method.
829              
830             =head2 remote_address
831              
832             Alias for C<address> method.
833              
834             =head2 remote_host
835              
836             Return the remote host of the client. This only works with web servers configured
837             to do a reverse DNS lookup on the client's IP address.
838              
839             =head2 request_method
840              
841             Alias to the C<method> accessor, for backward-compatibility with C<CGI> interface.
842              
843             =head2 request_uri
844              
845             Return the raw, undecoded request URI path.
846              
847             =head2 route
848              
849             Return the L<route|Dancer2::Core::Route> which this request matched.
850              
851             =head2 scheme
852              
853             Return the scheme of the request
854              
855             =head2 script_name
856              
857             Return script_name from the environment.
858              
859             =head2 secure
860              
861             Return true or false, indicating whether the connection is secure - this is
862             effectively checking if the scheme is I<HTTPS> or not.
863              
864             =head2 serializer
865              
866             Returns the optional serializer object used to deserialize request parameters.
867              
868             =head2 session
869              
870             Returns the C<psgix.session> hash, if exists.
871              
872             =head2 session_options
873              
874             Returns the C<psgix.session.options> hash, if exists.
875              
876             =head2 to_string
877              
878             Return a string representing the request object (e.g., C<GET /some/path>).
879              
880             =head2 upload($name)
881              
882             Context-aware accessor for uploads. It's a wrapper around an access to the hash
883             table provided by C<uploads()>. It looks at the calling context and returns a
884             corresponding value.
885              
886             If you have many file uploads under the same name, and call C<upload('name')> in
887             an array context, the accessor will unroll the ARRAY ref for you:
888              
889             my @uploads = request->upload('many_uploads'); # OK
890              
891             Whereas with a manual access to the hash table, you'll end up with one element
892             in C<@uploads>, being the arrayref:
893              
894             my @uploads = request->uploads->{'many_uploads'};
895             # $uploads[0]: ARRAY(0xXXXXX)
896              
897             That is why this accessor should be used instead of a manual access to
898             C<uploads>.
899              
900             =head2 uploads
901              
902             Returns a reference to a hash containing uploads. Values can be either a
903             L<Dancer2::Core::Request::Upload> object, or an arrayref of
904             L<Dancer2::Core::Request::Upload>
905             objects.
906              
907             You should probably use the C<upload($name)> accessor instead of manually accessing the
908             C<uploads> hash table.
909              
910             =head2 uri
911              
912             An alias to C<request_uri>.
913              
914             =head2 uri_base
915              
916             Same thing as C<base> above, except it removes the last trailing slash in the
917             path if it is the only path.
918              
919             This means that if your base is I<http://myserver/>, C<uri_base> will return
920             I<http://myserver> (notice no trailing slash). This is considered very useful
921             when using templates to do the following thing:
922              
923             <link rel="stylesheet" href="[% request.uri_base %]/css/style.css" />
924              
925             =head2 uri_for(path, params)
926              
927             Constructs a URI from the base and the passed path. If params (hashref) is
928             supplied, these are added to the query string of the URI.
929              
930             Thus, with the following base:
931              
932             http://localhost:5000/foo
933              
934             You get the following behavior:
935              
936             my $uri = request->uri_for('/bar', { baz => 'baz' });
937             print $uri; # http://localhost:5000/foo/bar?baz=baz
938              
939             C<uri_for> returns a L<URI> object (which can stringify to the value).
940              
941             =head2 user
942              
943             Return remote user if defined.
944              
945             =head2 var
946              
947             By-name interface to variables stored in this request object.
948              
949             my $stored = $request->var('some_variable');
950              
951             returns the value of 'some_variable', while
952              
953             $request->var('some_variable' => 'value');
954              
955             will set it.
956              
957             =head2 vars
958              
959             Access to the internal hash of variables:
960              
961             my $value = $request->vars->{'my_key'};
962              
963             You want to use C<var> above.
964              
965             =head1 Common HTTP request headers
966              
967             Commonly used client-supplied HTTP request headers are available through
968             specific accessors:
969              
970             =over 4
971              
972             =item C<accept>
973              
974             HTTP header: C<HTTP_ACCEPT>.
975              
976             =item C<accept_charset>
977              
978             HTTP header: C<HTTP_ACCEPT_CHARSET>.
979              
980             =item C<accept_encoding>
981              
982             HTTP header: C<HTTP_ACCEPT_ENCODING>.
983              
984             =item C<accept_language>
985              
986             HTTP header: C<HTTP_ACCEPT_LANGUAGE>.
987              
988             =item C<agent>
989              
990             Alias for C<user_agent>) below.
991              
992             =item C<connection>
993              
994             HTTP header: C<HTTP_CONNECTION>.
995              
996             =item C<content_encoding>
997              
998             HTTP header: C<HTTP_CONTENT_ENCODING>.
999              
1000             =item C<content_length>
1001              
1002             HTTP header: C<HTTP_CONTENT_LENGTH>.
1003              
1004             =item C<content_type>
1005              
1006             HTTP header: C<HTTP_CONTENT_TYPE>.
1007              
1008             =item C<forwarded_for_address>
1009              
1010             HTTP header: C<HTTP_X_FORWARDED_FOR>.
1011              
1012             =item C<forwarded_host>
1013              
1014             HTTP header: C<HTTP_X_FORWARDED_HOST>.
1015              
1016             =item C<forwarded_protocol>
1017              
1018             One of either C<HTTP_X_FORWARDED_PROTOCOL>, C<HTTP_X_FORWARDED_PROTO>, or
1019             C<HTTP_FORWARDED_PROTO>.
1020              
1021             =item C<host>
1022              
1023             Checks whether we are behind a proxy using the C<behind_proxy>
1024             configuration option, and if so returns the first
1025             C<HTTP_X_FORWARDED_HOST>, since this is a comma separated list.
1026              
1027             If you have not configured that you are behind a proxy, it returns HTTP
1028             header C<HTTP_HOST>.
1029              
1030             =item C<keep_alive>
1031              
1032             HTTP header: C<HTTP_KEEP_ALIVE>.
1033              
1034             =item C<referer>
1035              
1036             HTTP header: C<HTTP_REFERER>.
1037              
1038             =item C<user_agent>
1039              
1040             HTTP header: C<HTTP_USER_AGENT>.
1041              
1042             =item C<x_requested_with>
1043              
1044             HTTP header: C<HTTP_X_REQUESTED_WITH>.
1045              
1046             =back
1047              
1048             =head1 Fetching only params from a given source
1049              
1050             If a required source isn't specified, a mixed hashref (or list of key value
1051             pairs, in list context) will be returned; this will contain params from all
1052             sources (route, query, body).
1053              
1054             In practical terms, this means that if the param C<foo> is passed both on the
1055             querystring and in a POST body, you can only access one of them.
1056              
1057             If you want to see only params from a given source, you can say so by passing
1058             the C<$source> param to C<params()>:
1059              
1060             my %querystring_params = params('query');
1061             my %route_params = params('route');
1062             my %post_params = params('body');
1063              
1064             If source equals C<route>, then only params parsed from the route pattern
1065             are returned.
1066              
1067             If source equals C<query>, then only params parsed from the query string are
1068             returned.
1069              
1070             If source equals C<body>, then only params sent in the request body will be
1071             returned.
1072              
1073             If another value is given for C<$source>, then an exception is triggered.
1074              
1075             =head1 EXTRA SPEED
1076              
1077             If L<Dancer2::Core::Request> detects the following modules as installed,
1078             it will use them to speed things up:
1079              
1080             =over 4
1081              
1082             =item * L<URL::Encode::XS>
1083              
1084             =item * L<CGI::Deurl::XS>
1085              
1086             =back
1087              
1088             =head1 AUTHOR
1089              
1090             Dancer Core Developers
1091              
1092             =head1 COPYRIGHT AND LICENSE
1093              
1094             This software is copyright (c) 2022 by Alexis Sukrieh.
1095              
1096             This is free software; you can redistribute it and/or modify it under
1097             the same terms as the Perl 5 programming language system itself.
1098              
1099             =cut