e937fb193cf09894657850ea0a2dc51e14283289
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Request.pm
1 package Catalyst::Request;
2
3 use Socket qw( getaddrinfo getnameinfo AI_NUMERICHOST NI_NAMEREQD NIx_NOSERV );
4 use Carp;
5 use utf8;
6 use URI::http;
7 use URI::https;
8 use URI::QueryParam;
9 use HTTP::Headers;
10 use Stream::Buffered;
11 use Hash::MultiValue;
12 use Scalar::Util;
13 use HTTP::Body;
14 use Catalyst::Exception;
15 use Catalyst::Request::PartData;
16 use Moose;
17
18 use namespace::clean -except => 'meta';
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 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     my ( $self ) = @_;
54
55     if ( my $header = $self->header('Cookie') ) {
56         return { CGI::Simple::Cookie->parse($header) };
57     }
58     {};
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     my ($self) = @_;
80
81     my $env = $self->env;
82     my $headers = HTTP::Headers->new();
83
84     for my $header (keys %{ $env }) {
85         next unless $header =~ /^(HTTP|CONTENT|COOKIE)/i;
86         (my $field = $header) =~ s/^HTTPS?_//;
87         $field =~ tr/_/-/;
88         $headers->header($field => $env->{$header});
89     }
90     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     my $self = shift;
107     return $self->env->{'psgix.io'}
108       || (
109         $self->env->{'net.async.http.server.req'} &&
110         $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     my ($self) = @_;
123
124     # Not sure if these returns should not be exceptions...
125     my $content_type = $self->content_type || return;
126     return unless ($self->method eq 'POST' || $self->method eq 'PUT' || $self->method eq 'PATCH');
127
128     my ($match) = grep { $content_type =~/$_/i }
129       keys(%{$self->data_handlers});
130
131     if($match) {
132       my $fh = $self->body;
133       local $_ = $fh;
134       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           $content_type, join ', ', sort keys %{$self->data_handlers}
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     my ($self, $maxlength) = @_;
153     my $remaining = $self->_read_length - $self->_read_position;
154     $maxlength ||= $CHUNKSIZE;
155
156     # Are we done reading?
157     if ( $remaining <= 0 ) {
158         return;
159     }
160
161     my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
162     my $rc = $self->read_chunk( my $buffer, $readlen );
163     if ( defined $rc ) {
164         if (0 == $rc) { # Nothing more to read even though Content-Length
165                         # said there should be.
166             return;
167         }
168         $self->_set_read_position( $self->_read_position + $rc );
169         return $buffer;
170     }
171     else {
172         Catalyst::Exception->throw(
173             message => "Unknown error reading input: $!" );
174     }
175 }
176
177 sub read_chunk {
178     my $self = shift;
179     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     my ( $self ) = @_;
213     $self->_clear_parameters;
214     return $self->parameters;
215 }
216
217 sub _build_parameters {
218     my ( $self ) = @_;
219     my $parameters = {};
220     my $body_parameters = $self->body_parameters;
221     my $query_parameters = $self->query_parameters;
222
223     if($self->_use_hash_multivalue) {
224         return Hash::MultiValue->new($query_parameters->flatten, $body_parameters->flatten);
225     }
226
227     # We copy, no references
228     foreach my $name (keys %$query_parameters) {
229         my $param = $query_parameters->{$name};
230         $parameters->{$name} = ref $param eq 'ARRAY' ? [ @$param ] : $param;
231     }
232
233     # Merge query and body parameters
234     foreach my $name (keys %$body_parameters) {
235         my $param = $body_parameters->{$name};
236         my @values = ref $param eq 'ARRAY' ? @$param : ($param);
237         if ( my $existing = $parameters->{$name} ) {
238           unshift(@values, (ref $existing eq 'ARRAY' ? @$existing : $existing));
239         }
240         $parameters->{$name} = @values > 1 ? \@values : $values[0];
241     }
242     $parameters;
243 }
244
245 has _uploadtmp => (
246     is => 'ro',
247     predicate => '_has_uploadtmp',
248 );
249
250 sub prepare_body {
251     my ( $self ) = @_;
252
253     # If previously applied middleware created the HTTP::Body object, then we
254     # just use that one.
255
256     if(my $plack_body = $self->_has_env ? $self->env->{'plack.request.http.body'} : undef) {
257         $self->_body($plack_body);
258         $self->_body->cleanup(1);
259         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     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     unless ($self->_body) {
271         my $type = $self->header('Content-Type');
272         $self->_body(HTTP::Body->new( $type, $length ));
273         $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         $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     my $stream_buffer;
288     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         $self->env->{'psgi.input'}->seek(0, 0);
292     } else {
293         $stream_buffer = Stream::Buffered->new($length);
294     }
295
296     # Check for definedness as you could read '0'
297     while ( defined ( my $chunk = $self->read() ) ) {
298         $self->prepare_body_chunk($chunk);
299         next unless $stream_buffer;
300
301         $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     if ($stream_buffer) {
308         $self->env->{'psgix.input.buffered'} = 1;
309         $self->env->{'psgi.input'} = $stream_buffer->rewind;
310     } else {
311         $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     my $remaining = $length - $self->_read_position;
316     if ( $remaining > 0 ) {
317         Catalyst::Exception->throw("Wrong Content-Length value: $length" );
318     }
319 }
320
321 sub prepare_body_chunk {
322     my ( $self, $chunk ) = @_;
323
324     $self->_body->add($chunk);
325 }
326
327 sub prepare_body_parameters {
328     my ( $self, $c ) = @_;
329     return $self->body_parameters if $self->has_body_parameters;
330     $self->prepare_body if ! $self->_has_body;
331
332     unless($self->_body) {
333       my $return = $self->_use_hash_multivalue ? Hash::MultiValue->new : {};
334       $self->body_parameters($return);
335       return $return;
336     }
337
338     my $params;
339     my %part_data = %{$self->_body->part_data};
340     if(scalar %part_data && !$c->config->{skip_complex_post_part_handling}) {
341       foreach my $key (keys %part_data) {
342         my $proto_value = $part_data{$key};
343         my ($val, @extra) = (ref($proto_value)||'') eq 'ARRAY' ? @$proto_value : ($proto_value);
344
345         $key = $c->_handle_param_unicode_decoding($key)
346           if ($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding});
347
348         if(@extra) {
349           $params->{$key} = [map { Catalyst::Request::PartData->build_from_part_data($c, $_) } ($val,@extra)];
350         } else {
351           $params->{$key} = Catalyst::Request::PartData->build_from_part_data($c, $val);
352         }
353       }
354     } else {
355       $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       if($c and $c->encoding and !$c->config->{skip_body_param_unicode_decoding}) {
372         $params = $c->_handle_unicode_decoding($params);
373       }
374     }
375
376     my $return = $self->_use_hash_multivalue ?
377         Hash::MultiValue->from_mixed($params) :
378         $params;
379
380     $self->body_parameters($return) unless $self->has_body_parameters;
381     return $return;
382 }
383
384 sub prepare_connection {
385     my ($self) = @_;
386
387     my $env = $self->env;
388
389     $self->address( $env->{REMOTE_ADDR} );
390     $self->hostname( $env->{REMOTE_HOST} )
391         if exists $env->{REMOTE_HOST};
392     $self->protocol( $env->{SERVER_PROTOCOL} );
393     $self->remote_user( $env->{REMOTE_USER} );
394     $self->method( $env->{REQUEST_METHOD} );
395     $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   my $self = shift;
431   $self->prepare_body unless $self->_has_body;
432   croak 'body is a reader' if scalar @_;
433   return blessed $self->_body ? $self->_body->body : $self->_body;
434 }
435
436 has hostname => (
437   is        => 'rw',
438   required  => 1,
439   lazy      => 1,
440   default   => sub {
441     my ($self) = @_;
442     my ( $err, $sockaddr ) = getaddrinfo(
443         $self->address,
444         # no service
445         '',
446         { flags => AI_NUMERICHOST }
447     );
448     return $self->address
449         if $err;
450     ( $err, my $hostname ) = getnameinfo(
451         $sockaddr->{addr},
452         NI_NAMEREQD,
453         # we are only interested in the hostname, not the servicename
454         NIx_NOSERV
455     );
456     return $err ? $self->address : $hostname;
457   },
458 );
459
460 has _path => ( is => 'rw', predicate => '_has_path', clearer => '_clear_path' );
461
462 sub args            { shift->arguments(@_) }
463 sub body_params     { shift->body_parameters(@_) }
464 sub input           { shift->body(@_) }
465 sub params          { shift->parameters(@_) }
466 sub query_params    { shift->query_parameters(@_) }
467 sub path_info       { shift->path(@_) }
468
469 =for stopwords param params
470
471 =head1 NAME
472
473 Catalyst::Request - provides information about the current client request
474
475 =head1 SYNOPSIS
476
477     $req = $c->request;
478     $req->address eq "127.0.0.1";
479     $req->arguments;
480     $req->args;
481     $req->base;
482     $req->body;
483     $req->body_data;
484     $req->body_parameters;
485     $req->content_encoding;
486     $req->content_length;
487     $req->content_type;
488     $req->cookie;
489     $req->cookies;
490     $req->header;
491     $req->headers;
492     $req->hostname;
493     $req->input;
494     $req->query_keywords;
495     $req->match;
496     $req->method;
497     $req->param;
498     $req->parameters;
499     $req->params;
500     $req->path;
501     $req->protocol;
502     $req->query_parameters;
503     $req->read;
504     $req->referer;
505     $req->secure;
506     $req->captures;
507     $req->upload;
508     $req->uploads;
509     $req->uri;
510     $req->user;
511     $req->user_agent;
512     $req->env;
513
514 See also L<Catalyst>, L<Catalyst::Request::Upload>.
515
516 =head1 DESCRIPTION
517
518 This is the Catalyst Request class, which provides an interface to data for the
519 current client request. The request object is prepared by L<Catalyst::Engine>,
520 thus hiding the details of the particular engine implementation.
521
522 =head1 METHODS
523
524 =head2 $req->address
525
526 Returns the IP address of the client.
527
528 =head2 $req->arguments
529
530 Returns a reference to an array containing the arguments.
531
532     print $c->request->arguments->[0];
533
534 For example, if your action was
535
536     package MyApp::Controller::Foo;
537
538     sub moose : Local {
539         ...
540     }
541
542 and the URI for the request was C<http://.../foo/moose/bah>, the string C<bah>
543 would be the first and only argument.
544
545 Arguments get automatically URI-unescaped for you.
546
547 =head2 $req->args
548
549 Shortcut for L</arguments>.
550
551 =head2 $req->base
552
553 Contains the URI base. This will always have a trailing slash. Note that the
554 URI scheme (e.g., http vs. https) must be determined through heuristics;
555 depending on your server configuration, it may be incorrect. See $req->secure
556 for more info.
557
558 If your application was queried with the URI
559 C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
560
561 =head2 $req->body
562
563 Returns the message body of the request, as returned by L<HTTP::Body>: a string,
564 unless Content-Type is C<application/x-www-form-urlencoded>, C<text/xml>, or
565 C<multipart/form-data>, in which case a L<File::Temp> object is returned.
566
567 =head2 $req->body_data
568
569 Returns a Perl representation of POST/PUT body data that is not classic HTML
570 form data, such as JSON, XML, etc.  By default, Catalyst will parse incoming
571 data of the type 'application/json' and return access to that data via this
572 method.  You may define addition data_handlers via a global configuration
573 setting.  See L<Catalyst\DATA HANDLERS> for more information.
574
575 If the POST is malformed in some way (such as undefined or not content that
576 matches the content-type) we raise a L<Catalyst::Exception> with the error
577 text as the message.
578
579 If the POSTed content type does not match an available data handler, this
580 will also raise an exception.
581
582 =head2 $req->body_parameters
583
584 Returns a reference to a hash containing body (POST) parameters. Values can
585 be either a scalar or an arrayref containing scalars.
586
587     print $c->request->body_parameters->{field};
588     print $c->request->body_parameters->{field}->[0];
589
590 These are the parameters from the POST part of the request, if any.
591
592 B<NOTE> If your POST is multipart, but contains non file upload parts (such
593 as an line part with an alternative encoding or content type) we do our best to
594 try and figure out how the value should be presented.  If there's a specified character
595 set we will use that to decode rather than the default encoding set by the application.
596 However if there are complex headers and we cannot determine
597 the correct way to extra a meaningful value from the upload, in this case any
598 part like this will be represented as an instance of L<Catalyst::Request::PartData>.
599
600 Patches and review of this part of the code welcomed.
601
602 =head2 $req->body_params
603
604 Shortcut for body_parameters.
605
606 =head2 $req->content_encoding
607
608 Shortcut for $req->headers->content_encoding.
609
610 =head2 $req->content_length
611
612 Shortcut for $req->headers->content_length.
613
614 =head2 $req->content_type
615
616 Shortcut for $req->headers->content_type.
617
618 =head2 $req->cookie
619
620 A convenient method to access $req->cookies.
621
622     $cookie  = $c->request->cookie('name');
623     @cookies = $c->request->cookie;
624
625 =cut
626
627 sub cookie {
628     my $self = shift;
629
630     if ( @_ == 0 ) {
631         return keys %{ $self->cookies };
632     }
633
634     if ( @_ == 1 ) {
635
636         my $name = shift;
637
638         unless ( exists $self->cookies->{$name} ) {
639             return undef;
640         }
641
642         return $self->cookies->{$name};
643     }
644 }
645
646 =head2 $req->cookies
647
648 Returns a reference to a hash containing the cookies.
649
650     print $c->request->cookies->{mycookie}->value;
651
652 The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
653 objects.
654
655 =head2 $req->header
656
657 Shortcut for $req->headers->header.
658
659 =head2 $req->headers
660
661 Returns an L<HTTP::Headers> object containing the headers for the current request.
662
663     print $c->request->headers->header('X-Catalyst');
664
665 =head2 $req->hostname
666
667 Returns the hostname of the client. Use C<< $req->uri->host >> to get the hostname of the server.
668
669 =head2 $req->input
670
671 Alias for $req->body.
672
673 =head2 $req->query_keywords
674
675 Contains the keywords portion of a query string, when no '=' signs are
676 present.
677
678     http://localhost/path?some+keywords
679
680     $c->request->query_keywords will contain 'some keywords'
681
682 =head2 $req->match
683
684 This contains the matching part of a Regex action. Otherwise
685 it returns the same as 'action', except for default actions,
686 which return an empty string.
687
688 =head2 $req->method
689
690 Contains the request method (C<GET>, C<POST>, C<HEAD>, etc).
691
692 =head2 $req->param
693
694 Returns GET and POST parameters with a CGI.pm-compatible param method. This
695 is an alternative method for accessing parameters in $c->req->parameters.
696
697     $value  = $c->request->param( 'foo' );
698     @values = $c->request->param( 'foo' );
699     @params = $c->request->param;
700
701 Like L<CGI>, and B<unlike> earlier versions of Catalyst, passing multiple
702 arguments to this method, like this:
703
704     $c->request->param( 'foo', 'bar', 'gorch', 'quxx' );
705
706 will set the parameter C<foo> to the multiple values C<bar>, C<gorch> and
707 C<quxx>. Previously this would have added C<bar> as another value to C<foo>
708 (creating it if it didn't exist before), and C<quxx> as another value for
709 C<gorch>.
710
711 B<NOTE> this is considered a legacy interface and care should be taken when
712 using it. C<< scalar $c->req->param( 'foo' ) >> will return only the first
713 C<foo> param even if multiple are present; C<< $c->req->param( 'foo' ) >> will
714 return a list of as many are present, which can have unexpected consequences
715 when writing code of the form:
716
717     $foo->bar(
718         a => 'b',
719         baz => $c->req->param( 'baz' ),
720     );
721
722 If multiple C<baz> parameters are provided this code might corrupt data or
723 cause a hash initialization error. For a more straightforward interface see
724 C<< $c->req->parameters >>.
725
726 B<NOTE> Interfaces like this, which are based on L<CGI> and the C<param> method
727 are known to cause demonstrated exploits. It is highly recommended that you
728 avoid using this method, and migrate existing code away from it.  Here's a
729 whitepaper of the exploit:
730
731 L<http://blog.gerv.net/2014/10/new-class-of-vulnerability-in-perl-web-applications/>
732
733 B<NOTE> Further discussion on IRC indicate that the L<Catalyst> core team from 'back then'
734 were well aware of this hack and this is the main reason we added the new approach to
735 getting parameters in the first place.
736
737 Basically this is an exploit that takes advantage of how L<\param> will do one thing
738 in scalar context and another thing in list context.  This is combined with how Perl
739 chooses to deal with duplicate keys in a hash definition by overwriting the value of
740 existing keys with a new value if the same key shows up again.  Generally you will be
741 vulnerable to this exploit if you are using this method in a direct assignment in a
742 hash, such as with a L<DBIx::Class> create statement.  For example, if you have
743 parameters like:
744
745     user?user=123&foo=a&foo=user&foo=456
746
747 You could end up with extra parameters injected into your method calls:
748
749     $c->model('User')->create({
750       user => $c->req->param('user'),
751       foo => $c->req->param('foo'),
752     });
753
754 Which would look like:
755
756     $c->model('User')->create({
757       user => 123,
758       foo => qw(a user 456),
759     });
760
761 (or to be absolutely clear if you are not seeing it):
762
763     $c->model('User')->create({
764       user => 456,
765       foo => 'a',
766     });
767
768 Possible remediations include scrubbing your parameters with a form validator like
769 L<HTML::FormHandler> or being careful to force scalar context using the scalar
770 keyword:
771
772     $c->model('User')->create({
773       user => scalar($c->req->param('user')),
774       foo => scalar($c->req->param('foo')),
775     });
776
777 Upcoming versions of L<Catalyst> will disable this interface by default and require
778 you to positively enable it should you require it for backwards compatibility reasons.
779
780 =cut
781
782 sub param {
783     my $self = shift;
784
785     if ( @_ == 0 ) {
786         return keys %{ $self->parameters };
787     }
788
789     # If anything in @_ is undef, carp about that, and remove it from
790     # the list;
791
792     my @params = grep { defined($_) ? 1 : do {carp "You called ->params with an undefined value"; 0} } @_;
793
794     if ( @params == 1 ) {
795
796         defined(my $param = shift @params) ||
797           carp "You called ->params with an undefined value 2";
798
799         unless ( exists $self->parameters->{$param} ) {
800             return wantarray ? () : undef;
801         }
802
803         if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
804             return (wantarray)
805               ? @{ $self->parameters->{$param} }
806               : $self->parameters->{$param}->[0];
807         }
808         else {
809             return (wantarray)
810               ? ( $self->parameters->{$param} )
811               : $self->parameters->{$param};
812         }
813     }
814     elsif ( @params > 1 ) {
815         my $field = shift @params;
816         $self->parameters->{$field} = [@params];
817     }
818 }
819
820 =head2 $req->parameters
821
822 Returns a reference to a hash containing GET and POST parameters. Values can
823 be either a scalar or an arrayref containing scalars.
824
825     print $c->request->parameters->{field};
826     print $c->request->parameters->{field}->[0];
827
828 This is the combination of C<query_parameters> and C<body_parameters>.
829
830 =head2 $req->params
831
832 Shortcut for $req->parameters.
833
834 =head2 $req->path
835
836 Returns the path, i.e. the part of the URI after $req->base, for the current request.
837
838     http://localhost/path/foo
839
840     $c->request->path will contain 'path/foo'
841
842 =head2 $req->path_info
843
844 Alias for path, added for compatibility with L<CGI>.
845
846 =cut
847
848 sub path {
849     my ( $self, @params ) = @_;
850
851     if (@params) {
852         $self->uri->path(@params);
853         $self->_clear_path;
854     }
855     elsif ( $self->_has_path ) {
856         return $self->_path;
857     }
858     else {
859         my $path     = $self->uri->path;
860         my $location = $self->base->path;
861         $path =~ s/^(\Q$location\E)?//;
862         $path =~ s/^\///;
863         $self->_path($path);
864
865         return $path;
866     }
867 }
868
869 =head2 $req->protocol
870
871 Returns the protocol (HTTP/1.0 or HTTP/1.1) used for the current request.
872
873 =head2 $req->query_parameters
874
875 =head2 $req->query_params
876
877 Returns a reference to a hash containing query string (GET) parameters. Values can
878 be either a scalar or an arrayref containing scalars.
879
880     print $c->request->query_parameters->{field};
881     print $c->request->query_parameters->{field}->[0];
882
883 =head2 $req->read( [$maxlength] )
884
885 Reads a chunk of data from the request body. This method is intended to be
886 used in a while loop, reading $maxlength bytes on every call. $maxlength
887 defaults to the size of the request if not specified.
888
889 =head2 $req->read_chunk(\$buff, $max)
890
891 Reads a chunk.
892
893 You have to set MyApp->config(parse_on_demand => 1) to use this directly.
894
895 =head2 $req->referer
896
897 Shortcut for $req->headers->referer. Returns the referring page.
898
899 =head2 $req->secure
900
901 Returns true or false, indicating whether the connection is secure
902 (https). The reliability of $req->secure may depend on your server
903 configuration; Catalyst relies on PSGI to determine whether or not a
904 request is secure (Catalyst looks at psgi.url_scheme), and different
905 PSGI servers may make this determination in different ways (as by
906 directly passing along information from the server, interpreting any of
907 several HTTP headers, or using heuristics of their own).
908
909 =head2 $req->captures
910
911 Returns a reference to an array containing captured args from chained
912 actions or regex captures.
913
914     my @captures = @{ $c->request->captures };
915
916 =head2 $req->upload
917
918 A convenient method to access $req->uploads.
919
920     $upload  = $c->request->upload('field');
921     @uploads = $c->request->upload('field');
922     @fields  = $c->request->upload;
923
924     for my $upload ( $c->request->upload('field') ) {
925         print $upload->filename;
926     }
927
928 =cut
929
930 sub upload {
931     my $self = shift;
932
933     if ( @_ == 0 ) {
934         return keys %{ $self->uploads };
935     }
936
937     if ( @_ == 1 ) {
938
939         my $upload = shift;
940
941         unless ( exists $self->uploads->{$upload} ) {
942             return wantarray ? () : undef;
943         }
944
945         if ( ref $self->uploads->{$upload} eq 'ARRAY' ) {
946             return (wantarray)
947               ? @{ $self->uploads->{$upload} }
948               : $self->uploads->{$upload}->[0];
949         }
950         else {
951             return (wantarray)
952               ? ( $self->uploads->{$upload} )
953               : $self->uploads->{$upload};
954         }
955     }
956
957     if ( @_ > 1 ) {
958
959         while ( my ( $field, $upload ) = splice( @_, 0, 2 ) ) {
960
961             if ( exists $self->uploads->{$field} ) {
962                 for ( $self->uploads->{$field} ) {
963                     $_ = [$_] unless ref($_) eq "ARRAY";
964                     push( @$_, $upload );
965                 }
966             }
967             else {
968                 $self->uploads->{$field} = $upload;
969             }
970         }
971     }
972 }
973
974 =head2 $req->uploads
975
976 Returns a reference to a hash containing uploads. Values can be either a
977 L<Catalyst::Request::Upload> object, or an arrayref of
978 L<Catalyst::Request::Upload> objects.
979
980     my $upload = $c->request->uploads->{field};
981     my $upload = $c->request->uploads->{field}->[0];
982
983 =head2 $req->uri
984
985 Returns a L<URI> object for the current request. Stringifies to the URI text.
986
987 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
988
989 Returns a hashref of parameters stemming from the current request's params,
990 plus the ones supplied.  Keys for which no current param exists will be
991 added, keys with undefined values will be removed and keys with existing
992 params will be replaced.  Note that you can supply a true value as the final
993 argument to change behavior with regards to existing parameters, appending
994 values rather than replacing them.
995
996 A quick example:
997
998   # URI query params foo=1
999   my $hashref = $req->mangle_params({ foo => 2 });
1000   # Result is query params of foo=2
1001
1002 versus append mode:
1003
1004   # URI query params foo=1
1005   my $hashref = $req->mangle_params({ foo => 2 }, 1);
1006   # Result is query params of foo=1&foo=2
1007
1008 This is the code behind C<uri_with>.
1009
1010 =cut
1011
1012 sub mangle_params {
1013     my ($self, $args, $append) = @_;
1014
1015     carp('No arguments passed to mangle_params()') unless $args;
1016
1017     foreach my $value ( values %$args ) {
1018         next unless defined $value;
1019         for ( ref $value eq 'ARRAY' ? @$value : $value ) {
1020             $_ = "$_";
1021             #      utf8::encode($_);
1022         }
1023     };
1024
1025     my %params = %{ $self->uri->query_form_hash };
1026     foreach my $key (keys %{ $args }) {
1027         my $val = $args->{$key};
1028         if(defined($val)) {
1029
1030             if($append && exists($params{$key})) {
1031
1032                 # This little bit of heaven handles appending a new value onto
1033                 # an existing one regardless if the existing value is an array
1034                 # or not, and regardless if the new value is an array or not
1035                 $params{$key} = [
1036                     ref($params{$key}) eq 'ARRAY' ? @{ $params{$key} } : $params{$key},
1037                     ref($val) eq 'ARRAY' ? @{ $val } : $val
1038                 ];
1039
1040             } else {
1041                 $params{$key} = $val;
1042             }
1043         } else {
1044
1045             # If the param wasn't defined then we delete it.
1046             delete($params{$key});
1047         }
1048     }
1049
1050
1051     return \%params;
1052 }
1053
1054 =head2 $req->uri_with( { key => 'value' } );
1055
1056 Returns a rewritten URI object for the current request. Key/value pairs
1057 passed in will override existing parameters. You can remove an existing
1058 parameter by passing in an undef value. Unmodified pairs will be
1059 preserved.
1060
1061 You may also pass an optional second parameter that puts C<uri_with> into
1062 append mode:
1063
1064   $req->uri_with( { key => 'value' }, { mode => 'append' } );
1065
1066 See C<mangle_params> for an explanation of this behavior.
1067
1068 =cut
1069
1070 sub uri_with {
1071     my( $self, $args, $behavior) = @_;
1072
1073     carp( 'No arguments passed to uri_with()' ) unless $args;
1074
1075     my $append = 0;
1076     if((ref($behavior) eq 'HASH') && defined($behavior->{mode}) && ($behavior->{mode} eq 'append')) {
1077         $append = 1;
1078     }
1079
1080     my $params = $self->mangle_params($args, $append);
1081
1082     my $uri = $self->uri->clone;
1083     $uri->query_form($params);
1084
1085     return $uri;
1086 }
1087
1088 =head2 $req->remote_user
1089
1090 Returns the value of the C<REMOTE_USER> environment variable.
1091
1092 =head2 $req->user_agent
1093
1094 Shortcut to $req->headers->user_agent. Returns the user agent (browser)
1095 version string.
1096
1097 =head2 $req->io_fh
1098
1099 Returns a psgix.io bidirectional socket, if your server supports one.  Used for
1100 when you want to jailbreak out of PSGI and handle bidirectional client server
1101 communication manually, such as when you are using cometd or websockets.
1102
1103 =head1 SETUP METHODS
1104
1105 You should never need to call these yourself in application code,
1106 however they are useful if extending Catalyst by applying a request role.
1107
1108 =head2 $self->prepare_headers()
1109
1110 Sets up the C<< $res->headers >> accessor.
1111
1112 =head2 $self->prepare_body()
1113
1114 Sets up the body using L<HTTP::Body>
1115
1116 =head2 $self->prepare_body_chunk()
1117
1118 Add a chunk to the request body.
1119
1120 =head2 $self->prepare_body_parameters()
1121
1122 Sets up parameters from body.
1123
1124 =head2 $self->prepare_cookies()
1125
1126 Parse cookies from header. Sets up a L<CGI::Simple::Cookie> object.
1127
1128 =head2 $self->prepare_connection()
1129
1130 Sets up various fields in the request like the local and remote addresses,
1131 request method, hostname requested etc.
1132
1133 =head2 $self->prepare_parameters()
1134
1135 Ensures that the body has been parsed, then builds the parameters, which are
1136 combined from those in the request and those in the body.
1137
1138 If parameters have already been set will clear the parameters and build them again.
1139
1140 =head2 $self->env
1141
1142 Access to the raw PSGI env.
1143
1144 =head2 meta
1145
1146 Provided by Moose
1147
1148 =head1 AUTHORS
1149
1150 Catalyst Contributors, see Catalyst.pm
1151
1152 =head1 COPYRIGHT
1153
1154 This library is free software. You can redistribute it and/or modify
1155 it under the same terms as Perl itself.
1156
1157 =cut
1158
1159 __PACKAGE__->meta->make_immutable;
1160
1161 1;