allow $c->req->body to be a simple filehandle or a string
Brian Phillips [Tue, 20 Sep 2011 20:21:38 +0000 (15:21 -0500)]
Previously, it was assumed that the $c->req->body was both a filehandle
and a filename (something that was only true for File::Temp objects) and
didn't work if the request body was a plain string.  This distribution
now allows for either a filehandle or a string which is slightly different
semantics than specifically File::Temp objects (which are file handles
which string-ify to the filename)

lib/Catalyst/Action/Deserialize/Data/Serializer.pm
lib/Catalyst/Action/Deserialize/JSON.pm
lib/Catalyst/Action/Deserialize/XML/Simple.pm
lib/Catalyst/Action/Deserialize/YAML.pm

index 8b1df7c..a506c41 100644 (file)
@@ -6,6 +6,7 @@ use namespace::autoclean;
 extends 'Catalyst::Action';
 use Data::Serializer;
 use Safe;
+use Scalar::Util qw(openhandle);
 my $compartment = Safe->new;
 $compartment->permit_only( qw(padany null lineseq const pushmark list anonhash anonlist refgen leaveeval undef) );
 
@@ -29,14 +30,17 @@ sub execute {
     }
     my $body = $c->request->body;
     if ($body) {
-        my $rbody;
-        if ( -f $c->request->body ) {
-            open( BODY, "<", $c->request->body );
-            while ( my $line = <BODY> ) {
+        my $rbody = '';
+
+        if(openhandle $body) {
+            seek($body, 0, 0); # in case something has already read from it
+            while ( defined( my $line = <$body> ) ) {
                 $rbody .= $line;
             }
-            close(BODY);
+        } else {
+            $rbody = $body;
         }
+
         my $rdata;
         if ( $serializer eq "Data::Dumper" ) {
             # Taken from Data::Serialize::Data::Dumper::deserialize, but run within a Safe compartment
index 8799735..3f718bf 100644 (file)
@@ -2,6 +2,7 @@ package Catalyst::Action::Deserialize::JSON;
 
 use Moose;
 use namespace::autoclean;
+use Scalar::Util qw(openhandle);
 
 extends 'Catalyst::Action';
 use JSON;
@@ -13,12 +14,17 @@ sub execute {
     my $self = shift;
     my ( $controller, $c, $test ) = @_;
 
-    my $body = $c->request->body;
     my $rbody;
 
-    if ($body) {
-        while (my $line = <$body>) {
-            $rbody .= $line;
+    # could be a string or a FH
+    if ( my $body = $c->request->body ) {
+        if(openhandle $body) {
+            seek($body, 0, 0); # in case something has already read from it
+            while ( defined( my $line = <$body> ) ) {
+                $rbody .= $line;
+            }
+        } else {
+            $rbody = $body;
         }
     }
 
index 3dd3b6e..7f7ffa7 100644 (file)
@@ -2,6 +2,7 @@ package Catalyst::Action::Deserialize::XML::Simple;
 
 use Moose;
 use namespace::autoclean;
+use Scalar::Util qw(openhandle);
 
 extends 'Catalyst::Action';
 
@@ -26,7 +27,10 @@ sub execute {
         my $xs = XML::Simple->new('ForceArray' => 0,);
         my $rdata;
         eval {
-            $rdata = $xs->XMLin( "$body" );
+            if(openhandle $body){ # make sure we rewind the file handle
+                seek($body, 0, 0); # in case something has already read from it
+            }
+            $rdata = $xs->XMLin( $body );
         };
         if ($@) {
             return $@;
index b9003a6..fa5524c 100644 (file)
@@ -2,6 +2,7 @@ package Catalyst::Action::Deserialize::YAML;
 
 use Moose;
 use namespace::autoclean;
+use Scalar::Util qw(openhandle);
 
 extends 'Catalyst::Action';
 use YAML::Syck;
@@ -15,10 +16,21 @@ sub execute {
 
     my $body = $c->request->body;
     if ($body) {
+
+        my $rbody = '';
+
+        if(openhandle $body) {
+            seek($body, 0, 0); # in case something has already read from it
+            while ( defined( my $line = <$body> ) ) {
+                $rbody .= $line;
+            }
+        } else {
+            $rbody = $body;
+        }
+
         my $rdata;
         eval {
-            my $body = $c->request->body;
-            $rdata = LoadFile( "$body" );
+            $rdata = Load( $rbody );
         };
         if ($@) {
             return $@;