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