From 1756f1c47bfa2d1c06ef0de8875d2587dd5f3ab4 Mon Sep 17 00:00:00 2001 From: Dmitry Latin Date: Fri, 28 Jul 2017 14:35:28 +0300 Subject: [PATCH 01/18] Less dependencies no Filter::signatures; no feature 'signatures'; no Text::CleanFragment required (replacement into HTTP::Upload::FlowJs::Utils MIME::Detect is optional --- lib/HTTP/Upload/FlowJs.pm | 102 ++- lib/HTTP/Upload/FlowJs/Utils.pm | 83 +++ t/002_http_upload_disallowedContentType.t | 12 +- t/003_http_upload_flowjs.t | 716 +++++++++++----------- 4 files changed, 534 insertions(+), 379 deletions(-) create mode 100644 lib/HTTP/Upload/FlowJs/Utils.pm diff --git a/lib/HTTP/Upload/FlowJs.pm b/lib/HTTP/Upload/FlowJs.pm index 8f85b2a..b689787 100644 --- a/lib/HTTP/Upload/FlowJs.pm +++ b/lib/HTTP/Upload/FlowJs.pm @@ -1,12 +1,9 @@ package HTTP::Upload::FlowJs; use strict; use Carp qw(croak); -use Filter::signatures; -no warnings 'experimental::signatures'; -use feature 'signatures'; -use Text::CleanFragment 'clean_fragment'; + +use HTTP::Upload::FlowJs::Utils qw(clean_fragment mime_detect); use Data::Dumper; -use MIME::Detect; use vars '$VERSION'; $VERSION = '0.01'; @@ -200,7 +197,8 @@ fairly disk-intensive on some systems. =cut -sub new( $class, %options ) { +sub new { + my ( $class, %options ) = @_; croak "Need a directory name for the temporary upload parts" unless $options{ incomingDirectory }; @@ -210,17 +208,21 @@ sub new( $class, %options ) { $options{ minChunkSize } ||= 1024; $options{ simultaneousUploads } ||= 3; $options{ maxPendingUploads } ||= 1000; - $options{ mime } ||= MIME::Detect->new(); + $options{ mime } ||= mime_detect(); $options{ allowedContentType } ||= sub { 1 }; bless \%options => $class; }; -sub incomingDirectory( $self ) { +sub incomingDirectory { + my ($self) = @_; + $self->{incomingDirectory}; }; -sub mime($self) { +sub mime { + my ($self) = @_; + $self->{mime} }; @@ -235,7 +237,9 @@ object for inclusion with the JS side of the world =cut -sub jsConfig( $self, %override ) { +sub jsConfig { + my ( $self, %override ) = @_; + { map { $_ => $self->{$_} } (qw( chunkSize @@ -249,7 +253,9 @@ sub jsConfig( $self, %override ) { } } -sub jsConfigStr( $self, %override ) { +sub jsConfigStr { + my ( $self, %override ) = @_; + encode_json($self->js_Config(%override)) } @@ -269,7 +275,9 @@ check previously stored information. =cut -sub validateRequest( $self, $method, $info, $sessionId=undef ) { +sub validateRequest { + my ( $self, $method, $info, $sessionId ) = @_; + # Validate the input somewhat local $Data::Dumper::Useqq = 1; @@ -424,7 +432,11 @@ chunk as indicated by C<$info>. =cut -sub expectedChunkSize( $self, $info, $index=0 ) { +sub expectedChunkSize { + my ( $self, $info, $index ) = @_; + + $index //= 0; + # If we are not the last chunk, we need to be what the information says: $index ||= $info->{flowChunkNumber}; if( ! $info->{flowTotalChunks}) { @@ -460,7 +472,9 @@ is passed, it will remove all partial files from the directory. =cut -sub resetUploadDirectories( $self, $wipe=undef ) { +sub resetUploadDirectories { + my ( $self, $wipe ) = @_; + my $dir = $self->{incomingDirectory}; if( ! -d $dir ) { mkdir $dir @@ -486,7 +500,11 @@ the current chunk. =cut -sub chunkName( $self, $info, $sessionPrefix=undef, $index=0 ) { +sub chunkName { + my ( $self, $info, $sessionPrefix, $index ) = @_; + + $index //= 0; + my $dir = $self->{incomingDirectory}; $sessionPrefix = '' unless defined $sessionPrefix; my $chunkname = sprintf "%s/%s%s.part%03d", @@ -516,7 +534,11 @@ sub chunkName( $self, $info, $sessionPrefix=undef, $index=0 ) { =cut -sub chunkOK($self, $info, $sessionPrefix=undef, $index=0) { +sub chunkOK { + my ( $self, $info, $sessionPrefix, $index ) = @_; + + $index //= 0; + my @messages = $self->validateRequest( 'GET', $info, $sessionPrefix ); if( @messages ) { return 500, @messages @@ -539,7 +561,9 @@ sub chunkOK($self, $info, $sessionPrefix=undef, $index=0) { =cut -sub uploadComplete( $self, $info, $sessionPrefix=undef ) { +sub uploadComplete { + my ( $self, $info, $sessionPrefix) = @_; + my $complete = 1; for( 1.. $info->{ flowTotalChunks }) { my( $status, @messages ) = $self->chunkOK( $info, $sessionPrefix, $_ ) ; @@ -561,7 +585,11 @@ and the index are optional. =cut -sub chunkFh( $self, $info, $sessionPrefix=undef, $index=0 ) { +sub chunkFh { + my ( $self, $info, $sessionPrefix, $index ) = @_; + + $index //= 0; + my %info = %$info; $info{ chunkNumber } = $index if $index; my $chunkname = $self->chunkName( \%info, $sessionPrefix, $index ); @@ -580,7 +608,11 @@ and the index are optional. =cut -sub chunkContent( $self, $info, $sessionPrefix=undef, $index=0 ) { +sub chunkContent { + my ( $self, $info, $sessionPrefix, $index ) = @_; + + $index //= 0; + my $chunk = $self->chunkFh( $info, $sessionPrefix, $index ); local $/; <$chunk> @@ -597,7 +629,9 @@ this MIME type. Unrecognized files will be blocked. =cut -sub disallowedContentType( $self, $info, $session=undef ) { +sub disallowedContentType { + my ( $self, $info, $session) = @_; + my( $content_type, $image_ext ) = $self->sniffContentType($info,$session); if( !defined $content_type ) { # we need more chunks uploaded to check the content type @@ -639,13 +673,15 @@ check the upload type. =cut -sub sniffContentType( $self, $info, $sessionPrefix=undef ) { +sub sniffContentType { + my ( $self, $info, $sessionPrefix ) = @_; + my( $content_type, $image_ext ); my( $status, @messages ) = $self->chunkOK( $info, $sessionPrefix, 1 ); if( 200 == $status ) { my $fh = $self->chunkFh( $info, $sessionPrefix, 1 ); - my $t = $self->mime->mime_type($fh); + my $t = $self->mime->mime_type($fh) if $self->mime; if( $t ) { $content_type = $t->mime_type; $image_ext = $t->extension; @@ -686,7 +722,9 @@ sub sniffContentType( $self, $info, $sessionPrefix=undef ) { =cut -sub combineChunks( $self, $info, $sessionPrefix, $target_fh, $digest=undef ) { +sub combineChunks { + my ( $self, $info, $sessionPrefix, $target_fh, $digest ) = @_; + my @unlink_chunks; my $ok = 1; for( 1.. $info->{ flowTotalChunks }) { @@ -712,7 +750,9 @@ than one chunk. =cut -sub pendingUploads( $self ) { +sub pendingUploads { + my ($self) = @_; + my @files; my %uploads; @@ -752,7 +792,12 @@ It defaults to C