1 package Catalyst::Response;
5 use Moose::Util::TypeConstraints;
6 use namespace::autoclean;
7 use Scalar::Util 'blessed';
8 use Catalyst::Response::Writer;
10 with 'MooseX::Emulate::Class::Accessor::Fast';
15 writer => '_set_response_cb',
16 clearer => '_clear_response_cb',
17 predicate => '_has_response_cb',
20 subtype 'Catalyst::Engine::Types::Writer',
21 as duck_type([qw(write close)]);
25 isa => 'Catalyst::Engine::Types::Writer', #Pointless since we control how this is built
26 #writer => '_set_writer', Now that its lazy I think this is safe to remove
27 clearer => '_clear_writer',
28 predicate => '_has_writer',
30 builder => '_build_writer',
36 ## These two lines are probably crap now...
37 $self->_context->finalize_headers unless
38 $self->finalized_headers;
41 $self->headers->scan(sub { push @headers, @_ });
43 my $writer = $self->_response_cb->([ $self->status, \@headers ]);
44 $self->_clear_response_cb;
51 predicate=>'_has_write_fh',
53 builder=>'_build_write_fh',
57 my $writer = $_[0]->_writer; # We need to get the finalize headers side effect...
58 my $requires_encoding = $_[0]->content_type =~ m/^text|xml$|javascript$/;
61 _encoding => $_[0]->encoding,
62 _requires_encoding => $requires_encoding,
65 return bless \%fields, 'Catalyst::Response::Writer';
70 return if $self->_has_write_fh;
71 if($self->_has_writer) {
76 has cookies => (is => 'rw', default => sub { {} });
77 has body => (is => 'rw', default => undef);
78 sub has_body { defined($_[0]->body) }
80 has location => (is => 'rw');
81 has status => (is => 'rw', default => 200);
82 has finalized_headers => (is => 'rw', default => 0);
85 isa => 'HTTP::Headers',
86 handles => [qw(content_encoding content_length content_type header)],
87 default => sub { HTTP::Headers->new() },
94 clearer => '_clear_context',
97 has encoding => (is=>'ro');
99 before [qw(status headers content_encoding content_length content_type header)] => sub {
102 $self->_context->log->warn(
103 "Useless setting a header value after finalize_headers called." .
104 " Not what you want." )
105 if ( $self->finalized_headers && @_ );
108 sub output { shift->body(@_) }
110 sub code { shift->status(@_) }
113 my ( $self, $buffer ) = @_;
115 # Finalize headers if someone manually writes output
116 $self->_context->finalize_headers unless $self->finalized_headers;
118 $buffer = q[] unless defined $buffer;
120 $buffer = $self->_context->encoding->encode( $buffer, $self->_context->_encode_check )
121 if $self->_context->encoding && $self->content_type =~ /^text|xml$|javascript$/;
123 my $len = length($buffer);
124 $self->_writer->write($buffer);
129 sub finalize_headers {
134 sub from_psgi_response {
135 my ($self, $psgi_res) = @_;
136 if(blessed($psgi_res) && $psgi_res->can('as_psgi')) {
137 $psgi_res = $psgi_res->as_psgi;
139 if(ref $psgi_res eq 'ARRAY') {
140 my ($status, $headers, $body) = @$psgi_res;
141 $self->status($status);
142 $self->headers(HTTP::Headers->new(@$headers));
144 } elsif(ref $psgi_res eq 'CODE') {
146 my $response = shift;
147 my ($status, $headers, $maybe_body) = @$response;
148 $self->status($status);
149 $self->headers(HTTP::Headers->new(@$headers));
150 if(defined $maybe_body) {
151 $self->body($maybe_body);
153 return $self->write_fh;
157 die "You can't set a Catalyst response from that, expect a valid PSGI response";
163 Catalyst::Response - stores output responding to the current client request
170 $res->content_encoding;
171 $res->content_length;
183 This is the Catalyst Response class, which provides methods for responding to
184 the current client request. The appropriate L<Catalyst::Engine> for your environment
185 will turn the Catalyst::Response into a HTTP Response and return it to the client.
189 =head2 $res->body( $text | $fh | $iohandle_object )
191 $c->response->body('Catalyst rocks!');
193 Sets or returns the output (text or binary data). If you are returning a large body,
194 you might want to use a L<IO::Handle> type of object (Something that implements the read method
195 in the same fashion), or a filehandle GLOB. Catalyst
196 will write it piece by piece into the response.
198 When using a L<IO::Handle> type of object and no content length has been
199 already set in the response headers Catalyst will make a reasonable attempt
200 to determine the size of the Handle. Depending on the implementation of your
201 handle object, setting the content length may fail. If it is at all possible
202 for you to determine the content length of your handle object,
203 it is recommended that you set the content length in the response headers
204 yourself, which will be respected and sent by Catalyst in the response.
206 Please note that the object needs to implement C<getline>, not just
209 Starting from version 5.90060, when using an L<IO::Handle> object, you
210 may want to use L<Plack::Middleware::XSendfile>, to delegate the
211 actual serving to the frontend server. To do so, you need to pass to
212 C<body> an IO object with a C<path> method. This can be achieved in
215 Either using L<Plack::Util>:
217 my $fh = IO::File->new($file, 'r');
218 Plack::Util::set_io_path($fh, $file);
220 Or using L<IO::File::WithPath>
222 my $fh = IO::File::WithPath->new($file, 'r');
224 And then passing the filehandle to body and setting headers, if needed.
226 $c->response->body($fh);
227 $c->response->headers->content_type('text/plain');
228 $c->response->headers->content_length(-s $file);
229 $c->response->headers->last_modified((stat($file))[9]);
231 L<Plack::Middleware::XSendfile> can be loaded in the application so:
236 # other middlewares here...
240 B<Beware> that loading the middleware without configuring the
241 webserver to set the request header C<X-Sendfile-Type> to a supported
242 type (C<X-Accel-Redirect> for nginx, C<X-Sendfile> for Apache and
243 Lighttpd), could lead to the disclosure of private paths to malicious
244 clients setting that header.
246 Nginx needs the additional X-Accel-Mapping header to be set in the
247 webserver configuration, so the middleware will replace the absolute
248 path of the IO object with the internal nginx path. This is also
249 useful to prevent a buggy app to server random files from the
250 filesystem, as it's an internal redirect.
252 An nginx configuration for FastCGI could look so:
255 server_name example.com;
257 location /private/repo/ {
261 location /private/staging/ {
263 alias /my/app/staging/;
266 include /etc/nginx/fastcgi_params;
267 fastcgi_param SCRIPT_NAME '';
268 fastcgi_param PATH_INFO $fastcgi_script_name;
269 fastcgi_param HTTP_X_SENDFILE_TYPE X-Accel-Redirect;
270 fastcgi_param HTTP_X_ACCEL_MAPPING /my/app=/private;
271 fastcgi_pass unix:/my/app/run/app.sock;
275 In the example above, passing filehandles with a local path matching
276 /my/app/staging or /my/app/repo will be served by nginx. Passing paths
277 with other locations will lead to an internal server error.
279 Setting the body to a filehandle without the C<path> method bypasses
280 the middleware completely.
282 For Apache and Lighttpd, the mapping doesn't apply and setting the
283 X-Sendfile-Type is enough.
285 =head2 $res->has_body
287 Predicate which returns true when a body has been set.
291 Alias for $res->status.
293 =head2 $res->content_encoding
295 Shortcut for $res->headers->content_encoding.
297 =head2 $res->content_length
299 Shortcut for $res->headers->content_length.
301 =head2 $res->content_type
303 Shortcut for $res->headers->content_type.
305 This value is typically set by your view or plugin. For example,
306 L<Catalyst::Plugin::Static::Simple> will guess the mime type based on the file
307 it found, while L<Catalyst::View::TT> defaults to C<text/html>.
311 Returns a reference to a hash containing cookies to be set. The keys of the
312 hash are the cookies' names, and their corresponding values are hash
313 references used to construct a L<CGI::Simple::Cookie> object.
315 $c->response->cookies->{foo} = { value => '123' };
317 The keys of the hash reference on the right correspond to the L<CGI::Simple::Cookie>
318 parameters of the same name, except they are used without a leading dash.
319 Possible parameters are:
339 Shortcut for $res->headers->header.
343 Returns an L<HTTP::Headers> object, which can be used to set headers.
345 $c->response->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
349 Alias for $res->body.
351 =head2 $res->redirect( $url, $status )
353 Causes the response to redirect to the specified URL. The default status is
356 $c->response->redirect( 'http://slashdot.org' );
357 $c->response->redirect( 'http://slashdot.org', 307 );
359 This is a convenience method that sets the Location header to the
360 redirect destination, and then sets the response status. You will
361 want to C< return > or C<< $c->detach() >> to interrupt the normal
362 processing flow if you want the redirect to occur straight away.
364 B<Note:> do not give a relative URL as $url, i.e: one that is not fully
365 qualified (= C<http://...>, etc.) or that starts with a slash
366 (= C</path/here>). While it may work, it is not guaranteed to do the right
367 thing and is not a standard behaviour. You may opt to use uri_for() or
368 uri_for_action() instead.
370 B<Note:> If $url is an object that does ->as_string (such as L<URI>, which is
371 what you get from ->uri_for) we automatically call that to stringify. This
372 should ease the common case usage
374 return $c->res->redirect( $c->uri_for(...));
382 my $location = shift;
383 my $status = shift || 302;
385 if(blessed($location) && $location->can('as_string')) {
386 $location = $location->as_string;
389 $self->location($location);
390 $self->status($status);
393 return $self->location;
396 =head2 $res->location
398 Sets or returns the HTTP 'Location'.
402 Sets or returns the HTTP status.
404 $c->response->status(404);
406 $res->code is an alias for this, to match HTTP::Response->code.
408 =head2 $res->write( $data )
410 Writes $data to the output stream. Calling this method will finalize your
411 headers and send the headers and status code response to the client (so changing
412 them afterwards is a waste... be sure to set your headers correctly first).
414 You may call this as often as you want throughout your response cycle. You may
415 even set a 'body' afterward. So for example you might write your HTTP headers
416 and the HEAD section of your document and then set the body from a template
417 driven from a database. In some cases this can seem to the client as if you had
418 a faster overall response (but note that unless your server support chunked
419 body your content is likely to get queued anyway (L<Starman> and most other
420 http 1.1 webservers support this).
422 If there is an encoding set, we encode each line of the response (the default
425 =head2 $res->write_fh
427 Returns an instance of L<Catalyst::Response::Writer>, which is a lightweight
428 decorator over the PSGI C<$writer> object (see L<PSGI.pod\Delayed-Response-and-Streaming-Body>).
430 In addition to proxying the C<write> and C<close> method from the underlying PSGI
431 writer, this proxy object knows any application wide encoding, and provides a method
432 C<write_encoded> that will properly encode your written lines based upon your
433 encoding settings. By default in L<Catalyst> responses are UTF-8 encoded and this
434 is the encoding used if you respond via C<write_encoded>. If you want to handle
435 encoding yourself, you can use the C<write> method directly.
437 Encoding only applies to content types for which it matters. Currently the following
438 content types are assumed to need encoding: text (including HTML), xml and javascript.
440 We provide access to this object so that you can properly close over it for use in
441 asynchronous and nonblocking applications. For example (assuming you are using a supporting
442 server, like L<Twiggy>:
444 package AsyncExample::Controller::Root;
448 BEGIN { extends 'Catalyst::Controller' }
454 $write_fh->write("Finishing: $message\n");
459 sub anyevent :Local :Args(0) {
461 my $cb = $self->prepare_cb($c->res->write_fh);
464 $watcher = AnyEvent->timer(
467 $cb->(scalar localtime);
468 undef $watcher; # cancel circular-ref
472 Like the 'write' method, calling this will finalize headers. Unlike 'write' when you
473 can this it is assumed you are taking control of the response so the body is never
474 finalized (there isn't one anyway) and you need to call the close method.
476 =head2 $res->print( @data )
478 Prints @data to the output stream, separated by $,. This lets you pass
479 the response object to functions that want to write to an L<IO::Handle>.
481 =head2 $self->finalize_headers($c)
483 Writes headers to response if not already written
485 =head2 from_psgi_response
487 Given a PSGI response (either three element ARRAY reference OR coderef expecting
488 a $responder) set the response from it.
490 Properly supports streaming and delayed response and / or async IO if running
491 under an expected event loop.
493 If passed an object, will expect that object to do a method C<as_psgi>.
497 package MyApp::Web::Controller::Test;
499 use base 'Catalyst::Controller';
500 use Plack::App::Directory;
503 my $app = Plack::App::Directory->new({ root => "/path/to/htdocs" })
506 sub myaction :Local Args {
508 $c->res->from_psgi_response($app->($c->req->env));
511 Please note this does not attempt to map or nest your PSGI application under
512 the Controller and Action namespace or path.
516 Ensures that the response is flushed and closed at the end of the
529 defined $self->write($data) or return;
532 defined $self->write($,) or return;
533 defined $self->write($_) or return;
535 defined $self->write($\) or return;
542 Catalyst Contributors, see Catalyst.pm
546 This library is free software. You can redistribute it and/or modify
547 it under the same terms as Perl itself.
551 __PACKAGE__->meta->make_immutable;