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