HTTP-Upload-FlowJs

 view release on metacpan or  search on metacpan

lib/HTTP/Upload/FlowJs.pm  view on Meta::CPAN

        # Combine all chunks to final name

        my $digest = Digest::SHA256->new();

        my( $content_type, $ext ) = $flowjs->sniffContentType();
        my $final_name = "file1.$ext";
        open( my $fh, '>', $final_name )
            or die $!;
        binmode $fh;

        my( $ok, @unlink_chunks )
            = $flowjs->combineChunks( \%info, undef, $fh, $digest );
        unlink @unlink_chunks;

        # Notify backend that a file arrived
        print sprintf "File '%s' upload complete\n", $final_name;
    };

    # Signal OK
    return [200,[],[]]
  };

  # This checks whether a file has been received completely or
  # needs to be uploaded again
  sub GET_upload {
    my $params = params();
    my %info;
    @info{ @parameter_names} = @{$params}{@parameter_names};

    my @invalid = $flowjs->validateRequest( 'GET', \%info, session->{connid} );
    if( @invalid ) {
        warn 'Invalid flow.js upload request:';
        warn $_ for @invalid;
        return [500, [], [] ];

    } elsif( $flowjs->disallowedContentType( \%info, $session_id)) {
        # We can determine the content type, and it's not an image
        return [415,[],["File type disallowed"]];

    } else {
        my( $status, @messages )
            = $flowjs->chunkOK( $uploads, \%info, $session_id );
        if( $status != 500 ) {
            # 200 or 416
            return [$status, [], [] ];
        } else {
            warn $_ for @messages;
            return [$status, [], [] ];
        };
    };
  };

=head1 OVERVIEW

L<flow.js|https://github.com/flowjs/flow.js> is a client-side Javascript upload
library that uploads
a file in multiple parts. It requires two API points on the server side,
one C<GET> API point to check whether a part already has been uploaded
completely and one C<POST> API point to send the data of each partial
upload to. This Perl module implements the backend functionality for
both endpoints. It does not implement the handling of the HTTP requests
themselves, but you likely already use a framework like L<Mojolicious>
or L<Dancer> for that.

=head1 METHODS

=head2 C<< HTTP::Upload::FlowJs->new >>

  my $flowjs = HTTP::Upload::FlowJs->new(
      maxChunkCount => 1000,
      maxFileSize => 10_000_000,
      maxChunkSize => 1024*1024,
      simultaneousUploads => 3,
      allowedContentType => sub {
          my($type) = @_;
          $type =~ m!^image/!; # we only allow for cat images
      },
  );

=over 4

B<incomingDirectory> - path for the temporary upload parts

Required

B<maxChunkCount> - hard maximum chunks allowed for a single upload

Default 1000

B<maxFileSize> - hard maximum total file size for a single upload

Default 10_000_000

B<maxChunkSize> - hard maximum chunk size for a single chunk

Default 1048576

B<minChunkSize> - hard minimum chunk size for a single chunk

Default 1024

The minimum chunk size is required since the file type detection
works on the first chunk. If the first chunk is too small, its file type
cannot be checked.

B<forceChunkSize> - force all chunks to be less or equal than C<maxChunkSize>

Default: true

Otherwise, the last chunk will be greater than or equal to C<maxChunkSize>
(the last uploaded chunk will be at least this size and up to two the size).

Note: when C<forceChunkSize> is C<false> it only make C<chunkSize> value in
L</jsConfig> equal to C<maxChunkSize/2>.

B<simultaneousUploads> - simultaneously allowed uploads per file

Default 3

This is just an indication to the Javascript C<flow.js> client
if you pass it the configuration from this object. This is not enforced



( run in 0.992 second using v1.01-cache-2.11-cpan-39bf76dae61 )