Alien-ROOT
view release on metacpan or search on metacpan
inc/inc_File-Fetch/File/Fetch.pm view on Meta::CPAN
my $uri = $self->uri;
my $http = HTTP::Tiny->new( ( $TIMEOUT ? ( timeout => $TIMEOUT ) : () ) );
my $rc = $http->mirror( $uri, $to );
unless ( $rc->{success} ) {
return $self->_error(loc( "Fetch failed! HTTP response: %1 [%2]",
$rc->{status}, $rc->{reason} ) );
}
return $to;
}
else {
$METHOD_FAIL->{'httptiny'} = 1;
return;
}
}
### HTTP::Lite fetching ###
sub _httplite_fetch {
my $self = shift;
my %hash = @_;
my ($to);
my $tmpl = {
to => { required => 1, store => \$to }
};
check( $tmpl, \%hash ) or return;
### modules required to download with lwp ###
my $use_list = {
'HTTP::Lite' => '2.2',
};
if( can_load(modules => $use_list) ) {
my $uri = $self->uri;
my $retries = 0;
RETRIES: while ( $retries++ < 5 ) {
my $http = HTTP::Lite->new();
# Naughty naughty but there isn't any accessor/setter
$http->{timeout} = $TIMEOUT if $TIMEOUT;
$http->http11_mode(1);
my $fh = FileHandle->new;
unless ( $fh->open($to,'>') ) {
return $self->_error(loc(
"Could not open '%1' for writing: %2",$to,$!));
}
$fh->autoflush(1);
binmode $fh;
my $rc = $http->request( $uri, sub { my ($self,$dref,$cbargs) = @_; local $\; print {$cbargs} $$dref }, $fh );
close $fh;
if ( $rc == 301 || $rc == 302 ) {
my $loc;
HEADERS: for ($http->headers_array) {
/Location: (\S+)/ and $loc = $1, last HEADERS;
}
#$loc or last; # Think we should squeal here.
if ($loc =~ m!^/!) {
$uri =~ s{^(\w+?://[^/]+)/.*$}{$1};
$uri .= $loc;
}
else {
$uri = $loc;
}
next RETRIES;
}
elsif ( $rc == 200 ) {
return $to;
}
else {
return $self->_error(loc("Fetch failed! HTTP response: %1 [%2]",
$rc, $http->status_message));
}
} # Loop for 5 retries.
return $self->_error("Fetch failed! Gave up after 5 tries");
} else {
$METHOD_FAIL->{'httplite'} = 1;
return;
}
}
### Simple IO::Socket::INET fetching ###
sub _iosock_fetch {
my $self = shift;
my %hash = @_;
my ($to);
my $tmpl = {
to => { required => 1, store => \$to }
};
check( $tmpl, \%hash ) or return;
my $use_list = {
'IO::Socket::INET' => '0.0',
'IO::Select' => '0.0',
};
if( can_load(modules => $use_list) ) {
my $sock = IO::Socket::INET->new(
PeerHost => $self->host,
( $self->host =~ /:/ ? () : ( PeerPort => 80 ) ),
);
unless ( $sock ) {
return $self->_error(loc("Could not open socket to '%1', '%2'",$self->host,$!));
}
my $fh = FileHandle->new;
# Check open()
unless ( $fh->open($to,'>') ) {
return $self->_error(loc(
"Could not open '%1' for writing: %2",$to,$!));
}
$fh->autoflush(1);
binmode $fh;
my $path = File::Spec::Unix->catfile( $self->path, $self->file );
my $req = "GET $path HTTP/1.0\x0d\x0aHost: " . $self->host . "\x0d\x0a\x0d\x0a";
$sock->send( $req );
my $select = IO::Select->new( $sock );
my $resp = '';
my $normal = 0;
while ( $select->can_read( $TIMEOUT || 60 ) ) {
my $ret = $sock->sysread( $resp, 4096, length($resp) );
if ( !defined $ret or $ret == 0 ) {
$select->remove( $sock );
$normal++;
}
}
close $sock;
unless ( $normal ) {
return $self->_error(loc("Socket timed out after '%1' seconds", ( $TIMEOUT || 60 )));
}
# Check the "response"
# Strip preceding blank lines apparently they are allowed (RFC 2616 4.1)
$resp =~ s/^(\x0d?\x0a)+//;
# Check it is an HTTP response
unless ( $resp =~ m!^HTTP/(\d+)\.(\d+)!i ) {
return $self->_error(loc("Did not get a HTTP response from '%1'",$self->host));
}
# Check for OK
my ($code) = $resp =~ m!^HTTP/\d+\.\d+\s+(\d+)!i;
unless ( $code eq '200' ) {
return $self->_error(loc("Got a '%1' from '%2' expected '200'",$code,$self->host));
}
{
local $\;
print $fh +($resp =~ m/\x0d\x0a\x0d\x0a(.*)$/s )[0];
}
close $fh;
return $to;
} else {
$METHOD_FAIL->{'iosock'} = 1;
return;
}
}
### Net::FTP fetching
sub _netftp_fetch {
my $self = shift;
my %hash = @_;
my ($to);
my $tmpl = {
to => { required => 1, store => \$to }
};
check( $tmpl, \%hash ) or return;
( run in 0.671 second using v1.01-cache-2.11-cpan-787462296c9 )