Mailing List Archive

Catalyst::Test and POSTing non-form data
When I was writing tests for my C::C::REST stuff, I noticed that posting
stuff only worked if I set CATALYST_SERVER.

Here's a patch with a failing test:

Index: t/live_engine_request_body.t
===================================================================
--- t/live_engine_request_body.t (revision 8230)
+++ t/live_engine_request_body.t (working copy)
@@ -6,12 +6,13 @@
use FindBin;
use lib "$FindBin::Bin/lib";

-use Test::More tests => 18;
+use Test::More tests => 21;
use Catalyst::Test 'TestApp';

use Catalyst::Request;
use HTTP::Headers;
use HTTP::Request::Common;
+use HTTP::Request ();

{
my $creq;
@@ -75,3 +76,15 @@
is( $creq->content_length, $request->content_length,
'Catalyst::Request Content-Length' );
}
+
+{
+ my $request = HTTP::Request->new(POST => '/body');
+
+ $request->header('Content-Type' => 'text/xml');
+ $request->content('<item>chainsaw</item>');
+
+ ok( my $response = request($request), 'Request' );
+ ok( $response->is_success, 'Response Successful 2xx' );
+
+ is( $response->content, '<item>chainsaw</item>', '$c->req->body is
set' );
+}
Index: t/lib/TestApp/Controller/Body.pm
===================================================================
--- t/lib/TestApp/Controller/Body.pm (revision 0)
+++ t/lib/TestApp/Controller/Body.pm (revision 0)
@@ -0,0 +1,13 @@
+package TestApp::Controller::Body;
+
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+
+sub dump_body : Path Args(0) {
+ my ( $self, $c ) = @_;
+
+ $c->res->body($c->req->body);
+}
+
+1;

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Catalyst::Test and POSTing non-form data [ In reply to ]
Never mind, andyg pointed out that this was due to the missing
Content-Length header, adding which makes the test pass.

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Catalyst::Test and POSTing non-form data [ In reply to ]
Here's a small patch which adds a Content-Length header if it's not in
the request object passed to Catalyst::Test

Index: lib/Catalyst/Utils.pm
===================================================================
--- lib/Catalyst/Utils.pm (revision 8230)
+++ lib/Catalyst/Utils.pm (working copy)
@@ -233,6 +233,13 @@
unless ( ref $request eq 'HTTP::Request' ) {
$request = HTTP::Request->new( 'GET', $request );
}
+
+ if (defined $request->content
+ && !defined $request->header('Content-Length')) {
+ use bytes;
+ $request->header('Content-Length' => length $request->content);
+ }
+
return $request;
}


_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Catalyst::Test and POSTing non-form data [ In reply to ]
Rafael Kitover wrote:
> Here's a small patch which adds a Content-Length header if it's not in
> the request object passed to Catalyst::Test
>
> Index: lib/Catalyst/Utils.pm
> ===================================================================
> --- lib/Catalyst/Utils.pm (revision 8230)
> +++ lib/Catalyst/Utils.pm (working copy)
> @@ -233,6 +233,13 @@
> unless ( ref $request eq 'HTTP::Request' ) {
> $request = HTTP::Request->new( 'GET', $request );
> }
> +
> + if (defined $request->content
> + && !defined $request->header('Content-Length')) {
> + use bytes;
> + $request->header('Content-Length' => length $request->content);
> + }
> +
> return $request;
> }

That's going to break when unicode is involved is it not?

http://perldoc.perl.org/functions/length.html
> Note the characters: if the EXPR is in Unicode, you will get the number of characters, not the number of bytes. To get the length of the internal string in bytes, use bytes::length(EXPR) , see bytes. Note that the internal encoding is variable, and the number of bytes usually meaningless. To get the number of bytes that the string would have when encoded as UTF-8, use length(Encoding::encode_utf8(EXPR)).

-=Chris

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
Re: Catalyst::Test and POSTing non-form data [ In reply to ]
* On Mon, Aug 18 2008, Christopher H. Laco wrote:
> Rafael Kitover wrote:
>> Here's a small patch which adds a Content-Length header if it's not in
>> the request object passed to Catalyst::Test
>>
>> Index: lib/Catalyst/Utils.pm
>> ===================================================================
>> --- lib/Catalyst/Utils.pm (revision 8230)
>> +++ lib/Catalyst/Utils.pm (working copy)
>> @@ -233,6 +233,13 @@
>> unless ( ref $request eq 'HTTP::Request' ) {
>> $request = HTTP::Request->new( 'GET', $request );
>> }
>> +
>> + if (defined $request->content
>> + && !defined $request->header('Content-Length')) {
>> + use bytes;
>> + $request->header('Content-Length' => length $request->content);
>> + }
>> +
>> return $request;
>> }
>
> That's going to break when unicode is involved is it not?

I don't think you can get reliable behavior when you put raw perl
characters in the HTTP::Request object anyway. If you want to send a
unicode request, you need to encode the characters into bytes and set
the appropriate content-type header. So at that point, "length" will be
correct.

The real problem is the lack of a helper that automates this. Maybe
mech does, but I wouldn't count on it since mech goes out of its way to
be useless with anything other than ASCII.

Regards,
Jonathan Rockway

--
print just => another => perl => hacker => if $,=$"

_______________________________________________
Catalyst-dev mailing list
Catalyst-dev@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev