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