巨大ファイルのダウンロードに失敗したとき、また最初からは
大変なのでレジューム(継続ダウンロード)してみる。
resume.pl
use 5.10.1;
use strict;
use warnings;
use Furl;
use File::Basename;
use YAML;
my $url = "http://ftp.riken.jp/Linux/centos/7/os/x86_64/Packages/kernel-debug-3.10.0-123.el7.x86_64.rpm";
my $file = basename $url;
request_download($url, $file);
sub request_download
{
my ($url, $file) = @_;
// content_length取得
my $head_f = Furl->new( timeout => 30 );
my $head_res = $head_f->head($url);
unless ($head_res->is_success) {
warn $head_res->status_line;
return;
}
my $total_size = $head_res->content_length;
// ダウンロード済サイズ取得
my $size = 0;
if (-f $file) {
$size = (stat $file)[7];
if ($total_size == $size) {
return;
}
}
say "Range :bytes=$size-$total_size";
// Range headerを付けてダウンロード
open my $wfh, ">>:raw", $file or die $!;
my %special_headers = ('content-length' => undef);
my $get_f = Furl->new( timeout => 3600 );
my $get_res = $get_f->request(
method => 'GET',
url => $url,
special_headers => \%special_headers,
headers => [ 'Range' => "bytes=$size-$total_size" ],
write_code => sub {
my($status, $message, $headers, $chunk) = @_;
print $wfh $chunk;
my $size = tell $wfh;
if(my $total = $special_headers{'content-length'}) {
my $percent = $size*100/$total;
# printf "%d/%d %d\n", $size, $total, $percent if $percent % 10 == 0;
}
}
);
close $wfh;
my $s = $get_res->status_line;
print "$s\n";
print "end!\n";
}
___END___
// Ctrl+Cで途中で止める
$ perl resume.pl
Range :bytes=0-31787876
^C
// 再度実行(継続する)
$ perl resume.pl
Range :bytes=11744096-31787876
206 Partial Content
end!
// 正常か確認
$ wget http://ftp.riken.jp/Linux/centos/7/os/x86_64/Packages/kernel-debug-3.10.0-123.el7.x86_64.rpm -O org.rpm
// MD5一緒なのでOK!
$ md5sum *.rpm
ed73c5f412285b562199fc021f7aab7c kernel-debug-3.10.0-123.el7.x86_64.rpm
ed73c5f412285b562199fc021f7aab7c org.rpm