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