11package Mojo::UserAgent::Transactor ;
22use Mojo::Base -base;
33
4+ use Carp qw( croak) ;
45use Mojo::Asset::File;
56use Mojo::Asset::Memory;
67use Mojo::Content::MultiPart;
@@ -20,6 +21,44 @@ has name => 'Mojolicious (Perl)';
2021
2122sub add_generator { $_ [0]-> generators-> {$_ [1]} = $_ [2] and return $_ [0] }
2223
24+ sub download {
25+ my ($self , $head , $path ) = @_ ;
26+
27+ my $req = $head -> req;
28+ my $tx = $self -> tx(GET => $req -> url-> clone => $req -> headers-> to_hash);
29+ my $res = $tx -> res;
30+ if (my $error = $head -> error) { $res -> error($error ) and return $tx }
31+
32+ my $headers = $head -> res-> headers;
33+ my $accept_ranges = $headers -> accept_ranges =~ / bytes/ ;
34+ croak ' Download error: Unknown file size' unless my $size = $headers -> content_length;
35+
36+ my $current_size = 0;
37+ my $file = path($path );
38+ if (-f $file ) {
39+ $current_size = -s $file ;
40+ $res -> error({message => ' Download error' , complete_download => 1}) and return $tx if $current_size >= $size ;
41+ croak " Download error: Server does not support partial requests" unless $accept_ranges ;
42+ $tx -> req-> headers-> range(" bytes=$current_size -$size " );
43+ }
44+ my $fh = $file -> open (' +>>' );
45+ $res -> content-> unsubscribe(' read' )-> on(
46+ read => sub {
47+ my ($content , $bytes ) = @_ ;
48+ $current_size += length $bytes ;
49+ $fh -> syswrite ($bytes ) or croak qq/ Can't write to file "$path ": $! / ;
50+ }
51+ );
52+ $res -> on(
53+ finish => sub {
54+ my $res = shift ;
55+ $res -> error({message => ' Download error' , incomplete_download => 1}) if $current_size < $size ;
56+ }
57+ );
58+
59+ return $tx ;
60+ }
61+
2362sub endpoint {
2463 my ($self , $tx ) = @_ ;
2564
@@ -371,6 +410,14 @@ Register a content generator.
371410
372411 $t->add_generator(foo => sub ($t, $tx, @args) {...});
373412
413+ =head2 download
414+
415+ my $tx = $ua->download(Mojo::Transaction::HTTP->new, '/home/sri/test.tar.gz');
416+ my $tx = $ua->download(Mojo::Transaction::HTTP->new, '/home/sri/test.tar.gz', {headers => {Accept => '*/*'}});
417+
418+ Build L<Mojo::Transaction::HTTP> follow-up request for C<HEAD > request to allow for resumable file downloads. Note that
419+ this method is B<EXPERIMENTAL > and might change without warning!
420+
374421=head2 endpoint
375422
376423 my ($proto, $host, $port) = $t->endpoint(Mojo::Transaction::HTTP->new);
0 commit comments