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