Www :: curl - how to upload (send) large files

I use WWW :: Curl to upload files:

use WWW::Curl::Easy 4.14;
use WWW::Curl::Form;

my $url = 'http://example.com/backups/?sid=12313qwed323';
my $params = {
    name => 'upload',
    action => 'keep',
    backup1 => [ '/tmp/backup1.zip' ],   # 1st file for upload
};

my $form = WWW::Curl::Form->new();
foreach my $k (keys %{$params}) {
    if (ref $params->{$k}) {
        $form->formaddfile(@{$params->{$k}}[0], $k, 'multipart/form-data');
    } else {
        $form->formadd($k, $params->{$k});
    }
}

my $curl = WWW::Curl::Easy->new() or die $!; 
$curl->setopt(CURLOPT_HTTPPOST, $form);
$curl->setopt(CURLOPT_URL, $url);

my $body;   
$curl->setopt(CURLOPT_WRITEDATA, \$body);
my $retcode = $curl->perform();
my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE); 

nothing special here and this code works well.

I want to download large files, and I do not want to preload everything in memory. At least this is what I heard about what libcurl does.

CURLOPT_READFUNCTION accepts callbacks that return parts of the content. This means that I cannot use WWW :: Curl :: Form to set the POST parameters, but I have to return all the content through this callback. Is it correct?

I think the code might look like this:

use WWW::Curl::Easy 4.14;

my $url = 'http://example.com/backups/?sid=12313qwed323'
my $params = {
    name => 'upload',
    action => 'keep',
    backup1 => [ '/tmp/backup1.zip' ],   # 1st file for upload
};

my $fields;
foreach my $k (keys %{$params}) {
    $fields .= "$k=".(ref $params->{$k} ? '@'.@{$params->{$k}}[0] : uri_escape_utf8($params->{$k}))."&";
}
chop($fields);

my $curl = WWW::Curl::Easy->new() or die $!;
$curl->setopt(CURLOPT_POST, 1);
$curl->setopt(CURLOPT_POSTFIELDS, $fields); # is it needed with READFUNCTION??
$curl->setopt(CURLOPT_URL, $url);

my @header = ('Content-type: multipart/form-data', 'Transfer-Encoding: chunked');
$curl->setopt(CURLOPT_HTTPHEADER, \@header);

#$curl->setopt(CURLOPT_INFILESIZE, $size);
$curl->setopt(CURLOPT_READFUNCTION, sub {

    # which data to return here?
    # $params (without file) + file content?

    return 0;
});

What data should the CURLOPT_READFUNCTION callback return? $ params + File (s)? In what format?

( CURLOPT_READFUNCTION) ?

+5
2

16formpost.t . , . , CURLOPT_READFUNCTION Perl.

. ?

, , . , CURLOPT_INFILESIZE.

CURLOPT_READFUNCTION?

HTTP. , Content-Type multipart/form-data. HTTP:: Message. CURLOPT_HTTPPOST - .

use HTTP::Request::Common qw(POST);
use WWW::Curl::Easy 4.14;

my $curl = WWW::Curl::Easy->new or die $!;
$curl->setopt(CURLOPT_POST, 1);
$curl->setopt(CURLOPT_URL, 'http://localhost:5000');
$curl->setopt(CURLOPT_HTTPHEADER, [
    'Content-type: multipart/form-data', 'Transfer-Encoding: chunked'
]);
$curl->setopt(CURLOPT_READFUNCTION, sub {
    return POST(undef, Content_Type => 'multipart/form-data', Content => [
        name    => 'upload',
        action  => 'keep',
        backup1 => [ '/tmp/backup1.zip' ],   # 1st file for upload
    ])->content;
});
my $r = $curl->perform;
+4

CURLOPT_READFUNCTION . , , .

AWS, . POST . , , . , :

my $infile = 'file-to-upload.json';
my $size = -s $infile;
open( IN, $infile ) or die("Cannot open file - $infile. $! \n");

my $curl = WWW::Curl::Easy->new;
$curl->setopt(CURLOPT_HEADER,       1);
$curl->setopt(CURLOPT_NOPROGRESS,   1);
$curl->setopt(CURLOPT_POST,         1);
$curl->setopt(CURLOPT_URL,          $myPostUrl);
$curl->setopt(CURLOPT_HTTPHEADER,   
    ['Content-Type: application/json']); #For my use case
$curl->setopt(CURLOPT_POSTFIELDSIZE_LARGE, $size);
$curl->setopt(CURLOPT_READDATA, \*IN);

my $retcode = $curl->perform;

if ($retcode == 0) {
    print("File upload success\n");
} 
else {
    print("An error happened: $retcode ".$curl->strerror($retcode)."\n");
}

CURLOPT_READDATA. curl .

+3

All Articles