b27da58ab1052d05ccd68dd7be7d19e4dacf05bf
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Response.pm
1 package Catalyst::Response;
2
3 use Moose;
4 use HTTP::Headers;
5 use Moose::Util::TypeConstraints;
6 use namespace::autoclean;
7 use Scalar::Util 'blessed';
8 use Catalyst::Response::Writer;
9 use Catalyst::Utils ();
10
11 with 'MooseX::Emulate::Class::Accessor::Fast';
12
13 our $DEFAULT_ENCODE_CONTENT_TYPE_MATCH = qr{text|xml$|javascript$};
14
15 has encodable_content_type => (
16     is => 'rw',
17     required => 1,
18     default => sub { $DEFAULT_ENCODE_CONTENT_TYPE_MATCH }
19 );
20
21 has _response_cb => (
22     is      => 'ro',
23     isa     => 'CodeRef', 
24     writer  => '_set_response_cb',
25     clearer => '_clear_response_cb',
26     predicate => '_has_response_cb',
27 );
28
29 subtype 'Catalyst::Engine::Types::Writer',
30     as duck_type([qw(write close)]);
31
32 has _writer => (
33     is      => 'ro',
34     isa     => 'Catalyst::Engine::Types::Writer', #Pointless since we control how this is built
35     #writer  => '_set_writer', Now that its lazy I think this is safe to remove
36     clearer => '_clear_writer',
37     predicate => '_has_writer',
38     lazy      => 1,
39     builder => '_build_writer',
40 );
41
42 sub _build_writer {
43     my $self = shift;
44
45     ## These two lines are probably crap now...
46     $self->_context->finalize_headers unless
47       $self->finalized_headers;
48
49     my @headers;
50     $self->headers->scan(sub { push @headers, @_ });
51
52     my $writer = $self->_response_cb->([ $self->status, \@headers ]);
53     $self->_clear_response_cb;
54
55     return $writer;
56 }
57
58 has write_fh => (
59   is=>'ro',
60   predicate=>'_has_write_fh',
61   lazy=>1,
62   builder=>'_build_write_fh',
63 );
64
65 sub _build_write_fh {
66   my $writer = $_[0]->_writer; # We need to get the finalize headers side effect...
67   my $requires_encoding = $_[0]->encodable_response;
68   my %fields = (
69     _writer => $writer,
70     _context => $_[0]->_context,
71     _requires_encoding => $requires_encoding,
72   );
73
74   return bless \%fields, 'Catalyst::Response::Writer';
75 }
76
77 sub DEMOLISH {
78   my $self = shift;
79   return if $self->_has_write_fh;
80   if($self->_has_writer) {
81     $self->_writer->close
82   }
83 }
84
85 has cookies   => (is => 'rw', default => sub { {} });
86 has body      => (is => 'rw', default => undef);
87 sub has_body { defined($_[0]->body) }
88
89 has location  => (is => 'rw');
90 has status    => (is => 'rw', default => 200);
91 has finalized_headers => (is => 'rw', default => 0);
92 has headers   => (
93   is      => 'rw',
94   isa => 'HTTP::Headers',
95   handles => [qw(content_encoding content_length content_type content_type_charset header)],
96   default => sub { HTTP::Headers->new() },
97   required => 1,
98   lazy => 1,
99 );
100 has _context => (
101   is => 'rw',
102   weak_ref => 1,
103   clearer => '_clear_context',
104 );
105
106 before [qw(status headers content_encoding content_length content_type header)] => sub {
107   my $self = shift;
108
109   $self->_context->log->warn( 
110     "Useless setting a header value after finalize_headers and the response callback has been called." .
111     " Not what you want." )
112       if ( $self->finalized_headers && !$self->_has_response_cb && @_ );
113 };
114
115 sub output { shift->body(@_) }
116
117 sub code   { shift->status(@_) }
118
119 sub write {
120     my ( $self, $buffer ) = @_;
121
122     # Finalize headers if someone manually writes output
123     $self->_context->finalize_headers unless $self->finalized_headers;
124
125     $buffer = q[] unless defined $buffer;
126
127     if($self->encodable_response) {
128       $buffer = $self->_context->encoding->encode( $buffer, $self->_context->_encode_check )
129     }
130
131     my $len = length($buffer);
132     $self->_writer->write($buffer);
133
134     return $len;
135 }
136
137 sub finalize_headers {
138     my ($self) = @_;
139     return;
140 }
141
142 sub from_psgi_response {
143     my ($self, $psgi_res) = @_;
144     if(blessed($psgi_res) && $psgi_res->can('as_psgi')) {
145       $psgi_res = $psgi_res->as_psgi;
146     }
147     if(ref $psgi_res eq 'ARRAY') {
148         my ($status, $headers, $body) = @$psgi_res;
149         $self->status($status);
150         $self->headers(HTTP::Headers->new(@$headers));
151         $self->body(join('', @$body));
152     } elsif(ref $psgi_res eq 'CODE') {
153         $psgi_res->(sub {
154             my $response = shift;
155             my ($status, $headers, $maybe_body) = @$response;
156             $self->status($status);
157             $self->headers(HTTP::Headers->new(@$headers));
158             if(defined $maybe_body) {
159                 $self->body(join('', @$maybe_body));
160             } else {
161                 return $self->write_fh;
162             }
163         });  
164      } else {
165         die "You can't set a Catalyst response from that, expect a valid PSGI response";
166     }
167
168     # Encoding compatibilty.   If the response set a charset, well... we need
169     # to assume its properly encoded and NOT encode for this response.  Otherwise
170     # We risk double encoding.
171     if($self->content_type_charset) {
172       $self->_context->clear_encoding;
173     }
174 }
175
176 =head1 NAME
177
178 Catalyst::Response - stores output responding to the current client request
179
180 =head1 SYNOPSIS
181
182     $res = $c->response;
183     $res->body;
184     $res->code;
185     $res->content_encoding;
186     $res->content_length;
187     $res->content_type;
188     $res->cookies;
189     $res->header;
190     $res->headers;
191     $res->output;
192     $res->redirect;
193     $res->status;
194     $res->write;
195
196 =head1 DESCRIPTION
197
198 This is the Catalyst Response class, which provides methods for responding to
199 the current client request. The appropriate L<Catalyst::Engine> for your environment
200 will turn the Catalyst::Response into a HTTP Response and return it to the client.
201
202 =head1 METHODS
203
204 =head2 $res->body( $text | $fh | $iohandle_object )
205
206     $c->response->body('Catalyst rocks!');
207
208 Sets or returns the output (text or binary data). If you are returning a large body,
209 you might want to use a L<IO::Handle> type of object (Something that implements the getline method 
210 in the same fashion), or a filehandle GLOB. These will be passed down to the PSGI
211 handler you are using and might be optimized using server specific abilities (for
212 example L<Twiggy> will attempt to server a real local file in a non blocking manner).
213
214 If you are using a filehandle as the body response you are responsible for
215 making sure it conforms to the L<PSGI> specification with regards to content
216 encoding.  Unlike with scalar body values or when using the streaming interfaces
217 we currently do not attempt to normalize and encode your filehandle.  In general
218 this means you should be sure to be sending bytes not UTF8 decoded multibyte
219 characters.
220
221 Most of the time when you do:
222
223     open(my $fh, '<:raw', $path);
224
225 You should be fine.  If you open a filehandle with a L<PerlIO> layer you probably
226 are not fine.  You can usually fix this by explicitly using binmode to set
227 the IOLayer to :raw.  Its possible future versions of L<Catalyst> will try to
228 'do the right thing'.
229
230 When using a L<IO::Handle> type of object and no content length has been
231 already set in the response headers Catalyst will make a reasonable attempt
232 to determine the size of the Handle. Depending on the implementation of your
233 handle object, setting the content length may fail. If it is at all possible
234 for you to determine the content length of your handle object, 
235 it is recommended that you set the content length in the response headers
236 yourself, which will be respected and sent by Catalyst in the response.
237
238 Please note that the object needs to implement C<getline>, not just
239 C<read>.  Older versions of L<Catalyst> expected your filehandle like objects
240 to do read.  If you have code written for this expectation and you cannot
241 change the code to meet the L<PSGI> specification, you can try the following
242 middleware L<Plack::Middleware::AdaptFilehandleRead> which will attempt to
243 wrap your object in an interface that so conforms.
244
245 Starting from version 5.90060, when using an L<IO::Handle> object, you
246 may want to use L<Plack::Middleware::XSendfile>, to delegate the
247 actual serving to the frontend server. To do so, you need to pass to
248 C<body> an IO object with a C<path> method. This can be achieved in
249 two ways.
250
251 Either using L<Plack::Util>:
252
253   my $fh = IO::File->new($file, 'r');
254   Plack::Util::set_io_path($fh, $file);
255
256 Or using L<IO::File::WithPath>
257
258   my $fh = IO::File::WithPath->new($file, 'r');
259
260 And then passing the filehandle to body and setting headers, if needed.
261
262   $c->response->body($fh);
263   $c->response->headers->content_type('text/plain');
264   $c->response->headers->content_length(-s $file);
265   $c->response->headers->last_modified((stat($file))[9]);
266
267 L<Plack::Middleware::XSendfile> can be loaded in the application so:
268
269  __PACKAGE__->config(
270      psgi_middleware => [
271          'XSendfile',
272          # other middlewares here...
273         ],
274  );
275
276 B<Beware> that loading the middleware without configuring the
277 webserver to set the request header C<X-Sendfile-Type> to a supported
278 type (C<X-Accel-Redirect> for nginx, C<X-Sendfile> for Apache and
279 Lighttpd), could lead to the disclosure of private paths to malicious
280 clients setting that header.
281
282 Nginx needs the additional X-Accel-Mapping header to be set in the
283 webserver configuration, so the middleware will replace the absolute
284 path of the IO object with the internal nginx path. This is also
285 useful to prevent a buggy app to server random files from the
286 filesystem, as it's an internal redirect.
287
288 An nginx configuration for FastCGI could look so:
289
290  server {
291      server_name example.com;
292      root /my/app/root;
293      location /private/repo/ {
294          internal;
295          alias /my/app/repo/;
296      }
297      location /private/staging/ {
298          internal;
299          alias /my/app/staging/;
300      }
301      location @proxy {
302          include /etc/nginx/fastcgi_params;
303          fastcgi_param SCRIPT_NAME '';
304          fastcgi_param PATH_INFO   $fastcgi_script_name;
305          fastcgi_param HTTP_X_SENDFILE_TYPE X-Accel-Redirect;
306          fastcgi_param HTTP_X_ACCEL_MAPPING /my/app=/private;
307          fastcgi_pass  unix:/my/app/run/app.sock;
308     }
309  }
310
311 In the example above, passing filehandles with a local path matching
312 /my/app/staging or /my/app/repo will be served by nginx. Passing paths
313 with other locations will lead to an internal server error.
314
315 Setting the body to a filehandle without the C<path> method bypasses
316 the middleware completely.
317
318 For Apache and Lighttpd, the mapping doesn't apply and setting the
319 X-Sendfile-Type is enough.
320
321 =head2 $res->has_body
322
323 Predicate which returns true when a body has been set.
324
325 =head2 $res->code
326
327 Alias for $res->status.
328
329 =head2 $res->content_encoding
330
331 Shortcut for $res->headers->content_encoding.
332
333 =head2 $res->content_length
334
335 Shortcut for $res->headers->content_length.
336
337 =head2 $res->content_type
338
339 Shortcut for $res->headers->content_type.
340
341 This value is typically set by your view or plugin. For example,
342 L<Catalyst::Plugin::Static::Simple> will guess the mime type based on the file
343 it found, while L<Catalyst::View::TT> defaults to C<text/html>.
344
345 =head2 $res->content_type_charset
346
347 Shortcut for $res->headers->content_type_charset;
348
349 =head2 $res->cookies
350
351 Returns a reference to a hash containing cookies to be set. The keys of the
352 hash are the cookies' names, and their corresponding values are hash
353 references used to construct a L<CGI::Simple::Cookie> object.
354
355     $c->response->cookies->{foo} = { value => '123' };
356
357 The keys of the hash reference on the right correspond to the L<CGI::Simple::Cookie>
358 parameters of the same name, except they are used without a leading dash.
359 Possible parameters are:
360
361 =over
362
363 =item value
364
365 =item expires
366
367 =item domain
368
369 =item path
370
371 =item secure
372
373 =item httponly
374
375 =back
376
377 =head2 $res->header
378
379 Shortcut for $res->headers->header.
380
381 =head2 $res->headers
382
383 Returns an L<HTTP::Headers> object, which can be used to set headers.
384
385     $c->response->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
386
387 =head2 $res->output
388
389 Alias for $res->body.
390
391 =head2 $res->redirect( $url, $status )
392
393 Causes the response to redirect to the specified URL. The default status is
394 C<302>.
395
396     $c->response->redirect( 'http://slashdot.org' );
397     $c->response->redirect( 'http://slashdot.org', 307 );
398
399 This is a convenience method that sets the Location header to the
400 redirect destination, and then sets the response status.  You will
401 want to C< return > or C<< $c->detach() >> to interrupt the normal
402 processing flow if you want the redirect to occur straight away.
403
404 B<Note:> do not give a relative URL as $url, i.e: one that is not fully
405 qualified (= C<http://...>, etc.) or that starts with a slash
406 (= C</path/here>). While it may work, it is not guaranteed to do the right
407 thing and is not a standard behaviour. You may opt to use uri_for() or
408 uri_for_action() instead.
409
410 B<Note:> If $url is an object that does ->as_string (such as L<URI>, which is
411 what you get from ->uri_for) we automatically call that to stringify.  This
412 should ease the common case usage
413
414     return $c->res->redirect( $c->uri_for(...));
415
416 =cut
417
418 sub redirect {
419     my $self = shift;
420
421     if (@_) {
422         my $location = shift;
423         my $status   = shift || 302;
424
425         if(blessed($location) && $location->can('as_string')) {
426             $location = $location->as_string;
427         }
428
429         $self->location($location);
430         $self->status($status);
431     }
432
433     return $self->location;
434 }
435
436 =head2 $res->location
437
438 Sets or returns the HTTP 'Location'.
439
440 =head2 $res->status
441
442 Sets or returns the HTTP status.
443
444     $c->response->status(404);
445
446 $res->code is an alias for this, to match HTTP::Response->code.
447
448 =head2 $res->write( $data )
449
450 Writes $data to the output stream.  Calling this method will finalize your
451 headers and send the headers and status code response to the client (so changing
452 them afterwards is a waste... be sure to set your headers correctly first).
453
454 You may call this as often as you want throughout your response cycle.  You may
455 even set a 'body' afterward.  So for example you might write your HTTP headers
456 and the HEAD section of your document and then set the body from a template
457 driven from a database.  In some cases this can seem to the client as if you had
458 a faster overall response (but note that unless your server support chunked
459 body your content is likely to get queued anyway (L<Starman> and most other 
460 http 1.1 webservers support this).
461
462 If there is an encoding set, we encode each line of the response (the default
463 encoding is UTF-8).
464
465 =head2 $res->write_fh
466
467 Returns an instance of L<Catalyst::Response::Writer>, which is a lightweight
468 decorator over the PSGI C<$writer> object (see L<PSGI.pod\Delayed-Response-and-Streaming-Body>).
469
470 In addition to proxying the C<write> and C<close> method from the underlying PSGI
471 writer, this proxy object knows any application wide encoding, and provides a method
472 C<write_encoded> that will properly encode your written lines based upon your
473 encoding settings.  By default in L<Catalyst> responses are UTF-8 encoded and this
474 is the encoding used if you respond via C<write_encoded>.  If you want to handle
475 encoding yourself, you can use the C<write> method directly.
476
477 Encoding only applies to content types for which it matters.  Currently the following
478 content types are assumed to need encoding: text (including HTML), xml and javascript.
479
480 We provide access to this object so that you can properly close over it for use in
481 asynchronous and nonblocking applications.  For example (assuming you are using a supporting
482 server, like L<Twiggy>:
483
484     package AsyncExample::Controller::Root;
485
486     use Moose;
487
488     BEGIN { extends 'Catalyst::Controller' }
489
490     sub prepare_cb {
491       my $write_fh = pop;
492       return sub {
493         my $message = shift;
494         $write_fh->write("Finishing: $message\n");
495         $write_fh->close;
496       };
497     }
498
499     sub anyevent :Local :Args(0) {
500       my ($self, $c) = @_;
501       my $cb = $self->prepare_cb($c->res->write_fh);
502
503       my $watcher;
504       $watcher = AnyEvent->timer(
505         after => 5,
506         cb => sub {
507           $cb->(scalar localtime);
508           undef $watcher; # cancel circular-ref
509         });
510     }
511
512 Like the 'write' method, calling this will finalize headers. Unlike 'write' when you
513 can this it is assumed you are taking control of the response so the body is never
514 finalized (there isn't one anyway) and you need to call the close method.
515
516 =head2 $res->print( @data )
517
518 Prints @data to the output stream, separated by $,.  This lets you pass
519 the response object to functions that want to write to an L<IO::Handle>.
520
521 =head2 $self->finalize_headers($c)
522
523 Writes headers to response if not already written
524
525 =head2 from_psgi_response
526
527 Given a PSGI response (either three element ARRAY reference OR coderef expecting
528 a $responder) set the response from it.
529
530 Properly supports streaming and delayed response and / or async IO if running
531 under an expected event loop.
532
533 If passed an object, will expect that object to do a method C<as_psgi>.
534
535 Example:
536
537     package MyApp::Web::Controller::Test;
538
539     use base 'Catalyst::Controller';
540     use Plack::App::Directory;
541
542
543     my $app = Plack::App::Directory->new({ root => "/path/to/htdocs" })
544       ->to_app;
545
546     sub myaction :Local Args {
547       my ($self, $c) = @_;
548       $c->res->from_psgi_response($app->($c->req->env));
549     }
550
551 Please note this does not attempt to map or nest your PSGI application under
552 the Controller and Action namespace or path.  
553
554 =head2 encodable_content_type
555
556 This is a regular expression used to determine of the current content type
557 should be considered encodable.  Currently we apply default encoding (usually
558 UTF8) to text type contents.  Here's the default regular expression:
559
560 This would match content types like:
561
562     text/plain
563     text/html
564     text/xml
565     application/javascript
566     application/xml
567     application/vnd.user+xml
568
569 B<NOTE>: We don't encode JSON content type responses by default since most
570 of the JSON serializers that are commonly used for this task will do so
571 automatically and we don't want to double encode.  If you are not using a
572 tool like L<JSON> to produce JSON type content, (for example you are using
573 a template system, or creating the strings manually) you will need to either
574 encoding the body yourself:
575
576     $c->response->body( $c->encoding->encode( $body, $c->_encode_check ) );
577
578 Or you can alter the regular expression using this attribute.
579
580 =head2 encodable_response
581
582 Given a L<Catalyst::Response> return true if its one that can be encoded.  
583
584      make sure there is an encoding set on the response
585      make sure the content type is encodable
586      make sure no content type charset has been already set to something different from the global encoding
587      make sure no content encoding is present.
588
589 Note this does not inspect a body since we do allow automatic encoding on streaming
590 type responses.
591
592 =cut
593
594 sub encodable_response {
595   my ($self) = @_;
596   return 0 unless $self->_context; # Cases like returning a HTTP Exception response you don't have a context here...
597   return 0 unless $self->_context->encoding;
598
599   # The response is considered to have a 'manual charset' when a charset is already set on
600   # the content type of the response AND it is not the same as the one we set in encoding.
601   # If there is no charset OR we are asking for the one which is the same as the current
602   # required encoding, that is a flag that we want Catalyst to encode the response automatically.
603   my $has_manual_charset = 0;
604   if(my $charset = $self->content_type_charset) {
605     $has_manual_charset = (uc($charset) ne uc($self->_context->encoding->mime_name)) ? 1:0;
606   }
607
608   # Content type is encodable if it matches the regular expression stored in this attribute
609   my $encodable_content_type = $self->content_type =~ m/${\$self->encodable_content_type}/ ? 1:0;
610
611   # The content encoding is allowed (for charset encoding) only if its empty or is set to identity
612   my $allowed_content_encoding = (!$self->content_encoding || $self->content_encoding eq 'identity') ? 1:0;
613
614   # The content type must be an encodable type, and there must be NO manual charset and also
615   # the content encoding must be the allowed values;
616   if(
617       $encodable_content_type and
618       !$has_manual_charset and
619       $allowed_content_encoding
620   ) {
621     return 1;
622   } else {
623     return 0;
624   }
625 }
626
627 =head2 DEMOLISH
628
629 Ensures that the response is flushed and closed at the end of the
630 request.
631
632 =head2 meta
633
634 Provided by Moose
635
636 =cut
637
638 sub print {
639     my $self = shift;
640     my $data = shift;
641
642     defined $self->write($data) or return;
643
644     for (@_) {
645         defined $self->write($,) or return;
646         defined $self->write($_) or return;
647     }
648     defined $self->write($\) or return;
649
650     return 1;
651 }
652
653 =head1 AUTHORS
654
655 Catalyst Contributors, see Catalyst.pm
656
657 =head1 COPYRIGHT
658
659 This library is free software. You can redistribute it and/or modify
660 it under the same terms as Perl itself.
661
662 =cut
663
664 __PACKAGE__->meta->make_immutable;
665
666 1;