1 package Catalyst::Request;
3 use IO::Socket qw[AF_INET inet_aton];
16 use namespace::clean -except => 'meta';
18 with 'MooseX::Emulate::Class::Accessor::Fast';
20 has env => (is => 'ro', writer => '_set_env', predicate => 'has_env');
21 # XXX Deprecated crap here - warn?
22 has action => (is => 'rw');
23 # XXX: Deprecated in docs ages ago (2006), deprecated with warning in 5.8000 due
24 # to confusion between Engines and Plugin::Authentication. Remove in 5.8100?
25 has user => (is => 'rw');
26 sub snippets { shift->captures(@_) }
28 has _read_position => (
29 # FIXME: work around Moose bug RT#75367
32 writer => '_set_read_position',
36 # FIXME: work around Moose bug RT#75367
41 $self->header('Content-Length') || 0;
46 has address => (is => 'rw');
47 has arguments => (is => 'rw', default => sub { [] });
48 has cookies => (is => 'ro', builder => 'prepare_cookies', lazy => 1);
53 if ( my $header = $self->header('Cookie') ) {
54 return { CGI::Simple::Cookie->parse($header) };
59 has query_keywords => (is => 'rw');
60 has match => (is => 'rw');
61 has method => (is => 'rw');
62 has protocol => (is => 'rw');
63 has query_parameters => (is => 'rw', default => sub { {} });
64 has secure => (is => 'rw', default => 0);
65 has captures => (is => 'rw', default => sub { [] });
66 has uri => (is => 'rw', predicate => 'has_uri');
67 has remote_user => (is => 'rw');
70 isa => 'HTTP::Headers',
71 handles => [qw(content_encoding content_length content_type header referer user_agent)],
72 builder => 'prepare_headers',
80 my $headers = HTTP::Headers->new();
82 for my $header (keys %{ $env }) {
83 next unless $header =~ /^(HTTP|CONTENT|COOKIE)/i;
84 (my $field = $header) =~ s/^HTTPS?_//;
86 $headers->header($field => $env->{$header});
99 predicate=>'has_io_fh',
101 builder=>'_build_io_fh');
105 return $self->env->{'psgix.io'}
107 $self->env->{'net.async.http.server.req'} &&
108 $self->env->{'net.async.http.server.req'}->stream) ## Until I can make ioasync cabal see the value of supportin psgix.io (jnap)
109 || die "Your Server does not support psgix.io";
112 has data_handlers => ( is=>'ro', isa=>'HashRef', default=>sub { +{} } );
117 builder=>'_build_body_data');
119 sub _build_body_data {
121 my $content_type = $self->content_type;
122 my ($match) = grep { $content_type =~/$_/i }
123 keys(%{$self->data_handlers});
126 my $fh = $self->body;
128 return $self->data_handlers->{$match}->($fh, $self);
134 # Amount of data to read from input on each pass
135 our $CHUNKSIZE = 64 * 1024;
138 my ($self, $maxlength) = @_;
139 my $remaining = $self->_read_length - $self->_read_position;
140 $maxlength ||= $CHUNKSIZE;
142 # Are we done reading?
143 if ( $remaining <= 0 ) {
147 my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
148 my $rc = $self->read_chunk( my $buffer, $readlen );
150 if (0 == $rc) { # Nothing more to read even though Content-Length
151 # said there should be.
154 $self->_set_read_position( $self->_read_position + $rc );
158 Catalyst::Exception->throw(
159 message => "Unknown error reading input: $!" );
165 return $self->env->{'psgi.input'}->read(@_);
168 has body_parameters => (
172 builder => 'prepare_body_parameters',
178 default => sub { {} },
184 builder => '_build_parameters',
185 clearer => '_clear_parameters',
189 # - Can we lose the before modifiers which just call prepare_body ?
190 # they are wasteful, slow us down and feel cluttery.
192 # Can we make _body an attribute, have the rest of
193 # these lazy build from there and kill all the direct hash access
194 # in Catalyst.pm and Engine.pm?
196 sub prepare_parameters {
198 $self->_clear_parameters;
199 return $self->parameters;
202 sub _build_parameters {
205 my $body_parameters = $self->body_parameters;
206 my $query_parameters = $self->query_parameters;
208 ## setup for downstream plack
209 $self->env->{'plack.request.merged'} ||= do {
210 my $query = $self->env->{'plack.request.query'} || Hash::MultiValue->new;
211 my $body = $self->env->{'plack.request.body'} || Hash::MultiValue->new;
212 Hash::MultiValue->new($query->flatten, $body->flatten);
215 # We copy, no references
216 foreach my $name (keys %$query_parameters) {
217 my $param = $query_parameters->{$name};
218 $parameters->{$name} = ref $param eq 'ARRAY' ? [ @$param ] : $param;
221 # Merge query and body parameters
222 foreach my $name (keys %$body_parameters) {
223 my $param = $body_parameters->{$name};
224 my @values = ref $param eq 'ARRAY' ? @$param : ($param);
225 if ( my $existing = $parameters->{$name} ) {
226 unshift(@values, (ref $existing eq 'ARRAY' ? @$existing : $existing));
228 $parameters->{$name} = @values > 1 ? \@values : $values[0];
235 predicate => '_has_uploadtmp',
241 # If previously applied middleware created the HTTP::Body object, then we
244 if(my $plack_body = $self->env->{'plack.request.http.body'}) {
245 $self->_body($plack_body);
246 $self->_body->cleanup(1);
250 # Define PSGI ENV placeholders, or for empty should there be no content
251 # body (typical in HEAD or GET). Looks like from Plack::Request that
252 # middleware would probably expect to see this, even if empty
254 $self->env->{'plack.request.body'} = Hash::MultiValue->new;
255 $self->env->{'plack.request.upload'} = Hash::MultiValue->new;
257 # If there is nothing to read, set body to naught and return. This
258 # will cause all body code to be skipped
260 return $self->_body(0) unless my $length = $self->_read_length;
262 # Unless the body has already been set, create it. Not sure about this
263 # code, how else might it be set, but this was existing logic.
265 unless ($self->_body) {
266 my $type = $self->header('Content-Type');
267 $self->_body(HTTP::Body->new( $type, $length ));
268 $self->_body->cleanup(1);
270 # JNAP: I'm not sure this is doing what we expect, but it also doesn't
271 # seem to be hurting (seems ->_has_uploadtmp is true more than I would
274 $self->_body->tmpdir( $self->_uploadtmp )
275 if $self->_has_uploadtmp;
278 # Ok if we get this far, we have to read psgi.input into the new body
279 # object. Lets play nice with any plack app or other downstream, so
280 # we create a buffer unless one exists.
283 if ($self->env->{'psgix.input.buffered'}) {
284 # Be paranoid about previous psgi middleware or apps that read the
285 # input but didn't return the buffer to the start.
286 $self->env->{'psgi.input'}->seek(0, 0);
288 $stream_buffer = Stream::Buffered->new($length);
291 # Check for definedness as you could read '0'
292 while ( defined ( my $chunk = $self->read() ) ) {
293 $self->prepare_body_chunk($chunk);
294 $stream_buffer->print($chunk) if $stream_buffer;
297 # Ok, we read the body. Lets play nice for any PSGI app down the pipe
299 if ($stream_buffer) {
300 $self->env->{'psgix.input.buffered'} = 1;
301 $self->env->{'psgi.input'} = $stream_buffer->rewind;
303 $self->env->{'psgi.input'}->seek(0, 0); # Reset the buffer for downstream middleware or apps
306 $self->env->{'plack.request.http.body'} = $self->_body;
307 $self->env->{'plack.request.body'} = Hash::MultiValue->from_mixed($self->_body->param);
309 # paranoia against wrong Content-Length header
310 my $remaining = $length - $self->_read_position;
311 if ( $remaining > 0 ) {
312 Catalyst::Exception->throw("Wrong Content-Length value: $length" );
316 sub prepare_body_chunk {
317 my ( $self, $chunk ) = @_;
319 $self->_body->add($chunk);
322 sub prepare_body_parameters {
325 $self->prepare_body if ! $self->_has_body;
326 return {} unless $self->_body;
328 return $self->_body->param;
331 sub prepare_connection {
334 my $env = $self->env;
336 $self->address( $env->{REMOTE_ADDR} );
337 $self->hostname( $env->{REMOTE_HOST} )
338 if exists $env->{REMOTE_HOST};
339 $self->protocol( $env->{SERVER_PROTOCOL} );
340 $self->remote_user( $env->{REMOTE_USER} );
341 $self->method( $env->{REQUEST_METHOD} );
342 $self->secure( $env->{'psgi.url_scheme'} eq 'https' ? 1 : 0 );
345 # XXX - FIXME - method is here now, move this crap...
346 around parameters => sub {
347 my ($orig, $self, $params) = @_;
349 if ( !ref $params ) {
351 "Attempt to retrieve '$params' with req->params(), " .
352 "you probably meant to call req->param('$params')"
356 return $self->$orig($params);
367 return $self->path if $self->has_uri;
372 is => 'rw', clearer => '_clear_body', predicate => '_has_body',
374 # Eugh, ugly. Should just be able to rename accessor methods to 'body'
375 # and provide a custom reader..
378 $self->prepare_body unless $self->_has_body;
379 croak 'body is a reader' if scalar @_;
380 return blessed $self->_body ? $self->_body->body : $self->_body;
389 gethostbyaddr( inet_aton( $self->address ), AF_INET ) || $self->address
393 has _path => ( is => 'rw', predicate => '_has_path', clearer => '_clear_path' );
395 sub args { shift->arguments(@_) }
396 sub body_params { shift->body_parameters(@_) }
397 sub input { shift->body(@_) }
398 sub params { shift->parameters(@_) }
399 sub query_params { shift->query_parameters(@_) }
400 sub path_info { shift->path(@_) }
402 =for stopwords param params
406 Catalyst::Request - provides information about the current client request
411 $req->address eq "127.0.0.1";
417 $req->body_parameters;
418 $req->content_encoding;
419 $req->content_length;
427 $req->query_keywords;
435 $req->query_parameters;
446 See also L<Catalyst>, L<Catalyst::Request::Upload>.
450 This is the Catalyst Request class, which provides an interface to data for the
451 current client request. The request object is prepared by L<Catalyst::Engine>,
452 thus hiding the details of the particular engine implementation.
458 Returns the IP address of the client.
460 =head2 $req->arguments
462 Returns a reference to an array containing the arguments.
464 print $c->request->arguments->[0];
466 For example, if your action was
468 package MyApp::Controller::Foo;
474 and the URI for the request was C<http://.../foo/moose/bah>, the string C<bah>
475 would be the first and only argument.
477 Arguments get automatically URI-unescaped for you.
481 Shortcut for L</arguments>.
485 Contains the URI base. This will always have a trailing slash. Note that the
486 URI scheme (e.g., http vs. https) must be determined through heuristics;
487 depending on your server configuration, it may be incorrect. See $req->secure
490 If your application was queried with the URI
491 C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
495 Returns the message body of the request, as returned by L<HTTP::Body>: a string,
496 unless Content-Type is C<application/x-www-form-urlencoded>, C<text/xml>, or
497 C<multipart/form-data>, in which case a L<File::Temp> object is returned.
499 =head2 $req->body_data
501 Returns a Perl representation of POST/PUT body data that is not classic HTML
502 form data, such as JSON, XML, etc. By default, Catalyst will parse incoming
503 data of the type 'application/json' and return access to that data via this
504 method. You may define addition data_handlers via a global configuration
505 setting. See L<Catalyst\DATA HANDLERS> for more information.
507 =head2 $req->body_parameters
509 Returns a reference to a hash containing body (POST) parameters. Values can
510 be either a scalar or an arrayref containing scalars.
512 print $c->request->body_parameters->{field};
513 print $c->request->body_parameters->{field}->[0];
515 These are the parameters from the POST part of the request, if any.
517 =head2 $req->body_params
519 Shortcut for body_parameters.
521 =head2 $req->content_encoding
523 Shortcut for $req->headers->content_encoding.
525 =head2 $req->content_length
527 Shortcut for $req->headers->content_length.
529 =head2 $req->content_type
531 Shortcut for $req->headers->content_type.
535 A convenient method to access $req->cookies.
537 $cookie = $c->request->cookie('name');
538 @cookies = $c->request->cookie;
546 return keys %{ $self->cookies };
553 unless ( exists $self->cookies->{$name} ) {
557 return $self->cookies->{$name};
563 Returns a reference to a hash containing the cookies.
565 print $c->request->cookies->{mycookie}->value;
567 The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
572 Shortcut for $req->headers->header.
576 Returns an L<HTTP::Headers> object containing the headers for the current request.
578 print $c->request->headers->header('X-Catalyst');
580 =head2 $req->hostname
582 Returns the hostname of the client. Use C<< $req->uri->host >> to get the hostname of the server.
586 Alias for $req->body.
588 =head2 $req->query_keywords
590 Contains the keywords portion of a query string, when no '=' signs are
593 http://localhost/path?some+keywords
595 $c->request->query_keywords will contain 'some keywords'
599 This contains the matching part of a Regex action. Otherwise
600 it returns the same as 'action', except for default actions,
601 which return an empty string.
605 Contains the request method (C<GET>, C<POST>, C<HEAD>, etc).
609 Returns GET and POST parameters with a CGI.pm-compatible param method. This
610 is an alternative method for accessing parameters in $c->req->parameters.
612 $value = $c->request->param( 'foo' );
613 @values = $c->request->param( 'foo' );
614 @params = $c->request->param;
616 Like L<CGI>, and B<unlike> earlier versions of Catalyst, passing multiple
617 arguments to this method, like this:
619 $c->request->param( 'foo', 'bar', 'gorch', 'quxx' );
621 will set the parameter C<foo> to the multiple values C<bar>, C<gorch> and
622 C<quxx>. Previously this would have added C<bar> as another value to C<foo>
623 (creating it if it didn't exist before), and C<quxx> as another value for
626 B<NOTE> this is considered a legacy interface and care should be taken when
627 using it. C<< scalar $c->req->param( 'foo' ) >> will return only the first
628 C<foo> param even if multiple are present; C<< $c->req->param( 'foo' ) >> will
629 return a list of as many are present, which can have unexpected consequences
630 when writing code of the form:
634 baz => $c->req->param( 'baz' ),
637 If multiple C<baz> parameters are provided this code might corrupt data or
638 cause a hash initialization error. For a more straightforward interface see
639 C<< $c->req->parameters >>.
647 return keys %{ $self->parameters };
654 unless ( exists $self->parameters->{$param} ) {
655 return wantarray ? () : undef;
658 if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
660 ? @{ $self->parameters->{$param} }
661 : $self->parameters->{$param}->[0];
665 ? ( $self->parameters->{$param} )
666 : $self->parameters->{$param};
671 $self->parameters->{$field} = [@_];
675 =head2 $req->parameters
677 Returns a reference to a hash containing GET and POST parameters. Values can
678 be either a scalar or an arrayref containing scalars.
680 print $c->request->parameters->{field};
681 print $c->request->parameters->{field}->[0];
683 This is the combination of C<query_parameters> and C<body_parameters>.
687 Shortcut for $req->parameters.
691 Returns the path, i.e. the part of the URI after $req->base, for the current request.
693 http://localhost/path/foo
695 $c->request->path will contain 'path/foo'
697 =head2 $req->path_info
699 Alias for path, added for compatibility with L<CGI>.
704 my ( $self, @params ) = @_;
707 $self->uri->path(@params);
710 elsif ( $self->_has_path ) {
714 my $path = $self->uri->path;
715 my $location = $self->base->path;
716 $path =~ s/^(\Q$location\E)?//;
724 =head2 $req->protocol
726 Returns the protocol (HTTP/1.0 or HTTP/1.1) used for the current request.
728 =head2 $req->query_parameters
730 =head2 $req->query_params
732 Returns a reference to a hash containing query string (GET) parameters. Values can
733 be either a scalar or an arrayref containing scalars.
735 print $c->request->query_parameters->{field};
736 print $c->request->query_parameters->{field}->[0];
738 =head2 $req->read( [$maxlength] )
740 Reads a chunk of data from the request body. This method is intended to be
741 used in a while loop, reading $maxlength bytes on every call. $maxlength
742 defaults to the size of the request if not specified.
744 =head2 $req->read_chunk(\$buff, $max)
748 You have to set MyApp->config(parse_on_demand => 1) to use this directly.
752 Shortcut for $req->headers->referer. Returns the referring page.
756 Returns true or false, indicating whether the connection is secure
757 (https). The reliability of $req->secure may depend on your server
758 configuration; Catalyst relies on PSGI to determine whether or not a
759 request is secure (Catalyst looks at psgi.url_scheme), and different
760 PSGI servers may make this determination in different ways (as by
761 directly passing along information from the server, interpreting any of
762 several HTTP headers, or using heuristics of their own).
764 =head2 $req->captures
766 Returns a reference to an array containing captured args from chained
767 actions or regex captures.
769 my @captures = @{ $c->request->captures };
773 A convenient method to access $req->uploads.
775 $upload = $c->request->upload('field');
776 @uploads = $c->request->upload('field');
777 @fields = $c->request->upload;
779 for my $upload ( $c->request->upload('field') ) {
780 print $upload->filename;
789 return keys %{ $self->uploads };
796 unless ( exists $self->uploads->{$upload} ) {
797 return wantarray ? () : undef;
800 if ( ref $self->uploads->{$upload} eq 'ARRAY' ) {
802 ? @{ $self->uploads->{$upload} }
803 : $self->uploads->{$upload}->[0];
807 ? ( $self->uploads->{$upload} )
808 : $self->uploads->{$upload};
814 while ( my ( $field, $upload ) = splice( @_, 0, 2 ) ) {
816 if ( exists $self->uploads->{$field} ) {
817 for ( $self->uploads->{$field} ) {
818 $_ = [$_] unless ref($_) eq "ARRAY";
819 push( @$_, $upload );
823 $self->uploads->{$field} = $upload;
831 Returns a reference to a hash containing uploads. Values can be either a
832 L<Catalyst::Request::Upload> object, or an arrayref of
833 L<Catalyst::Request::Upload> objects.
835 my $upload = $c->request->uploads->{field};
836 my $upload = $c->request->uploads->{field}->[0];
840 Returns a L<URI> object for the current request. Stringifies to the URI text.
842 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
844 Returns a hashref of parameters stemming from the current request's params,
845 plus the ones supplied. Keys for which no current param exists will be
846 added, keys with undefined values will be removed and keys with existing
847 params will be replaced. Note that you can supply a true value as the final
848 argument to change behavior with regards to existing parameters, appending
849 values rather than replacing them.
853 # URI query params foo=1
854 my $hashref = $req->mangle_params({ foo => 2 });
855 # Result is query params of foo=2
859 # URI query params foo=1
860 my $hashref = $req->mangle_params({ foo => 2 }, 1);
861 # Result is query params of foo=1&foo=2
863 This is the code behind C<uri_with>.
868 my ($self, $args, $append) = @_;
870 carp('No arguments passed to mangle_params()') unless $args;
872 foreach my $value ( values %$args ) {
873 next unless defined $value;
874 for ( ref $value eq 'ARRAY' ? @$value : $value ) {
876 utf8::encode( $_ ) if utf8::is_utf8($_);
880 my %params = %{ $self->uri->query_form_hash };
881 foreach my $key (keys %{ $args }) {
882 my $val = $args->{$key};
885 if($append && exists($params{$key})) {
887 # This little bit of heaven handles appending a new value onto
888 # an existing one regardless if the existing value is an array
889 # or not, and regardless if the new value is an array or not
891 ref($params{$key}) eq 'ARRAY' ? @{ $params{$key} } : $params{$key},
892 ref($val) eq 'ARRAY' ? @{ $val } : $val
896 $params{$key} = $val;
900 # If the param wasn't defined then we delete it.
901 delete($params{$key});
909 =head2 $req->uri_with( { key => 'value' } );
911 Returns a rewritten URI object for the current request. Key/value pairs
912 passed in will override existing parameters. You can remove an existing
913 parameter by passing in an undef value. Unmodified pairs will be
916 You may also pass an optional second parameter that puts C<uri_with> into
919 $req->uri_with( { key => 'value' }, { mode => 'append' } );
921 See C<mangle_params> for an explanation of this behavior.
926 my( $self, $args, $behavior) = @_;
928 carp( 'No arguments passed to uri_with()' ) unless $args;
931 if((ref($behavior) eq 'HASH') && defined($behavior->{mode}) && ($behavior->{mode} eq 'append')) {
935 my $params = $self->mangle_params($args, $append);
937 my $uri = $self->uri->clone;
938 $uri->query_form($params);
943 =head2 $req->remote_user
945 Returns the value of the C<REMOTE_USER> environment variable.
947 =head2 $req->user_agent
949 Shortcut to $req->headers->user_agent. Returns the user agent (browser)
954 Returns a psgix.io bidirectional socket, if your server supports one. Used for
955 when you want to jailbreak out of PSGI and handle bidirectional client server
956 communication manually, such as when you are using cometd or websockets.
960 You should never need to call these yourself in application code,
961 however they are useful if extending Catalyst by applying a request role.
963 =head2 $self->prepare_headers()
965 Sets up the C<< $res->headers >> accessor.
967 =head2 $self->prepare_body()
969 Sets up the body using L<HTTP::Body>
971 =head2 $self->prepare_body_chunk()
973 Add a chunk to the request body.
975 =head2 $self->prepare_body_parameters()
977 Sets up parameters from body.
979 =head2 $self->prepare_cookies()
981 Parse cookies from header. Sets up a L<CGI::Simple::Cookie> object.
983 =head2 $self->prepare_connection()
985 Sets up various fields in the request like the local and remote addresses,
986 request method, hostname requested etc.
988 =head2 $self->prepare_parameters()
990 Ensures that the body has been parsed, then builds the parameters, which are
991 combined from those in the request and those in the body.
993 If parameters have already been set will clear the parameters and build them again.
1002 Catalyst Contributors, see Catalyst.pm
1006 This library is free software. You can redistribute it and/or modify
1007 it under the same terms as Perl itself.
1011 __PACKAGE__->meta->make_immutable;