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