From: Christian Hansen Date: Tue, 19 Jul 2005 13:16:06 +0000 (+0000) Subject: rename dist from HTTP-Body-Multipart to HTTP-Body X-Git-Tag: v0.01~18 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=32b29b79aeea4062fc08ecaedadfa4bce864abcf;p=catagits%2FHTTP-Body.git rename dist from HTTP-Body-Multipart to HTTP-Body --- diff --git a/lib/HTTP/Body.pm b/lib/HTTP/Body.pm new file mode 100644 index 0000000..16864c2 --- /dev/null +++ b/lib/HTTP/Body.pm @@ -0,0 +1,108 @@ +package HTTP::Body; + +use strict; + +use Carp qw[ ]; +use List::Util qw[ first ]; +use Scalar::Util qw[ blessed ]; + +our $PARSERS = { + 'application/octet-stream' => 'HTTP::Body::Octetstream', + 'application/x-www-form-urlencoded' => 'HTTP::Body::Urlencoded', + 'multipart/form-data' => 'HTTP::Body::Multipart' +}; + +sub new { + my ( $class, $content_type, $content_length ) = @_; + + unless ( @_ == 3 ) { + Carp::croak( $class, '->new( $content_type, $content_length )' ); + } + + my $type = first { index( lc($content_type), $_ ) >= 0 } keys %{ $PARSERS }; + my $body = $PARSERS->{ $type || 'application/octet-stream' }; + + eval "require $body"; + + if ( $@ ) { + die $@; + } + + my $self = { + buffer => '', + content_length => $content_length, + content_type => $content_type, + param => { }, + upload => { } + }; + + bless( $self, $body ); + + return $self->init; +} + +sub add { + Carp::croak('Define abstract method add() in implementation'); +} + +sub init { + return $_[0]; +} + +sub body { + my $self = shift; + $self->{body} = shift if @_; + return $self->{body}; +} + +sub content_length { + return shift->{content_length}; +} + +sub content_type { + return shift->{content_type}; +} + +sub param { + my $self = shift; + + if ( @_ == 2 ) { + + my ( $name, $value ) = @_; + + if ( exists $self->{param}->{$name} ) { + for ( $self->{param}->{$name} ) { + $_ = [$_] unless ref($_) eq "ARRAY"; + push( @$_, $value ); + } + } + else { + $self->{param}->{$name} = $value; + } + } + + return $self->{param}; +} + +sub upload { + my $self = shift; + + if ( @_ == 2 ) { + + my ( $name, $upload ) = @_; + + if ( exists $self->{upload}->{$name} ) { + for ( $self->{upload}->{$name} ) { + $_ = [$_] unless ref($_) eq "ARRAY"; + push( @$_, $upload ); + } + } + else { + $self->{upload}->{$name} = $upload; + } + } + + return $self->{upload}; +} + +1; diff --git a/lib/HTTP/Body/Multipart.pm b/lib/HTTP/Body/Multipart.pm index 46d280c..89b88d2 100644 --- a/lib/HTTP/Body/Multipart.pm +++ b/lib/HTTP/Body/Multipart.pm @@ -1,101 +1,244 @@ package HTTP::Body::Multipart; use strict; -use base 'HTTP::Body::Multipart::Parser'; +use base 'HTTP::Body'; +use bytes; use File::Temp 0.14; -sub new { - my $class = shift; - - my $self = $class->SUPER::new(@_); - $self->{param} = {}; - $self->{upload} = {}; +sub init { + my $self = shift; + + unless ( $self->content_type =~ /boundary=\"?([^\";,]+)\"?/ ) { + my $content_type = $self->content_type; + Carp::croak("Invalid boudrary in content_type: '$content_type'"); + } + + $self->{boundary} = $1; + $self->{state} = 'preamble'; + $self->{length} = $self->content_length - $self->content_length * 2; return $self; } -sub handler { - my ( $self, $part ) = @_; +sub add { + my ( $self, $buffer ) = @_; - if ( $part->{done} && $part->{size} == 0 ) { + unless ( defined $buffer ) { + $buffer = ''; + } + + $self->{buffer} .= $buffer; + $self->{length} += length($buffer); + + while (1) { + + if ( $self->{state} eq 'done' ) { + return 0; + } + + elsif ( $self->{state} =~ /^(preamble|boundary|header|body)$/ ) { + my $method = "parse_$1"; + return $self->{length} unless $self->$method; + } + + else { + Carp::croak('Unknown state'); + } + } +} + +sub boundary { + my $self = shift; + $self->{boundary} = shift if @_; + return $self->{boundary}; +} + +sub boundary_begin { + return "--" . shift->boundary; +} + +sub boundary_end { + return shift->boundary_begin . "--"; +} + +sub crlf { + return "\x0d\x0a"; +} + +sub delimiter_begin { + my $self = shift; + return $self->crlf . $self->boundary_begin; +} + +sub delimiter_end { + my $self = shift; + return $self->crlf . $self->boundary_end; +} + +sub parse_preamble { + my $self = shift; + + my $index = index( $self->{buffer}, $self->boundary_begin ); + + unless ( $index >= 0 ) { return 0; } - unless ( $self->{seen}->{"$part"}++ ) { + # replace preamble with CRLF so we can match dash-boundary as delimiter + substr( $self->{buffer}, 0, $index, $self->crlf ); - my $disposition = $part->{headers}->{'Content-Disposition'}; - my ($name) = $disposition =~ / name="?([^\";]+)"?"/; - my ($filename) = $disposition =~ / filename="?([^\"]+)"?/; + $self->{state} = 'boundary'; - $part->{name} = $name; - $part->{filename} = $filename; + return 1; +} - if ($filename) { +sub parse_boundary { + my $self = shift; - my $fh = File::Temp->new( UNLINK => 0 ); + if ( index( $self->{buffer}, $self->delimiter_begin . $self->crlf ) == 0 ) { - $part->{fh} = $fh; - $part->{tempname} = $fh->filename; - } + substr( $self->{buffer}, 0, length( $self->delimiter_begin ) + 2, '' ); + $self->{current} = {}; + $self->{state} = 'header'; + + return 1; } - if ( $part->{filename} ) { - $part->{fh}->write( delete $part->{data} ); + if ( index( $self->{buffer}, $self->delimiter_end . $self->crlf ) == 0 ) { + $self->{current} = {}; + $self->{state} = 'done'; + return 0; + } + + return 0; +} + +sub parse_header { + my $self = shift; + + my $crlf = $self->crlf; + my $index = index( $self->{buffer}, $crlf . $crlf ); + + unless ( $index >= 0 ) { + return 0; } - if ( $part->{done} ) { + my $header = substr( $self->{buffer}, 0, $index ); - if ( $part->{filename} ) { - $self->upload( $part->{name}, $part ); - } + substr( $self->{buffer}, 0, $index + 4, '' ); + my @headers; + for ( split /$crlf/, $header ) { + if (s/^[ \t]+//) { + $headers[-1] .= $_; + } else { - $self->param( $part->{name}, $part->{data} ); + push @headers, $_; } } -} -sub param { - my $self = shift; + my $token = qr/[^][\x00-\x1f\x7f()<>@,;:\\"\/?={} \t]+/; - if ( @_ == 2 ) { + for my $header (@headers) { - my ( $name, $value ) = @_; + $header =~ s/^($token):[\t ]*//; - if ( exists $self->{param}->{$name} ) { - for ( $self->{param}->{$name} ) { + ( my $field = $1 ) =~ s/\b(\w)/uc($1)/eg; + + if ( exists $self->{current}->{headers}->{$field} ) { + for ( $self->{current}->{headers}->{$field} ) { $_ = [$_] unless ref($_) eq "ARRAY"; - push( @$_, $value ); + push( @$_, $header ); } } else { - $self->{param}->{$name} = $value; + $self->{current}->{headers}->{$field} = $header; } } - return $self->{param}; + $self->{state} = 'body'; + + return 1; } -sub upload { +sub parse_body { my $self = shift; - if ( @_ == 2 ) { + my $index = index( $self->{buffer}, $self->delimiter_begin ); - my ( $name, $upload ) = @_; + if ( $index < 0 ) { - if ( exists $self->{upload}->{$name} ) { - for ( $self->{upload}->{$name} ) { - $_ = [$_] unless ref($_) eq "ARRAY"; - push( @$_, $upload ); - } + # make sure we have enough buffer to detect end delimiter + my $length = length( $self->{buffer} ) - ( length( $self->delimiter_end ) + 2 ); + + unless ( $length > 0 ) { + return 0; } - else { - $self->{upload}->{$name} = $upload; + + $self->{current}->{data} .= substr( $self->{buffer}, 0, $length, '' ); + $self->{current}->{size} += $length; + $self->{current}->{done} = 0; + + $self->handler( $self->{current} ); + + return 0; + } + + $self->{current}->{data} .= substr( $self->{buffer}, 0, $index, '' ); + $self->{current}->{size} += $index; + $self->{current}->{done} = 1; + + $self->handler( $self->{current} ); + + $self->{state} = 'boundary'; + + return 1; +} + +sub handler { + my ( $self, $part ) = @_; + + if ( $part->{done} && $part->{size} == 0 ) { + return 0; + } + + unless ( $self->{seen}->{"$part"}++ ) { + + my $disposition = $part->{headers}->{'Content-Disposition'}; + my ($name) = $disposition =~ / name="?([^\";]+)"?"/; + my ($filename) = $disposition =~ / filename="?([^\"]+)"?/; + + $part->{name} = $name; + $part->{filename} = $filename; + + if ($filename) { + + my $fh = File::Temp->new( UNLINK => 0 ); + + $part->{fh} = $fh; + $part->{tempname} = $fh->filename; } } - return $self->{upload}; + if ( $part->{filename} ) { + $part->{fh}->write( delete $part->{data} ); + } + + if ( $part->{done} ) { + + if ( $part->{filename} ) { + + my $fh = delete $part->{fh}; + $fh->close; + + $self->upload( $part->{name}, $part ); + } + + else { + $self->param( $part->{name}, $part->{data} ); + } + } } 1; diff --git a/lib/HTTP/Body/Octetstream.pm b/lib/HTTP/Body/Octetstream.pm new file mode 100644 index 0000000..8c50264 --- /dev/null +++ b/lib/HTTP/Body/Octetstream.pm @@ -0,0 +1,9 @@ +package HTTP::Body::Octetstream; + +use strict; +use base 'HTTP::Body'; +use bytes; + +use File::Temp 0.14; + +1; diff --git a/lib/HTTP/Body/Urlencoded.pm b/lib/HTTP/Body/Urlencoded.pm new file mode 100644 index 0000000..e2a52c7 --- /dev/null +++ b/lib/HTTP/Body/Urlencoded.pm @@ -0,0 +1,7 @@ +package HTTP::Body::Urlencoded; + +use strict; +use base 'HTTP::Body'; +use bytes; + +1; diff --git a/t/data/multipart/001-content.dat b/t/data/multipart/001-content.dat new file mode 100644 index 0000000..c45f909 --- /dev/null +++ b/t/data/multipart/001-content.dat @@ -0,0 +1,63 @@ +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="text2" + + +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="select" + +A +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="select" + +B +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="upload1"; filename="" + + +------------0xKhTmLbOuNdArY +Content-Disposition: form-data; name="upload2"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +------------0xKhTmLbOuNdArY-- diff --git a/t/data/multipart/001-headers.yml b/t/data/multipart/001-headers.yml new file mode 100644 index 0000000..e2f5998 --- /dev/null +++ b/t/data/multipart/001-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1559 +Content-Type: multipart/form-data; boundary=----------0xKhTmLbOuNdArY +User-Agent: 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312' diff --git a/t/data/multipart/002-content.dat b/t/data/multipart/002-content.dat new file mode 100644 index 0000000..e2e9299 --- /dev/null +++ b/t/data/multipart/002-content.dat @@ -0,0 +1,70 @@ +--LYNX +Content-Disposition: form-data; name="text1" +Content-Type: text/plain; charset=utf-8 + +Ratione accusamus aspernatur aliquam +--LYNX +Content-Disposition: form-data; name="text2" +Content-Type: text/plain; charset=utf-8 + + +--LYNX +Content-Disposition: form-data; name="select" +Content-Type: text/plain; charset=utf-8 + +A +--LYNX +Content-Disposition: form-data; name="select" +Content-Type: text/plain; charset=utf-8 + +B +--LYNX +Content-Disposition: form-data; name="textarea" +Content-Type: text/plain; charset=utf-8 + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. + +--LYNX +Content-Disposition: form-data; name="upload"; filename="/Users/chansen/hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +--LYNX +Content-Disposition: form-data; name="upload"; filename="/Users/chansen/hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +--LYNX +Content-Disposition: form-data; name="upload1"; filename="" +Content-Type: text/plain + + +--LYNX +Content-Disposition: form-data; name="upload2"; filename="/Users/chansen/hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +--LYNX-- diff --git a/t/data/multipart/002-headers.yml b/t/data/multipart/002-headers.yml new file mode 100644 index 0000000..bf95402 --- /dev/null +++ b/t/data/multipart/002-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1585 +Content-Type: multipart/form-data; boundary=LYNX +User-Agent: Lynx/2.8.5rel.2 libwww-FM/2.14 diff --git a/t/data/multipart/003-content.dat b/t/data/multipart/003-content.dat new file mode 100644 index 0000000..3461959 --- /dev/null +++ b/t/data/multipart/003-content.dat @@ -0,0 +1,60 @@ +--00000000000000000000000000000000 +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +--00000000000000000000000000000000 +Content-Disposition: form-data; name="text2" + + +--00000000000000000000000000000000 +Content-Disposition: form-data; name="select" + +A +--00000000000000000000000000000000 +Content-Disposition: form-data; name="select" + +B +--00000000000000000000000000000000 +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +--00000000000000000000000000000000 +Content-Disposition: form-data; name="upload"; filename="hello.pl" + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +--00000000000000000000000000000000 +Content-Disposition: form-data; name="upload"; filename="hello.pl" + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +--00000000000000000000000000000000 +Content-Disposition: form-data; name="upload1"; filename="" + + +--00000000000000000000000000000000 +Content-Disposition: form-data; name="upload2"; filename="hello.pl" + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +--00000000000000000000000000000000-- diff --git a/t/data/multipart/003-headers.yml b/t/data/multipart/003-headers.yml new file mode 100644 index 0000000..9895c88 --- /dev/null +++ b/t/data/multipart/003-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1507 +Content-Type: multipart/form-data; boundary=00000000000000000000000000000000 +User-Agent: ELinks/0.9.2 (textmode; Darwin 7.9.0 Power Macintosh; 167x36) diff --git a/t/data/multipart/004-content.dat b/t/data/multipart/004-content.dat new file mode 100644 index 0000000..ea8b099 --- /dev/null +++ b/t/data/multipart/004-content.dat @@ -0,0 +1,69 @@ +-----------------------------168071508944249 +Content-Disposition: form-data; name="text1" +Content-Type: text/plain; charset="utf-8" + +Ratione accusamus aspernatur aliquam +-----------------------------168071508944249 +Content-Disposition: form-data; name="text2" +Content-Type: text/plain; charset="utf-8" + + +-----------------------------168071508944249 +Content-Disposition: form-data; name="select" +Content-Type: text/plain; charset="utf-8" + +A +-----------------------------168071508944249 +Content-Disposition: form-data; name="select" +Content-Type: text/plain; charset="utf-8" + +B +-----------------------------168071508944249 +Content-Disposition: form-data; name="textarea" +Content-Type: text/plain; charset="utf-8" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------168071508944249 +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------168071508944249 +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------168071508944249 +Content-Disposition: form-data; name="upload1"; filename="" +Content-Type: text/plain; charset="utf-8" + + +-----------------------------168071508944249 +Content-Disposition: form-data; name="upload2"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------168071508944249-- diff --git a/t/data/multipart/004-headers.yml b/t/data/multipart/004-headers.yml new file mode 100644 index 0000000..f56c767 --- /dev/null +++ b/t/data/multipart/004-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1987 +Content-Type: multipart/form-data; boundary=---------------------------168071508944249 +User-Agent: Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC) diff --git a/t/data/multipart/005-content.dat b/t/data/multipart/005-content.dat new file mode 100644 index 0000000..c0132d2 --- /dev/null +++ b/t/data/multipart/005-content.dat @@ -0,0 +1,64 @@ +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="text2" + + +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="select" + +A +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="select" + +B +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="upload1"; filename="" +Content-Type: application/octet-stream + + +-----------------------------168072824752491622650073 +Content-Disposition: form-data; name="upload2"; filename="hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------168072824752491622650073-- diff --git a/t/data/multipart/005-headers.yml b/t/data/multipart/005-headers.yml new file mode 100644 index 0000000..2041da1 --- /dev/null +++ b/t/data/multipart/005-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1817 +Content-Type: multipart/form-data; boundary=---------------------------168072824752491622650073 +User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4 diff --git a/t/data/multipart/006-content.dat b/t/data/multipart/006-content.dat new file mode 100644 index 0000000..fbc3532 --- /dev/null +++ b/t/data/multipart/006-content.dat @@ -0,0 +1,64 @@ +-----------------------------7d53c2922c +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +-----------------------------7d53c2922c +Content-Disposition: form-data; name="text2" + + +-----------------------------7d53c2922c +Content-Disposition: form-data; name="select" + +A +-----------------------------7d53c2922c +Content-Disposition: form-data; name="select" + +B +-----------------------------7d53c2922c +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------7d53c2922c +Content-Disposition: form-data; name="upload"; filename="C:\WINDOWS\Skrivbord\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d53c2922c +Content-Disposition: form-data; name="upload"; filename="C:\WINDOWS\Skrivbord\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d53c2922c +Content-Disposition: form-data; name="upload1"; filename="" +Content-Type: application/octet-stream + + +-----------------------------7d53c2922c +Content-Disposition: form-data; name="upload2"; filename="C:\WINDOWS\Skrivbord\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d53c2922c-- diff --git a/t/data/multipart/006-headers.yml b/t/data/multipart/006-headers.yml new file mode 100644 index 0000000..af0a4f9 --- /dev/null +++ b/t/data/multipart/006-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1740 +Content-Type: multipart/form-data; boundary=---------------------------7d53c2922c +User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98) diff --git a/t/data/multipart/007-content.dat b/t/data/multipart/007-content.dat new file mode 100644 index 0000000..da090f9 --- /dev/null +++ b/t/data/multipart/007-content.dat @@ -0,0 +1,63 @@ +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="text2" + + +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="select" + +A +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="select" + +B +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="upload"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="upload1"; filename="" + + +------------Bv684bhJBhreYbdRAUxHhF +Content-Disposition: form-data; name="upload2"; filename="hello.pl" +Content-Type: application/octet-stream + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +------------Bv684bhJBhreYbdRAUxHhF-- diff --git a/t/data/multipart/007-headers.yml b/t/data/multipart/007-headers.yml new file mode 100644 index 0000000..1e7208a --- /dev/null +++ b/t/data/multipart/007-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1629 +Content-Type: multipart/form-data; boundary=----------Bv684bhJBhreYbdRAUxHhF +User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Mac_PowerPC Mac OS X; en) Opera 8.01 diff --git a/t/data/multipart/008-content.dat b/t/data/multipart/008-content.dat new file mode 100644 index 0000000..59547b8 --- /dev/null +++ b/t/data/multipart/008-content.dat @@ -0,0 +1,64 @@ +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="text2" + + +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="select" + +A +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="select" + +B +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="upload"; filename="C:\WINDOWS\Skrivbord\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="upload"; filename="C:\WINDOWS\Skrivbord\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="upload1"; filename="" +Content-Type: application/octet-stream + + +-----------------------------7d52bc247fc +Content-Disposition: form-data; name="upload2"; filename="C:\WINDOWS\Skrivbord\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d52bc247fc-- diff --git a/t/data/multipart/008-headers.yml b/t/data/multipart/008-headers.yml new file mode 100644 index 0000000..b1f2567 --- /dev/null +++ b/t/data/multipart/008-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1750 +Content-Type: multipart/form-data; boundary=---------------------------7d52bc247fc +User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98) diff --git a/t/data/multipart/009-content.dat b/t/data/multipart/009-content.dat new file mode 100644 index 0000000..285f5d5 --- /dev/null +++ b/t/data/multipart/009-content.dat @@ -0,0 +1,64 @@ +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="text2" + + +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="select" + +A +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="select" + +B +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="upload"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="upload"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="upload1"; filename="" +Content-Type: application/octet-stream + + +-----------------------------7d53941f40118 +Content-Disposition: form-data; name="upload2"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d53941f40118-- diff --git a/t/data/multipart/009-headers.yml b/t/data/multipart/009-headers.yml new file mode 100644 index 0000000..ec3b8e4 --- /dev/null +++ b/t/data/multipart/009-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1851 +Content-Type: multipart/form-data; boundary=---------------------------7d53941f40118 +User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) diff --git a/t/data/multipart/010-content.dat b/t/data/multipart/010-content.dat new file mode 100644 index 0000000..6fc1771 --- /dev/null +++ b/t/data/multipart/010-content.dat @@ -0,0 +1,64 @@ +-----------------------------7d561c5012e +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +-----------------------------7d561c5012e +Content-Disposition: form-data; name="text2" + + +-----------------------------7d561c5012e +Content-Disposition: form-data; name="select" + +A +-----------------------------7d561c5012e +Content-Disposition: form-data; name="select" + +B +-----------------------------7d561c5012e +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------7d561c5012e +Content-Disposition: form-data; name="upload"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d561c5012e +Content-Disposition: form-data; name="upload"; filename="" +Content-Type: application/octet-stream + + +-----------------------------7d561c5012e +Content-Disposition: form-data; name="upload1"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d561c5012e +Content-Disposition: form-data; name="upload2"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d561c5012e-- diff --git a/t/data/multipart/010-headers.yml b/t/data/multipart/010-headers.yml new file mode 100644 index 0000000..7dae7fe --- /dev/null +++ b/t/data/multipart/010-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1831 +Content-Type: multipart/form-data; boundary=---------------------------7d561c5012e +User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) diff --git a/t/data/multipart/011-content.dat b/t/data/multipart/011-content.dat new file mode 100644 index 0000000..a4d29c3 --- /dev/null +++ b/t/data/multipart/011-content.dat @@ -0,0 +1,64 @@ +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="text1" + +Ratione accusamus aspernatur aliquam +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="text2" + + +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="select" + +A +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="select" + +B +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="textarea" + +Voluptatem cumque voluptate sit recusandae at. Et quas facere rerum unde esse. Sit est et voluptatem. Vel temporibus velit neque odio non. + +Molestias rerum ut sapiente facere repellendus illo. Eum nulla quis aut. Quidem voluptas vitae ipsam officia voluptatibus eveniet. Aspernatur cupiditate ratione aliquam quidem corrupti. Eos sunt rerum non optio culpa. +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="upload"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="upload"; filename="" +Content-Type: application/octet-stream + + +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="upload1"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d534d1d60150 +Content-Disposition: form-data; name="upload2"; filename="C:\Documents and Settings\Administrator\Desktop\hello.pl" +Content-Type: text/plain + +#!/usr/bin/perl + +use strict; +use warnings; + +print "Hello World :)\n"; + + +-----------------------------7d534d1d60150-- diff --git a/t/data/multipart/011-headers.yml b/t/data/multipart/011-headers.yml new file mode 100644 index 0000000..2ed7715 --- /dev/null +++ b/t/data/multipart/011-headers.yml @@ -0,0 +1,4 @@ +--- +Content-Length: 1851 +Content-Type: multipart/form-data; boundary=---------------------------7d534d1d60150 +User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) diff --git a/test.pl b/test.pl index d34e3c4..a9ef755 100644 --- a/test.pl +++ b/test.pl @@ -5,15 +5,17 @@ use warnings; use lib './lib'; use Data::Dumper; -use HTTP::Body::Multipart; +use HTTP::Body; use IO::File; use YAML qw[LoadFile]; my $test = shift(@ARGV) || 1; -my $headers = LoadFile( sprintf( "t/data/%.3d-headers.yml", $test ) ); -my $content = IO::File->new( sprintf( "t/data/%.3d-content.dat", $test ), O_RDONLY ); -my $parser = HTTP::Body::Multipart->new( $headers->{'Content-Type'}, $headers->{'Content-Length'} ); +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); binmode $content; @@ -21,8 +23,8 @@ while ( $content->read( my $buffer, 1024 ) ) { last if $parser->add($buffer) == 0; } -warn "length : $parser->{length}\n"; -warn "state : $parser->{state}\n"; +warn "length : $parser->{length}\n"; +warn "state : $parser->{state}\n"; warn Dumper( $parser->param ); warn Dumper( $parser->upload );