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