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