[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