Subject: | [PATCH] Wrong Content-Length when $c->res->body is a glob |
If you set $c->res->body to a glob that is not tied to a file (e.g. a
handle from IPC::Open3), then the Content-Length is set to the length of
the length of the first chunk of data read from that handle. Instead,
pipes like this should have indeterminate content length. The attached
patch (against SVN rev 5943) corrects this issue, cribbing from
Catalyst::Engine::finalize_body.
With this patch, the example action below works. In my example, the
@cmd is a variation on "make test".
-- Chris
use IPC::Open3 qw();
sub test : Local {
my ( $self, $c ) = @_;
local %ENV = (
PATH => $ENV{PATH},
);
my @cmd = get_cmd();
my ($wtr, $rdr);
my $pid = IPC::Open3::open3($wtr, $rdr, undef, @cmd);
if (!$pid) {
$c->res->status(500);
$c->res->body('Failed to run tests');
} else {
close $wtr;
$c->res->content_type('text/plain');
$c->res->body($rdr);
# TODO: figure out how to waitpid after finalize_body
# and adjust CHUNKSIZE
to something smaller than 4096
#waitpid $pid, 0;
}
return;
}
Subject: | glob_body.patch |
Index: lib/Catalyst.pm
===================================================================
--- lib/Catalyst.pm (revision 5943)
+++ lib/Catalyst.pm (working copy)
@@ -1386,9 +1386,11 @@
if ( $c->response->body && !$c->response->content_length ) {
# get the length from a filehandle
- if ( blessed( $c->response->body ) && $c->response->body->can('read') )
+ my $body = $c->response->body;
+ if ( blessed( $body ) && $body->can('read') or ref($body) eq 'GLOB')
{
- if ( my $stat = stat $c->response->body ) {
+ my $stat = stat $body;
+ if ( $stat && $stat->size ) {
$c->response->content_length( $stat->size );
}
else {
@@ -1396,7 +1398,7 @@
}
}
else {
- $c->response->content_length( bytes::length( $c->response->body ) );
+ $c->response->content_length( bytes::length( $body ) );
}
}