Fix the RV of the first call to ->config
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Request.pm
CommitLineData
fc7ec1d9 1package Catalyst::Request;
2
3use strict;
4use base 'Class::Accessor::Fast';
5
b4ca0ee8 6use IO::Socket qw[AF_INET inet_aton];
bd917b94 7use Carp;
fc42a730 8use utf8;
e669e88a 9use URI::QueryParam;
b4ca0ee8 10
fc7ec1d9 11__PACKAGE__->mk_accessors(
8b76bfcf 12 qw/action address arguments cookies headers match method
7ce7ca2e 13 protocol query_parameters secure snippets uri user/
fc7ec1d9 14);
15
fbcc39ad 16*args = \&arguments;
17*body_params = \&body_parameters;
18*input = \&body;
19*params = \&parameters;
20*query_params = \&query_parameters;
21*path_info = \&path;
fc7ec1d9 22
f7e4e231 23sub content_encoding { shift->headers->content_encoding(@_) }
fbcc39ad 24sub content_length { shift->headers->content_length(@_) }
25sub content_type { shift->headers->content_type(@_) }
26sub header { shift->headers->header(@_) }
27sub referer { shift->headers->referer(@_) }
28sub user_agent { shift->headers->user_agent(@_) }
f7e4e231 29
fc7ec1d9 30=head1 NAME
31
3e19f4f6 32Catalyst::Request - provides information about the current client request
fc7ec1d9 33
34=head1 SYNOPSIS
35
b22c6668 36 $req = $c->request;
37 $req->action;
38 $req->address;
b22c6668 39 $req->arguments;
3e19f4f6 40 $req->args;
b22c6668 41 $req->base;
06e1b616 42 $req->body;
fbcc39ad 43 $req->body_parameters;
b5176d9e 44 $req->content_encoding;
45 $req->content_length;
46 $req->content_type;
b77e7869 47 $req->cookie;
b22c6668 48 $req->cookies;
b5176d9e 49 $req->header;
b22c6668 50 $req->headers;
51 $req->hostname;
61bacdcc 52 $req->input;
b22c6668 53 $req->match;
54 $req->method;
e7c0c583 55 $req->param;
e7c0c583 56 $req->parameters;
3e19f4f6 57 $req->params;
b22c6668 58 $req->path;
bfde09a2 59 $req->protocol;
fbcc39ad 60 $req->query_parameters;
61 $req->read;
b5176d9e 62 $req->referer;
bfde09a2 63 $req->secure;
b22c6668 64 $req->snippets;
e7c0c583 65 $req->upload;
b22c6668 66 $req->uploads;
77d12cae 67 $req->uri;
7ce7ca2e 68 $req->user;
66294129 69 $req->user_agent;
b22c6668 70
3e22baa5 71See also L<Catalyst>, L<Catalyst::Request::Upload>.
fc7ec1d9 72
73=head1 DESCRIPTION
74
3e19f4f6 75This is the Catalyst Request class, which provides an interface to data for the
76current client request. The request object is prepared by L<Catalyst::Engine>,
77thus hiding the details of the particular engine implementation.
b22c6668 78
79=head1 METHODS
fc7ec1d9 80
b5ecfcf0 81=head2 $req->action
fc7ec1d9 82
3e19f4f6 83Returns the requested action as a L<Catalyst::Action> object.
fc7ec1d9 84
b5ecfcf0 85=head2 $req->address
0556eb49 86
3e19f4f6 87Returns the IP address of the client.
61b1e958 88
b5ecfcf0 89=head2 $req->arguments
61b1e958 90
b22c6668 91Returns a reference to an array containing the arguments.
fc7ec1d9 92
93 print $c->request->arguments->[0];
94
c436c1e8 95For example, if your action was
96
97 package MyApp::C::Foo;
98
99 sub moose : Local {
100 ...
101 }
102
3e19f4f6 103and the URI for the request was C<http://.../foo/moose/bah>, the string C<bah>
c436c1e8 104would be the first and only argument.
105
b5ecfcf0 106=head2 $req->args
3e19f4f6 107
108Shortcut for arguments.
109
b5ecfcf0 110=head2 $req->base
fc7ec1d9 111
c436c1e8 112Contains the URI base. This will always have a trailing slash.
113
3e19f4f6 114If your application was queried with the URI
115C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
fc7ec1d9 116
e561386f 117=cut
118
119sub base {
120 my ( $self, $base ) = @_;
6aa02946 121
e561386f 122 return $self->{base} unless $base;
6aa02946 123
e561386f 124 $self->{base} = $base;
6aa02946 125
e561386f 126 # set the value in path for backwards-compat
127 if ( $self->uri ) {
128 $self->path;
129 }
6aa02946 130
e561386f 131 return $self->{base};
132}
133
b5ecfcf0 134=head2 $req->body
06e1b616 135
3e19f4f6 136Returns the message body of the request, unless Content-Type is
e060fe05 137C<application/x-www-form-urlencoded> or C<multipart/form-data>.
138
fbcc39ad 139=cut
140
141sub body {
142 my ( $self, $body ) = @_;
143 $self->{_context}->prepare_body;
144 return $self->{_body}->body;
145}
146
b5ecfcf0 147=head2 $req->body_parameters
fbcc39ad 148
3e19f4f6 149Returns a reference to a hash containing body (POST) parameters. Values can
fbcc39ad 150be either a scalar or an arrayref containing scalars.
151
152 print $c->request->body_parameters->{field};
153 print $c->request->body_parameters->{field}->[0];
c436c1e8 154
d631b5f9 155These are the parameters from the POST part of the request, if any.
fbcc39ad 156
b5ecfcf0 157=head2 $req->body_params
fbcc39ad 158
3e19f4f6 159Shortcut for body_parameters.
fbcc39ad 160
161=cut
162
163sub body_parameters {
164 my ( $self, $params ) = @_;
165 $self->{_context}->prepare_body;
166 $self->{body_parameters} = $params if $params;
167 return $self->{body_parameters};
168}
169
b5ecfcf0 170=head2 $req->content_encoding
b5176d9e 171
3e19f4f6 172Shortcut for $req->headers->content_encoding.
b5176d9e 173
b5ecfcf0 174=head2 $req->content_length
b5176d9e 175
3e19f4f6 176Shortcut for $req->headers->content_length.
b5176d9e 177
b5ecfcf0 178=head2 $req->content_type
b5176d9e 179
3e19f4f6 180Shortcut for $req->headers->content_type.
b5176d9e 181
b5ecfcf0 182=head2 $req->cookie
3ad654e0 183
3e19f4f6 184A convenient method to access $req->cookies.
3ad654e0 185
186 $cookie = $c->request->cookie('name');
187 @cookies = $c->request->cookie;
188
189=cut
190
191sub cookie {
192 my $self = shift;
193
194 if ( @_ == 0 ) {
b77e7869 195 return keys %{ $self->cookies };
3ad654e0 196 }
197
198 if ( @_ == 1 ) {
199
200 my $name = shift;
201
b77e7869 202 unless ( exists $self->cookies->{$name} ) {
3ad654e0 203 return undef;
204 }
fbcc39ad 205
b77e7869 206 return $self->cookies->{$name};
3ad654e0 207 }
208}
209
b5ecfcf0 210=head2 $req->cookies
fc7ec1d9 211
b22c6668 212Returns a reference to a hash containing the cookies.
fc7ec1d9 213
214 print $c->request->cookies->{mycookie}->value;
215
3e19f4f6 216The cookies in the hash are indexed by name, and the values are L<CGI::Cookie>
c436c1e8 217objects.
218
b5ecfcf0 219=head2 $req->header
b5176d9e 220
3e19f4f6 221Shortcut for $req->headers->header.
b5176d9e 222
b5ecfcf0 223=head2 $req->headers
fc7ec1d9 224
3e19f4f6 225Returns an L<HTTP::Headers> object containing the headers for the current request.
fc7ec1d9 226
227 print $c->request->headers->header('X-Catalyst');
228
b5ecfcf0 229=head2 $req->hostname
0556eb49 230
3e19f4f6 231Returns the hostname of the client.
b4ca0ee8 232
233=cut
234
235sub hostname {
236 my $self = shift;
237
a268a011 238 if ( @_ == 0 && not $self->{hostname} ) {
fbcc39ad 239 $self->{hostname} =
240 gethostbyaddr( inet_aton( $self->address ), AF_INET );
b4ca0ee8 241 }
242
a268a011 243 if ( @_ == 1 ) {
244 $self->{hostname} = shift;
b4ca0ee8 245 }
246
247 return $self->{hostname};
248}
0556eb49 249
b5ecfcf0 250=head2 $req->input
61bacdcc 251
3e19f4f6 252Alias for $req->body.
61bacdcc 253
b5ecfcf0 254=head2 $req->match
fc7ec1d9 255
3e19f4f6 256This contains the matching part of a Regex action. Otherwise
2c83fd5a 257it returns the same as 'action', except for default actions,
258which return an empty string.
fc7ec1d9 259
b5ecfcf0 260=head2 $req->method
b5176d9e 261
262Contains the request method (C<GET>, C<POST>, C<HEAD>, etc).
263
b5ecfcf0 264=head2 $req->param
e7c0c583 265
3e19f4f6 266Returns GET and POST parameters with a CGI.pm-compatible param method. This
267is an alternative method for accessing parameters in $c->req->parameters.
e7c0c583 268
a82c2894 269 $value = $c->request->param( 'foo' );
270 @values = $c->request->param( 'foo' );
e7c0c583 271 @params = $c->request->param;
272
3e705254 273Like L<CGI>, and B<unlike> earlier versions of Catalyst, passing multiple
a82c2894 274arguments to this method, like this:
275
3e705254 276 $c->request->param( 'foo', 'bar', 'gorch', 'quxx' );
a82c2894 277
278will set the parameter C<foo> to the multiple values C<bar>, C<gorch> and
279C<quxx>. Previously this would have added C<bar> as another value to C<foo>
3e19f4f6 280(creating it if it didn't exist before), and C<quxx> as another value for
281C<gorch>.
a82c2894 282
e7c0c583 283=cut
284
285sub param {
286 my $self = shift;
287
288 if ( @_ == 0 ) {
289 return keys %{ $self->parameters };
290 }
291
bfde09a2 292 if ( @_ == 1 ) {
e7c0c583 293
bfde09a2 294 my $param = shift;
6bd2b72c 295
bfde09a2 296 unless ( exists $self->parameters->{$param} ) {
297 return wantarray ? () : undef;
298 }
299
300 if ( ref $self->parameters->{$param} eq 'ARRAY' ) {
301 return (wantarray)
302 ? @{ $self->parameters->{$param} }
303 : $self->parameters->{$param}->[0];
304 }
305 else {
306 return (wantarray)
307 ? ( $self->parameters->{$param} )
308 : $self->parameters->{$param};
309 }
d7945f32 310 }
a82c2894 311 elsif ( @_ > 1 ) {
312 my $field = shift;
313 $self->parameters->{$field} = [@_];
d7945f32 314 }
e7c0c583 315}
b5176d9e 316
b5ecfcf0 317=head2 $req->parameters
61b1e958 318
3e19f4f6 319Returns a reference to a hash containing GET and POST parameters. Values can
d08ced28 320be either a scalar or an arrayref containing scalars.
fc7ec1d9 321
e7c0c583 322 print $c->request->parameters->{field};
323 print $c->request->parameters->{field}->[0];
fc7ec1d9 324
c436c1e8 325This is the combination of C<query_parameters> and C<body_parameters>.
326
b5ecfcf0 327=head2 $req->params
3e19f4f6 328
329Shortcut for $req->parameters.
330
fbcc39ad 331=cut
332
333sub parameters {
334 my ( $self, $params ) = @_;
335 $self->{_context}->prepare_body;
ee26f4bd 336 if ( $params ) {
337 if ( ref $params ) {
338 $self->{parameters} = $params;
339 }
340 else {
341 $self->{_context}->log->warn(
342 "Attempt to retrieve '$params' with req->params(), " .
343 "you probably meant to call req->param('$params')" );
344 }
345 }
fbcc39ad 346 return $self->{parameters};
347}
348
b5ecfcf0 349=head2 $req->path
fc7ec1d9 350
3e19f4f6 351Returns the path, i.e. the part of the URI after $req->base, for the current request.
fc7ec1d9 352
b5ecfcf0 353=head2 $req->path_info
fbcc39ad 354
3e19f4f6 355Alias for path, added for compability with L<CGI>.
fbcc39ad 356
357=cut
358
359sub path {
360 my ( $self, $params ) = @_;
4f5ebacd 361
362 if ($params) {
4f5ebacd 363 $self->uri->path($params);
fbcc39ad 364 }
e561386f 365 else {
366 return $self->{path} if $self->{path};
367 }
fbcc39ad 368
4f5ebacd 369 my $path = $self->uri->path;
fbcc39ad 370 my $location = $self->base->path;
371 $path =~ s/^(\Q$location\E)?//;
fbcc39ad 372 $path =~ s/^\///;
e561386f 373 $self->{path} = $path;
4f5ebacd 374
fbcc39ad 375 return $path;
376}
377
b5ecfcf0 378=head2 $req->protocol
bfde09a2 379
3e19f4f6 380Returns the protocol (HTTP/1.0 or HTTP/1.1) used for the current request.
bfde09a2 381
b5ecfcf0 382=head2 $req->query_parameters
fbcc39ad 383
3e19f4f6 384Returns a reference to a hash containing query string (GET) parameters. Values can
fbcc39ad 385be either a scalar or an arrayref containing scalars.
386
387 print $c->request->query_parameters->{field};
388 print $c->request->query_parameters->{field}->[0];
389
b5ecfcf0 390=head2 $req->read( [$maxlength] )
fbcc39ad 391
3e19f4f6 392Reads a chunk of data from the request body. This method is intended to be
393used in a while loop, reading $maxlength bytes on every call. $maxlength
fbcc39ad 394defaults to the size of the request if not specified.
395
396You have to set MyApp->config->{parse_on_demand} to use this directly.
397
398=cut
399
400sub read { shift->{_context}->read(@_); }
401
b5ecfcf0 402=head2 $req->referer
fc7ec1d9 403
3e19f4f6 404Shortcut for $req->headers->referer. Returns the referring page.
fc7ec1d9 405
b5ecfcf0 406=head2 $req->secure
bfde09a2 407
3e19f4f6 408Returns true or false, indicating whether the connection is secure (https).
bfde09a2 409
b5ecfcf0 410=head2 $req->snippets
fc7ec1d9 411
b22c6668 412Returns a reference to an array containing regex snippets.
fc7ec1d9 413
414 my @snippets = @{ $c->request->snippets };
415
b5ecfcf0 416=head2 $req->upload
e7c0c583 417
3e19f4f6 418A convenient method to access $req->uploads.
e7c0c583 419
420 $upload = $c->request->upload('field');
421 @uploads = $c->request->upload('field');
422 @fields = $c->request->upload;
bfde09a2 423
e7c0c583 424 for my $upload ( $c->request->upload('field') ) {
146554c5 425 print $upload->filename;
e7c0c583 426 }
427
428=cut
429
430sub upload {
431 my $self = shift;
432
433 if ( @_ == 0 ) {
434 return keys %{ $self->uploads };
435 }
436
bfde09a2 437 if ( @_ == 1 ) {
e7c0c583 438
bfde09a2 439 my $upload = shift;
440
441 unless ( exists $self->uploads->{$upload} ) {
442 return wantarray ? () : undef;
443 }
6bd2b72c 444
bfde09a2 445 if ( ref $self->uploads->{$upload} eq 'ARRAY' ) {
446 return (wantarray)
447 ? @{ $self->uploads->{$upload} }
448 : $self->uploads->{$upload}->[0];
449 }
450 else {
451 return (wantarray)
fbcc39ad 452 ? ( $self->uploads->{$upload} )
453 : $self->uploads->{$upload};
bfde09a2 454 }
d7945f32 455 }
bfde09a2 456
a4f5c51e 457 if ( @_ > 1 ) {
bfde09a2 458
459 while ( my ( $field, $upload ) = splice( @_, 0, 2 ) ) {
460
461 if ( exists $self->uploads->{$field} ) {
462 for ( $self->uploads->{$field} ) {
463 $_ = [$_] unless ref($_) eq "ARRAY";
464 push( @$_, $upload );
465 }
466 }
467 else {
468 $self->uploads->{$field} = $upload;
469 }
470 }
e7c0c583 471 }
472}
473
b5ecfcf0 474=head2 $req->uploads
fc7ec1d9 475
bfde09a2 476Returns a reference to a hash containing uploads. Values can be either a
3e19f4f6 477hashref or a arrayref containing L<Catalyst::Request::Upload> objects.
e7c0c583 478
479 my $upload = $c->request->uploads->{field};
480 my $upload = $c->request->uploads->{field}->[0];
481
77d12cae 482=cut
483
fbcc39ad 484sub uploads {
485 my ( $self, $uploads ) = @_;
486 $self->{_context}->prepare_body;
487 $self->{uploads} = $uploads if $uploads;
488 return $self->{uploads};
77d12cae 489}
490
b5ecfcf0 491=head2 $req->uri
fbcc39ad 492
3e19f4f6 493Returns a URI object for the current request. Stringifies to the URI text.
fbcc39ad 494
bd917b94 495=head2 $req->uri_with( { key => 'value' } );
496
497Returns a rewriten URI object for the current uri. Key/value pairs passed in
498will override existing parameters. Unmodified pairs will be preserved.
499
500=cut
501
502sub uri_with {
503 my( $self, $args ) = @_;
504
505 carp( 'No arguments passed to uri_with()' ) unless $args;
506
fc42a730 507 for my $value ( values %$args ) {
508 my $isa_ref = ref $value;
509 if( $isa_ref and $isa_ref ne 'ARRAY' ) {
510 croak( "Non-array reference ($isa_ref) passed to uri_with()" );
511 }
0e8ab4ca 512 utf8::encode( $_ ) for grep{ defined } $isa_ref ? @$value : $value;
fc42a730 513 };
bd917b94 514 my $uri = $self->uri->clone;
515
516 $uri->query_form( {
27d9619a 517 %{ $uri->query_form_hash },
bd917b94 518 %$args
519 } );
520 return $uri;
521}
522
b5ecfcf0 523=head2 $req->user
7ce7ca2e 524
3e19f4f6 525Returns the currently logged in user. Deprecated. The method recommended for
526newer plugins is $c->user.
7ce7ca2e 527
b5ecfcf0 528=head2 $req->user_agent
b5176d9e 529
3e19f4f6 530Shortcut to $req->headers->user_agent. Returns the user agent (browser)
531version string.
b5176d9e 532
3e19f4f6 533=head1 AUTHORS
fc7ec1d9 534
535Sebastian Riedel, C<sri@cpan.org>
3e19f4f6 536
61b1e958 537Marcus Ramberg, C<mramberg@cpan.org>
fc7ec1d9 538
539=head1 COPYRIGHT
540
e7c0c583 541This program is free software, you can redistribute it and/or modify
61b1e958 542it under the same terms as Perl itself.
fc7ec1d9 543
544=cut
545
5461;