[Catalyst-commits] r6614 - in trunk/Catalyst-Runtime: . lib lib/Catalyst t t/lib t/lib/TestAppOnDemand t/lib/TestAppOnDemand/Controller

andyg at dev.catalyst.perl.org andyg at dev.catalyst.perl.org
Fri Aug 3 06:11:53 GMT 2007


Author: andyg
Date: 2007-08-03 06:11:51 +0100 (Fri, 03 Aug 2007)
New Revision: 6614

Added:
   trunk/Catalyst-Runtime/t/lib/TestAppOnDemand.pm
   trunk/Catalyst-Runtime/t/lib/TestAppOnDemand/
   trunk/Catalyst-Runtime/t/lib/TestAppOnDemand/Controller/
   trunk/Catalyst-Runtime/t/lib/TestAppOnDemand/Controller/Body.pm
   trunk/Catalyst-Runtime/t/live_engine_request_body_demand.t
Modified:
   trunk/Catalyst-Runtime/Changes
   trunk/Catalyst-Runtime/lib/Catalyst.pm
   trunk/Catalyst-Runtime/lib/Catalyst/Engine.pm
Log:
Fixed a bug where c->read didn't work properly, and added some tests for parse_on_demand mode

Modified: trunk/Catalyst-Runtime/Changes
===================================================================
--- trunk/Catalyst-Runtime/Changes	2007-08-03 04:57:21 UTC (rev 6613)
+++ trunk/Catalyst-Runtime/Changes	2007-08-03 05:11:51 UTC (rev 6614)
@@ -15,6 +15,7 @@
           properly exit after a write error.
           (http://rt.cpan.org/Ticket/Display.html?id=27135)
         - Remove warning for captures that are undef.
+        - Fixed $c->read and parse_on_demand mode.
 
 5.7007  2007-03-13 14:18:00
         - Many performance improvements by not using URI.pm:

Modified: trunk/Catalyst-Runtime/lib/Catalyst/Engine.pm
===================================================================
--- trunk/Catalyst-Runtime/lib/Catalyst/Engine.pm	2007-08-03 04:57:21 UTC (rev 6613)
+++ trunk/Catalyst-Runtime/lib/Catalyst/Engine.pm	2007-08-03 05:11:51 UTC (rev 6614)
@@ -279,12 +279,8 @@
 
 =cut
 
-sub finalize_read {
-    my ( $self, $c ) = @_;
+sub finalize_read { }
 
-    undef $self->{_prepared_read};
-}
-
 =head2 $self->finalize_uploads($c)
 
 Clean up after uploads, deleting temp files.
@@ -312,12 +308,8 @@
 
 sub prepare_body {
     my ( $self, $c ) = @_;
-    
-    my $length = $c->request->header('Content-Length') || 0;
 
-    $self->read_length( $length );
-
-    if ( $length > 0 ) {
+    if ( my $length = $self->read_length ) {
         unless ( $c->request->{_body} ) {
             my $type = $c->request->header('Content-Type');
             $c->request->{_body} = HTTP::Body->new( $type, $length );
@@ -494,8 +486,11 @@
 sub prepare_read {
     my ( $self, $c ) = @_;
 
-    # Reset the read position
+    # Initialize the read position
     $self->read_position(0);
+    
+    # Initialize the amount of data we think we need to read
+    $self->read_length( $c->request->header('Content-Length') || 0 );
 }
 
 =head2 $self->prepare_request(@arguments)
@@ -565,11 +560,6 @@
 sub read {
     my ( $self, $c, $maxlength ) = @_;
 
-    unless ( $self->{_prepared_read} ) {
-        $self->prepare_read($c);
-        $self->{_prepared_read} = 1;
-    }
-
     my $remaining = $self->read_length - $self->read_position;
     $maxlength ||= $CHUNKSIZE;
 

Modified: trunk/Catalyst-Runtime/lib/Catalyst.pm
===================================================================
--- trunk/Catalyst-Runtime/lib/Catalyst.pm	2007-08-03 04:57:21 UTC (rev 6613)
+++ trunk/Catalyst-Runtime/lib/Catalyst.pm	2007-08-03 05:11:51 UTC (rev 6614)
@@ -1590,8 +1590,14 @@
         $c->prepare_cookies;
         $c->prepare_path;
 
-        # On-demand parsing
-        $c->prepare_body unless $c->config->{parse_on_demand};
+        # Prepare the body for reading, either by prepare_body
+        # or the user, if they are using $c->read
+        $c->prepare_read;
+        
+        # Parse the body unless the user wants it on-demand
+        unless ( $c->config->{parse_on_demand} ) {
+            $c->prepare_body;
+        }
     }
 
     my $method  = $c->req->method  || '';
@@ -1806,6 +1812,10 @@
 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
 directly.
 
+Warning: If you use read(), Catalyst will not process the body,
+so you will not be able to access POST parameters or file uploads via
+$c->request.  You must handle all body parsing yourself.
+
 =cut
 
 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
@@ -2217,8 +2227,8 @@
 =head1 ON-DEMAND PARSER
 
 The request body is usually parsed at the beginning of a request,
-but if you want to handle input yourself or speed things up a bit,
-you can enable on-demand parsing with a config parameter.
+but if you want to handle input yourself, you can enable on-demand
+parsing with a config parameter.
 
     MyApp->config->{parse_on_demand} = 1;
     

Added: trunk/Catalyst-Runtime/t/lib/TestAppOnDemand/Controller/Body.pm
===================================================================
--- trunk/Catalyst-Runtime/t/lib/TestAppOnDemand/Controller/Body.pm	                        (rev 0)
+++ trunk/Catalyst-Runtime/t/lib/TestAppOnDemand/Controller/Body.pm	2007-08-03 05:11:51 UTC (rev 6614)
@@ -0,0 +1,29 @@
+package TestAppOnDemand::Controller::Body;
+
+use strict;
+use base 'Catalyst::Base';
+
+use Data::Dump ();
+
+sub params : Local {
+    my ( $self, $c ) = @_;
+
+    $c->res->body( Data::Dump::dump( $c->req->body_parameters ) );
+}
+
+sub read : Local {
+    my ( $self, $c ) = @_;
+    
+    # read some data
+    my @chunks;
+    
+    while ( my $data = $c->read( 10_000 ) ) {
+        push @chunks, $data;
+    }
+
+    $c->res->content_type( 'text/plain');
+    
+    $c->res->body( join ( '|', map { length $_ } @chunks ) );
+}
+
+1;
\ No newline at end of file

Added: trunk/Catalyst-Runtime/t/lib/TestAppOnDemand.pm
===================================================================
--- trunk/Catalyst-Runtime/t/lib/TestAppOnDemand.pm	                        (rev 0)
+++ trunk/Catalyst-Runtime/t/lib/TestAppOnDemand.pm	2007-08-03 05:11:51 UTC (rev 6614)
@@ -0,0 +1,20 @@
+package TestAppOnDemand;
+
+use strict;
+use Catalyst qw/
+    Test::Errors 
+    Test::Headers 
+/;
+use Catalyst::Utils;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config(
+    name            => __PACKAGE__,
+    root            => '/some/dir',
+    parse_on_demand => 1,
+);
+
+__PACKAGE__->setup;
+
+1;

Added: trunk/Catalyst-Runtime/t/live_engine_request_body_demand.t
===================================================================
--- trunk/Catalyst-Runtime/t/live_engine_request_body_demand.t	                        (rev 0)
+++ trunk/Catalyst-Runtime/t/live_engine_request_body_demand.t	2007-08-03 05:11:51 UTC (rev 6614)
@@ -0,0 +1,66 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 8;
+use Catalyst::Test 'TestAppOnDemand';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+# Test a simple POST request to make sure body parsing
+# works in on-demand mode.
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip "Using remote server", 8;
+    }
+    
+    {
+        my $params;
+
+        my $request = POST(
+            'http://localhost/body/params',
+            'Content-Type' => 'application/x-www-form-urlencoded',
+            'Content'      => 'foo=bar&baz=quux'
+        );
+    
+        my $expected = { foo => 'bar', baz => 'quux' };
+
+        ok( my $response = request($request), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+
+        {
+            no strict 'refs';
+            ok(
+                eval '$params = ' . $response->content,
+                'Unserialize params'
+            );
+        }
+
+        is_deeply( $params, $expected, 'Catalyst::Request body parameters' );
+    }
+
+    # Test reading chunks of the request body using $c->read
+    {
+        my $creq;
+    
+        my $request = POST(
+            'http://localhost/body/read',
+            'Content-Type' => 'text/plain',
+            'Content'      => 'x' x 105_000
+        );
+    
+        my $expected = '10000|10000|10000|10000|10000|10000|10000|10000|10000|10000|5000';
+
+        ok( my $response = request($request), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $expected, 'Response Content' );
+    }
+}




More information about the Catalyst-commits mailing list