1 package Catalyst::Response;
5 use Moose::Util::TypeConstraints;
6 use namespace::autoclean;
8 with 'MooseX::Emulate::Class::Accessor::Fast';
13 writer => '_set_response_cb',
14 clearer => '_clear_response_cb',
15 predicate => '_has_response_cb',
18 subtype 'Catalyst::Engine::Types::Writer',
19 as duck_type([qw(write close)]);
23 isa => 'Catalyst::Engine::Types::Writer', #Pointless since we control how this is built
24 #writer => '_set_writer', Now that its lazy I think this is safe to remove
25 clearer => '_clear_writer',
26 predicate => '_has_writer',
28 builder => '_build_writer',
34 ## These two lines are probably crap now...
35 $self->_context->finalize_headers unless
36 $self->finalized_headers;
39 $self->headers->scan(sub { push @headers, @_ });
41 my $writer = $self->_response_cb->([ $self->status, \@headers ]);
42 $self->_clear_response_cb;
49 predicate=>'_has_write_fh',
51 builder=>'_build_write_fh',
54 sub _build_write_fh { shift ->_writer }
58 return if $self->_has_write_fh;
59 if($self->_has_writer) {
64 has cookies => (is => 'rw', default => sub { {} });
65 has body => (is => 'rw', default => undef);
66 sub has_body { defined($_[0]->body) }
68 has location => (is => 'rw');
69 has status => (is => 'rw', default => 200);
70 has finalized_headers => (is => 'rw', default => 0);
73 isa => 'HTTP::Headers',
74 handles => [qw(content_encoding content_length content_type header)],
75 default => sub { HTTP::Headers->new() },
82 clearer => '_clear_context',
85 before [qw(status headers content_encoding content_length content_type header)] => sub {
88 $self->_context->log->warn(
89 "Useless setting a header value after finalize_headers called." .
90 " Not what you want." )
91 if ( $self->finalized_headers && @_ );
94 sub output { shift->body(@_) }
96 sub code { shift->status(@_) }
99 my ( $self, $buffer ) = @_;
101 # Finalize headers if someone manually writes output
102 $self->_context->finalize_headers unless $self->finalized_headers;
104 $buffer = q[] unless defined $buffer;
106 my $len = length($buffer);
107 $self->_writer->write($buffer);
112 sub finalize_headers {
117 sub from_psgi_response {
118 my ($self, $psgi_res) = @_;
119 if(ref $psgi_res eq 'ARRAY') {
120 my ($status, $headers, $body) = @$psgi_res;
121 $self->status($status);
122 $self->headers(HTTP::Headers->new(@$headers));
124 } elsif(ref $psgi_res eq 'CODE') {
126 my $response = shift;
127 my ($status, $headers, $maybe_body) = @$response;
128 $self->status($status);
129 $self->headers(HTTP::Headers->new(@$headers));
130 if(defined $maybe_body) {
131 $self->body($maybe_body);
133 return $self->write_fh;
137 die "You can't set a Catalyst response from that, expect a valid PSGI response";
143 Catalyst::Response - stores output responding to the current client request
150 $res->content_encoding;
151 $res->content_length;
163 This is the Catalyst Response class, which provides methods for responding to
164 the current client request. The appropriate L<Catalyst::Engine> for your environment
165 will turn the Catalyst::Response into a HTTP Response and return it to the client.
169 =head2 $res->body( $text | $fh | $iohandle_object )
171 $c->response->body('Catalyst rocks!');
173 Sets or returns the output (text or binary data). If you are returning a large body,
174 you might want to use a L<IO::Handle> type of object (Something that implements the read method
175 in the same fashion), or a filehandle GLOB. Catalyst
176 will write it piece by piece into the response.
178 When using a L<IO::Handle> type of object and no content length has been
179 already set in the response headers Catalyst will make a reasonable attempt
180 to determine the size of the Handle. Depending on the implementation of your
181 handle object, setting the content length may fail. If it is at all possible
182 for you to determine the content length of your handle object,
183 it is recommended that you set the content length in the response headers
184 yourself, which will be respected and sent by Catalyst in the response.
186 Please note that the object needs to implement C<getline>, not just
189 Starting from version 5.90060, when using an L<IO::Handle> object, you
190 may want to use L<Plack::Middleware::XSendfile>, to delegate the
191 actual serving to the frontend server. To do so, you need to pass to
192 C<body> an IO object with a C<path> method. This can be achieved in
195 Either using L<Plack::Util>:
197 my $fh = IO::File->new($file, 'r');
198 Plack::Util::set_io_path($fh, $file);
200 Or using L<IO::File::WithPath>
202 my $fh = IO::File::WithPath->new($file, 'r');
204 And then passing the filehandle to body and setting headers, if needed.
206 $c->response->body($fh);
207 $c->response->headers->content_type('text/plain');
208 $c->response->headers->content_length(-s $file);
209 $c->response->headers->last_modified((stat($file))[9]);
211 L<Plack::Middleware::XSendfile> can be loaded in the application so:
216 # other middlewares here...
220 B<Beware> that loading the middleware without configuring the
221 webserver to set the request header C<X-Sendfile-Type> to a supported
222 type (C<X-Accel-Redirect> for nginx, C<X-Sendfile> for Apache and
223 Lighttpd), could lead to the disclosure of private paths to malicious
224 clients setting that header.
226 Nginx needs the additional X-Accel-Mapping header to be set in the
227 webserver configuration, so the middleware will replace the absolute
228 path of the IO object with the internal nginx path. This is also
229 useful to prevent a buggy app to server random files from the
230 filesystem, as it's an internal redirect.
232 An nginx configuration for FastCGI could look so:
235 server_name example.com;
237 location /private/repo/ {
241 location /private/staging/ {
243 alias /my/app/staging/;
246 include /etc/nginx/fastcgi_params;
247 fastcgi_param SCRIPT_NAME '';
248 fastcgi_param PATH_INFO $fastcgi_script_name;
249 fastcgi_param HTTP_X_SENDFILE_TYPE X-Accel-Redirect;
250 fastcgi_param HTTP_X_ACCEL_MAPPING /my/app=/private;
251 fastcgi_pass unix:/my/app/run/app.sock;
255 In the example above, passing filehandles with a local path matching
256 /my/app/staging or /my/app/repo will be served by nginx. Passing paths
257 with other locations will lead to an internal server error.
259 Setting the body to a filehandle without the C<path> method bypasses
260 the middleware completely.
262 For Apache and Lighttpd, the mapping doesn't apply and setting the
263 X-Sendfile-Type is enough.
265 =head2 $res->has_body
267 Predicate which returns true when a body has been set.
271 Alias for $res->status.
273 =head2 $res->content_encoding
275 Shortcut for $res->headers->content_encoding.
277 =head2 $res->content_length
279 Shortcut for $res->headers->content_length.
281 =head2 $res->content_type
283 Shortcut for $res->headers->content_type.
285 This value is typically set by your view or plugin. For example,
286 L<Catalyst::Plugin::Static::Simple> will guess the mime type based on the file
287 it found, while L<Catalyst::View::TT> defaults to C<text/html>.
291 Returns a reference to a hash containing cookies to be set. The keys of the
292 hash are the cookies' names, and their corresponding values are hash
293 references used to construct a L<CGI::Simple::Cookie> object.
295 $c->response->cookies->{foo} = { value => '123' };
297 The keys of the hash reference on the right correspond to the L<CGI::Simple::Cookie>
298 parameters of the same name, except they are used without a leading dash.
299 Possible parameters are:
319 Shortcut for $res->headers->header.
323 Returns an L<HTTP::Headers> object, which can be used to set headers.
325 $c->response->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
329 Alias for $res->body.
331 =head2 $res->redirect( $url, $status )
333 Causes the response to redirect to the specified URL. The default status is
336 $c->response->redirect( 'http://slashdot.org' );
337 $c->response->redirect( 'http://slashdot.org', 307 );
339 This is a convenience method that sets the Location header to the
340 redirect destination, and then sets the response status. You will
341 want to C< return > or C<< $c->detach() >> to interrupt the normal
342 processing flow if you want the redirect to occur straight away.
344 B<Note:> do not give a relative URL as $url, i.e: one that is not fully
345 qualified (= C<http://...>, etc.) or that starts with a slash
346 (= C</path/here>). While it may work, it is not guaranteed to do the right
347 thing and is not a standard behaviour. You may opt to use uri_for() or
348 uri_for_action() instead.
356 my $location = shift;
357 my $status = shift || 302;
359 $self->location($location);
360 $self->status($status);
363 return $self->location;
366 =head2 $res->location
368 Sets or returns the HTTP 'Location'.
372 Sets or returns the HTTP status.
374 $c->response->status(404);
376 $res->code is an alias for this, to match HTTP::Response->code.
378 =head2 $res->write( $data )
380 Writes $data to the output stream.
382 =head2 $res->write_fh
384 Returns a PSGI $writer object that has two methods, write and close. You can
385 close over this object for asynchronous and nonblocking applications. For
386 example (assuming you are using a supporting server, like L<Twiggy>
388 package AsyncExample::Controller::Root;
392 BEGIN { extends 'Catalyst::Controller' }
398 $write_fh->write("Finishing: $message\n");
403 sub anyevent :Local :Args(0) {
405 my $cb = $self->prepare_cb($c->res->write_fh);
408 $watcher = AnyEvent->timer(
411 $cb->(scalar localtime);
412 undef $watcher; # cancel circular-ref
416 =head2 $res->print( @data )
418 Prints @data to the output stream, separated by $,. This lets you pass
419 the response object to functions that want to write to an L<IO::Handle>.
421 =head2 $self->finalize_headers($c)
423 Writes headers to response if not already written
425 =head2 from_psgi_response
427 Given a PSGI response (either three element ARRAY reference OR coderef expecting
428 a $responder) set the response from it.
430 Properly supports streaming and delayed response and / or async IO if running
431 under an expected event loop.
435 package MyApp::Web::Controller::Test;
437 use base 'Catalyst::Controller';
438 use Plack::App::Directory;
441 my $app = Plack::App::Directory->new({ root => "/path/to/htdocs" })
444 sub myaction :Local Args {
446 $c->res->from_psgi_response($app->($c->req->env));
449 Please note this does not attempt to map or nest your PSGI application under
450 the Controller and Action namespace or path.
454 Ensures that the response is flushed and closed at the end of the
467 defined $self->write($data) or return;
470 defined $self->write($,) or return;
471 defined $self->write($_) or return;
473 defined $self->write($\) or return;
480 Catalyst Contributors, see Catalyst.pm
484 This library is free software. You can redistribute it and/or modify
485 it under the same terms as Perl itself.
489 __PACKAGE__->meta->make_immutable;