donot encode write unless the content type is one of the encodable types
[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
9 with 'MooseX::Emulate::Class::Accessor::Fast';
10
11 has _response_cb => (
12     is      => 'ro',
13     isa     => 'CodeRef', 
14     writer  => '_set_response_cb',
15     clearer => '_clear_response_cb',
16     predicate => '_has_response_cb',
17 );
18
19 subtype 'Catalyst::Engine::Types::Writer',
20     as duck_type([qw(write close)]);
21
22 has _writer => (
23     is      => 'ro',
24     isa     => 'Catalyst::Engine::Types::Writer', #Pointless since we control how this is built
25     #writer  => '_set_writer', Now that its lazy I think this is safe to remove
26     clearer => '_clear_writer',
27     predicate => '_has_writer',
28     lazy      => 1,
29     builder => '_build_writer',
30 );
31
32 sub _build_writer {
33     my $self = shift;
34
35     ## These two lines are probably crap now...
36     $self->_context->finalize_headers unless
37       $self->finalized_headers;
38
39     my @headers;
40     $self->headers->scan(sub { push @headers, @_ });
41
42     my $writer = $self->_response_cb->([ $self->status, \@headers ]);
43     $self->_clear_response_cb;
44
45     return $writer;
46 }
47
48 has write_fh => (
49   is=>'ro',
50   predicate=>'_has_write_fh',
51   lazy=>1,
52   builder=>'_build_write_fh',
53 );
54
55 sub _build_write_fh { shift ->_writer }
56
57 sub DEMOLISH {
58   my $self = shift;
59   return if $self->_has_write_fh;
60   if($self->_has_writer) {
61     $self->_writer->close
62   }
63 }
64
65 has cookies   => (is => 'rw', default => sub { {} });
66 has body      => (is => 'rw', default => undef);
67 sub has_body { defined($_[0]->body) }
68
69 has location  => (is => 'rw');
70 has status    => (is => 'rw', default => 200);
71 has finalized_headers => (is => 'rw', default => 0);
72 has headers   => (
73   is      => 'rw',
74   isa => 'HTTP::Headers',
75   handles => [qw(content_encoding content_length content_type header)],
76   default => sub { HTTP::Headers->new() },
77   required => 1,
78   lazy => 1,
79 );
80 has _context => (
81   is => 'rw',
82   weak_ref => 1,
83   clearer => '_clear_context',
84 );
85
86 before [qw(status headers content_encoding content_length content_type header)] => sub {
87   my $self = shift;
88
89   $self->_context->log->warn( 
90     "Useless setting a header value after finalize_headers called." .
91     " Not what you want." )
92       if ( $self->finalized_headers && @_ );
93 };
94
95 sub output { shift->body(@_) }
96
97 sub code   { shift->status(@_) }
98
99 sub write {
100     my ( $self, $buffer ) = @_;
101
102     # Finalize headers if someone manually writes output
103     $self->_context->finalize_headers unless $self->finalized_headers;
104
105     $buffer = q[] unless defined $buffer;
106
107     $buffer = $self->_context->encoding->encode( $buffer, $self->_context->_encode_check )
108       if $self->_context->encoding && $self->content_type =~ /^text|xml$|javascript$/;
109
110     my $len = length($buffer);
111     $self->_writer->write($buffer);
112
113     return $len;
114 }
115
116 sub finalize_headers {
117     my ($self) = @_;
118     return;
119 }
120
121 sub from_psgi_response {
122     my ($self, $psgi_res) = @_;
123     if(blessed($psgi_res) && $psgi_res->can('as_psgi')) {
124       $psgi_res = $psgi_res->as_psgi;
125     }
126     if(ref $psgi_res eq 'ARRAY') {
127         my ($status, $headers, $body) = @$psgi_res;
128         $self->status($status);
129         $self->headers(HTTP::Headers->new(@$headers));
130         $self->body($body);
131     } elsif(ref $psgi_res eq 'CODE') {
132         $psgi_res->(sub {
133             my $response = shift;
134             my ($status, $headers, $maybe_body) = @$response;
135             $self->status($status);
136             $self->headers(HTTP::Headers->new(@$headers));
137             if(defined $maybe_body) {
138                 $self->body($maybe_body);
139             } else {
140                 return $self->write_fh;
141             }
142         });  
143      } else {
144         die "You can't set a Catalyst response from that, expect a valid PSGI response";
145     }
146 }
147
148 =head1 NAME
149
150 Catalyst::Response - stores output responding to the current client request
151
152 =head1 SYNOPSIS
153
154     $res = $c->response;
155     $res->body;
156     $res->code;
157     $res->content_encoding;
158     $res->content_length;
159     $res->content_type;
160     $res->cookies;
161     $res->header;
162     $res->headers;
163     $res->output;
164     $res->redirect;
165     $res->status;
166     $res->write;
167
168 =head1 DESCRIPTION
169
170 This is the Catalyst Response class, which provides methods for responding to
171 the current client request. The appropriate L<Catalyst::Engine> for your environment
172 will turn the Catalyst::Response into a HTTP Response and return it to the client.
173
174 =head1 METHODS
175
176 =head2 $res->body( $text | $fh | $iohandle_object )
177
178     $c->response->body('Catalyst rocks!');
179
180 Sets or returns the output (text or binary data). If you are returning a large body,
181 you might want to use a L<IO::Handle> type of object (Something that implements the read method
182 in the same fashion), or a filehandle GLOB. Catalyst
183 will write it piece by piece into the response.
184
185 When using a L<IO::Handle> type of object and no content length has been
186 already set in the response headers Catalyst will make a reasonable attempt
187 to determine the size of the Handle. Depending on the implementation of your
188 handle object, setting the content length may fail. If it is at all possible
189 for you to determine the content length of your handle object, 
190 it is recommended that you set the content length in the response headers
191 yourself, which will be respected and sent by Catalyst in the response.
192
193 Please note that the object needs to implement C<getline>, not just
194 C<read>.
195
196 Starting from version 5.90060, when using an L<IO::Handle> object, you
197 may want to use L<Plack::Middleware::XSendfile>, to delegate the
198 actual serving to the frontend server. To do so, you need to pass to
199 C<body> an IO object with a C<path> method. This can be achieved in
200 two ways.
201
202 Either using L<Plack::Util>:
203
204   my $fh = IO::File->new($file, 'r');
205   Plack::Util::set_io_path($fh, $file);
206
207 Or using L<IO::File::WithPath>
208
209   my $fh = IO::File::WithPath->new($file, 'r');
210
211 And then passing the filehandle to body and setting headers, if needed.
212
213   $c->response->body($fh);
214   $c->response->headers->content_type('text/plain');
215   $c->response->headers->content_length(-s $file);
216   $c->response->headers->last_modified((stat($file))[9]);
217
218 L<Plack::Middleware::XSendfile> can be loaded in the application so:
219
220  __PACKAGE__->config(
221      psgi_middleware => [
222          'XSendfile',
223          # other middlewares here...
224         ],
225  );
226
227 B<Beware> that loading the middleware without configuring the
228 webserver to set the request header C<X-Sendfile-Type> to a supported
229 type (C<X-Accel-Redirect> for nginx, C<X-Sendfile> for Apache and
230 Lighttpd), could lead to the disclosure of private paths to malicious
231 clients setting that header.
232
233 Nginx needs the additional X-Accel-Mapping header to be set in the
234 webserver configuration, so the middleware will replace the absolute
235 path of the IO object with the internal nginx path. This is also
236 useful to prevent a buggy app to server random files from the
237 filesystem, as it's an internal redirect.
238
239 An nginx configuration for FastCGI could look so:
240
241  server {
242      server_name example.com;
243      root /my/app/root;
244      location /private/repo/ {
245          internal;
246          alias /my/app/repo/;
247      }
248      location /private/staging/ {
249          internal;
250          alias /my/app/staging/;
251      }
252      location @proxy {
253          include /etc/nginx/fastcgi_params;
254          fastcgi_param SCRIPT_NAME '';
255          fastcgi_param PATH_INFO   $fastcgi_script_name;
256          fastcgi_param HTTP_X_SENDFILE_TYPE X-Accel-Redirect;
257          fastcgi_param HTTP_X_ACCEL_MAPPING /my/app=/private;
258          fastcgi_pass  unix:/my/app/run/app.sock;
259     }
260  }
261
262 In the example above, passing filehandles with a local path matching
263 /my/app/staging or /my/app/repo will be served by nginx. Passing paths
264 with other locations will lead to an internal server error.
265
266 Setting the body to a filehandle without the C<path> method bypasses
267 the middleware completely.
268
269 For Apache and Lighttpd, the mapping doesn't apply and setting the
270 X-Sendfile-Type is enough.
271
272 =head2 $res->has_body
273
274 Predicate which returns true when a body has been set.
275
276 =head2 $res->code
277
278 Alias for $res->status.
279
280 =head2 $res->content_encoding
281
282 Shortcut for $res->headers->content_encoding.
283
284 =head2 $res->content_length
285
286 Shortcut for $res->headers->content_length.
287
288 =head2 $res->content_type
289
290 Shortcut for $res->headers->content_type.
291
292 This value is typically set by your view or plugin. For example,
293 L<Catalyst::Plugin::Static::Simple> will guess the mime type based on the file
294 it found, while L<Catalyst::View::TT> defaults to C<text/html>.
295
296 =head2 $res->cookies
297
298 Returns a reference to a hash containing cookies to be set. The keys of the
299 hash are the cookies' names, and their corresponding values are hash
300 references used to construct a L<CGI::Simple::Cookie> object.
301
302     $c->response->cookies->{foo} = { value => '123' };
303
304 The keys of the hash reference on the right correspond to the L<CGI::Simple::Cookie>
305 parameters of the same name, except they are used without a leading dash.
306 Possible parameters are:
307
308 =over
309
310 =item value
311
312 =item expires
313
314 =item domain
315
316 =item path
317
318 =item secure
319
320 =item httponly
321
322 =back
323
324 =head2 $res->header
325
326 Shortcut for $res->headers->header.
327
328 =head2 $res->headers
329
330 Returns an L<HTTP::Headers> object, which can be used to set headers.
331
332     $c->response->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
333
334 =head2 $res->output
335
336 Alias for $res->body.
337
338 =head2 $res->redirect( $url, $status )
339
340 Causes the response to redirect to the specified URL. The default status is
341 C<302>.
342
343     $c->response->redirect( 'http://slashdot.org' );
344     $c->response->redirect( 'http://slashdot.org', 307 );
345
346 This is a convenience method that sets the Location header to the
347 redirect destination, and then sets the response status.  You will
348 want to C< return > or C<< $c->detach() >> to interrupt the normal
349 processing flow if you want the redirect to occur straight away.
350
351 B<Note:> do not give a relative URL as $url, i.e: one that is not fully
352 qualified (= C<http://...>, etc.) or that starts with a slash
353 (= C</path/here>). While it may work, it is not guaranteed to do the right
354 thing and is not a standard behaviour. You may opt to use uri_for() or
355 uri_for_action() instead.
356
357 B<Note:> If $url is an object that does ->as_string (such as L<URI>, which is
358 what you get from ->uri_for) we automatically call that to stringify.  This
359 should ease the common case usage
360
361     return $c->res->redirect( $c->uri_for(...));
362
363 =cut
364
365 sub redirect {
366     my $self = shift;
367
368     if (@_) {
369         my $location = shift;
370         my $status   = shift || 302;
371
372         if(blessed($location) && $location->can('as_string')) {
373             $location = $location->as_string;
374         }
375
376         $self->location($location);
377         $self->status($status);
378     }
379
380     return $self->location;
381 }
382
383 =head2 $res->location
384
385 Sets or returns the HTTP 'Location'.
386
387 =head2 $res->status
388
389 Sets or returns the HTTP status.
390
391     $c->response->status(404);
392
393 $res->code is an alias for this, to match HTTP::Response->code.
394
395 =head2 $res->write( $data )
396
397 Writes $data to the output stream.  Calling this method will finalize your
398 headers and send the headers and status code response to the client (so changing
399 them afterwards is a waste... be sure to set your headers correctly first).
400
401 You may call this as often as you want throughout your response cycle.  You may
402 even set a 'body' afterward.  So for example you might write your HTTP headers
403 and the HEAD section of your document and then set the body from a template
404 driven from a database.  In some cases this can seem to the client as if you had
405 a faster overall response (but note that unless your server support chunked
406 body your content is likely to get queued anyway (L<Starman> and most other 
407 http 1.1 webservers support this).
408
409 If there is an encoding set, we encode each line of the response (the default
410 encoding is UTF-8).
411
412 =head2 $res->write_fh
413
414 Returns a PSGI $writer object that has two methods, write and close.  You can
415 close over this object for asynchronous and nonblocking applications.  For
416 example (assuming you are using a supporting server, like L<Twiggy>
417
418     package AsyncExample::Controller::Root;
419
420     use Moose;
421
422     BEGIN { extends 'Catalyst::Controller' }
423
424     sub prepare_cb {
425       my $write_fh = pop;
426       return sub {
427         my $message = shift;
428         $write_fh->write("Finishing: $message\n");
429         $write_fh->close;
430       };
431     }
432
433     sub anyevent :Local :Args(0) {
434       my ($self, $c) = @_;
435       my $cb = $self->prepare_cb($c->res->write_fh);
436
437       my $watcher;
438       $watcher = AnyEvent->timer(
439         after => 5,
440         cb => sub {
441           $cb->(scalar localtime);
442           undef $watcher; # cancel circular-ref
443         });
444     }
445
446 Like the 'write' method, calling this will finalize headers. Unlike 'write' when you
447 can this it is assumed you are taking control of the response so the body is never
448 finalized (there isn't one anyway) and you need to call the close method.
449
450 =head2 $res->print( @data )
451
452 Prints @data to the output stream, separated by $,.  This lets you pass
453 the response object to functions that want to write to an L<IO::Handle>.
454
455 =head2 $self->finalize_headers($c)
456
457 Writes headers to response if not already written
458
459 =head2 from_psgi_response
460
461 Given a PSGI response (either three element ARRAY reference OR coderef expecting
462 a $responder) set the response from it.
463
464 Properly supports streaming and delayed response and / or async IO if running
465 under an expected event loop.
466
467 If passed an object, will expect that object to do a method C<as_psgi>.
468
469 Example:
470
471     package MyApp::Web::Controller::Test;
472
473     use base 'Catalyst::Controller';
474     use Plack::App::Directory;
475
476
477     my $app = Plack::App::Directory->new({ root => "/path/to/htdocs" })
478       ->to_app;
479
480     sub myaction :Local Args {
481       my ($self, $c) = @_;
482       $c->res->from_psgi_response($app->($c->req->env));
483     }
484
485 Please note this does not attempt to map or nest your PSGI application under
486 the Controller and Action namespace or path.  
487
488 =head2 DEMOLISH
489
490 Ensures that the response is flushed and closed at the end of the
491 request.
492
493 =head2 meta
494
495 Provided by Moose
496
497 =cut
498
499 sub print {
500     my $self = shift;
501     my $data = shift;
502
503     defined $self->write($data) or return;
504
505     for (@_) {
506         defined $self->write($,) or return;
507         defined $self->write($_) or return;
508     }
509     defined $self->write($\) or return;
510
511     return 1;
512 }
513
514 =head1 AUTHORS
515
516 Catalyst Contributors, see Catalyst.pm
517
518 =head1 COPYRIGHT
519
520 This library is free software. You can redistribute it and/or modify
521 it under the same terms as Perl itself.
522
523 =cut
524
525 __PACKAGE__->meta->make_immutable;
526
527 1;