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