Search code examples
perllwp-useragentmojolicious

Mojo::UserAgent get() with userdefined callback


Is there a way to write something like this with Mojo::UserAgent ,having the possibility to set equivalent options ( Range, :content_file, :content_cb, size_hint).

#!/usr/bin/env perl
use warnings;
use 5.12.0;
use LWP::UserAgent;
use File::Basename;

my $url = 'ftp://ftp.vim.org/pub/vim/runtime/spell/en.utf-8.spl';
my $file = basename $url;
my $ua = LWP::UserAgent->new();
my $bytes = 0;

open my $fh, '>>:raw', $file or die $!;
my $res = $ua->get( 
    $url,
    'Range' => "bytes=$bytes-",
    ':content_cb' => sub { 
        my ( $chunk, $res, $proto ) = @_;
        print $fh $chunk; 
        state $old_size = 0;
        my $size = tell $fh;
        my $total;
        say 'chunk size :', $size - $old_size;
        if ( $total = $res->header( 'Content-Length' ) ) {
            say 'total size : ', $total;
            say 'downloaded : ', $size;
            say 'remaining  : ', $total - $size;
        }
        say "";
        $old_size = $size;
    }
);
close $fh;

say $res->status_line;

Solution

  • #!/usr/bin/env perl
    
    use 5.12.0;
    use warnings;
    
    use File::Basename qw(basename);
    use Mojo::UserAgent ();
    
    my $url = 'ftp://ftp.vim.org/pub/vim/runtime/spell/en.utf-8.spl';
    my $ua  = Mojo::UserAgent->new();
    my $tx  = $ua->build_tx(GET => $url);
    
    open(my $fh, '>:raw', basename($url)) or die($!);
    $tx->req->headers->header(range => 'bytes=0-');
    $tx->res->content->on(read => sub {
        print($fh $_[1]);
        say('chunk size: ', length($_[1]));
        say('total size: ', $_[0]->headers->content_length);
        say('downloaded: ', $_[0]->body_size);
        say('');
    });
    $ua->start($tx);
    close($fh);
    
    say($tx->res->code, ' ', $tx->res->message);