11package File::Fetch ;
22
33use strict;
4+ use warnings;
45use FileHandle;
56use File::Temp;
67use File::Copy;
@@ -22,7 +23,7 @@ use vars qw[ $VERBOSE $PREFER_BIN $FROM_EMAIL $USER_AGENT
2223 $FTP_PASSIVE $TIMEOUT $DEBUG $WARN $FORCEIPV4
2324 ] ;
2425
25- $VERSION = ' 1.04 ' ;
26+ $VERSION = ' 1.08 ' ;
2627$VERSION = eval $VERSION ; # avoid warnings with development releases
2728$PREFER_BIN = 0; # XXX TODO implement
2829$FROM_EMAIL =
' [email protected] ' ;
@@ -39,7 +40,7 @@ $FORCEIPV4 = 0;
3940# ## methods available to fetch the file depending on the scheme
4041$METHODS = {
4142 http => [ qw| lwp httptiny wget curl lftp fetch httplite lynx iosock| ],
42- https => [ qw| lwp wget curl| ],
43+ https => [ qw| lwp httptiny wget curl| ],
4344 ftp => [ qw| lwp netftp wget curl lftp fetch ncftp ftp| ],
4445 file => [ qw| lwp lftp file| ],
4546 rsync => [ qw| rsync| ],
@@ -58,7 +59,7 @@ use constant ON_VMS => ($^O eq 'VMS');
5859use constant ON_UNIX => (!ON_WIN);
5960use constant HAS_VOL => (ON_WIN);
6061use constant HAS_SHARE => (ON_WIN);
61- use constant HAS_FETCH => ( $^O =~ m ! ^(freebsd|netbsd|dragonfly)$ ! );
62+ use constant HAS_FETCH => ( $^O =~ m ! ^(freebsd|netbsd|dragonfly|midnightbsd )$ ! );
6263
6364=pod
6465
@@ -400,9 +401,12 @@ sub _parse_uri {
400401 # ## rebuild the path from the leftover parts;
401402 $href -> {path } = join ' /' , ' ' , splice ( @parts , $index , $#parts );
402403
403- } else {
404+ } elsif ( $href -> { scheme } eq ' http ' || $href -> { scheme } eq ' https ' ) {
404405 # ## using anything but qw() in hash slices may produce warnings
405406 # ## in older perls :-(
407+ @{$href }{ qw( userinfo host path) } = $uri =~ m | (?:([^\@ :]*:[^\:\@ ]*)@)?([^/]*)(/.*)?$ | s ;
408+ $href -> {path } = ' /' unless defined $href -> {path };
409+ } else {
406410 @{$href }{ qw( userinfo host path) } = $uri =~ m | (?:([^\@ :]*:[^\:\@ ]*)@)?([^/]*)(/.*)$ | s ;
407411 }
408412
@@ -491,7 +495,9 @@ sub fetch {
491495 next if grep { lc $_ eq $method } @$BLACKLIST ;
492496
493497 # ## method is known to fail ###
494- next if $METHOD_FAIL -> {$method };
498+ next if ref $METHOD_FAIL -> {$method }
499+ ? $METHOD_FAIL -> {$method }{$self -> scheme}
500+ : $METHOD_FAIL -> {$method };
495501
496502 # ## there's serious issues with IPC::Run and quoting of command
497503 # ## line arguments. using quotes in the wrong place breaks things,
@@ -569,17 +575,24 @@ sub _lwp_fetch {
569575
570576 };
571577
572- if ($self -> scheme eq ' https' ) {
573- $use_list -> {' LWP::Protocol::https' } = ' 0' ;
574- }
575-
576578 # ## Fix CVE-2016-1238 ###
577579 local $Module::Load::Conditional::FORCE_SAFE_INC = 1;
578580 unless ( can_load( modules => $use_list ) ) {
579581 $METHOD_FAIL -> {' lwp' } = 1;
580582 return ;
581583 }
582584
585+ if ($self -> scheme eq ' https' ) {
586+ my $https_use_list = {
587+ ' LWP::Protocol::https' => ' 0.0' ,
588+ };
589+
590+ unless ( can_load(modules => $https_use_list ) ) {
591+ $METHOD_FAIL -> {' lwp' } = { ' https' => 1 };
592+ return ;
593+ }
594+ }
595+
583596 # ## setup the uri object
584597 my $uri = URI-> new( File::Spec::Unix-> catfile(
585598 $self -> path, $self -> file
@@ -638,6 +651,10 @@ sub _httptiny_fetch {
638651 $METHOD_FAIL -> {' httptiny' } = 1;
639652 return ;
640653 }
654+ if ( $self -> scheme eq ' https' && !HTTP::Tiny-> can_ssl ) {
655+ $METHOD_FAIL -> {' httptiny' } = 1;
656+ return ;
657+ }
641658
642659 my $uri = $self -> uri;
643660
@@ -962,6 +979,9 @@ sub _lftp_fetch {
962979 # ## if a timeout is set, add it ###
963980 $str .= " set net:timeout $TIMEOUT ;\n " if $TIMEOUT ;
964981
982+ # ## lftp can get stuck in a loop of retries without this
983+ $str .= " set net:reconnect-interval-base 5;\n set net:max-retries 2;\n " ;
984+
965985 # ## run passive if specified ###
966986 $str .= " set ftp:passive-mode 1;\n " if $FTP_PASSIVE ;
967987
0 commit comments