1 package Catalyst::Request;
3 use IO::Socket qw[AF_INET inet_aton];
13 use namespace::clean -except => 'meta';
15 with 'MooseX::Emulate::Class::Accessor::Fast';
17 has env => (is => 'ro', writer => '_set_env');
18 # XXX Deprecated crap here - warn?
19 has action => (is => 'rw');
20 # XXX: Deprecated in docs ages ago (2006), deprecated with warning in 5.8000 due
21 # to confusion between Engines and Plugin::Authentication. Remove in 5.8100?
22 has user => (is => 'rw');
23 sub snippets { shift->captures(@_) }
25 has _read_position => (
26 # FIXME: work around Moose bug RT#75367
29 writer => '_set_read_position',
33 # FIXME: work around Moose bug RT#75367
38 $self->header('Content-Length') || 0;
43 has address => (is => 'rw');
44 has arguments => (is => 'rw', default => sub { [] });
45 has cookies => (is => 'ro', builder => 'prepare_cookies', lazy => 1);
50 if ( my $header = $self->header('Cookie') ) {
51 return { CGI::Simple::Cookie->parse($header) };
56 has query_keywords => (is => 'rw');
57 has match => (is => 'rw');
58 has method => (is => 'rw');
59 has protocol => (is => 'rw');
60 has query_parameters => (is => 'rw', default => sub { {} });
61 has secure => (is => 'rw', default => 0);
62 has captures => (is => 'rw', default => sub { [] });
63 has uri => (is => 'rw', predicate => 'has_uri');
64 has remote_user => (is => 'rw');
67 isa => 'HTTP::Headers',
68 handles => [qw(content_encoding content_length content_type header referer user_agent)],
69 builder => 'prepare_headers',
77 my $headers = HTTP::Headers->new();
79 for my $header (keys %{ $env }) {
80 next unless $header =~ /^(HTTP|CONTENT|COOKIE)/i;
81 (my $field = $header) =~ s/^HTTPS?_//;
83 $headers->header($field => $env->{$header});
94 # Amount of data to read from input on each pass
95 our $CHUNKSIZE = 64 * 1024;
98 my ($self, $maxlength) = @_;
99 my $remaining = $self->_read_length - $self->_read_position;
100 $maxlength ||= $CHUNKSIZE;
102 # Are we done reading?
103 if ( $remaining <= 0 ) {
107 my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
108 my $rc = $self->read_chunk( my $buffer, $readlen );
110 if (0 == $rc) { # Nothing more to read even though Content-Length
111 # said there should be.
114 $self->_set_read_position( $self->_read_position + $rc );
118 Catalyst::Exception->throw(
119 message => "Unknown error reading input: $!" );
125 return $self->env->{'psgi.input'}->read(@_);
128 has body_parameters => (
132 builder => 'prepare_body_parameters',
138 default => sub { {} },
144 builder => 'prepare_parameters',
148 # - Can we lose the before modifiers which just call prepare_body ?
149 # they are wasteful, slow us down and feel cluttery.
151 # Can we make _body an attribute, have the rest of
152 # these lazy build from there and kill all the direct hash access
153 # in Catalyst.pm and Engine.pm?
155 sub prepare_parameters {
158 my $body_parameters = $self->body_parameters;
159 my $query_parameters = $self->query_parameters;
160 # We copy, no references
161 foreach my $name (keys %$query_parameters) {
162 my $param = $query_parameters->{$name};
163 $parameters->{$name} = ref $param eq 'ARRAY' ? [ @$param ] : $param;
166 # Merge query and body parameters
167 foreach my $name (keys %$body_parameters) {
168 my $param = $body_parameters->{$name};
169 my @values = ref $param eq 'ARRAY' ? @$param : ($param);
170 if ( my $existing = $parameters->{$name} ) {
171 unshift(@values, (ref $existing eq 'ARRAY' ? @$existing : $existing));
173 $parameters->{$name} = @values > 1 ? \@values : $values[0];
180 predicate => '_has_uploadtmp',
186 if ( my $length = $self->_read_length ) {
187 unless ( $self->_body ) {
188 my $type = $self->header('Content-Type');
189 $self->_body(HTTP::Body->new( $type, $length ));
190 $self->_body->cleanup(1); # Make extra sure!
191 $self->_body->tmpdir( $self->_uploadtmp )
192 if $self->_has_uploadtmp;
195 # Check for definedness as you could read '0'
196 while ( defined ( my $buffer = $self->read() ) ) {
197 $self->prepare_body_chunk($buffer);
200 # paranoia against wrong Content-Length header
201 my $remaining = $length - $self->_read_position;
202 if ( $remaining > 0 ) {
203 Catalyst::Exception->throw(
204 "Wrong Content-Length value: $length" );
208 # Defined but will cause all body code to be skipped
213 sub prepare_body_chunk {
214 my ( $self, $chunk ) = @_;
216 $self->_body->add($chunk);
219 sub prepare_body_parameters {
222 $self->prepare_body if ! $self->_has_body;
223 return {} unless $self->_body;
225 return $self->_body->param;
228 sub prepare_connection {
231 my $env = $self->env;
233 $self->address( $env->{REMOTE_ADDR} );
234 $self->hostname( $env->{REMOTE_HOST} )
235 if exists $env->{REMOTE_HOST};
236 $self->protocol( $env->{SERVER_PROTOCOL} );
237 $self->remote_user( $env->{REMOTE_USER} );
238 $self->method( $env->{REQUEST_METHOD} );
239 $self->secure( $env->{'psgi.url_scheme'} eq 'https' ? 1 : 0 );
242 # XXX - FIXME - method is here now, move this crap...
243 around parameters => sub {
244 my ($orig, $self, $params) = @_;
246 if ( !ref $params ) {
248 "Attempt to retrieve '$params' with req->params(), " .
249 "you probably meant to call req->param('$params')"
253 return $self->$orig($params);
264 return $self->path if $self->has_uri;
269 is => 'rw', clearer => '_clear_body', predicate => '_has_body',
271 # Eugh, ugly. Should just be able to rename accessor methods to 'body'
272 # and provide a custom reader..
275 $self->prepare_body unless ! $self->_has_body;
276 croak 'body is a reader' if scalar @_;
277 return blessed $self->_body ? $self->_body->body : $self->_body;
286 gethostbyaddr( inet_aton( $self->address ), AF_INET ) || $self->address
290 has _path => ( is => 'rw', predicate => '_has_path', clearer => '_clear_path' );
292 sub args { shift->arguments(@_) }
293 sub body_params { shift->body_parameters(@_) }
294 sub input { shift->body(@_) }
295 sub params { shift->parameters(@_) }
296 sub query_params { shift->query_parameters(@_) }
297 sub path_info { shift->path(@_) }
299 =for stopwords param params
303 Catalyst::Request - provides information about the current client request
308 $req->address eq "127.0.0.1";
313 $req->body_parameters;
314 $req->content_encoding;
315 $req->content_length;
323 $req->query_keywords;
331 $req->query_parameters;
342 See also L<Catalyst>, L<Catalyst::Request::Upload>.
346 This is the Catalyst Request class, which provides an interface to data for the
347 current client request. The request object is prepared by L<Catalyst::Engine>,
348 thus hiding the details of the particular engine implementation.
354 Returns the IP address of the client.
356 =head2 $req->arguments
358 Returns a reference to an array containing the arguments.
360 print $c->request->arguments->[0];
362 For example, if your action was
364 package MyApp::Controller::Foo;
370 and the URI for the request was C<http://.../foo/moose/bah>, the string C<bah>
371 would be the first and only argument.
373 Arguments get automatically URI-unescaped for you.
377 Shortcut for L</arguments>.
381 Contains the URI base. This will always have a trailing slash. Note that the
382 URI scheme (e.g., http vs. https) must be determined through heuristics;
383 depending on your server configuration, it may be incorrect. See $req->secure
386 If your application was queried with the URI
387 C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
391 Returns the message body of the request, as returned by L<HTTP::Body>: a string,
392 unless Content-Type is C<application/x-www-form-urlencoded>, C<text/xml>, or
393 C<multipart/form-data>, in which case a L<File::Temp> object is returned.
395 =head2 $req->body_parameters
397 Returns a reference to a hash containing body (POST) parameters. Values can
398 be either a scalar or an arrayref containing scalars.
400 print $c->request->body_parameters->{field};
401 print $c->request->body_parameters->{field}->[0];
403 These are the parameters from the POST part of the request, if any.
405 =head2 $req->body_params
407 Shortcut for body_parameters.
409 =head2 $req->content_encoding
411 Shortcut for $req->headers->content_encoding.
413 =head2 $req->content_length
415 Shortcut for $req->headers->content_length.
417 =head2 $req->content_type
419 Shortcut for $req->headers->content_type.
423 A convenient method to access $req->cookies.
425 $cookie = $c->request->cookie('name');
426 @cookies = $c->request->cookie;
434 return keys %{ $self->cookies };
441 unless ( exists $self->cookies->{$name} ) {
445 return $self->cookies->{$name};
451 Returns a reference to a hash containing the cookies.
453 print $c->request->cookies->{mycookie}->value;
455 The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
460 Shortcut for $req->headers->header.
464 Returns an L<HTTP::Headers> object containing the headers for the current request.
466 print $c->request->headers->header('X-Catalyst');
468 =head2 $req->hostname
470 Returns the hostname of the client. Use C<< $req->uri->host >> to get the hostname of the server.
474 Alias for $req->body.
476 =head2 $req->query_keywords
478 Contains the keywords portion of a query string, when no '=' signs are
481 http://localhost/path?some+keywords
483 $c->request->query_keywords will contain 'some keywords'
487 This contains the matching part of a Regex action. Otherwise
488 it returns the same as 'action', except for default actions,
489 which return an empty string.
493 Contains the request method (C<GET>, C<POST>, C<HEAD>, etc).
497 Returns GET and POST parameters with a CGI.pm-compatible param method. This
498 is an alternative method for accessing parameters in $c->req->parameters.
500 $value = $c->request->param( 'foo' );
501 @values = $c->request->param( 'foo' );
502 @params = $c->request->param;
504 Like L<CGI>, and B<unlike> earlier versions of Catalyst, passing multiple
505 arguments to this method, like this:
507 $c->request->param( 'foo', 'bar', 'gorch', 'quxx' );
509 will set the parameter C<foo> to the multiple values C<bar>, C<gorch> and
510 C<quxx>. Previously this would have added C<bar> as another value to C<foo>
511 (creating it if it didn't exist before), and C<quxx> as another value for
514 B<NOTE> this is considered a legacy interface and care should be taken when
515 using it. C<< scalar $c->req->param( 'foo' ) >> will return only the first
516 C<foo> param even if multiple are present; C<< $c->req->param( 'foo' ) >> will
517 return a list of as many are present, which can have unexpected consequences
518 when writing code of the form:
522 baz => $c->req->param( 'baz' ),
525 If multiple C<baz> parameters are provided this code might corrupt data or
526 cause a hash initialization error. For a more straightforward interface see
527 C<< $c->req->parameters >>.
535 return keys %{ $self->parameters };
542 unless ( exists $self->parameters->{$param} ) {
543 return wantarray ? () : undef;
546 if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
548 ? @{ $self->parameters->{$param} }
549 : $self->parameters->{$param}->[0];
553 ? ( $self->parameters->{$param} )
554 : $self->parameters->{$param};
559 $self->parameters->{$field} = [@_];
563 =head2 $req->parameters
565 Returns a reference to a hash containing GET and POST parameters. Values can
566 be either a scalar or an arrayref containing scalars.
568 print $c->request->parameters->{field};
569 print $c->request->parameters->{field}->[0];
571 This is the combination of C<query_parameters> and C<body_parameters>.
575 Shortcut for $req->parameters.
579 Returns the path, i.e. the part of the URI after $req->base, for the current request.
581 http://localhost/path/foo
583 $c->request->path will contain 'path/foo'
585 =head2 $req->path_info
587 Alias for path, added for compatibility with L<CGI>.
592 my ( $self, @params ) = @_;
595 $self->uri->path(@params);
598 elsif ( $self->_has_path ) {
602 my $path = $self->uri->path;
603 my $location = $self->base->path;
604 $path =~ s/^(\Q$location\E)?//;
612 =head2 $req->protocol
614 Returns the protocol (HTTP/1.0 or HTTP/1.1) used for the current request.
616 =head2 $req->query_parameters
618 =head2 $req->query_params
620 Returns a reference to a hash containing query string (GET) parameters. Values can
621 be either a scalar or an arrayref containing scalars.
623 print $c->request->query_parameters->{field};
624 print $c->request->query_parameters->{field}->[0];
626 =head2 $req->read( [$maxlength] )
628 Reads a chunk of data from the request body. This method is intended to be
629 used in a while loop, reading $maxlength bytes on every call. $maxlength
630 defaults to the size of the request if not specified.
632 =head2 $req->read_chunk(\$buff, $max)
636 You have to set MyApp->config(parse_on_demand => 1) to use this directly.
640 Shortcut for $req->headers->referer. Returns the referring page.
644 Returns true or false, indicating whether the connection is secure
645 (https). Note that the URI scheme (e.g., http vs. https) must be determined
646 through heuristics, and therefore the reliability of $req->secure will depend
647 on your server configuration. If you are setting the HTTPS environment variable,
648 $req->secure should be valid.
650 =head2 $req->captures
652 Returns a reference to an array containing captured args from chained
653 actions or regex captures.
655 my @captures = @{ $c->request->captures };
659 A convenient method to access $req->uploads.
661 $upload = $c->request->upload('field');
662 @uploads = $c->request->upload('field');
663 @fields = $c->request->upload;
665 for my $upload ( $c->request->upload('field') ) {
666 print $upload->filename;
675 return keys %{ $self->uploads };
682 unless ( exists $self->uploads->{$upload} ) {
683 return wantarray ? () : undef;
686 if ( ref $self->uploads->{$upload} eq 'ARRAY' ) {
688 ? @{ $self->uploads->{$upload} }
689 : $self->uploads->{$upload}->[0];
693 ? ( $self->uploads->{$upload} )
694 : $self->uploads->{$upload};
700 while ( my ( $field, $upload ) = splice( @_, 0, 2 ) ) {
702 if ( exists $self->uploads->{$field} ) {
703 for ( $self->uploads->{$field} ) {
704 $_ = [$_] unless ref($_) eq "ARRAY";
705 push( @$_, $upload );
709 $self->uploads->{$field} = $upload;
717 Returns a reference to a hash containing uploads. Values can be either a
718 L<Catalyst::Request::Upload> object, or an arrayref of
719 L<Catalyst::Request::Upload> objects.
721 my $upload = $c->request->uploads->{field};
722 my $upload = $c->request->uploads->{field}->[0];
726 Returns a L<URI> object for the current request. Stringifies to the URI text.
728 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
730 Returns a hashref of parameters stemming from the current request's params,
731 plus the ones supplied. Keys for which no current param exists will be
732 added, keys with undefined values will be removed and keys with existing
733 params will be replaced. Note that you can supply a true value as the final
734 argument to change behavior with regards to existing parameters, appending
735 values rather than replacing them.
739 # URI query params foo=1
740 my $hashref = $req->mangle_params({ foo => 2 });
741 # Result is query params of foo=2
745 # URI query params foo=1
746 my $hashref = $req->mangle_params({ foo => 2 }, 1);
747 # Result is query params of foo=1&foo=2
749 This is the code behind C<uri_with>.
754 my ($self, $args, $append) = @_;
756 carp('No arguments passed to mangle_params()') unless $args;
758 foreach my $value ( values %$args ) {
759 next unless defined $value;
760 for ( ref $value eq 'ARRAY' ? @$value : $value ) {
762 utf8::encode( $_ ) if utf8::is_utf8($_);
766 my %params = %{ $self->uri->query_form_hash };
767 foreach my $key (keys %{ $args }) {
768 my $val = $args->{$key};
771 if($append && exists($params{$key})) {
773 # This little bit of heaven handles appending a new value onto
774 # an existing one regardless if the existing value is an array
775 # or not, and regardless if the new value is an array or not
777 ref($params{$key}) eq 'ARRAY' ? @{ $params{$key} } : $params{$key},
778 ref($val) eq 'ARRAY' ? @{ $val } : $val
782 $params{$key} = $val;
786 # If the param wasn't defined then we delete it.
787 delete($params{$key});
795 =head2 $req->uri_with( { key => 'value' } );
797 Returns a rewritten URI object for the current request. Key/value pairs
798 passed in will override existing parameters. You can remove an existing
799 parameter by passing in an undef value. Unmodified pairs will be
802 You may also pass an optional second parameter that puts C<uri_with> into
805 $req->uri_with( { key => 'value' }, { mode => 'append' } );
807 See C<mangle_params> for an explanation of this behavior.
812 my( $self, $args, $behavior) = @_;
814 carp( 'No arguments passed to uri_with()' ) unless $args;
817 if((ref($behavior) eq 'HASH') && defined($behavior->{mode}) && ($behavior->{mode} eq 'append')) {
821 my $params = $self->mangle_params($args, $append);
823 my $uri = $self->uri->clone;
824 $uri->query_form($params);
829 =head2 $req->remote_user
831 Returns the value of the C<REMOTE_USER> environment variable.
833 =head2 $req->user_agent
835 Shortcut to $req->headers->user_agent. Returns the user agent (browser)
840 You should never need to call these yourself in application code,
841 however they are useful if extending Catalyst by applying a request role.
843 =head2 $self->prepare_headers()
845 Sets up the C<< $res->headers >> accessor.
847 =head2 $self->prepare_body()
849 Sets up the body using L<HTTP::Body>
851 =head2 $self->prepare_body_chunk()
853 Add a chunk to the request body.
855 =head2 $self->prepare_body_parameters()
857 Sets up parameters from body.
859 =head2 $self->prepare_cookies()
861 Parse cookies from header. Sets up a L<CGI::Simple::Cookie> object.
863 =head2 $self->prepare_connection()
865 Sets up various fields in the request like the local and remote addresses,
866 request method, hostname requested etc.
868 =head2 $self->prepare_parameters()
870 Ensures that the body has been parsed, then builds the parameters, which are
871 combined from those in the request and those in the body.
873 This method is the builder for the 'parameters' attribute.
881 Catalyst Contributors, see Catalyst.pm
885 This library is free software. You can redistribute it and/or modify
886 it under the same terms as Perl itself.
890 __PACKAGE__->meta->make_immutable;