File Coverage

blib/lib/Catalyst/Request.pm
Criterion Covered Total %
statement 229 264 86.7
branch 107 148 72.3
condition 20 39 51.2
subroutine 35 41 85.3
pod 22 23 95.6
total 413 515 80.1


line stmt bran cond sub pod time code
1              
2             use Socket qw( getaddrinfo getnameinfo AI_NUMERICHOST NI_NAMEREQD NIx_NOSERV );
3 166     166   264096 use Carp;
  166         554825  
  166         24271  
4 166     166   1282 use utf8;
  166         449  
  166         8606  
5 166     166   70400 use URI::http;
  166         3068  
  166         1068  
6 166     166   56569 use URI::https;
  166         1052341  
  166         5105  
7 166     166   55513 use URI::QueryParam;
  166         32896  
  166         5379  
8 166     166   57336 use HTTP::Headers;
  166         111877  
  166         4804  
9 166     166   17026 use Stream::Buffered;
  166         132399  
  166         4447  
10 166     166   58561 use Hash::MultiValue;
  166         895720  
  166         4039  
11 166     166   63575 use Scalar::Util;
  166         337522  
  166         4547  
12 166     166   1068 use HTTP::Body;
  166         404  
  166         5217  
13 166     166   65525 use Catalyst::Exception;
  166         1877614  
  166         5035  
14 166     166   2249 use Catalyst::Request::PartData;
  166         421  
  166         5181  
15 166     166   60753 use Moose;
  166         58563  
  166         4971  
16 166     166   1068  
  166         337  
  166         935  
17             use namespace::clean -except => 'meta';
18 166     166   942440  
  166         374  
  166         1933  
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 922     922 1 1814 return { CGI::Simple::Cookie->parse($header) };
54             }
55 922 100       3492 {};
56 1         71 }
57              
58 921         65637 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 922     922 1 1852  
80             for my $header (keys %{ $env }) {
81 922         20205 next unless $header =~ /^(HTTP|CONTENT|COOKIE)/i;
82 922         5126 (my $field = $header) =~ s/^HTTPS?_//;
83             $field =~ tr/_/-/;
84 922         6906 $headers->header($field => $env->{$header});
  922         5209  
85 22223 100       106749 }
86 1928         5765 return $headers;
87 1928         3504 }
88 1928         4825  
89             has _log => (
90 922         26800 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');
121              
122 7     7   15 my ($match) = grep { $content_type =~/$_/i }
123             keys(%{$self->data_handlers});
124              
125 7   50     36 if($match) {
126 7 0 33     339 my $fh = $self->body;
      33        
127             local $_ = $fh;
128 14         129 return $self->data_handlers->{$match}->($fh, $self);
129 7         15 } else {
  7         163  
130             Catalyst::Exception->throw(
131 7 100       20 sprintf '%s does not have an available data handler. Valid data_handlers are %s.',
132 6         29 $content_type, join ', ', sort keys %{$self->data_handlers}
133 6         32 );
134 6         134 }
135             }
136              
137             has _use_hash_multivalue => (
138 1         3 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 891 }
153 112         2846  
154 112   66     483 my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
155             my $rc = $self->read_chunk( my $buffer, $readlen );
156             if ( defined $rc ) {
157 112 100       256 if (0 == $rc) { # Nothing more to read even though Content-Length
158 49         168 # said there should be.
159             return;
160             }
161 63 100       168 $self->_set_read_position( $self->_read_position + $rc );
162 63         190 return $buffer;
163 63 50       1123 }
164 63 100       168 else {
165             Catalyst::Exception->throw(
166 1         4 message => "Unknown error reading input: $!" );
167             }
168 62         1510 }
169 62         278  
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 107 predicate => 'has_body_parameters',
179 63         1340 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 920     920   1806 foreach my $name (keys %$query_parameters) {
219 920         1592 my $param = $query_parameters->{$name};
220 920         21252 $parameters->{$name} = ref $param eq 'ARRAY' ? [ @$param ] : $param;
221 920         21321 }
222              
223 920 100       21012 # Merge query and body parameters
224 4         18 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 916         3113 unshift(@values, (ref $existing eq 'ARRAY' ? @$existing : $existing));
229 118         297 }
230 118 100       433 $parameters->{$name} = @values > 1 ? \@values : $values[0];
231             }
232             $parameters;
233             }
234 916         2369  
235 54         136 has _uploadtmp => (
236 54 100       159 is => 'ro',
237 54 100       142 predicate => '_has_uploadtmp',
238 5 100       23 );
239              
240 54 100       201 my ( $self ) = @_;
241              
242 916         20150 # 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 921     921 1 1972 # 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 921 50       23470 # 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 921 100       20405 # 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       1158 }
271 49         197  
272 49         2228 # Ok if we get this far, we have to read psgi.input into the new body
273 49         1110 # 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       1580 # 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         117 $self->prepare_body_chunk($chunk);
288 49 50       1058 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         417  
294             # Ok, we read the body. Lets play nice for any PSGI app down the pipe
295              
296             if ($stream_buffer) {
297 49         1395 $self->env->{'psgix.input.buffered'} = 1;
298 51         185 $self->env->{'psgi.input'} = $stream_buffer->rewind;
299 51 50       30677 } else {
300             $self->env->{'psgi.input'}->seek(0, 0); # Reset the buffer for downstream middleware or apps
301 51 50       234 }
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       153 }
308 49         1126 }
309 49         252  
310             my ( $self, $chunk ) = @_;
311 0         0  
312             $self->_body->add($chunk);
313             }
314              
315 49         1156 my ( $self, $c ) = @_;
316 49 100       339 return $self->body_parameters if $self->has_body_parameters;
317 1         15 $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 140 return $return;
323             }
324 51         1105  
325             my $params;
326             my %part_data = %{$self->_body->part_data};
327             if(scalar %part_data && !$c->config->{skip_complex_post_part_handling}) {
328 921     921 1 2265 foreach my $key (keys %part_data) {
329 921 100       25803 my $proto_value = $part_data{$key};
330 919 100       22423 my ($val, @extra) = (ref($proto_value)||'') eq 'ARRAY' ? @$proto_value : ($proto_value);
331              
332 919 100       19475 $key = $c->_handle_param_unicode_decoding($key)
333 871 100       20061 if ($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding});
334 871         21310  
335 871         1984 if(@extra) {
336             $params->{$key} = [map { Catalyst::Request::PartData->build_from_part_data($c, $_) } ($val,@extra)];
337             } else {
338 48         104 $params->{$key} = Catalyst::Request::PartData->build_from_part_data($c, $val);
339 48         96 }
  48         1030  
340 48 100 66     561 }
341 11         54 } else {
342 21         267 $params = $self->_body->param;
343 21 100 50     100  
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     87 # encoding (good change wide chars could be in HTML entity style llike the old
      33        
347             # days -JNAP
348 21 100       390  
349 1         3 # so, now that HTTP::Body prepared the body params, we gotta 'walk' the structure
  2         52  
350             # and do any needed decoding.
351 20         120  
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         861 #
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     342 my ($self) = @_;
      66        
372 36         217  
373             my $env = $self->env;
374              
375             $self->address( $env->{REMOTE_ADDR} );
376 47 100       1615 $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       1468 $self->method( $env->{REQUEST_METHOD} );
381 47         170 $self->secure( $env->{'psgi.url_scheme'} eq 'https' ? 1 : 0 );
382             }
383              
384             # XXX - FIXME - method is here now, move this crap...
385 923     923 1 2296 around parameters => sub {
386             my ($orig, $self, $params) = @_;
387 923         20265 if ($params) {
388             if ( !ref $params ) {
389 923         26301 $self->_log->warn(
390             "Attempt to retrieve '$params' with req->params(), " .
391 923 100       22709 "you probably meant to call req->param('$params')"
392 923         22065 );
393 923         22439 $params = undef;
394 923         21577 }
395 923 100       21338 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 1180 { flags => AI_NUMERICHOST }
431 631 50       15876 );
432 631 50       1922 if ( $err ) {
433 631 100       13268 $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 15018     15018 1 327269 $req->body_data;
468 9     9 1 213 $req->body_parameters;
469 0     0 1 0 $req->content_encoding;
470 25     25 1 112 $req->content_length;
471 7     7 1 156 $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 POST/PUT 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' and return access to that data via this
556             method. You may define addition data_handlers via a global configuration
557             setting. See L<Catalyst\DATA HANDLERS> for more information.
558              
559             If the POST is malformed in some way (such as undefined or not content that
560             matches the content-type) we raise a L<Catalyst::Exception> with the error
561             text as the message.
562              
563             If the POSTed content type does not match an available data handler, this
564             will also raise an exception.
565              
566             =head2 $req->body_parameters
567              
568             Returns a reference to a hash containing body (POST) parameters. Values can
569             be either a scalar or an arrayref containing scalars.
570              
571             print $c->request->body_parameters->{field};
572             print $c->request->body_parameters->{field}->[0];
573              
574             These are the parameters from the POST part of the request, if any.
575              
576             B<NOTE> If your POST is multipart, but contains non file upload parts (such
577             as an line part with an alternative encoding or content type) we do our best to
578             try and figure out how the value should be presented. If there's a specified character
579             set we will use that to decode rather than the default encoding set by the application.
580             However if there are complex headers and we cannot determine
581             the correct way to extra a meaningful value from the upload, in this case any
582             part like this will be represented as an instance of L<Catalyst::Request::PartData>.
583              
584             Patches and review of this part of the code welcomed.
585              
586             =head2 $req->body_params
587              
588             Shortcut for body_parameters.
589              
590             =head2 $req->content_encoding
591              
592             Shortcut for $req->headers->content_encoding.
593              
594             =head2 $req->content_length
595              
596             Shortcut for $req->headers->content_length.
597              
598             =head2 $req->content_type
599              
600             Shortcut for $req->headers->content_type.
601              
602             =head2 $req->cookie
603              
604             A convenient method to access $req->cookies.
605              
606             $cookie = $c->request->cookie('name');
607             @cookies = $c->request->cookie;
608              
609             =cut
610              
611             my $self = shift;
612              
613             if ( @_ == 0 ) {
614             return keys %{ $self->cookies };
615             }
616              
617             if ( @_ == 1 ) {
618              
619             my $name = shift;
620              
621             unless ( exists $self->cookies->{$name} ) {
622             return undef;
623             }
624              
625             return $self->cookies->{$name};
626             }
627             }
628              
629             =head2 $req->cookies
630              
631             Returns a reference to a hash containing the cookies.
632              
633 0     0 1 0 print $c->request->cookies->{mycookie}->value;
634              
635 0 0       0 The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
636 0         0 objects.
  0         0  
637              
638             =head2 $req->header
639 0 0       0  
640             Shortcut for $req->headers->header.
641 0         0  
642             =head2 $req->headers
643 0 0       0  
644 0         0 Returns an L<HTTP::Headers> object containing the headers for the current request.
645              
646             print $c->request->headers->header('X-Catalyst');
647 0         0  
648             =head2 $req->hostname
649              
650             Returns the hostname of the client. Use C<< $req->uri->host >> to get the hostname of the server.
651              
652             =head2 $req->input
653              
654             Alias for $req->body.
655              
656             =head2 $req->query_keywords
657              
658             Contains the keywords portion of a query string, when no '=' signs are
659             present.
660              
661             http://localhost/path?some+keywords
662              
663             $c->request->query_keywords will contain 'some keywords'
664              
665             =head2 $req->match
666              
667             This contains the matching part of a Regex action. Otherwise
668             it returns the same as 'action', except for default actions,
669             which return an empty string.
670              
671             =head2 $req->method
672              
673             Contains the request method (C<GET>, C<POST>, C<HEAD>, etc).
674              
675             =head2 $req->param
676              
677             Returns GET and POST parameters with a CGI.pm-compatible param method. This
678             is an alternative method for accessing parameters in $c->req->parameters.
679              
680             $value = $c->request->param( 'foo' );
681             @values = $c->request->param( 'foo' );
682             @params = $c->request->param;
683              
684             Like L<CGI>, and B<unlike> earlier versions of Catalyst, passing multiple
685             arguments to this method, like this:
686              
687             $c->request->param( 'foo', 'bar', 'gorch', 'quxx' );
688              
689             will set the parameter C<foo> to the multiple values C<bar>, C<gorch> and
690             C<quxx>. Previously this would have added C<bar> as another value to C<foo>
691             (creating it if it didn't exist before), and C<quxx> as another value for
692             C<gorch>.
693              
694             B<NOTE> this is considered a legacy interface and care should be taken when
695             using it. C<< scalar $c->req->param( 'foo' ) >> will return only the first
696             C<foo> param even if multiple are present; C<< $c->req->param( 'foo' ) >> will
697             return a list of as many are present, which can have unexpected consequences
698             when writing code of the form:
699              
700             $foo->bar(
701             a => 'b',
702             baz => $c->req->param( 'baz' ),
703             );
704              
705             If multiple C<baz> parameters are provided this code might corrupt data or
706             cause a hash initialization error. For a more straightforward interface see
707             C<< $c->req->parameters >>.
708              
709             B<NOTE> Interfaces like this, which are based on L<CGI> and the C<param> method
710             are known to cause demonstrated exploits. It is highly recommended that you
711             avoid using this method, and migrate existing code away from it. Here's a
712             whitepaper of the exploit:
713              
714             L<http://blog.gerv.net/2014/10/new-class-of-vulnerability-in-perl-web-applications/>
715              
716             B<NOTE> Further discussion on IRC indicate that the L<Catalyst> core team from 'back then'
717             were well aware of this hack and this is the main reason we added the new approach to
718             getting parameters in the first place.
719              
720             Basically this is an exploit that takes advantage of how L<\param> will do one thing
721             in scalar context and another thing in list context. This is combined with how Perl
722             chooses to deal with duplicate keys in a hash definition by overwriting the value of
723             existing keys with a new value if the same key shows up again. Generally you will be
724             vulnerable to this exploit if you are using this method in a direct assignment in a
725             hash, such as with a L<DBIx::Class> create statement. For example, if you have
726             parameters like:
727              
728             user?user=123&foo=a&foo=user&foo=456
729              
730             You could end up with extra parameters injected into your method calls:
731              
732             $c->model('User')->create({
733             user => $c->req->param('user'),
734             foo => $c->req->param('foo'),
735             });
736              
737             Which would look like:
738              
739             $c->model('User')->create({
740             user => 123,
741             foo => qw(a user 456),
742             });
743              
744             (or to be absolutely clear if you are not seeing it):
745              
746             $c->model('User')->create({
747             user => 456,
748             foo => 'a',
749             });
750              
751             Possible remediations include scrubbing your parameters with a form validator like
752             L<HTML::FormHandler> or being careful to force scalar context using the scalar
753             keyword:
754              
755             $c->model('User')->create({
756             user => scalar($c->req->param('user')),
757             foo => scalar($c->req->param('foo')),
758             });
759              
760             Upcoming versions of L<Catalyst> will disable this interface by default and require
761             you to positively enable it should you require it for backwards compatibility reasons.
762              
763             =cut
764              
765             my $self = shift;
766              
767             if ( @_ == 0 ) {
768             return keys %{ $self->parameters };
769             }
770              
771             # If anything in @_ is undef, carp about that, and remove it from
772             # the list;
773              
774             my @params = grep { defined($_) ? 1 : do {carp "You called ->params with an undefined value"; 0} } @_;
775              
776             if ( @params == 1 ) {
777              
778             defined(my $param = shift @params) ||
779             carp "You called ->params with an undefined value 2";
780              
781             unless ( exists $self->parameters->{$param} ) {
782             return wantarray ? () : undef;
783             }
784              
785             if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
786             return (wantarray)
787             ? @{ $self->parameters->{$param} }
788 14     14 1 29 : $self->parameters->{$param}->[0];
789             }
790 14 50       40 else {
791 0         0 return (wantarray)
  0         0  
792             ? ( $self->parameters->{$param} )
793             : $self->parameters->{$param};
794             }
795             }
796             elsif ( @params > 1 ) {
797 14 100       31 my $field = shift @params;
  17         64  
  1         215  
  1         703  
798             $self->parameters->{$field} = [@params];
799 14 100       39 }
    100          
800             }
801 12 50       33  
802             =head2 $req->parameters
803              
804 12 100       52 Returns a reference to a hash containing GET and POST parameters. Values can
805 2 50       8 be either a scalar or an arrayref containing scalars.
806              
807             print $c->request->parameters->{field};
808 10 100       29 print $c->request->parameters->{field}->[0];
809              
810 1         3 This is the combination of C<query_parameters> and C<body_parameters>.
811 1 50       3  
812             =head2 $req->params
813              
814             Shortcut for $req->parameters.
815              
816 9 100       40 =head2 $req->path
817              
818             Returns the path, i.e. the part of the URI after $req->base, for the current request.
819              
820 1         3 http://localhost/path/foo
821 1         5  
822             $c->request->path will contain 'path/foo'
823              
824             =head2 $req->path_info
825              
826             Alias for path, added for compatibility with L<CGI>.
827              
828             =cut
829              
830             my ( $self, @params ) = @_;
831              
832             if (@params) {
833             $self->uri->path(@params);
834             $self->_clear_path;
835             }
836             elsif ( $self->_has_path ) {
837             return $self->_path;
838             }
839             else {
840             my $path = $self->uri->path;
841             my $location = $self->base->path;
842             $path =~ s/^(\Q$location\E)?//;
843             $path =~ s/^\///;
844             $self->_path($path);
845              
846             return $path;
847             }
848             }
849              
850             =head2 $req->protocol
851              
852             Returns the protocol (HTTP/1.0 or HTTP/1.1) used for the current request.
853              
854 1985     1985 1 3831 =head2 $req->query_parameters
855              
856 1985 100       50163 =head2 $req->query_params
    100          
857 1         22  
858 1         86 Returns a reference to a hash containing query string (GET) parameters. Values can
859             be either a scalar or an arrayref containing scalars.
860              
861 1060         22400 print $c->request->query_parameters->{field};
862             print $c->request->query_parameters->{field}->[0];
863              
864 924         19776 =head2 $req->read( [$maxlength] )
865 924         28879  
866 924         13001 Reads a chunk of data from the request body. This method is intended to be
867 924         2028 used in a while loop, reading $maxlength bytes on every call. $maxlength
868 924         21822 defaults to the size of the request if not specified.
869              
870 924         2784 =head2 $req->read_chunk(\$buff, $max)
871              
872             Reads a chunk.
873              
874             You have to set MyApp->config(parse_on_demand => 1) to use this directly.
875              
876             =head2 $req->referer
877              
878             Shortcut for $req->headers->referer. Returns the referring page.
879              
880             =head2 $req->secure
881              
882             Returns true or false, indicating whether the connection is secure
883             (https). The reliability of $req->secure may depend on your server
884             configuration; Catalyst relies on PSGI to determine whether or not a
885             request is secure (Catalyst looks at psgi.url_scheme), and different
886             PSGI servers may make this determination in different ways (as by
887             directly passing along information from the server, interpreting any of
888             several HTTP headers, or using heuristics of their own).
889              
890             =head2 $req->captures
891              
892             Returns a reference to an array containing captured args from chained
893             actions or regex captures.
894              
895             my @captures = @{ $c->request->captures };
896              
897             =head2 $req->upload
898              
899             A convenient method to access $req->uploads.
900              
901             $upload = $c->request->upload('field');
902             @uploads = $c->request->upload('field');
903             @fields = $c->request->upload;
904              
905             for my $upload ( $c->request->upload('field') ) {
906             print $upload->filename;
907             }
908              
909             =cut
910              
911             my $self = shift;
912              
913             if ( @_ == 0 ) {
914             return keys %{ $self->uploads };
915             }
916              
917             if ( @_ == 1 ) {
918              
919             my $upload = shift;
920              
921             unless ( exists $self->uploads->{$upload} ) {
922             return wantarray ? () : undef;
923             }
924              
925             if ( ref $self->uploads->{$upload} eq 'ARRAY' ) {
926             return (wantarray)
927             ? @{ $self->uploads->{$upload} }
928             : $self->uploads->{$upload}->[0];
929             }
930             else {
931             return (wantarray)
932             ? ( $self->uploads->{$upload} )
933             : $self->uploads->{$upload};
934             }
935             }
936 8     8 1 781  
937             if ( @_ > 1 ) {
938 8 100       24  
939 1         2 while ( my ( $field, $upload ) = splice( @_, 0, 2 ) ) {
  1         30  
940              
941             if ( exists $self->uploads->{$field} ) {
942 7 50       18 for ( $self->uploads->{$field} ) {
943             $_ = [$_] unless ref($_) eq "ARRAY";
944 7         10 push( @$_, $upload );
945             }
946 7 100       160 }
947 1 50       4 else {
948             $self->uploads->{$field} = $upload;
949             }
950 6 50       124 }
951             }
952 0         0 }
953 0 0       0  
954             =head2 $req->uploads
955              
956             Returns a reference to a hash containing uploads. Values can be either a
957             L<Catalyst::Request::Upload> object, or an arrayref of
958 6 50       131 L<Catalyst::Request::Upload> objects.
959              
960             my $upload = $c->request->uploads->{field};
961             my $upload = $c->request->uploads->{field}->[0];
962 0 0       0  
963             =head2 $req->uri
964 0         0  
965             Returns a L<URI> object for the current request. Stringifies to the URI text.
966 0 0       0  
967 0         0 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
968 0 0       0  
969 0         0 Returns a hashref of parameters stemming from the current request's params,
970             plus the ones supplied. Keys for which no current param exists will be
971             added, keys with undefined values will be removed and keys with existing
972             params will be replaced. Note that you can supply a true value as the final
973 0         0 argument to change behavior with regards to existing parameters, appending
974             values rather than replacing them.
975              
976             A quick example:
977              
978             # URI query params foo=1
979             my $hashref = $req->mangle_params({ foo => 2 });
980             # Result is query params of foo=2
981              
982             versus append mode:
983              
984             # URI query params foo=1
985             my $hashref = $req->mangle_params({ foo => 2 }, 1);
986             # Result is query params of foo=1&foo=2
987              
988             This is the code behind C<uri_with>.
989              
990             =cut
991              
992             my ($self, $args, $append) = @_;
993              
994             carp('No arguments passed to mangle_params()') unless $args;
995              
996             foreach my $value ( values %$args ) {
997             next unless defined $value;
998             for ( ref $value eq 'ARRAY' ? @$value : $value ) {
999             $_ = "$_";
1000             # utf8::encode($_);
1001             }
1002             };
1003              
1004             my %params = %{ $self->uri->query_form_hash };
1005             foreach my $key (keys %{ $args }) {
1006             my $val = $args->{$key};
1007             if(defined($val)) {
1008              
1009             if($append && exists($params{$key})) {
1010              
1011             # This little bit of heaven handles appending a new value onto
1012             # an existing one regardless if the existing value is an array
1013             # or not, and regardless if the new value is an array or not
1014             $params{$key} = [
1015             ref($params{$key}) eq 'ARRAY' ? @{ $params{$key} } : $params{$key},
1016             ref($val) eq 'ARRAY' ? @{ $val } : $val
1017             ];
1018 22     22 1 43  
1019             } else {
1020 22 50       46 $params{$key} = $val;
1021             }
1022 22         120 } else {
1023 26 100       55  
1024 16 100       48 # If the param wasn't defined then we delete it.
1025 18         46 delete($params{$key});
1026             }
1027             }
1028              
1029              
1030 22         41 return \%params;
  22         572  
1031 22         1125 }
  22         93  
1032 26         50  
1033 26 100       53 =head2 $req->uri_with( { key => 'value' } );
1034              
1035 16 100 66     46 Returns a rewritten URI object for the current request. Key/value pairs
1036             passed in will override existing parameters. You can remove an existing
1037             parameter by passing in an undef value. Unmodified pairs will be
1038             preserved.
1039              
1040             You may also pass an optional second parameter that puts C<uri_with> into
1041 0         0 append mode:
1042 2 50       9  
  1 100       3  
1043             $req->uri_with( { key => 'value' }, { mode => 'append' } );
1044              
1045             See C<mangle_params> for an explanation of this behavior.
1046 14         36  
1047             =cut
1048              
1049             my( $self, $args, $behavior) = @_;
1050              
1051 10         27 carp( 'No arguments passed to uri_with()' ) unless $args;
1052              
1053             my $append = 0;
1054             if((ref($behavior) eq 'HASH') && defined($behavior->{mode}) && ($behavior->{mode} eq 'append')) {
1055             $append = 1;
1056 22         54 }
1057              
1058             my $params = $self->mangle_params($args, $append);
1059              
1060             my $uri = $self->uri->clone;
1061             $uri->query_form($params);
1062              
1063             return $uri;
1064             }
1065              
1066             =head2 $req->remote_user
1067              
1068             Returns the value of the C<REMOTE_USER> environment variable.
1069              
1070             =head2 $req->user_agent
1071              
1072             Shortcut to $req->headers->user_agent. Returns the user agent (browser)
1073             version string.
1074              
1075             =head2 $req->io_fh
1076 22     22 1 61  
1077             Returns a psgix.io bidirectional socket, if your server supports one. Used for
1078 22 50       49 when you want to jailbreak out of PSGI and handle bidirectional client server
1079             communication manually, such as when you are using cometd or websockets.
1080 22         38  
1081 22 50 66     71 =head1 SETUP METHODS
      66        
1082 2         4  
1083             You should never need to call these yourself in application code,
1084             however they are useful if extending Catalyst by applying a request role.
1085 22         58  
1086             =head2 $self->prepare_headers()
1087 22         524  
1088 22         174 Sets up the C<< $res->headers >> accessor.
1089              
1090 22         1819 =head2 $self->prepare_body()
1091              
1092             Sets up the body using L<HTTP::Body>
1093              
1094             =head2 $self->prepare_body_chunk()
1095              
1096             Add a chunk to the request body.
1097              
1098             =head2 $self->prepare_body_parameters()
1099              
1100             Sets up parameters from body.
1101              
1102             =head2 $self->prepare_cookies()
1103              
1104             Parse cookies from header. Sets up a L<CGI::Simple::Cookie> object.
1105              
1106             =head2 $self->prepare_connection()
1107              
1108             Sets up various fields in the request like the local and remote addresses,
1109             request method, hostname requested etc.
1110              
1111             =head2 $self->prepare_parameters()
1112              
1113             Ensures that the body has been parsed, then builds the parameters, which are
1114             combined from those in the request and those in the body.
1115              
1116             If parameters have already been set will clear the parameters and build them again.
1117              
1118             =head2 $self->env
1119              
1120             Access to the raw PSGI env.
1121              
1122             =head2 meta
1123              
1124             Provided by Moose
1125              
1126             =head1 AUTHORS
1127              
1128             Catalyst Contributors, see Catalyst.pm
1129              
1130             =head1 COPYRIGHT
1131              
1132             This library is free software. You can redistribute it and/or modify
1133             it under the same terms as Perl itself.
1134              
1135             =cut
1136              
1137             __PACKAGE__->meta->make_immutable;
1138              
1139             1;