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