File Coverage

blib/lib/Catalyst/Request.pm
Criterion Covered Total %
statement 229 264 86.7
branch 107 148 72.3
condition 20 42 47.6
subroutine 35 41 85.3
pod 22 23 95.6
total 413 518 79.7


line stmt bran cond sub pod time code
1              
2             use Socket qw( getaddrinfo getnameinfo AI_NUMERICHOST NI_NAMEREQD NIx_NOSERV );
3 167     167   313236 use Carp;
  167         646094  
  167         28752  
4 167     167   1602 use utf8;
  167         373  
  167         8630  
5 167     167   82416 use URI::http;
  167         3474  
  167         992  
6 167     167   64744 use URI::https;
  167         1225259  
  167         6044  
7 167     167   65270 use URI::QueryParam;
  167         38923  
  167         5866  
8 167     167   65056 use HTTP::Headers;
  167         128694  
  167         5516  
9 167     167   19515 use Stream::Buffered;
  167         252897  
  167         4785  
10 167     167   66661 use Hash::MultiValue;
  167         1042770  
  167         4553  
11 167     167   72354 use Scalar::Util;
  167         391289  
  167         5473  
12 167     167   1249 use HTTP::Body;
  167         409  
  167         6302  
13 167     167   73030 use Catalyst::Exception;
  167         2204615  
  167         5909  
14 167     167   3491 use Catalyst::Request::PartData;
  167         413  
  167         4871  
15 167     167   72698 use Moose;
  167         68166  
  167         6362  
16 167     167   1359  
  167         378  
  167         1197  
17             use namespace::clean -except => 'meta';
18 167     167   1151606  
  167         444  
  167         1740  
19             with 'MooseX::Emulate::Class::Accessor::Fast';
20              
21             has env => (is => 'ro', writer => '_set_env', predicate => '_has_env');
22             # XXX Deprecated crap here - warn?
23             has action => (is => 'rw');
24             # XXX: Deprecated in docs ages ago (2006), deprecated with warning in 5.8000 due
25             # to confusion between Engines and Plugin::Authentication. Remove in 5.8100?
26             has user => (is => 'rw');
27              
28 0     0 0 0 has _read_position => (
29             # FIXME: work around Moose bug RT#75367
30             # init_arg => undef,
31             is => 'ro',
32             writer => '_set_read_position',
33             default => 0,
34             );
35             has _read_length => (
36             # FIXME: work around Moose bug RT#75367
37             # init_arg => undef,
38             is => 'ro',
39             default => sub {
40             my $self = shift;
41             $self->header('Content-Length') || 0;
42             },
43             lazy => 1,
44             );
45              
46             has address => (is => 'rw');
47             has arguments => (is => 'rw', default => sub { [] });
48             has cookies => (is => 'ro', builder => 'prepare_cookies', lazy => 1);
49              
50             my ( $self ) = @_;
51              
52             if ( my $header = $self->header('Cookie') ) {
53 924     924 1 2697 return { CGI::Simple::Cookie->parse($header) };
54             }
55 924 100       5393 {};
56 1         60 }
57              
58 923         79865 has query_keywords => (is => 'rw');
59             has match => (is => 'rw');
60             has method => (is => 'rw');
61             has protocol => (is => 'rw');
62             has query_parameters => (is => 'rw', lazy=>1, default => sub { shift->_use_hash_multivalue ? Hash::MultiValue->new : +{} });
63             has secure => (is => 'rw', default => 0);
64             has captures => (is => 'rw', default => sub { [] });
65             has uri => (is => 'rw', predicate => 'has_uri');
66             has remote_user => (is => 'rw');
67             has headers => (
68             is => 'rw',
69             isa => 'HTTP::Headers',
70             handles => [qw(content_encoding content_length content_type header referer user_agent)],
71             builder => 'prepare_headers',
72             lazy => 1,
73             );
74              
75             my ($self) = @_;
76              
77             my $env = $self->env;
78             my $headers = HTTP::Headers->new();
79 924     924 1 2555  
80             for my $header (keys %{ $env }) {
81 924         24070 next unless $header =~ /^(HTTP|CONTENT|COOKIE)/i;
82 924         6932 (my $field = $header) =~ s/^HTTPS?_//;
83             $field =~ tr/_/-/;
84 924         8664 $headers->header($field => $env->{$header});
  924         6881  
85 22271 100       130075 }
86 1932         7361 return $headers;
87 1932         4231 }
88 1932         6296  
89             has _log => (
90 924         31632 is => 'ro',
91             weak_ref => 1,
92             required => 1,
93             );
94              
95             has io_fh => (
96             is=>'ro',
97             predicate=>'_has_io_fh',
98             lazy=>1,
99             builder=>'_build_io_fh');
100              
101             my $self = shift;
102             return $self->env->{'psgix.io'}
103             || (
104             $self->env->{'net.async.http.server.req'} &&
105             $self->env->{'net.async.http.server.req'}->stream) ## Until I can make ioasync cabal see the value of supportin psgix.io (jnap)
106 0     0   0 || die "Your Server does not support psgix.io";
107             };
108              
109             has data_handlers => ( is=>'ro', isa=>'HashRef', default=>sub { +{} } );
110 0   0     0  
111             has body_data => (
112             is=>'ro',
113             lazy=>1,
114             builder=>'_build_body_data');
115              
116             my ($self) = @_;
117              
118             # Not sure if these returns should not be exceptions...
119             my $content_type = $self->content_type || return;
120             return unless ($self->method eq 'POST' || $self->method eq 'PUT' || $self->method eq 'PATCH' || $self->method eq 'DELETE');
121              
122 7     7   18 my ($match) = grep { $content_type =~/$_/i }
123             keys(%{$self->data_handlers});
124              
125 7   50     34 if($match) {
126 7 0 33     373 my $fh = $self->body;
      33        
      0        
127             local $_ = $fh;
128 14         150 return $self->data_handlers->{$match}->($fh, $self);
129 7         14 } else {
  7         176  
130             Catalyst::Exception->throw(
131 7 100       24 sprintf '%s does not have an available data handler. Valid data_handlers are %s.',
132 6         25 $content_type, join ', ', sort keys %{$self->data_handlers}
133 6         41 );
134 6         149 }
135             }
136              
137             has _use_hash_multivalue => (
138 1         2 is=>'ro',
  1         24  
139             required=>1,
140             default=> sub {0});
141              
142             # Amount of data to read from input on each pass
143             our $CHUNKSIZE = 64 * 1024;
144              
145             my ($self, $maxlength) = @_;
146             my $remaining = $self->_read_length - $self->_read_position;
147             $maxlength ||= $CHUNKSIZE;
148              
149             # Are we done reading?
150             if ( $remaining <= 0 ) {
151             return;
152 112     112 1 1301 }
153 112         3323  
154 112   66     547 my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
155             my $rc = $self->read_chunk( my $buffer, $readlen );
156             if ( defined $rc ) {
157 112 100       306 if (0 == $rc) { # Nothing more to read even though Content-Length
158 49         167 # said there should be.
159             return;
160             }
161 63 100       174 $self->_set_read_position( $self->_read_position + $rc );
162 63         252 return $buffer;
163 63 50       1260 }
164 63 100       248 else {
165             Catalyst::Exception->throw(
166 1         4 message => "Unknown error reading input: $!" );
167             }
168 62         1813 }
169 62         302  
170             my $self = shift;
171             return $self->env->{'psgi.input'}->read(@_);
172 0         0 }
173              
174             has body_parameters => (
175             is => 'rw',
176             required => 1,
177             lazy => 1,
178 63     63 1 123 predicate => 'has_body_parameters',
179 63         1530 builder => 'prepare_body_parameters',
180             );
181              
182             has uploads => (
183             is => 'rw',
184             required => 1,
185             default => sub { {} },
186             );
187              
188             has parameters => (
189             is => 'rw',
190             lazy => 1,
191             builder => '_build_parameters',
192             clearer => '_clear_parameters',
193             );
194              
195             # TODO:
196             # - Can we lose the before modifiers which just call prepare_body ?
197             # they are wasteful, slow us down and feel cluttery.
198              
199             # Can we make _body an attribute, have the rest of
200             # these lazy build from there and kill all the direct hash access
201             # in Catalyst.pm and Engine.pm?
202              
203             my ( $self ) = @_;
204             $self->_clear_parameters;
205             return $self->parameters;
206             }
207              
208             my ( $self ) = @_;
209             my $parameters = {};
210             my $body_parameters = $self->body_parameters;
211             my $query_parameters = $self->query_parameters;
212 0     0 1 0  
213 0         0 if($self->_use_hash_multivalue) {
214 0         0 return Hash::MultiValue->new($query_parameters->flatten, $body_parameters->flatten);
215             }
216              
217             # We copy, no references
218 922     922   2444 foreach my $name (keys %$query_parameters) {
219 922         2100 my $param = $query_parameters->{$name};
220 922         25611 $parameters->{$name} = ref $param eq 'ARRAY' ? [ @$param ] : $param;
221 922         25813 }
222              
223 922 100       25851 # Merge query and body parameters
224 4         22 foreach my $name (keys %$body_parameters) {
225             my $param = $body_parameters->{$name};
226             my @values = ref $param eq 'ARRAY' ? @$param : ($param);
227             if ( my $existing = $parameters->{$name} ) {
228 918         3981 unshift(@values, (ref $existing eq 'ARRAY' ? @$existing : $existing));
229 118         279 }
230 118 100       527 $parameters->{$name} = @values > 1 ? \@values : $values[0];
231             }
232             $parameters;
233             }
234 918         3136  
235 54         122 has _uploadtmp => (
236 54 100       181 is => 'ro',
237 54 100       148 predicate => '_has_uploadtmp',
238 5 100       31 );
239              
240 54 100       236 my ( $self ) = @_;
241              
242 918         24244 # If previously applied middleware created the HTTP::Body object, then we
243             # just use that one.
244              
245             if(my $plack_body = $self->_has_env ? $self->env->{'plack.request.http.body'} : undef) {
246             $self->_body($plack_body);
247             $self->_body->cleanup(1);
248             return;
249             }
250              
251 923     923 1 2529 # If there is nothing to read, set body to naught and return. This
252             # will cause all body code to be skipped
253              
254             return $self->_body(0) unless my $length = $self->_read_length;
255              
256 923 50       28384 # Unless the body has already been set, create it. Not sure about this
    50          
257 0         0 # code, how else might it be set, but this was existing logic.
258 0         0  
259 0         0 unless ($self->_body) {
260             my $type = $self->header('Content-Type');
261             $self->_body(HTTP::Body->new( $type, $length ));
262             $self->_body->cleanup(1);
263              
264             # JNAP: I'm not sure this is doing what we expect, but it also doesn't
265 923 100       24578 # seem to be hurting (seems ->_has_uploadtmp is true more than I would
266             # expect.
267              
268             $self->_body->tmpdir( $self->_uploadtmp )
269             if $self->_has_uploadtmp;
270 49 50       1340 }
271 49         195  
272 49         2498 # Ok if we get this far, we have to read psgi.input into the new body
273 49         1201 # object. Lets play nice with any plack app or other downstream, so
274             # we create a buffer unless one exists.
275              
276             my $stream_buffer;
277             if ($self->env->{'psgix.input.buffered'}) {
278             # Be paranoid about previous psgi middleware or apps that read the
279 49 100       1918 # input but didn't return the buffer to the start.
280             $self->env->{'psgi.input'}->seek(0, 0);
281             } else {
282             $stream_buffer = Stream::Buffered->new($length);
283             }
284              
285             # Check for definedness as you could read '0'
286             while ( defined ( my $chunk = $self->read() ) ) {
287 49         131 $self->prepare_body_chunk($chunk);
288 49 50       1196 next unless $stream_buffer;
289              
290             $stream_buffer->print($chunk)
291 0         0 || die sprintf "Failed to write %d bytes to psgi.input file: $!", length( $chunk );
292             }
293 49         427  
294             # Ok, we read the body. Lets play nice for any PSGI app down the pipe
295              
296             if ($stream_buffer) {
297 49         1720 $self->env->{'psgix.input.buffered'} = 1;
298 51         226 $self->env->{'psgi.input'} = $stream_buffer->rewind;
299 51 50       37245 } else {
300             $self->env->{'psgi.input'}->seek(0, 0); # Reset the buffer for downstream middleware or apps
301 51 50       232 }
302              
303             # paranoia against wrong Content-Length header
304             my $remaining = $length - $self->_read_position;
305             if ( $remaining > 0 ) {
306             Catalyst::Exception->throw("Wrong Content-Length value: $length" );
307 49 50       176 }
308 49         1237 }
309 49         276  
310             my ( $self, $chunk ) = @_;
311 0         0  
312             $self->_body->add($chunk);
313             }
314              
315 49         1275 my ( $self, $c ) = @_;
316 49 100       364 return $self->body_parameters if $self->has_body_parameters;
317 1         18 $self->prepare_body if ! $self->_has_body;
318              
319             unless($self->_body) {
320             my $return = $self->_use_hash_multivalue ? Hash::MultiValue->new : {};
321             $self->body_parameters($return);
322 51     51 1 147 return $return;
323             }
324 51         1291  
325             my $params;
326             my %part_data = %{$self->_body->part_data};
327             if(scalar %part_data && !$c->config->{skip_complex_post_part_handling}) {
328 923     923 1 2825 foreach my $key (keys %part_data) {
329 923 100       31575 my $proto_value = $part_data{$key};
330 921 100       26643 my ($val, @extra) = (ref($proto_value)||'') eq 'ARRAY' ? @$proto_value : ($proto_value);
331              
332 921 100       23152 $key = $c->_handle_param_unicode_decoding($key)
333 873 100       24227 if ($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding});
334 873         26279  
335 873         2390 if(@extra) {
336             $params->{$key} = [map { Catalyst::Request::PartData->build_from_part_data($c, $_) } ($val,@extra)];
337             } else {
338 48         121 $params->{$key} = Catalyst::Request::PartData->build_from_part_data($c, $val);
339 48         100 }
  48         1156  
340 48 100 66     630 }
341 11         66 } else {
342 21         315 $params = $self->_body->param;
343 21 100 50     103  
344             # If we have an encoding configured (like UTF-8) in general we expect a client
345             # to POST with the encoding we fufilled the request in. Otherwise don't do any
346 21 50 33     107 # encoding (good change wide chars could be in HTML entity style llike the old
      33        
347             # days -JNAP
348 21 100       456  
349 1         3 # so, now that HTTP::Body prepared the body params, we gotta 'walk' the structure
  2         38  
350             # and do any needed decoding.
351 20         160  
352             # This only does something if the encoding is set via the encoding param. Remember
353             # this is assuming the client is not bad and responds with what you provided. In
354             # general you can just use utf8 and get away with it.
355 37         986 #
356             # I need to see if $c is here since this also doubles as a builder for the object :(
357              
358             if($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding}) {
359             $params = $c->_handle_unicode_decoding($params);
360             }
361             }
362              
363             my $return = $self->_use_hash_multivalue ?
364             Hash::MultiValue->from_mixed($params) :
365             $params;
366              
367             $self->body_parameters($return) unless $self->has_body_parameters;
368             return $return;
369             }
370              
371 37 50 66     419 my ($self) = @_;
      66        
372 36         296  
373             my $env = $self->env;
374              
375             $self->address( $env->{REMOTE_ADDR} );
376 47 100       1935 $self->hostname( $env->{REMOTE_HOST} )
377             if exists $env->{REMOTE_HOST};
378             $self->protocol( $env->{SERVER_PROTOCOL} );
379             $self->remote_user( $env->{REMOTE_USER} );
380 47 50       1578 $self->method( $env->{REQUEST_METHOD} );
381 47         181 $self->secure( $env->{'psgi.url_scheme'} eq 'https' ? 1 : 0 );
382             }
383              
384             # XXX - FIXME - method is here now, move this crap...
385 925     925 1 2882 around parameters => sub {
386             my ($orig, $self, $params) = @_;
387 925         30298 if ($params) {
388             if ( !ref $params ) {
389 925         26696 $self->_log->warn(
390             "Attempt to retrieve '$params' with req->params(), " .
391 925 100       29124 "you probably meant to call req->param('$params')"
392 925         26134 );
393 925         27580 $params = undef;
394 925         26959 }
395 925 100       26310 return $self->$orig($params);
396             }
397             $self->$orig();
398             };
399              
400             has base => (
401             is => 'rw',
402             required => 1,
403             lazy => 1,
404             default => sub {
405             my $self = shift;
406             return $self->path if $self->has_uri;
407             },
408             );
409              
410             has _body => (
411             is => 'rw', clearer => '_clear_body', predicate => '_has_body',
412             );
413             # Eugh, ugly. Should just be able to rename accessor methods to 'body'
414             # and provide a custom reader..
415             my $self = shift;
416             $self->prepare_body unless $self->_has_body;
417             croak 'body is a reader' if scalar @_;
418             return blessed $self->_body ? $self->_body->body : $self->_body;
419             }
420              
421             has hostname => (
422             is => 'rw',
423             lazy => 1,
424             default => sub {
425             my ($self) = @_;
426             my ( $err, $sockaddr ) = getaddrinfo(
427             $self->address,
428             # no service
429             '',
430 631     631 1 1441 { flags => AI_NUMERICHOST }
431 631 50       18949 );
432 631 50       2425 if ( $err ) {
433 631 100       17025 $self->_log->warn("resolve of hostname failed: $err");
434             return $self->address;
435             }
436             ( $err, my $hostname ) = getnameinfo(
437             $sockaddr->{addr},
438             NI_NAMEREQD,
439             # we are only interested in the hostname, not the servicename
440             NIx_NOSERV
441             );
442             if ( $err ) {
443             $self->_log->warn("resolve of hostname failed: $err");
444             return $self->address;
445             }
446             return $hostname;
447             },
448             );
449              
450             has _path => ( is => 'rw', predicate => '_has_path', clearer => '_clear_path' );
451              
452              
453             =for stopwords param params
454              
455             =head1 NAME
456              
457             Catalyst::Request - provides information about the current client request
458              
459             =head1 SYNOPSIS
460              
461             $req = $c->request;
462             $req->address eq "127.0.0.1";
463             $req->arguments;
464             $req->args;
465             $req->base;
466             $req->body;
467 15038     15038 1 395691 $req->body_data;
468 9     9 1 213 $req->body_parameters;
469 0     0 1 0 $req->content_encoding;
470 25     25 1 133 $req->content_length;
471 7     7 1 158 $req->content_type;
472 0     0 1 0 $req->cookie;
473             $req->cookies;
474             $req->header;
475             $req->headers;
476             $req->hostname;
477             $req->input;
478             $req->query_keywords;
479             $req->match;
480             $req->method;
481             $req->param;
482             $req->parameters;
483             $req->params;
484             $req->path;
485             $req->protocol;
486             $req->query_parameters;
487             $req->read;
488             $req->referer;
489             $req->secure;
490             $req->captures;
491             $req->upload;
492             $req->uploads;
493             $req->uri;
494             $req->user;
495             $req->user_agent;
496             $req->env;
497              
498             See also L<Catalyst>, L<Catalyst::Request::Upload>.
499              
500             =head1 DESCRIPTION
501              
502             This is the Catalyst Request class, which provides an interface to data for the
503             current client request. The request object is prepared by L<Catalyst::Engine>,
504             thus hiding the details of the particular engine implementation.
505              
506             =head1 METHODS
507              
508             =head2 $req->address
509              
510             Returns the IP address of the client.
511              
512             =head2 $req->arguments
513              
514             Returns a reference to an array containing the arguments.
515              
516             print $c->request->arguments->[0];
517              
518             For example, if your action was
519              
520             package MyApp::Controller::Foo;
521              
522             sub moose : Local {
523             ...
524             }
525              
526             and the URI for the request was C<http://.../foo/moose/bah>, the string C<bah>
527             would be the first and only argument.
528              
529             Arguments get automatically URI-unescaped for you.
530              
531             =head2 $req->args
532              
533             Shortcut for L</arguments>.
534              
535             =head2 $req->base
536              
537             Contains the URI base. This will always have a trailing slash. Note that the
538             URI scheme (e.g., http vs. https) must be determined through heuristics;
539             depending on your server configuration, it may be incorrect. See $req->secure
540             for more info.
541              
542             If your application was queried with the URI
543             C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
544              
545             =head2 $req->body
546              
547             Returns the message body of the request, as returned by L<HTTP::Body>: a string,
548             unless Content-Type is C<application/x-www-form-urlencoded>, C<text/xml>, or
549             C<multipart/form-data>, in which case a L<File::Temp> object is returned.
550              
551             =head2 $req->body_data
552              
553             Returns a Perl representation of body data that is not classic HTML
554             form data, such as JSON, XML, etc. By default, Catalyst will parse incoming
555             data of the type 'application/json' for POST, PUT, PATCH or DELETE methods,
556             and return access to that data via this method.
557              
558             You may define addition data_handlers via a global configuration
559             setting. See L<Catalyst\DATA HANDLERS> for more information.
560              
561             If the body is malformed in some way (such as undefined or not content that
562             matches the content-type) we raise a L<Catalyst::Exception> with the error
563             text as the message.
564              
565             If the body content type does not match an available data handler, this
566             will also raise an exception.
567              
568             =head2 $req->body_parameters
569              
570             Returns a reference to a hash containing body (POST) parameters. Values can
571             be either a scalar or an arrayref containing scalars.
572              
573             print $c->request->body_parameters->{field};
574             print $c->request->body_parameters->{field}->[0];
575              
576             These are the parameters from the POST part of the request, if any.
577              
578             B<NOTE> If your POST is multipart, but contains non file upload parts (such
579             as an line part with an alternative encoding or content type) we do our best to
580             try and figure out how the value should be presented. If there's a specified character
581             set we will use that to decode rather than the default encoding set by the application.
582             However if there are complex headers and we cannot determine
583             the correct way to extra a meaningful value from the upload, in this case any
584             part like this will be represented as an instance of L<Catalyst::Request::PartData>.
585              
586             Patches and review of this part of the code welcomed.
587              
588             =head2 $req->body_params
589              
590             Shortcut for body_parameters.
591              
592             =head2 $req->content_encoding
593              
594             Shortcut for $req->headers->content_encoding.
595              
596             =head2 $req->content_length
597              
598             Shortcut for $req->headers->content_length.
599              
600             =head2 $req->content_type
601              
602             Shortcut for $req->headers->content_type.
603              
604             =head2 $req->cookie
605              
606             A convenient method to access $req->cookies.
607              
608             $cookie = $c->request->cookie('name');
609             @cookies = $c->request->cookie;
610              
611             =cut
612              
613             my $self = shift;
614              
615             if ( @_ == 0 ) {
616             return keys %{ $self->cookies };
617             }
618              
619             if ( @_ == 1 ) {
620              
621             my $name = shift;
622              
623             unless ( exists $self->cookies->{$name} ) {
624             return undef;
625             }
626              
627             return $self->cookies->{$name};
628             }
629             }
630              
631             =head2 $req->cookies
632              
633             Returns a reference to a hash containing the cookies.
634              
635 0     0 1 0 print $c->request->cookies->{mycookie}->value;
636              
637 0 0       0 The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
638 0         0 objects.
  0         0  
639              
640             =head2 $req->header
641 0 0       0  
642             Shortcut for $req->headers->header.
643 0         0  
644             =head2 $req->headers
645 0 0       0  
646 0         0 Returns an L<HTTP::Headers> object containing the headers for the current request.
647              
648             print $c->request->headers->header('X-Catalyst');
649 0         0  
650             =head2 $req->hostname
651              
652             Returns the hostname of the client. Use C<< $req->uri->host >> to get the hostname of the server.
653              
654             =head2 $req->input
655              
656             Alias for $req->body.
657              
658             =head2 $req->query_keywords
659              
660             Contains the keywords portion of a query string, when no '=' signs are
661             present.
662              
663             http://localhost/path?some+keywords
664              
665             $c->request->query_keywords will contain 'some keywords'
666              
667             =head2 $req->match
668              
669             This contains the matching part of a Regex action. Otherwise
670             it returns the same as 'action', except for default actions,
671             which return an empty string.
672              
673             =head2 $req->method
674              
675             Contains the request method (C<GET>, C<POST>, C<HEAD>, etc).
676              
677             =head2 $req->param
678              
679             Returns GET and POST parameters with a CGI.pm-compatible param method. This
680             is an alternative method for accessing parameters in $c->req->parameters.
681              
682             $value = $c->request->param( 'foo' );
683             @values = $c->request->param( 'foo' );
684             @params = $c->request->param;
685              
686             Like L<CGI>, and B<unlike> earlier versions of Catalyst, passing multiple
687             arguments to this method, like this:
688              
689             $c->request->param( 'foo', 'bar', 'gorch', 'quxx' );
690              
691             will set the parameter C<foo> to the multiple values C<bar>, C<gorch> and
692             C<quxx>. Previously this would have added C<bar> as another value to C<foo>
693             (creating it if it didn't exist before), and C<quxx> as another value for
694             C<gorch>.
695              
696             B<NOTE> this is considered a legacy interface and care should be taken when
697             using it. C<< scalar $c->req->param( 'foo' ) >> will return only the first
698             C<foo> param even if multiple are present; C<< $c->req->param( 'foo' ) >> will
699             return a list of as many are present, which can have unexpected consequences
700             when writing code of the form:
701              
702             $foo->bar(
703             a => 'b',
704             baz => $c->req->param( 'baz' ),
705             );
706              
707             If multiple C<baz> parameters are provided this code might corrupt data or
708             cause a hash initialization error. For a more straightforward interface see
709             C<< $c->req->parameters >>.
710              
711             B<NOTE> Interfaces like this, which are based on L<CGI> and the C<param> method
712             are known to cause demonstrated exploits. It is highly recommended that you
713             avoid using this method, and migrate existing code away from it. Here's a
714             whitepaper of the exploit:
715              
716             L<http://blog.gerv.net/2014/10/new-class-of-vulnerability-in-perl-web-applications/>
717              
718             B<NOTE> Further discussion on IRC indicate that the L<Catalyst> core team from 'back then'
719             were well aware of this hack and this is the main reason we added the new approach to
720             getting parameters in the first place.
721              
722             Basically this is an exploit that takes advantage of how L<\param> will do one thing
723             in scalar context and another thing in list context. This is combined with how Perl
724             chooses to deal with duplicate keys in a hash definition by overwriting the value of
725             existing keys with a new value if the same key shows up again. Generally you will be
726             vulnerable to this exploit if you are using this method in a direct assignment in a
727             hash, such as with a L<DBIx::Class> create statement. For example, if you have
728             parameters like:
729              
730             user?user=123&foo=a&foo=user&foo=456
731              
732             You could end up with extra parameters injected into your method calls:
733              
734             $c->model('User')->create({
735             user => $c->req->param('user'),
736             foo => $c->req->param('foo'),
737             });
738              
739             Which would look like:
740              
741             $c->model('User')->create({
742             user => 123,
743             foo => qw(a user 456),
744             });
745              
746             (or to be absolutely clear if you are not seeing it):
747              
748             $c->model('User')->create({
749             user => 456,
750             foo => 'a',
751             });
752              
753             Possible remediations include scrubbing your parameters with a form validator like
754             L<HTML::FormHandler> or being careful to force scalar context using the scalar
755             keyword:
756              
757             $c->model('User')->create({
758             user => scalar($c->req->param('user')),
759             foo => scalar($c->req->param('foo')),
760             });
761              
762             Upcoming versions of L<Catalyst> will disable this interface by default and require
763             you to positively enable it should you require it for backwards compatibility reasons.
764              
765             =cut
766              
767             my $self = shift;
768              
769             if ( @_ == 0 ) {
770             return keys %{ $self->parameters };
771             }
772              
773             # If anything in @_ is undef, carp about that, and remove it from
774             # the list;
775              
776             my @params = grep { defined($_) ? 1 : do {carp "You called ->params with an undefined value"; 0} } @_;
777              
778             if ( @params == 1 ) {
779              
780             defined(my $param = shift @params) ||
781             carp "You called ->params with an undefined value 2";
782              
783             unless ( exists $self->parameters->{$param} ) {
784             return wantarray ? () : undef;
785             }
786              
787             if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
788             return (wantarray)
789             ? @{ $self->parameters->{$param} }
790 14     14 1 32 : $self->parameters->{$param}->[0];
791             }
792 14 50       52 else {
793 0         0 return (wantarray)
  0         0  
794             ? ( $self->parameters->{$param} )
795             : $self->parameters->{$param};
796             }
797             }
798             elsif ( @params > 1 ) {
799 14 100       36 my $field = shift @params;
  17         76  
  1         210  
  1         803  
800             $self->parameters->{$field} = [@params];
801 14 100       47 }
    100          
802             }
803 12 50       40  
804             =head2 $req->parameters
805              
806 12 100       70 Returns a reference to a hash containing GET and POST parameters. Values can
807 2 50       10 be either a scalar or an arrayref containing scalars.
808              
809             print $c->request->parameters->{field};
810 10 100       54 print $c->request->parameters->{field}->[0];
811              
812 1         13 This is the combination of C<query_parameters> and C<body_parameters>.
813 1 50       3  
814             =head2 $req->params
815              
816             Shortcut for $req->parameters.
817              
818 9 100       45 =head2 $req->path
819              
820             Returns the path, i.e. the part of the URI after $req->base, for the current request.
821              
822 1         2 http://localhost/path/foo
823 1         5  
824             $c->request->path will contain 'path/foo'
825              
826             =head2 $req->path_info
827              
828             Alias for path, added for compatibility with L<CGI>.
829              
830             =cut
831              
832             my ( $self, @params ) = @_;
833              
834             if (@params) {
835             $self->uri->path(@params);
836             $self->_clear_path;
837             }
838             elsif ( $self->_has_path ) {
839             return $self->_path;
840             }
841             else {
842             my $path = $self->uri->path;
843             my $location = $self->base->path;
844             $path =~ s/^(\Q$location\E)?//;
845             $path =~ s/^\///;
846             $self->_path($path);
847              
848             return $path;
849             }
850             }
851              
852             =head2 $req->protocol
853              
854             Returns the protocol (HTTP/1.0 or HTTP/1.1) used for the current request.
855              
856 1989     1989 1 4782 =head2 $req->query_parameters
857              
858 1989 100       61600 =head2 $req->query_params
    100          
859 1         41  
860 1         128 Returns a reference to a hash containing query string (GET) parameters. Values can
861             be either a scalar or an arrayref containing scalars.
862              
863 1062         26827 print $c->request->query_parameters->{field};
864             print $c->request->query_parameters->{field}->[0];
865              
866 926         23656 =head2 $req->read( [$maxlength] )
867 926         34453  
868 926         16238 Reads a chunk of data from the request body. This method is intended to be
869 926         2846 used in a while loop, reading $maxlength bytes on every call. $maxlength
870 926         27045 defaults to the size of the request if not specified.
871              
872 926         3435 =head2 $req->read_chunk(\$buff, $max)
873              
874             Reads a chunk.
875              
876             You have to set MyApp->config(parse_on_demand => 1) to use this directly.
877              
878             =head2 $req->referer
879              
880             Shortcut for $req->headers->referer. Returns the referring page.
881              
882             =head2 $req->secure
883              
884             Returns true or false, indicating whether the connection is secure
885             (https). The reliability of $req->secure may depend on your server
886             configuration; Catalyst relies on PSGI to determine whether or not a
887             request is secure (Catalyst looks at psgi.url_scheme), and different
888             PSGI servers may make this determination in different ways (as by
889             directly passing along information from the server, interpreting any of
890             several HTTP headers, or using heuristics of their own).
891              
892             =head2 $req->captures
893              
894             Returns a reference to an array containing captured args from chained
895             actions or regex captures.
896              
897             my @captures = @{ $c->request->captures };
898              
899             =head2 $req->upload
900              
901             A convenient method to access $req->uploads.
902              
903             $upload = $c->request->upload('field');
904             @uploads = $c->request->upload('field');
905             @fields = $c->request->upload;
906              
907             for my $upload ( $c->request->upload('field') ) {
908             print $upload->filename;
909             }
910              
911             =cut
912              
913             my $self = shift;
914              
915             if ( @_ == 0 ) {
916             return keys %{ $self->uploads };
917             }
918              
919             if ( @_ == 1 ) {
920              
921             my $upload = shift;
922              
923             unless ( exists $self->uploads->{$upload} ) {
924             return wantarray ? () : undef;
925             }
926              
927             if ( ref $self->uploads->{$upload} eq 'ARRAY' ) {
928             return (wantarray)
929             ? @{ $self->uploads->{$upload} }
930             : $self->uploads->{$upload}->[0];
931             }
932             else {
933             return (wantarray)
934             ? ( $self->uploads->{$upload} )
935             : $self->uploads->{$upload};
936             }
937             }
938 8     8 1 1178  
939             if ( @_ > 1 ) {
940 8 100       29  
941 1         3 while ( my ( $field, $upload ) = splice( @_, 0, 2 ) ) {
  1         36  
942              
943             if ( exists $self->uploads->{$field} ) {
944 7 50       20 for ( $self->uploads->{$field} ) {
945             $_ = [$_] unless ref($_) eq "ARRAY";
946 7         16 push( @$_, $upload );
947             }
948 7 100       188 }
949 1 50       5 else {
950             $self->uploads->{$field} = $upload;
951             }
952 6 50       150 }
953             }
954 0         0 }
955 0 0       0  
956             =head2 $req->uploads
957              
958             Returns a reference to a hash containing uploads. Values can be either a
959             L<Catalyst::Request::Upload> object, or an arrayref of
960 6 50       170 L<Catalyst::Request::Upload> objects.
961              
962             my $upload = $c->request->uploads->{field};
963             my $upload = $c->request->uploads->{field}->[0];
964 0 0       0  
965             =head2 $req->uri
966 0         0  
967             Returns a L<URI> object for the current request. Stringifies to the URI text.
968 0 0       0  
969 0         0 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
970 0 0       0  
971 0         0 Returns a hashref of parameters stemming from the current request's params,
972             plus the ones supplied. Keys for which no current param exists will be
973             added, keys with undefined values will be removed and keys with existing
974             params will be replaced. Note that you can supply a true value as the final
975 0         0 argument to change behavior with regards to existing parameters, appending
976             values rather than replacing them.
977              
978             A quick example:
979              
980             # URI query params foo=1
981             my $hashref = $req->mangle_params({ foo => 2 });
982             # Result is query params of foo=2
983              
984             versus append mode:
985              
986             # URI query params foo=1
987             my $hashref = $req->mangle_params({ foo => 2 }, 1);
988             # Result is query params of foo=1&foo=2
989              
990             This is the code behind C<uri_with>.
991              
992             =cut
993              
994             my ($self, $args, $append) = @_;
995              
996             carp('No arguments passed to mangle_params()') unless $args;
997              
998             foreach my $value ( values %$args ) {
999             next unless defined $value;
1000             for ( ref $value eq 'ARRAY' ? @$value : $value ) {
1001             $_ = "$_";
1002             # utf8::encode($_);
1003             }
1004             };
1005              
1006             my %params = %{ $self->uri->query_form_hash };
1007             foreach my $key (keys %{ $args }) {
1008             my $val = $args->{$key};
1009             if(defined($val)) {
1010              
1011             if($append && exists($params{$key})) {
1012              
1013             # This little bit of heaven handles appending a new value onto
1014             # an existing one regardless if the existing value is an array
1015             # or not, and regardless if the new value is an array or not
1016             $params{$key} = [
1017             ref($params{$key}) eq 'ARRAY' ? @{ $params{$key} } : $params{$key},
1018             ref($val) eq 'ARRAY' ? @{ $val } : $val
1019             ];
1020 22     22 1 112  
1021             } else {
1022 22 50       56 $params{$key} = $val;
1023             }
1024 22         76 } else {
1025 26 100       80  
1026 16 100       55 # If the param wasn't defined then we delete it.
1027 18         52 delete($params{$key});
1028             }
1029             }
1030              
1031              
1032 22         46 return \%params;
  22         655  
1033 22         1368 }
  22         114  
1034 26         61  
1035 26 100       72 =head2 $req->uri_with( { key => 'value' } );
1036              
1037 16 100 66     57 Returns a rewritten URI object for the current request. Key/value pairs
1038             passed in will override existing parameters. You can remove an existing
1039             parameter by passing in an undef value. Unmodified pairs will be
1040             preserved.
1041              
1042             You may also pass an optional second parameter that puts C<uri_with> into
1043 0         0 append mode:
1044 2 50       12  
  1 100       4  
1045             $req->uri_with( { key => 'value' }, { mode => 'append' } );
1046              
1047             See C<mangle_params> for an explanation of this behavior.
1048 14         44  
1049             =cut
1050              
1051             my( $self, $args, $behavior) = @_;
1052              
1053 10         26 carp( 'No arguments passed to uri_with()' ) unless $args;
1054              
1055             my $append = 0;
1056             if((ref($behavior) eq 'HASH') && defined($behavior->{mode}) && ($behavior->{mode} eq 'append')) {
1057             $append = 1;
1058 22         65 }
1059              
1060             my $params = $self->mangle_params($args, $append);
1061              
1062             my $uri = $self->uri->clone;
1063             $uri->query_form($params);
1064              
1065             return $uri;
1066             }
1067              
1068             =head2 $req->remote_user
1069              
1070             Returns the value of the C<REMOTE_USER> environment variable.
1071              
1072             =head2 $req->user_agent
1073              
1074             Shortcut to $req->headers->user_agent. Returns the user agent (browser)
1075             version string.
1076              
1077             =head2 $req->io_fh
1078 22     22 1 72  
1079             Returns a psgix.io bidirectional socket, if your server supports one. Used for
1080 22 50       68 when you want to jailbreak out of PSGI and handle bidirectional client server
1081             communication manually, such as when you are using cometd or websockets.
1082 22         45  
1083 22 50 66     90 =head1 SETUP METHODS
      66        
1084 2         5  
1085             You should never need to call these yourself in application code,
1086             however they are useful if extending Catalyst by applying a request role.
1087 22         75  
1088             =head2 $self->prepare_headers()
1089 22         658  
1090 22         208 Sets up the C<< $res->headers >> accessor.
1091              
1092 22         2162 =head2 $self->prepare_body()
1093              
1094             Sets up the body using L<HTTP::Body>
1095              
1096             =head2 $self->prepare_body_chunk()
1097              
1098             Add a chunk to the request body.
1099              
1100             =head2 $self->prepare_body_parameters()
1101              
1102             Sets up parameters from body.
1103              
1104             =head2 $self->prepare_cookies()
1105              
1106             Parse cookies from header. Sets up a L<CGI::Simple::Cookie> object.
1107              
1108             =head2 $self->prepare_connection()
1109              
1110             Sets up various fields in the request like the local and remote addresses,
1111             request method, hostname requested etc.
1112              
1113             =head2 $self->prepare_parameters()
1114              
1115             Ensures that the body has been parsed, then builds the parameters, which are
1116             combined from those in the request and those in the body.
1117              
1118             If parameters have already been set will clear the parameters and build them again.
1119              
1120             =head2 $self->env
1121              
1122             Access to the raw PSGI env.
1123              
1124             =head2 meta
1125              
1126             Provided by Moose
1127              
1128             =head1 AUTHORS
1129              
1130             Catalyst Contributors, see Catalyst.pm
1131              
1132             =head1 COPYRIGHT
1133              
1134             This library is free software. You can redistribute it and/or modify
1135             it under the same terms as Perl itself.
1136              
1137             =cut
1138              
1139             __PACKAGE__->meta->make_immutable;
1140              
1141             1;