package urpm::download;
use strict;
use urpm::msg;
use urpm::util qw(cat_ basename dirname file_size max member output_safe reduce_pathname);
use bytes ();
use Cwd;
use Exporter;
# perl_checker: require urpm
# help perl_checker:
sub getcwd { goto &Cwd::getcwd }
our @ISA = 'Exporter';
our @EXPORT = qw(get_proxy
propagate_sync_callback
sync_file sync_rsync sync_ssh
set_proxy_config dump_proxy_config
);
#- proxy config file.
our $PROXY_CFG = '/etc/urpmi/proxy.cfg';
my $proxy_config;
#- Timeout for curl connection and wget operations
our $CONNECT_TIMEOUT = 60; #- (in seconds)
=head1 NAME
urpm::download - download routines for the urpm* tools
=head1 SYNOPSIS
=head1 DESCRIPTION
=over
=cut
sub ftp_http_downloaders() { qw(curl wget prozilla aria2) }
sub available_ftp_http_downloaders() {
my %binaries = (
curl => 'curl',
wget => 'wget',
prozilla => 'proz',
aria2 => 'aria2c',
);
grep { -x "/usr/bin/$binaries{$_}" || -x "/bin/$binaries{$_}" } ftp_http_downloaders();
}
sub metalink_downloaders() { qw(aria2) }
sub available_metalink_downloaders() {
my %binaries = (
aria2 => 'aria2c',
);
grep { -x "/usr/bin/$binaries{$_}" || -x "/bin/$binaries{$_}" } metalink_downloaders();
}
sub use_metalink {
my ($urpm, $medium) = @_;
$medium->{allow_metalink} //= do {
my $use_metalink = 1;
preferred_downloader($urpm, $medium, \$use_metalink);
$use_metalink;
};
}
my %warned;
sub preferred_downloader {
my ($urpm, $medium, $use_metalink) = @_;
my @available = urpm::download::available_ftp_http_downloaders();
my @metalink_downloaders = urpm::download::available_metalink_downloaders();
my $metalink_disabled = !$$use_metalink && $medium->{disable_metalink};
if ($$use_metalink && !$metalink_disabled) {
#- If metalink is used, only aria2 is available as other downloaders doesn't support metalink
unshift @available, @metalink_downloaders;
}
#- first downloader of @available is the default one
my $preferred = $available[0];
my $requested_downloader = requested_ftp_http_downloader($urpm, $medium);
if ($requested_downloader) {
if (member($requested_downloader, @available)) {
#- use user default downloader if provided and available
$preferred = $requested_downloader;
} elsif ($warned{webfetch_not_available}++ == 0) {
$urpm->{log}(N("%s is not available, falling back on %s", $requested_downloader, $preferred));
}
}
if ($$use_metalink && !member($preferred, @metalink_downloaders)) {
$warned{not_using_metalink}++ or
$urpm->{log}($requested_downloader eq $preferred ?
"not using metalink since requested downloader does not handle it" :
"not using metalink since no downloaders handling metalink are available");
$$use_metalink = 0;
}
$preferred;
}
sub parse_http_proxy {
$_[0] =~ m!^(?:http://)?([^:/]+(:\d+)?)/*$!;
}
#- parses proxy.cfg (private)
sub load_proxy_config () {
return if defined $proxy_config;
$proxy_config = {};
foreach (cat_($PROXY_CFG)) {
chomp; s/#.*$//; s/^\s*//; s/\s*$//;
if (/^(?:(.*):\s*)?(ftp_proxy|http_proxy)\s*=\s*(.*)$/) {
$proxy_config->{$1 || ''}{$2} = $3;
next;
}
if (/^(?:(.*):\s*)?proxy_user\s*=\s*([^:]*)(?::(.*))?$/) {
$proxy_config->{$1 || ''}{user} = $2;
$proxy_config->{$1 || ''}{pwd} = $3 if defined $3;
next;
}
if (/^(?:(.*):\s*)?proxy_user_ask/) {
$proxy_config->{$1 || ''}{ask} = 1;
next;
}
}
}
|