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