use Moose::Util::TypeConstraints;
use namespace::autoclean;
use Scalar::Util 'blessed';
+use Catalyst::Response::Writer;
with 'MooseX::Emulate::Class::Accessor::Fast';
builder=>'_build_write_fh',
);
-sub _build_write_fh { shift ->_writer }
+sub _build_write_fh {
+ my $writer = $_[0]->_writer; # We need to get the finalize headers side effect...
+ my $requires_encoding = $_[0]->content_type =~ m/$Catalyst::DEFAULT_ENCODE_CONTENT_TYPE_MATCH/;
+ my %fields = (
+ _writer => $writer,
+ _encoding => $_[0]->encoding,
+ _requires_encoding => $requires_encoding,
+ );
+
+ return bless \%fields, 'Catalyst::Response::Writer';
+}
sub DEMOLISH {
my $self = shift;
clearer => '_clear_context',
);
+has encoding => (is=>'ro');
+
before [qw(status headers content_encoding content_length content_type header)] => sub {
my $self = shift;
$buffer = q[] unless defined $buffer;
$buffer = $self->_context->encoding->encode( $buffer, $self->_context->_encode_check )
- if $self->_context->encoding && $self->content_type =~ /^text|xml$|javascript$/;
+ if $self->_context->encoding && $self->content_type =~ /$Catalyst::DEFAULT_ENCODE_CONTENT_TYPE_MATCH/;
my $len = length($buffer);
$self->_writer->write($buffer);
=head2 $res->write_fh
-Returns a PSGI $writer object that has two methods, write and close. You can
-close over this object for asynchronous and nonblocking applications. For
-example (assuming you are using a supporting server, like L<Twiggy>
+Returns an instance of L<Catalyst::Response::Writer>, which is a lightweight
+decorator over the PSGI C<$writer> object (see L<PSGI.pod\Delayed-Response-and-Streaming-Body>).
+
+In addition to proxying the C<write> and C<close> method from the underlying PSGI
+writer, this proxy object knows any application wide encoding, and provides a method
+C<write_encoded> that will properly encode your written lines based upon your
+encoding settings. By default in L<Catalyst> responses are UTF-8 encoded and this
+is the encoding used if you respond via C<write_encoded>. If you want to handle
+encoding yourself, you can use the C<write> method directly.
+
+Encoding only applies to content types for which it matters. Currently the following
+content types are assumed to need encoding: text (including HTML), xml and javascript.
+
+We provide access to this object so that you can properly close over it for use in
+asynchronous and nonblocking applications. For example (assuming you are using a supporting
+server, like L<Twiggy>:
package AsyncExample::Controller::Root;