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