1
1
package Mojo::UserAgent::Transactor ;
2
2
use Mojo::Base -base;
3
3
4
+ use Carp qw( croak) ;
4
5
use Mojo::Asset::File;
5
6
use Mojo::Asset::Memory;
6
7
use Mojo::Content::MultiPart;
@@ -20,6 +21,44 @@ has name => 'Mojolicious (Perl)';
20
21
21
22
sub add_generator { $_ [0]-> generators-> {$_ [1]} = $_ [2] and return $_ [0] }
22
23
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
+
23
62
sub endpoint {
24
63
my ($self , $tx ) = @_ ;
25
64
@@ -371,6 +410,14 @@ Register a content generator.
371
410
372
411
$t->add_generator(foo => sub ($t, $tx, @args) {...});
373
412
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
+
374
421
=head2 endpoint
375
422
376
423
my ($proto, $host, $port) = $t->endpoint(Mojo::Transaction::HTTP->new);
0 commit comments