From: Stefan Seifert Date: Fri, 19 Nov 2010 12:08:17 +0000 (+0000) Subject: Fix passing file GLOBs to $c->res->body X-Git-Tag: 5.80030~24 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=f397b3064091f4b9f03210d5b630cfd757534c50 Fix passing file GLOBs to $c->res->body Contrary to the documentation of Catalyst::Response, passing a filehandle GLOB did not work, since the content-length header was not computed correctly. body checked if it was passed a blessed object and only then use stat to get the file size. In all other cases the passed thing was considered a string and length was used. Filehandle GLOBs are neither blessed nor strings, so the content-length header always got set to 15 (length of a stringified GLOB: "GLOB(0x123456)"). --- diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index f3bf321..ea011de 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -1858,7 +1858,7 @@ sub finalize_headers { if ( $response->body && !$response->content_length ) { # get the length from a filehandle - if ( blessed( $response->body ) && $response->body->can('read') ) + if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' ) { my $stat = stat $response->body; if ( $stat && $stat->size > 0 ) { diff --git a/t/aggregate/live_component_controller_action_streaming.t b/t/aggregate/live_component_controller_action_streaming.t index 4300744..4a42e3f 100644 --- a/t/aggregate/live_component_controller_action_streaming.t +++ b/t/aggregate/live_component_controller_action_streaming.t @@ -10,7 +10,7 @@ our $iters; BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; } -use Test::More tests => 15*$iters; +use Test::More tests => 20*$iters; use Catalyst::Test 'TestApp'; if ( $ENV{CAT_BENCHMARK} ) { @@ -51,14 +51,14 @@ EOF SKIP: { if ( $ENV{CATALYST_SERVER} ) { - skip "Using remote server", 5; + skip "Using remote server", 10; } my $file = "$FindBin::Bin/../lib/TestApp/Controller/Action/Streaming.pm"; my $fh = IO::File->new( $file, 'r' ); my $buffer; if ( defined $fh ) { - $fh->read( $buffer, 1024 ); + $fh->read( $buffer, 2048 ); $fh->close; } @@ -68,6 +68,13 @@ EOF is( $response->content_type, 'text/plain', 'Response Content-Type' ); is( $response->content_length, -s $file, 'Response Content-Length' ); is( $response->content, $buffer, 'Content is read from filehandle' ); + + ok( $response = request('http://localhost/action/streaming/body_glob'), + 'Request' ); + ok( $response->is_success, 'Response Successful 2xx' ); + is( $response->content_type, 'text/plain', 'Response Content-Type' ); + is( $response->content_length, -s $file, 'Response Content-Length' ); + is( $response->content, $buffer, 'Content is read from filehandle' ); } { diff --git a/t/lib/TestApp/Controller/Action/Streaming.pm b/t/lib/TestApp/Controller/Action/Streaming.pm index 08c7c65..a5b2c81 100644 --- a/t/lib/TestApp/Controller/Action/Streaming.pm +++ b/t/lib/TestApp/Controller/Action/Streaming.pm @@ -27,6 +27,19 @@ sub body : Local { } } +sub body_glob : Local { + my ( $self, $c ) = @_; + + my $file = "$FindBin::Bin/../lib/TestApp/Controller/Action/Streaming.pm"; + open my $fh, '<', $file; + if ( defined $fh ) { + $c->res->body( $fh ); + } + else { + $c->res->body( "Unable to read $file" ); + } +} + sub body_large : Local { my ($self, $c) = @_;