At 03:34 2002-07-03 +0400, UpocoY wrote:
>Can LWP resume downloading?
With FTP? I don't know. With HTTP? Yes. Below is a primitive program I
wrote that pulls down files with HTTP resumption. Don't try it on servers
that just blithely ignore Range headers. Some time I should rewrite it so
that it can detect when the remote server doesn't know about Range, and so
that can detect when the remote file has changed.
use strict;
use LWP;
use URI;
die "What URL(s)?" unless @ARGV;
my $ua = LWP::UserAgent->new;
sub c { # add commas to
my $c = $_[0];
1 while $c =~ s/^([-+]?\d+)(\d{3})/$1,$2/;
return $c;
}
foreach my $x (@ARGV) {
my $url = $x;
#print "Heading $url ...\n";
my $head = $ua->request(HTTP::Request->new('HEAD'=>$url));
die "HEAD error: ", $head->request->url, ' - ',
$head->headers_as_string, "\n"
unless $head->is_success;
# print $head->as_string;
my $cl = $head->content_length();
die "No content length\n" unless defined $cl;
die "content length is 0.\n" unless $cl;
print "$url\nLength on server: ", c($cl), "\n";
$url = $head->request->url;
my $base;
$url = URI->new($url) unless ref $url;
die "what url?" unless $url->scheme;
if($url->path =~ m<([^/]+)$>) {
$base = $1;
} else {
$base = 'index.html';
}
$base =~ s/[^\x20-\x7E]/_/g;
$base =~ s/[\/\\\:\*\?\"\<\>\|]/_/g;
# illegal characters under MSDOS: / \ : * ? " < > |
my $file_size = 0;
if(-e $base) {
die unless -f $base;
$file_size = -s $base;
}
my $req_size = 20;
if($file_size == $cl) {
print "$base is the right size\n\n";
next;
}
open(OUT, ">>$base") or die "Can't write-open $base: $!\n";
binmode(OUT);
select(OUT);
$| = 1;
select(STDOUT);
$| = 1;
my $req = HTTP::Request->new('GET' => $url);
$req->init_header('Range' => sprintf("bytes=%s-%s",
$file_size, # so if it's 1 byte long, start at byte 1
$cl - 1
));
printf "Requesting %s - %s\n", c($file_size), c($cl - 1);
my $dots = 0;
my $to_get = $cl - $file_size;
my $response = $ua->request($req, sub {
print OUT $_[0];
print ".";
++$dots;
$to_get -= length($_[0]);
if($dots == 60) {
$dots = 0;
print " ", c($to_get), "\n";
}
});
print "\n", $base, " ", scalar(localtime), "\n\n";
die "GET error: ", $response->request->uri, " - ",
$response->status_line, "\n"
unless $response->is_success;
close(OUT);
}
exit;
__END__
--
Sean M. Burke http://www.spinn.net/~sburke/