Skip to content

Commit

Permalink
Add support for HTTP::Lite
Browse files Browse the repository at this point in the history
This commit adds support for HTTP::Lite as a pure-perl fallback
option if LWP is not installed.  HTTP::Lite (and MIME::Base64 and
Digest::MD5) have been added as prerequisites.

As a result of this change, HTTP::Lite will need to be added to the
Perl 5 core.  This will allow CPAN to bootstrap LWP (and the rest of
Bundle::CPAN) over http without reliance on external commands.  Jesse
Vincent has said this feature is a major goal for Perl 5.14.

The CPAN::HTTP::Lite module provides limited support for redirection and
authentication for HTTP::Lite, which does not natively support them,
and an API consistent with CPAN::LWP::UserAgent.

This patch changes auto-mirror selection to prefer 'http' over
'ftp' mirrors.
  • Loading branch information
xdg committed Nov 5, 2010
1 parent dc64415 commit a189037
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 24 deletions.
6 changes: 6 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
* add support for (and prerequisite on) HTTP::Lite; also adds
prerequisites for MIME::Base64 and Digest::MD5 to support
proxy authentication

* automatic mirror selection now returns only http mirrors

2010-10-26 Andreas J. Koenig <[email protected]>

* release 1.94_62
Expand Down
3 changes: 3 additions & 0 deletions Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ my $prereq_pm = {
# Scalar::Util;
# PathTools-3.16.tar.gz
'File::Temp' => 0, # TJENNESS; requires Test::More;
'HTTP::Lite' => 2.2, # allow bootstrap with pure perl HTTP
'MIME::Base64' => 0, # allow HTTP Basic authentication
'Digest::MD5' => 0, # allow HTTP Digest authentication
'Net::Ping' => 0, # SMPETERS;
'Scalar::Util' => 0, # GBARR;
# Scalar-List-Utils-1.18.tar.gz;
Expand Down
17 changes: 14 additions & 3 deletions lib/CPAN.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,17 @@ sub has_usable {
sub {require Net::FTP},
sub {require Net::Config},
],
'HTTP::Lite' => [
sub {
require HTTP::Lite;
unless (CPAN::Version->vge(HTTP::Lite->VERSION, 2.2)) {
for ("Will not use HTTP::Lite, need version 2.2\n") {
$CPAN::Frontend->mywarn($_);
die $_;
}
}
},
],
'File::HomeDir' => [
sub {require File::HomeDir;
unless (CPAN::Version->vge(File::HomeDir::->VERSION, 0.52)) {
Expand Down Expand Up @@ -1385,8 +1396,8 @@ Basic commands:
The CPAN module automates or at least simplifies the make and install
of perl modules and extensions. It includes some primitive searching
capabilities and knows how to use Net::FTP, LWP, and certain external
download clients to fetch distributions from the net.
capabilities and knows how to use LWP, HTTP::Lite, Net::FTP and certain
external download clients to fetch distributions from the net.
These are fetched from one or more mirrored CPAN (Comprehensive
Perl Archive Network) sites and unpacked in a dedicated directory.
Expand Down Expand Up @@ -3381,7 +3392,7 @@ or in your web browser you've proxy information set, then you know
you are running behind an http firewall.
To access servers outside these types of firewalls with perl (even for
ftp), you need LWP.
ftp), you need LWP or HTTP::Lite.
=item ftp firewall
Expand Down
37 changes: 35 additions & 2 deletions lib/CPAN/FTP.pm
Original file line number Diff line number Diff line change
Expand Up @@ -652,8 +652,41 @@ sub hostdleasy { #called from hostdlxxx
# Net::FTP can still succeed where LWP fails. So we do not
# skip Net::FTP anymore when LWP is available.
}
} else {
$CPAN::Frontend->mywarn(" LWP not available\n");
} elsif ($url =~ /^http:/ && $CPAN::META->has_usable('HTTP::Lite')) {
require CPAN::HTTP::Lite;
my $chl = CPAN::HTTP::Lite->new(
proxy => $CPAN::Config->{http_proxy} || $ENV{http_proxy},
no_proxy => $CPAN::Config->{no_proxy} || $ENV{no_proxy},
);
for my $try ( $url, ( $url !~ /\.gz(?!\n)\Z/ ? "$url.gz" : () ) ) {
$CPAN::Frontend->myprint("Fetching with HTTP::Lite:\n$try\n");
my $res = eval { $chl->mirror($try, $aslocal) };
if ( $res && defined $res->status
&& substr($res->status, 0, 1) eq '2' # 2XX
) {
$ThesiteURL = $ro_url;
my $now = time;
utime $now, $now, $aslocal; # download time is more
# important than upload
# time
return $aslocal;
}
elsif ($res && defined $res->status) {
$CPAN::Frontend->myprint(sprintf(
"HTTP::Lite failed with code[%s] message[%s]\n",
$res->status,
$res->status_message,
)
);
}
else {
my $err = $@ || 'Could not connect';
$CPAN::Frontend->myprint(sprintf(
"Error downloading with HTTP::Lite: %s\n", $err
)
);
}
}
}
return if $CPAN::Signal;
if ($url =~ m|^ftp://(.*?)/(.*)/(.*)|) {
Expand Down
2 changes: 1 addition & 1 deletion lib/CPAN/FirstTime.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1630,7 +1630,7 @@ sub auto_mirrored_by {
how_many => 5,
callback => sub { $CPAN::Frontend->myprint(".") },
);
my $urllist = [ map { $_->ftp } @best ];
my $urllist = [ map { $_->http } @best ];
push @$urllist, grep { /^file:/ } @{$CPAN::Config->{urllist}};
$CPAN::Frontend->myprint(" done!\n\n");
return $urllist;
Expand Down
32 changes: 21 additions & 11 deletions lib/CPAN/HTTP/Credentials.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,51 @@
# vim: ts=4 sts=4 sw=4:
package CPAN::HTTP::Credentials;
use strict;
use vars qw($USER $PASSWD);
use vars qw($USER $PASSWORD $PROXY_USER $PROXY_PASSWORD);

$CPAN::HTTP::Credentials::VERSION = $CPAN::HTTP::Credentials::VERSION = "1.94";

sub clear_credentials {
_clear_non_proxy_credentials();
_clear_proxy_credentials();
}

sub clear_non_proxy_credentials {
undef $USER;
undef $PASSWD;
undef $PASSWORD;
}

sub clear_proxy_credentials {
undef $PROXY_USER;
undef $PROXY_PASSWORD;
}

sub get_proxy_credentials {
my $self = shift;
if ($USER && $PASSWD) {
return ($USER, $PASSWD);
if ($PROXY_USER && $PROXY_PASSWORD) {
return ($PROXY_USER, $PROXY_PASSWORD);
}
if ( defined $CPAN::Config->{proxy_user}
&& $CPAN::Config->{proxy_user}
) {
$USER = $CPAN::Config->{proxy_user};
$PASSWORD = $CPAN::Config->{proxy_pass} || "";
return ($USER, $PASSWORD);
$PROXY_USER = $CPAN::Config->{proxy_user};
$PROXY_PASSWORD = $CPAN::Config->{proxy_pass} || "";
return ($PROXY_USER, $PROXY_PASSWORD);
}
my $username_prompt = "\nProxy authentication needed!
(Note: to permanently configure username and password run
o conf proxy_user your_username
o conf proxy_pass your_password
)\nUsername:";
($USER, $PASSWORD) =
($PROXY_USER, $PROXY_PASSWORD) =
_get_username_and_password_from_user($username_prompt);
return ($USER,$PASSWORD);
return ($PROXY_USER,$PROXY_PASSWORD);
}

sub get_non_proxy_credentials {
my $self = shift;
if ($USER && $PASSWD) {
return ($USER, $PASSWD);
if ($USER && $PASSWORD) {
return ($USER, $PASSWORD);
}
if ( defined $CPAN::Config->{username} ) {
$USER = $CPAN::Config->{username};
Expand Down
Loading

0 comments on commit a189037

Please sign in to comment.