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