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