File Coverage

blib/lib/Catalyst/Response.pm
Criterion Covered Total %
statement 103 105 98.1
branch 47 58 81.0
condition 16 20 80.0
subroutine 22 22 100.0
pod 11 11 100.0
total 199 216 92.1


line stmt bran cond sub pod time code
1              
2             use Moose;
3 166     166   5803 use HTTP::Headers;
  166         467993  
  166         1468  
4 166     166   1134155 use Moose::Util::TypeConstraints;
  166         7734  
  166         5098  
5 166     166   1020 use Scalar::Util 'blessed';
  166         388  
  166         1645  
6 166     166   363591 use Catalyst::Response::Writer;
  166         450  
  166         11373  
7 166     166   94996 use Catalyst::Utils ();
  166         547  
  166         5484  
8 166     166   18584  
  166         458  
  166         6972  
9             use namespace::clean -except => ['meta'];
10 166     166   998  
  166         420  
  166         1603  
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             my $self = shift;
43              
44 17     17   43 ## These two lines are probably crap now...
45             $self->_context->finalize_headers unless
46             $self->finalized_headers;
47 17 100       456  
48             my @headers;
49             $self->headers->scan(sub { push @headers, @_ });
50 17         45  
51 17     89   74 my $writer = $self->_response_cb->([ $self->status, \@headers ]);
  89         1217  
52             $self->_clear_response_cb;
53 17         157  
54 17         7775 return $writer;
55             }
56 17         430  
57             has write_fh => (
58             is=>'ro',
59             predicate=>'_has_write_fh',
60             lazy=>1,
61             builder=>'_build_write_fh',
62             );
63              
64             my $writer = $_[0]->_writer; # We need to get the finalize headers side effect...
65             my $requires_encoding = $_[0]->encodable_response;
66             my %fields = (
67 5     5   142 _writer => $writer,
68 5         21 _context => $_[0]->_context,
69 5         143 _requires_encoding => $requires_encoding,
70             );
71              
72             return bless \%fields, 'Catalyst::Response::Writer';
73             }
74              
75 5         142 my $self = shift;
76             return if $self->_has_write_fh;
77             if($self->_has_writer) {
78             $self->_writer->close
79 921     921 1 2712 }
80 921 50       28737 }
81 921 50       29848  
82 0         0 has cookies => (is => 'rw', default => sub { {} });
83             has body => (is => 'rw', default => undef);
84              
85             has location => (is => 'rw');
86             has status => (is => 'rw', default => 200);
87             has finalized_headers => (is => 'rw', default => 0);
88 1     1 1 41 has headers => (
89             is => 'rw',
90             isa => 'HTTP::Headers',
91             handles => [qw(content_encoding content_length content_type content_type_charset header)],
92             default => sub { HTTP::Headers->new() },
93             required => 1,
94             lazy => 1,
95             );
96             has _context => (
97             is => 'rw',
98             weak_ref => 1,
99             clearer => '_clear_context',
100             );
101              
102             before [qw(status headers content_encoding content_length content_type )] => sub {
103             my $self = shift;
104              
105             $self->_context->log->warn(
106             "Useless setting a header value after finalize_headers and the response callback has been called." .
107             " Since we don't support tail headers this will not work as you might expect." )
108             if ( $self->_context && $self->finalized_headers && !$self->_has_response_cb && @_ );
109             };
110              
111             # This has to be different since the first param to ->header is the header name and presumably
112             # you should be able to request the header even after finalization, just not try to change it.
113             before 'header' => sub {
114             my $self = shift;
115             my $header = shift;
116              
117             $self->_context->log->warn(
118             "Useless setting a header value after finalize_headers and the response callback has been called." .
119             " Since we don't support tail headers this will not work as you might expect." )
120             if ( $self->_context && $self->finalized_headers && !$self->_has_response_cb && @_ );
121             };
122              
123              
124              
125             my ( $self, $buffer ) = @_;
126              
127             # Finalize headers if someone manually writes output
128 128     128 1 3931 $self->_context->finalize_headers unless $self->finalized_headers;
129              
130 3     3 1 18 $buffer = q[] unless defined $buffer;
131              
132             if($self->encodable_response) {
133 31     31 1 85 $buffer = $self->_context->encoding->encode( $buffer, $self->_context->_encode_check )
134             }
135              
136 31 100       803 my $len = length($buffer);
137             $self->_writer->write($buffer);
138 31 100       86  
139             return $len;
140 31 100       91 }
141 18         449  
142             my ( $self, $buffer ) = @_;
143              
144 31         99 # Finalize headers if someone manually writes output
145 31         862 $self->_context->finalize_headers unless $self->finalized_headers;
146              
147 31         1355 $buffer = q[] unless defined $buffer;
148              
149             my $len = length($buffer);
150             $self->_writer->write($buffer);
151 3     3 1 10  
152             return $len;
153             }
154 3 50       76  
155             my ($self) = @_;
156 3 50       13 return;
157             }
158 3         7  
159 3         72 my ($self, $psgi_res) = @_;
160             if(blessed($psgi_res) && $psgi_res->can('as_psgi')) {
161 3         964 $psgi_res = $psgi_res->as_psgi;
162             }
163             if(ref $psgi_res eq 'ARRAY') {
164             my ($status, $headers, $body) = @$psgi_res;
165 920     920 1 2535 $self->status($status);
166 920         1895 $self->headers(HTTP::Headers->new(@$headers));
167             # Can be arrayref or filehandle...
168             if(defined $body) { # probably paranoia
169             ref $body eq 'ARRAY' ? $self->body(join('', @$body)) : $self->body($body);
170 44     44 1 1506 }
171 44 100 66     223 } elsif(ref $psgi_res eq 'CODE') {
172 1         5  
173             # Its not clear to me this is correct. Right now if the PSGI application wants
174 44 100       199 # to stream, we stream immediately and then completely bypass the rest of the
    50          
175 36         79 # Catalyst finalization process (unlike if the PSGI app sets an arrayref). Part of
176 36         166 # me thinks we should override the current _response_cb and then let finalize_body
177 36         142 # call that. I'm not sure the downside of bypassing those bits. I'm going to leave
178             # this be for now and document the behavior.
179 36 50       82  
180 36 100       955 $psgi_res->(sub {
181             my $response = shift;
182             my ($status, $headers, $maybe_body) = @$response;
183             $self->status($status);
184             $self->headers(HTTP::Headers->new(@$headers));
185             if(defined $maybe_body) {
186             # Can be arrayref or filehandle...
187             ref $maybe_body eq 'ARRAY' ? $self->body(join('', @$maybe_body)) : $self->body($maybe_body);
188             } else {
189             return $self->write_fh;
190             }
191             });
192 8     8   800 } else {
193 8         24 die "You can't set a Catalyst response from that, expect a valid PSGI response";
194 8         37 }
195 8         42  
196 8 100       57 # Encoding compatibilty. If the response set a charset, well... we need
197             # to assume its properly encoded and NOT encode for this response. Otherwise
198 5 50       153 # We risk double encoding.
199              
200 3         81 # We check first to make sure headers have not been finalized. Headers might be finalized
201             # in the case where a PSGI response is streaming and the PSGI application already wrote
202 8         80 # to the output stream and close the filehandle.
203             if(!$self->finalized_headers && $self->content_type_charset) {
204 0         0 # We have to do this since for backcompat reasons having a charset doesn't always
205             # mean that the body is already encoded :(
206             $self->_context->clear_encoding;
207             }
208             }
209              
210             =head1 NAME
211              
212             Catalyst::Response - stores output responding to the current client request
213              
214 44 100 100     1686 =head1 SYNOPSIS
215              
216             $res = $c->response;
217 1         114 $res->body;
218             $res->code;
219             $res->content_encoding;
220             $res->content_length;
221             $res->content_type;
222             $res->cookies;
223             $res->header;
224             $res->headers;
225             $res->output;
226             $res->redirect;
227             $res->status;
228             $res->write;
229              
230             =head1 DESCRIPTION
231              
232             This is the Catalyst Response class, which provides methods for responding to
233             the current client request. The appropriate L<Catalyst::Engine> for your environment
234             will turn the Catalyst::Response into a HTTP Response and return it to the client.
235              
236             =head1 METHODS
237              
238             =head2 $res->body( $text | $fh | $iohandle_object )
239              
240             $c->response->body('Catalyst rocks!');
241              
242             Sets or returns the output (text or binary data). If you are returning a large body,
243             you might want to use a L<IO::Handle> type of object (Something that implements the getline method
244             in the same fashion), or a filehandle GLOB. These will be passed down to the PSGI
245             handler you are using and might be optimized using server specific abilities (for
246             example L<Twiggy> will attempt to server a real local file in a non blocking manner).
247              
248             If you are using a filehandle as the body response you are responsible for
249             making sure it conforms to the L<PSGI> specification with regards to content
250             encoding. Unlike with scalar body values or when using the streaming interfaces
251             we currently do not attempt to normalize and encode your filehandle. In general
252             this means you should be sure to be sending bytes not UTF8 decoded multibyte
253             characters.
254              
255             Most of the time when you do:
256              
257             open(my $fh, '<:raw', $path);
258              
259             You should be fine. If you open a filehandle with a L<PerlIO> layer you probably
260             are not fine. You can usually fix this by explicitly using binmode to set
261             the IOLayer to :raw. Its possible future versions of L<Catalyst> will try to
262             'do the right thing'.
263              
264             When using a L<IO::Handle> type of object and no content length has been
265             already set in the response headers Catalyst will make a reasonable attempt
266             to determine the size of the Handle. Depending on the implementation of your
267             handle object, setting the content length may fail. If it is at all possible
268             for you to determine the content length of your handle object,
269             it is recommended that you set the content length in the response headers
270             yourself, which will be respected and sent by Catalyst in the response.
271              
272             Please note that the object needs to implement C<getline>, not just
273             C<read>. Older versions of L<Catalyst> expected your filehandle like objects
274             to do read. If you have code written for this expectation and you cannot
275             change the code to meet the L<PSGI> specification, you can try the following
276             middleware L<Plack::Middleware::AdaptFilehandleRead> which will attempt to
277             wrap your object in an interface that so conforms.
278              
279             Starting from version 5.90060, when using an L<IO::Handle> object, you
280             may want to use L<Plack::Middleware::XSendfile>, to delegate the
281             actual serving to the frontend server. To do so, you need to pass to
282             C<body> an IO object with a C<path> method. This can be achieved in
283             two ways.
284              
285             Either using L<Plack::Util>:
286              
287             my $fh = IO::File->new($file, 'r');
288             Plack::Util::set_io_path($fh, $file);
289              
290             Or using L<IO::File::WithPath>
291              
292             my $fh = IO::File::WithPath->new($file, 'r');
293              
294             And then passing the filehandle to body and setting headers, if needed.
295              
296             $c->response->body($fh);
297             $c->response->headers->content_type('text/plain');
298             $c->response->headers->content_length(-s $file);
299             $c->response->headers->last_modified((stat($file))[9]);
300              
301             L<Plack::Middleware::XSendfile> can be loaded in the application so:
302              
303             __PACKAGE__->config(
304             psgi_middleware => [
305             'XSendfile',
306             # other middlewares here...
307             ],
308             );
309              
310             B<Beware> that loading the middleware without configuring the
311             webserver to set the request header C<X-Sendfile-Type> to a supported
312             type (C<X-Accel-Redirect> for nginx, C<X-Sendfile> for Apache and
313             Lighttpd), could lead to the disclosure of private paths to malicious
314             clients setting that header.
315              
316             Nginx needs the additional X-Accel-Mapping header to be set in the
317             webserver configuration, so the middleware will replace the absolute
318             path of the IO object with the internal nginx path. This is also
319             useful to prevent a buggy app to server random files from the
320             filesystem, as it's an internal redirect.
321              
322             An nginx configuration for FastCGI could look so:
323              
324             server {
325             server_name example.com;
326             root /my/app/root;
327             location /private/repo/ {
328             internal;
329             alias /my/app/repo/;
330             }
331             location /private/staging/ {
332             internal;
333             alias /my/app/staging/;
334             }
335             location @proxy {
336             include /etc/nginx/fastcgi_params;
337             fastcgi_param SCRIPT_NAME '';
338             fastcgi_param PATH_INFO $fastcgi_script_name;
339             fastcgi_param HTTP_X_SENDFILE_TYPE X-Accel-Redirect;
340             fastcgi_param HTTP_X_ACCEL_MAPPING /my/app=/private;
341             fastcgi_pass unix:/my/app/run/app.sock;
342             }
343             }
344              
345             In the example above, passing filehandles with a local path matching
346             /my/app/staging or /my/app/repo will be served by nginx. Passing paths
347             with other locations will lead to an internal server error.
348              
349             Setting the body to a filehandle without the C<path> method bypasses
350             the middleware completely.
351              
352             For Apache and Lighttpd, the mapping doesn't apply and setting the
353             X-Sendfile-Type is enough.
354              
355             =head2 $res->has_body
356              
357             Predicate which returns true when a body has been set.
358              
359             =head2 $res->code
360              
361             Alias for $res->status.
362              
363             =head2 $res->content_encoding
364              
365             Shortcut for $res->headers->content_encoding.
366              
367             =head2 $res->content_length
368              
369             Shortcut for $res->headers->content_length.
370              
371             =head2 $res->content_type
372              
373             Shortcut for $res->headers->content_type.
374              
375             This value is typically set by your view or plugin. For example,
376             L<Catalyst::Plugin::Static::Simple> will guess the mime type based on the file
377             it found, while L<Catalyst::View::TT> defaults to C<text/html>.
378              
379             =head2 $res->content_type_charset
380              
381             Shortcut for $res->headers->content_type_charset;
382              
383             =head2 $res->cookies
384              
385             Returns a reference to a hash containing cookies to be set. The keys of the
386             hash are the cookies' names, and their corresponding values are hash
387             references used to construct a L<CGI::Simple::Cookie> object.
388              
389             $c->response->cookies->{foo} = { value => '123' };
390              
391             The keys of the hash reference on the right correspond to the L<CGI::Simple::Cookie>
392             parameters of the same name, except they are used without a leading dash.
393             Possible parameters are:
394              
395             =over
396              
397             =item value
398              
399             =item expires
400              
401             =item domain
402              
403             =item path
404              
405             =item secure
406              
407             =item httponly
408              
409             =back
410              
411             =head2 $res->header
412              
413             Shortcut for $res->headers->header.
414              
415             =head2 $res->headers
416              
417             Returns an L<HTTP::Headers> object, which can be used to set headers.
418              
419             $c->response->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
420              
421             =head2 $res->output
422              
423             Alias for $res->body.
424              
425             =head2 $res->redirect( $url, $status )
426              
427             Causes the response to redirect to the specified URL. The default status is
428             C<302>.
429              
430             $c->response->redirect( 'http://slashdot.org' );
431             $c->response->redirect( 'http://slashdot.org', 307 );
432              
433             This is a convenience method that sets the Location header to the
434             redirect destination, and then sets the response status. You will
435             want to C< return > or C<< $c->detach() >> to interrupt the normal
436             processing flow if you want the redirect to occur straight away.
437              
438             B<Note:> do not give a relative URL as $url, i.e: one that is not fully
439             qualified (= C<http://...>, etc.) or that starts with a slash
440             (= C</path/here>). While it may work, it is not guaranteed to do the right
441             thing and is not a standard behaviour. You may opt to use uri_for() or
442             uri_for_action() instead.
443              
444             B<Note:> If $url is an object that does ->as_string (such as L<URI>, which is
445             what you get from ->uri_for) we automatically call that to stringify. This
446             should ease the common case usage
447              
448             return $c->res->redirect( $c->uri_for(...));
449              
450             =cut
451              
452             my $self = shift;
453              
454             if (@_) {
455             my $location = shift;
456             my $status = shift || 302;
457              
458             if(blessed($location) && $location->can('as_string')) {
459             $location = $location->as_string;
460             }
461              
462             $self->location($location);
463             $self->status($status);
464 934     934 1 2080 }
465              
466 934 100       2936 return $self->location;
467 14         29 }
468 14   50     99  
469             =head2 $res->location
470 14 100 66     128  
471 4         17 Sets or returns the HTTP 'Location'.
472              
473             =head2 $res->status
474 14         454  
475 14         61 Sets or returns the HTTP status.
476              
477             $c->response->status(404);
478 934         26341  
479             $res->code is an alias for this, to match HTTP::Response->code.
480              
481             =head2 $res->write( $data )
482              
483             Writes $data to the output stream. Calling this method will finalize your
484             headers and send the headers and status code response to the client (so changing
485             them afterwards is a waste... be sure to set your headers correctly first).
486              
487             You may call this as often as you want throughout your response cycle. You may
488             even set a 'body' afterward. So for example you might write your HTTP headers
489             and the HEAD section of your document and then set the body from a template
490             driven from a database. In some cases this can seem to the client as if you had
491             a faster overall response (but note that unless your server support chunked
492             body your content is likely to get queued anyway (L<Starman> and most other
493             http 1.1 webservers support this).
494              
495             If there is an encoding set, we encode each line of the response (the default
496             encoding is UTF-8).
497              
498             =head2 $res->unencoded_write( $data )
499              
500             Works just like ->write but we don't apply any content encoding to C<$data>. Use
501             this if you are already encoding the $data or the data is arriving from an encoded
502             storage.
503              
504             =head2 $res->write_fh
505              
506             Returns an instance of L<Catalyst::Response::Writer>, which is a lightweight
507             decorator over the PSGI C<$writer> object (see L<PSGI.pod\Delayed-Response-and-Streaming-Body>).
508              
509             In addition to proxying the C<write> and C<close> method from the underlying PSGI
510             writer, this proxy object knows any application wide encoding, and provides a method
511             C<write_encoded> that will properly encode your written lines based upon your
512             encoding settings. By default in L<Catalyst> responses are UTF-8 encoded and this
513             is the encoding used if you respond via C<write_encoded>. If you want to handle
514             encoding yourself, you can use the C<write> method directly.
515              
516             Encoding only applies to content types for which it matters. Currently the following
517             content types are assumed to need encoding: text (including HTML), xml and javascript.
518              
519             We provide access to this object so that you can properly close over it for use in
520             asynchronous and nonblocking applications. For example (assuming you are using a supporting
521             server, like L<Twiggy>:
522              
523             package AsyncExample::Controller::Root;
524              
525             use Moose;
526              
527             BEGIN { extends 'Catalyst::Controller' }
528              
529             sub prepare_cb {
530             my $write_fh = pop;
531             return sub {
532             my $message = shift;
533             $write_fh->write("Finishing: $message\n");
534             $write_fh->close;
535             };
536             }
537              
538             sub anyevent :Local :Args(0) {
539             my ($self, $c) = @_;
540             my $cb = $self->prepare_cb($c->res->write_fh);
541              
542             my $watcher;
543             $watcher = AnyEvent->timer(
544             after => 5,
545             cb => sub {
546             $cb->(scalar localtime);
547             undef $watcher; # cancel circular-ref
548             });
549             }
550              
551             Like the 'write' method, calling this will finalize headers. Unlike 'write' when you
552             can this it is assumed you are taking control of the response so the body is never
553             finalized (there isn't one anyway) and you need to call the close method.
554              
555             =head2 $res->print( @data )
556              
557             Prints @data to the output stream, separated by $,. This lets you pass
558             the response object to functions that want to write to an L<IO::Handle>.
559              
560             =head2 $res->finalize_headers()
561              
562             Writes headers to response if not already written
563              
564             =head2 from_psgi_response
565              
566             Given a PSGI response (either three element ARRAY reference OR coderef expecting
567             a $responder) set the response from it.
568              
569             Properly supports streaming and delayed response and / or async IO if running
570             under an expected event loop.
571              
572             If passed an object, will expect that object to do a method C<as_psgi>.
573              
574             Example:
575              
576             package MyApp::Web::Controller::Test;
577              
578             use base 'Catalyst::Controller';
579             use Plack::App::Directory;
580              
581              
582             my $app = Plack::App::Directory->new({ root => "/path/to/htdocs" })
583             ->to_app;
584              
585             sub myaction :Local Args {
586             my ($self, $c) = @_;
587             $c->res->from_psgi_response($app->($c->req->env));
588             }
589              
590             sub streaming_body :Local {
591             my ($self, $c) = @_;
592             my $psgi_app = sub {
593             my $respond = shift;
594             my $writer = $respond->([200,["Content-Type" => "text/plain"]]);
595             $writer->write("body");
596             $writer->close;
597             };
598             $c->res->from_psgi_response($psgi_app);
599             }
600              
601             Please note this does not attempt to map or nest your PSGI application under
602             the Controller and Action namespace or path. You may wish to review 'PSGI Helpers'
603             under L<Catalyst::Utils> for help in properly nesting applications.
604              
605             B<NOTE> If your external PSGI application returns a response that has a character
606             set associated with the content type (such as "text/html; charset=UTF-8") we set
607             $c->clear_encoding to remove any additional content type encoding processing later
608             in the application (this is done to avoid double encoding issues).
609              
610             B<NOTE> If your external PSGI application is streaming, we assume you completely
611             handle the entire jobs (including closing the stream). This will also bypass
612             the output finalization methods on Catalyst (such as 'finalize_body' which gets
613             called but then skipped when it finds that output is already finished.) Its possible
614             this might cause issue with some plugins that want to do 'things' during those
615             finalization methods. Just understand what is happening.
616              
617             =head2 encodable_content_type
618              
619             This is a regular expression used to determine of the current content type
620             should be considered encodable. Currently we apply default encoding (usually
621             UTF8) to text type contents. Here's the default regular expression:
622              
623             This would match content types like:
624              
625             text/plain
626             text/html
627             text/xml
628             application/javascript
629             application/xml
630             application/vnd.user+xml
631              
632             B<NOTE>: We don't encode JSON content type responses by default since most
633             of the JSON serializers that are commonly used for this task will do so
634             automatically and we don't want to double encode. If you are not using a
635             tool like L<JSON> to produce JSON type content, (for example you are using
636             a template system, or creating the strings manually) you will need to either
637             encoding the body yourself:
638              
639             $c->response->body( $c->encoding->encode( $body, $c->_encode_check ) );
640              
641             Or you can alter the regular expression using this attribute.
642              
643             =head2 encodable_response
644              
645             Given a L<Catalyst::Response> return true if its one that can be encoded.
646              
647             make sure there is an encoding set on the response
648             make sure the content type is encodable
649             make sure no content type charset has been already set to something different from the global encoding
650             make sure no content encoding is present.
651              
652             Note this does not inspect a body since we do allow automatic encoding on streaming
653             type responses.
654              
655             =cut
656              
657             my ($self) = @_;
658             return 0 unless $self->_context; # Cases like returning a HTTP Exception response you don't have a context here...
659             return 0 unless $self->_context->encoding;
660              
661             # The response is considered to have a 'manual charset' when a charset is already set on
662             # the content type of the response AND it is not the same as the one we set in encoding.
663             # If there is no charset OR we are asking for the one which is the same as the current
664             # required encoding, that is a flag that we want Catalyst to encode the response automatically.
665             my $has_manual_charset = 0;
666             if(my $charset = $self->content_type_charset) {
667             $has_manual_charset = (uc($charset) ne uc($self->_context->encoding->mime_name)) ? 1:0;
668             }
669              
670 956     956 1 2685 # Content type is encodable if it matches the regular expression stored in this attribute
671 956 100       28131 my $encodable_content_type = $self->content_type =~ m/${\$self->encodable_content_type}/ ? 1:0;
672 949 100       25196  
673             # The content encoding is allowed (for charset encoding) only if its empty or is set to identity
674             my $allowed_content_encoding = (!$self->content_encoding || $self->content_encoding eq 'identity') ? 1:0;
675              
676             # The content type must be an encodable type, and there must be NO manual charset and also
677             # the content encoding must be the allowed values;
678 917         2505 if(
679 917 100       3359 $encodable_content_type and
680 72 100       11562 !$has_manual_charset and
681             $allowed_content_encoding
682             ) {
683             return 1;
684 917 100       41530 } else {
  917         49684  
685             return 0;
686             }
687 917 100 66     4347 }
688              
689             =head2 DEMOLISH
690              
691 917 100 100     42845 Ensures that the response is flushed and closed at the end of the
      100        
692             request.
693              
694             =head2 meta
695              
696 244         7035 Provided by Moose
697              
698 673         3426 =cut
699              
700             my $self = shift;
701             my $data = shift;
702              
703             defined $self->write($data) or return;
704              
705             for (@_) {
706             defined $self->write($,) or return;
707             defined $self->write($_) or return;
708             }
709             defined $self->write($\) or return;
710              
711             return 1;
712             }
713              
714 3     3 1 8 =head1 AUTHORS
715 3         7  
716             Catalyst Contributors, see Catalyst.pm
717 3 50       14  
718             =head1 COPYRIGHT
719 3         14  
720 3 50       12 This library is free software. You can redistribute it and/or modify
721 3 50       11 it under the same terms as Perl itself.
722              
723 3 50       10 =cut
724              
725 3         29 __PACKAGE__->meta->make_immutable;
726              
727             1;