minor refactoring, created HTTP::Body::Octetstream
Christian Hansen [Tue, 19 Jul 2005 15:07:31 +0000 (15:07 +0000)]
lib/HTTP/Body.pm
lib/HTTP/Body/Multipart.pm
lib/HTTP/Body/Octetstream.pm
lib/HTTP/Body/Urlencoded.pm
test.pl

index 16864c2..b8d2c92 100644 (file)
@@ -2,9 +2,8 @@ package HTTP::Body;
 
 use strict;
 
-use Carp         qw[ ];
-use List::Util   qw[ first ];
-use Scalar::Util qw[ blessed ];
+use Carp       qw[ ];
+use List::Util qw[ first ];
 
 our $PARSERS = {
     'application/octet-stream'          => 'HTTP::Body::Octetstream',
@@ -32,6 +31,7 @@ sub new {
         buffer         => '',
         content_length => $content_length,
         content_type   => $content_type,
+        length         => 0,
         param          => { },
         upload         => { }
     };
@@ -42,11 +42,16 @@ sub new {
 }
 
 sub add {
-    Carp::croak('Define abstract method add() in implementation');
-}
-
-sub init {
-    return $_[0];
+    my $self = shift;
+    
+    if ( defined $_[0] ) {
+        $self->{buffer} .= $_[0];
+        $self->{length} += length($_[0]);
+    }
+    
+    $self->spin;
+    
+    return ( $self->length - $self->content_length );
 }
 
 sub body {
@@ -55,6 +60,10 @@ sub body {
     return $self->{body};
 }
 
+sub buffer {
+    return shift->{buffer};
+}
+
 sub content_length {
     return shift->{content_length};
 }
@@ -63,6 +72,18 @@ sub content_type {
     return shift->{content_type};
 }
 
+sub init {
+    return $_[0];
+}
+
+sub length {
+    return shift->{length};
+}
+
+sub spin {
+    Carp::croak('Define abstract method spin() in implementation');
+}
+
 sub param {
     my $self = shift;
 
index 89b88d2..c042903 100644 (file)
@@ -16,20 +16,12 @@ sub init {
 
     $self->{boundary} = $1;
     $self->{state}    = 'preamble';
-    $self->{length}   = $self->content_length - $self->content_length * 2;
 
     return $self;
 }
 
-sub add {
-    my ( $self, $buffer ) = @_;
-
-    unless ( defined $buffer ) {
-        $buffer = '';
-    }
-
-    $self->{buffer} .= $buffer;
-    $self->{length} += length($buffer);
+sub spin {
+    my $self = shift;
 
     while (1) {
 
@@ -39,7 +31,7 @@ sub add {
 
         elsif ( $self->{state} =~ /^(preamble|boundary|header|body)$/ ) {
             my $method = "parse_$1";
-            return $self->{length} unless $self->$method;
+            return unless $self->$method;
         }
 
         else {
@@ -49,9 +41,7 @@ sub add {
 }
 
 sub boundary {
-    my $self = shift;
-    $self->{boundary} = shift if @_;
-    return $self->{boundary};
+    return shift->{boundary};
 }
 
 sub boundary_begin {
@@ -99,17 +89,20 @@ sub parse_boundary {
     if ( index( $self->{buffer}, $self->delimiter_begin . $self->crlf ) == 0 ) {
 
         substr( $self->{buffer}, 0, length( $self->delimiter_begin ) + 2, '' );
-        $self->{current}  = {};
-        $self->{state}    = 'header';
+        $self->{part}  = {};
+        $self->{state} = 'header';
 
         return 1;
     }
 
     if ( index( $self->{buffer}, $self->delimiter_end . $self->crlf ) == 0 ) {
-        $self->{current}  = {};
-        $self->{state}    = 'done';
+        
+        substr( $self->{buffer}, 0, length( $self->delimiter_end ) + 2, '' );
+        $self->{part}  = {};
+        $self->{state} = 'done';
+        
         return 0;
-    }    
+    }
 
     return 0;
 }
@@ -146,14 +139,14 @@ sub parse_header {
 
         ( my $field = $1 ) =~ s/\b(\w)/uc($1)/eg;
 
-        if ( exists $self->{current}->{headers}->{$field} ) {
-            for ( $self->{current}->{headers}->{$field} ) {
+        if ( exists $self->{part}->{headers}->{$field} ) {
+            for ( $self->{part}->{headers}->{$field} ) {
                 $_ = [$_] unless ref($_) eq "ARRAY";
                 push( @$_, $header );
             }
         }
         else {
-            $self->{current}->{headers}->{$field} = $header;
+            $self->{part}->{headers}->{$field} = $header;
         }
     }
 
@@ -176,20 +169,20 @@ sub parse_body {
             return 0;
         }
 
-        $self->{current}->{data} .= substr( $self->{buffer}, 0, $length, '' );
-        $self->{current}->{size} += $length;
-        $self->{current}->{done}  = 0;
+        $self->{part}->{data} .= substr( $self->{buffer}, 0, $length, '' );
+        $self->{part}->{size} += $length;
+        $self->{part}->{done}  = 0;
 
-        $self->handler( $self->{current} );
+        $self->handler( $self->{part} );
 
         return 0;
     }
 
-    $self->{current}->{data} .= substr( $self->{buffer}, 0, $index, '' );
-    $self->{current}->{size} += $index;
-    $self->{current}->{done}  = 1;
+    $self->{part}->{data} .= substr( $self->{buffer}, 0, $index, '' );
+    $self->{part}->{size} += $index;
+    $self->{part}->{done}  = 1;
 
-    $self->handler( $self->{current} );
+    $self->handler( $self->{part} );
 
     $self->{state} = 'boundary';
 
@@ -229,8 +222,9 @@ sub handler {
 
         if ( $part->{filename} ) {
             
-            my $fh = delete $part->{fh};
-            $fh->close;
+            $part->{fh}->close;
+            
+            delete @{ $part }{ qw[ done fh ] };
             
             $self->upload( $part->{name}, $part );
         }
index 8c50264..8f14f85 100644 (file)
@@ -6,4 +6,20 @@ use bytes;
 
 use File::Temp 0.14;
 
+sub spin {
+    my $self = shift;
+    
+    unless ( $self->body ) {
+        $self->body( File::Temp->new );
+    }
+    
+    if ( my $length = length( $self->{buffer} ) ) {
+        $self->body->write( delete $self->{buffer}, $length );
+    }
+    
+    if ( $self->length == $self->content_length ) {
+        seek( $self->body, 0, 0 );
+    }
+}
+
 1;
index e2a52c7..c01b9b2 100644 (file)
@@ -4,4 +4,10 @@ use strict;
 use base 'HTTP::Body';
 use bytes;
 
+sub spin {
+    my $self = shift;
+    
+    
+}
+
 1;
diff --git a/test.pl b/test.pl
index a9ef755..2142c6a 100644 (file)
--- a/test.pl
+++ b/test.pl
@@ -13,18 +13,19 @@ my $test = shift(@ARGV) || 1;
 
 my $headers = LoadFile( sprintf( "t/data/multipart/%.3d-headers.yml", $test ) );
 my $content = IO::File->new( sprintf( "t/data/multipart/%.3d-content.dat", $test ), O_RDONLY );
-my $parser  = HTTP::Body->new( $headers->{'Content-Type'}, $headers->{'Content-Length'} );
-
-warn ref($parser);
+my $body    = HTTP::Body->new( $headers->{'Content-Type'}, $headers->{'Content-Length'} );
 
 binmode $content;
 
 while ( $content->read( my $buffer, 1024 ) ) {
-    last if $parser->add($buffer) == 0;
+    $body->add($buffer);
 }
 
-warn "length   : $parser->{length}\n";
-warn "state    : $parser->{state}\n";
+warn Dumper( $body->param  );
+warn Dumper( $body->upload );
+warn Dumper( $body->body   );
 
-warn Dumper( $parser->param );
-warn Dumper( $parser->upload );
+warn "length         : " . $body->length;
+warn "content length : " . $body->content_length;
+warn "state          : " . $body->{state};
+warn "buffer         : " . $body->buffer;