1
1
package File::Fetch ;
2
2
3
3
use strict;
4
+ use warnings;
4
5
use FileHandle;
5
6
use File::Temp;
6
7
use File::Copy;
@@ -22,7 +23,7 @@ use vars qw[ $VERBOSE $PREFER_BIN $FROM_EMAIL $USER_AGENT
22
23
$FTP_PASSIVE $TIMEOUT $DEBUG $WARN $FORCEIPV4
23
24
] ;
24
25
25
- $VERSION = ' 1.04 ' ;
26
+ $VERSION = ' 1.08 ' ;
26
27
$VERSION = eval $VERSION ; # avoid warnings with development releases
27
28
$PREFER_BIN = 0; # XXX TODO implement
28
29
$FROM_EMAIL = ' File-Fetch@example.com' ;
@@ -39,7 +40,7 @@ $FORCEIPV4 = 0;
39
40
# ## methods available to fetch the file depending on the scheme
40
41
$METHODS = {
41
42
http => [ qw| lwp httptiny wget curl lftp fetch httplite lynx iosock| ],
42
- https => [ qw| lwp wget curl| ],
43
+ https => [ qw| lwp httptiny wget curl| ],
43
44
ftp => [ qw| lwp netftp wget curl lftp fetch ncftp ftp| ],
44
45
file => [ qw| lwp lftp file| ],
45
46
rsync => [ qw| rsync| ],
@@ -58,7 +59,7 @@ use constant ON_VMS => ($^O eq 'VMS');
58
59
use constant ON_UNIX => (!ON_WIN);
59
60
use constant HAS_VOL => (ON_WIN);
60
61
use 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 )$ ! );
62
63
63
64
=pod
64
65
@@ -400,9 +401,12 @@ sub _parse_uri {
400
401
# ## rebuild the path from the leftover parts;
401
402
$href -> {path } = join ' /' , ' ' , splice ( @parts , $index , $#parts );
402
403
403
- } else {
404
+ } elsif ( $href -> { scheme } eq ' http ' || $href -> { scheme } eq ' https ' ) {
404
405
# ## using anything but qw() in hash slices may produce warnings
405
406
# ## in older perls :-(
407
+ @{$href }{ qw( userinfo host path) } = $uri =~ m | (?:([^\@ :]*:[^\:\@ ]*)@)?([^/]*)(/.*)?$ | s ;
408
+ $href -> {path } = ' /' unless defined $href -> {path };
409
+ } else {
406
410
@{$href }{ qw( userinfo host path) } = $uri =~ m | (?:([^\@ :]*:[^\:\@ ]*)@)?([^/]*)(/.*)$ | s ;
407
411
}
408
412
@@ -491,7 +495,9 @@ sub fetch {
491
495
next if grep { lc $_ eq $method } @$BLACKLIST ;
492
496
493
497
# ## 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 };
495
501
496
502
# ## there's serious issues with IPC::Run and quoting of command
497
503
# ## line arguments. using quotes in the wrong place breaks things,
@@ -569,17 +575,24 @@ sub _lwp_fetch {
569
575
570
576
};
571
577
572
- if ($self -> scheme eq ' https' ) {
573
- $use_list -> {' LWP::Protocol::https' } = ' 0' ;
574
- }
575
-
576
578
# ## Fix CVE-2016-1238 ###
577
579
local $Module::Load::Conditional::FORCE_SAFE_INC = 1;
578
580
unless ( can_load( modules => $use_list ) ) {
579
581
$METHOD_FAIL -> {' lwp' } = 1;
580
582
return ;
581
583
}
582
584
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
+
583
596
# ## setup the uri object
584
597
my $uri = URI-> new( File::Spec::Unix-> catfile(
585
598
$self -> path, $self -> file
@@ -638,6 +651,10 @@ sub _httptiny_fetch {
638
651
$METHOD_FAIL -> {' httptiny' } = 1;
639
652
return ;
640
653
}
654
+ if ( $self -> scheme eq ' https' && !HTTP::Tiny-> can_ssl ) {
655
+ $METHOD_FAIL -> {' httptiny' } = 1;
656
+ return ;
657
+ }
641
658
642
659
my $uri = $self -> uri;
643
660
@@ -962,6 +979,9 @@ sub _lftp_fetch {
962
979
# ## if a timeout is set, add it ###
963
980
$str .= " set net:timeout $TIMEOUT ;\n " if $TIMEOUT ;
964
981
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
+
965
985
# ## run passive if specified ###
966
986
$str .= " set ftp:passive-mode 1;\n " if $FTP_PASSIVE ;
967
987
0 commit comments