proposal to fix problem when we lose multipart meta info
[catagits/HTTP-Body.git] / lib / HTTP / Body.pm
index acecd21..807703d 100644 (file)
@@ -9,7 +9,8 @@ our $TYPES = {
     'application/x-www-form-urlencoded' => 'HTTP::Body::UrlEncoded',
     'multipart/form-data'               => 'HTTP::Body::MultiPart',
     'multipart/related'                 => 'HTTP::Body::XFormsMultipart',
-    'application/xml'                   => 'HTTP::Body::XForms'
+    'application/xml'                   => 'HTTP::Body::XForms',
+    'application/json'                  => 'HTTP::Body::OctetStream',
 };
 
 require HTTP::Body::OctetStream;
@@ -55,9 +56,9 @@ HTTP::Body - HTTP Body Parser
 
 =head1 DESCRIPTION
 
-HTTP::Body parses chunks of HTTP POST data and supports 
-application/octet-stream, application/x-www-form-urlencoded, and
-multipart/form-data.
+HTTP::Body parses chunks of HTTP POST data and supports
+application/octet-stream, application/json, application/x-www-form-urlencoded,
+and multipart/form-data.
 
 Chunked bodies are supported by not passing a length value to new().
 
@@ -89,9 +90,12 @@ sub new {
     }
 
     my $type;
+    my $earliest_index;
     foreach my $supported ( keys %{$TYPES} ) {
-        if ( index( lc($content_type), $supported ) >= 0 ) {
-            $type = $supported;
+        my $index = index( lc($content_type), $supported );
+        if ($index >= 0 && (!defined $earliest_index || $index < $earliest_index)) {
+            $type           = $supported;
+            $earliest_index = $index;
         }
     }
 
@@ -110,6 +114,7 @@ sub new {
         param_order    => [],
         state          => 'buffering',
         upload         => {},
+        part_data      => {},
         tmpdir         => File::Spec->tmpdir(),
     };
 
@@ -380,6 +385,45 @@ sub upload {
     return $self->{upload};
 }
 
+=item part_data
+
+Just like 'param' but gives you a hash of the full data associated with the
+part in a multipart type POST/PUT.  Example:
+
+    {
+      data => "test",
+      done => 1,
+      headers => {
+        "Content-Disposition" => "form-data; name=\"arg2\"",
+        "Content-Type" => "text/plain"
+      },
+      name => "arg2",
+      size => 4
+    }
+
+=cut
+
+sub part_data {
+    my $self = shift;
+
+    if ( @_ == 2 ) {
+
+        my ( $name, $data ) = @_;
+
+        if ( exists $self->{part_data}->{$name} ) {
+            for ( $self->{part_data}->{$name} ) {
+                $_ = [$_] unless ref($_) eq "ARRAY";
+                push( @$_, $data );
+            }
+        }
+        else {
+            $self->{part_data}->{$name} = $data;
+        }
+    }
+
+    return $self->{part_data};
+}
+
 =item tmpdir 
 
 Specify a different path for temporary files.  Defaults to the system temporary path.