diff --git a/Changes b/Changes
index 2e738816..9a5dfac8 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-See http://github.com/miyagawa/cpanminus/ for the latest development.
+See https://github.com/miyagawa/cpanminus/ for the latest development.
{{$NEXT}}
diff --git a/META.json b/META.json
index 7e135b65..e7370d82 100644
--- a/META.json
+++ b/META.json
@@ -9,7 +9,7 @@
"perl_5"
],
"meta-spec" : {
- "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+ "url" : "https://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
},
"name" : "App-cpanminus",
diff --git a/README.md b/README.md
index 213f6562..f72ea646 100644
--- a/README.md
+++ b/README.md
@@ -85,16 +85,16 @@ perl 5.8.1 or later.
## How does cpanm get/parse/update the CPAN index?
-It queries the CPAN Meta DB site at [http://cpanmetadb.plackperl.org/](http://cpanmetadb.plackperl.org/).
+It queries the CPAN Meta DB site at [https://cpanmetadb.plackperl.org/](https://cpanmetadb.plackperl.org/).
The site is updated at least every hour to reflect the latest changes
from fast syncing mirrors. The script then also falls back to query the
-module at [http://metacpan.org/](http://metacpan.org/) using its search API.
+module at [https://metacpan.org/](https://metacpan.org/) using its search API.
Upon calling these API hosts, cpanm (1.6004 or later) will send the
local perl versions to the server in User-Agent string by default. You
can turn it off with `--no-report-perl-version` option. Read more
about the option with [cpanm](https://metacpan.org/pod/cpanm), and read more about the privacy policy
-about this data collection at [http://cpanmetadb.plackperl.org/#privacy](http://cpanmetadb.plackperl.org/#privacy)
+about this data collection at [https://cpanmetadb.plackperl.org/#privacy](https://cpanmetadb.plackperl.org/#privacy)
Fetched files are unpacked in `~/.cpanm` and automatically cleaned up
periodically. You can configure the location of this with the
@@ -201,7 +201,7 @@ Arnfjord Bjarmason, Eric Wilhelm, Florian Ragwitz and xaicron.
# COMMUNITY
-- [http://github.com/miyagawa/cpanminus](http://github.com/miyagawa/cpanminus) - source code repository, issue tracker
+- [https://github.com/miyagawa/cpanminus](https://github.com/miyagawa/cpanminus) - source code repository, issue tracker
- [irc://irc.perl.org/#cpanm](irc://irc.perl.org/#cpanm) - discussions about cpanm and its related tools
# NO WARRANTY
diff --git a/lib/App/cpanminus.pm b/lib/App/cpanminus.pm
index abfeaa42..6b4dbde1 100644
--- a/lib/App/cpanminus.pm
+++ b/lib/App/cpanminus.pm
@@ -105,16 +105,16 @@ Module::Build (core in 5.10)
=head2 How does cpanm get/parse/update the CPAN index?
-It queries the CPAN Meta DB site at L.
+It queries the CPAN Meta DB site at L.
The site is updated at least every hour to reflect the latest changes
from fast syncing mirrors. The script then also falls back to query the
-module at L using its search API.
+module at L using its search API.
Upon calling these API hosts, cpanm (1.6004 or later) will send the
local perl versions to the server in User-Agent string by default. You
can turn it off with C<--no-report-perl-version> option. Read more
about the option with L, and read more about the privacy policy
-about this data collection at L
+about this data collection at L
Fetched files are unpacked in C<~/.cpanm> and automatically cleaned up
periodically. You can configure the location of this with the
@@ -270,7 +270,7 @@ Arnfjord Bjarmason, Eric Wilhelm, Florian Ragwitz and xaicron.
=over 4
-=item L - source code repository, issue tracker
+=item L - source code repository, issue tracker
=item L - discussions about cpanm and its related tools
diff --git a/lib/App/cpanminus/script.pm b/lib/App/cpanminus/script.pm
index eb764e3f..2ef5316a 100644
--- a/lib/App/cpanminus/script.pm
+++ b/lib/App/cpanminus/script.pm
@@ -69,7 +69,7 @@ sub new {
mirrors => [],
mirror_only => undef,
mirror_index => undef,
- cpanmetadb => "http://cpanmetadb.plackperl.org/v1.0/",
+ cpanmetadb => "https://cpanmetadb.plackperl.org/v1.0/",
perl => $^X,
argv => [],
local_lib => undef,
@@ -83,6 +83,7 @@ sub new {
try_lwp => 1,
try_wget => 1,
try_curl => 1,
+ use_http => 0,
uninstall_shadows => ($] < 5.012),
skip_installed => 1,
skip_satisfied => 0,
@@ -200,6 +201,7 @@ sub parse_options {
'lwp!' => \$self->{try_lwp},
'wget!' => \$self->{try_wget},
'curl!' => \$self->{try_curl},
+ 'insecure!' => \$self->{use_http},
'auto-cleanup=s' => \$self->{auto_cleanup},
'man-pages!' => \$self->{pod2man},
'scandeps' => \$self->{scandeps},
@@ -526,7 +528,7 @@ sub numify_ver {
sub search_metacpan {
my($self, $module, $version, $dev_release) = @_;
- my $metacpan_uri = 'http://fastapi.metacpan.org/v1/download_url/';
+ my $metacpan_uri = 'https://fastapi.metacpan.org/v1/download_url/';
my $url = $metacpan_uri . $module;
@@ -543,7 +545,7 @@ sub search_metacpan {
if ($dist_meta && $dist_meta->{download_url}) {
(my $distfile = $dist_meta->{download_url}) =~ s!.+/authors/id/!!;
local $self->{mirrors} = $self->{mirrors};
- $self->{mirrors} = [ 'http://cpan.metacpan.org' ];
+ $self->{mirrors} = [ 'https://cpan.metacpan.org' ];
return $self->cpan_module($module, $distfile, $dist_meta->{version});
}
@@ -619,7 +621,7 @@ sub search_cpanmetadb_history {
for my $try (sort { $b->{version_obj} cmp $a->{version_obj} } @found) {
if ($self->satisfy_version($module, $try->{version_obj}, $version)) {
local $self->{mirrors} = $self->{mirrors};
- unshift @{$self->{mirrors}}, 'http://backpan.perl.org'
+ unshift @{$self->{mirrors}}, 'https://backpan.perl.org'
unless $try->{latest};
return $self->cpan_module($module, $try->{distfile}, $try->{version});
}
@@ -747,7 +749,7 @@ Options:
--installdeps Only install dependencies
--showdeps Only display direct dependencies
--reinstall Reinstall the distribution even if you already have the latest version installed
- --mirror Specify the base URL for the mirror (e.g. http://cpan.cpantesters.org/)
+ --mirror Specify the base URL for the mirror (e.g. https://cpan.cpantesters.org/)
--mirror-only Use the mirror's index file instead of the CPAN Meta DB
-M,--from Use only this mirror base URL and its index file
--prompt Prompt when configure/build/test fails
@@ -767,18 +769,18 @@ Examples:
cpanm Test::More # install Test::More
cpanm MIYAGAWA/Plack-0.99_05.tar.gz # full distribution path
- cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
+ cpanm https://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz # install from a local file
cpanm --interactive Task::Kensho # Configure interactively
cpanm . # install from local directory
cpanm --installdeps . # install all the deps for the current directory
cpanm -L extlib Plack # install Plack and all non-core deps into extlib
- cpanm --mirror http://cpan.cpantesters.org/ DBI # use the fast-syncing mirror
+ cpanm --mirror https://cpan.cpantesters.org/ DBI # use the fast-syncing mirror
cpanm -M https://cpan.metacpan.org App::perlbrew # use only this secure mirror and its index
You can also specify the default options in PERL_CPANM_OPT environment variable in the shell rc:
- export PERL_CPANM_OPT="--prompt --reinstall -l ~/perl --mirror http://cpan.cpantesters.org"
+ export PERL_CPANM_OPT="--prompt --reinstall -l ~/perl --mirror https://cpan.cpantesters.org"
Type `man cpanm` or `perldoc cpanm` for the more detailed explanation of the options.
@@ -1271,12 +1273,19 @@ sub chdir {
sub configure_mirrors {
my $self = shift;
unless (@{$self->{mirrors}}) {
- $self->{mirrors} = [ 'http://www.cpan.org' ];
+ $self->{mirrors} = [ 'https://www.cpan.org' ];
}
for (@{$self->{mirrors}}) {
s!^/!file:///!;
s!/$!!;
}
+
+ if ( grep { m/^http:/ } @{$self->{mirrors}} ) {
+ warn "WARNING: Detected a non TLS mirror, enforcing http requests.\n";
+ $self->{use_http} = 1;
+ }
+
+ return;
}
sub self_upgrade {
@@ -1761,7 +1770,7 @@ sub cpan_dist {
sub git_uri {
my ($self, $uri) = @_;
- # similar to http://www.pip-installer.org/en/latest/logic.html#vcs-support
+ # similar to https://www.pip-installer.org/en/latest/logic.html#vcs-support
# git URL has to end with .git when you need to use pin @ commit/tag/branch
($uri, my $commitish) = split /(?<=\.git)@/i, $uri, 2;
@@ -2738,8 +2747,9 @@ sub mirror {
if ($uri =~ /^file:/) {
$self->file_mirror($uri, $local);
} else {
- $self->{_backends}{mirror}->(@_);
+ $self->{_backends}{mirror}->(@_);
}
+
}
sub untar { $_[0]->{_backends}{untar}->(@_) };
@@ -2780,7 +2790,9 @@ sub file_mirror {
sub has_working_lwp {
my($self, $mirrors) = @_;
+
my $https = grep /^https:/, @$mirrors;
+ $https = 0 if $self->{use_http};
eval {
require LWP::UserAgent; # no fatpack
LWP::UserAgent->VERSION(5.802);
@@ -2798,6 +2810,8 @@ sub init_tools {
$self->chat("You have make $self->{make}\n");
}
+ my ( $http_get, $http_mirror );
+
# use --no-lwp if they have a broken LWP, to upgrade LWP
if ($self->{try_lwp} && $self->has_working_lwp($self->{mirrors})) {
$self->chat("You have LWP $LWP::VERSION\n");
@@ -2810,13 +2824,13 @@ sub init_tools {
@_,
);
};
- $self->{_backends}{get} = sub {
+ $http_get = sub {
my $self = shift;
my $res = $ua->()->request(HTTP::Request->new(GET => $_[0]));
return unless $res->is_success;
return $res->decoded_content;
};
- $self->{_backends}{mirror} = sub {
+ $http_mirror = sub {
my $self = shift;
my $res = $ua->()->mirror(@_);
die $res->content if $res->code == 501;
@@ -2829,13 +2843,13 @@ sub init_tools {
'--retry-connrefused',
($self->{verbose} ? () : ('-q')),
);
- $self->{_backends}{get} = sub {
+ $http_get = sub {
my($self, $uri) = @_;
$self->safeexec( my $fh, $wget, $uri, @common, '-O', '-' ) or die "wget $uri: $!";
local $/;
<$fh>;
};
- $self->{_backends}{mirror} = sub {
+ $http_mirror = sub {
my($self, $uri, $path) = @_;
$self->safeexec( my $fh, $wget, $uri, @common, '-O', $path ) or die "wget $uri: $!";
local $/;
@@ -2848,13 +2862,13 @@ sub init_tools {
'--user-agent', $self->agent,
($self->{verbose} ? () : '-s'),
);
- $self->{_backends}{get} = sub {
+ $http_get = sub {
my($self, $uri) = @_;
$self->safeexec( my $fh, $curl, @common, $uri ) or die "curl $uri: $!";
local $/;
<$fh>;
};
- $self->{_backends}{mirror} = sub {
+ $http_mirror = sub {
my($self, $uri, $path) = @_;
$self->safeexec( my $fh, $curl, @common, $uri, '-#', '-o', $path ) or die "curl $uri: $!";
local $/;
@@ -2866,19 +2880,23 @@ sub init_tools {
my %common = (
agent => $self->agent,
);
- $self->{_backends}{get} = sub {
+ $http_get = sub {
my $self = shift;
my $res = HTTP::Tiny->new(%common)->get($_[0]);
return unless $res->{success};
return $res->{content};
};
- $self->{_backends}{mirror} = sub {
+ $http_mirror = sub {
my $self = shift;
my $res = HTTP::Tiny->new(%common)->mirror(@_);
return $res->{status};
};
}
+ # handle the insecure mode to honor and force http requests
+ $self->{_backends}{get} = $self->wrap_http_request( $http_get );
+ $self->{_backends}{mirror} = $self->wrap_http_request( $http_mirror );
+
my $tar = $self->which('tar');
my $tar_ver;
my $maybe_bad_tar = sub { WIN32 || BAD_TAR || (($tar_ver = `$tar --version 2>/dev/null`) =~ /GNU.*1\.13/i) };
@@ -3017,6 +3035,40 @@ sub init_tools {
}
}
+sub wrap_http_request {
+ my ( $self, $code ) = @_;
+
+ die unless ref $code eq 'CODE';
+
+ my $wrapper = sub {
+ my ( $self, $uri, @extra ) = @_;
+
+ # certificates check, let's switch to http on demand.
+ $uri =~ s/^https:/http:/ if $self->{use_http};
+
+ # call the get or mirror
+ my $reply = $code->( $self, $uri, @extra );
+
+ if ( $uri =~ m{^https:} && !$self->{has_displayed_insecure_advice} ) {
+ if ( !defined $reply || $reply eq 500 || $reply =~ m{certificate}mi ) {
+
+die <<"DIE";
+Failed to fetch $uri: $reply\n
+
+This could a TLS issue with the HTTP client used.
+Please verify your certificates or force an HTTP-only request/mirror
+using --insecure option at your own risk.
+DIE
+ $self->{has_displayed_insecure_advice} = 1;
+ }
+ }
+
+ return $reply;
+ };
+
+ return $wrapper;
+}
+
sub safeexec {
my $self = shift;
my $rdr = $_[0] ||= Symbol::gensym();
diff --git a/script/cpanm.PL b/script/cpanm.PL
index 3477adca..6ff66943 100755
--- a/script/cpanm.PL
+++ b/script/cpanm.PL
@@ -38,14 +38,14 @@ cpanm - get, unpack build and install modules from CPAN
cpanm Test::More # install Test::More
cpanm MIYAGAWA/Plack-0.99_05.tar.gz # full distribution path
- cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
+ cpanm https://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz # install from a local file
cpanm --interactive Task::Kensho # Configure interactively
cpanm . # install from local directory
cpanm --installdeps . # install all the deps for the current directory
cpanm -L extlib Plack # install Plack and all non-core deps into extlib
- cpanm --mirror http://cpan.cpantesters.org/ DBI # use the fast-syncing mirror
- cpanm --from https://cpan.metacpan.org/ Plack # use only the HTTPS mirror
+ cpanm --mirror https://cpan.cpantesters.org/ DBI # use the fast-syncing mirror
+ cpanm --from https://cpan.metacpan.org/ Plack # use a different mirror
=head1 COMMANDS
@@ -61,7 +61,7 @@ will all work as you expect.
cpanm Plack/Request.pm
cpanm MIYAGAWA/Plack-1.0000.tar.gz
cpanm /path/to/Plack-1.0000.tar.gz
- cpanm http://cpan.metacpan.org/authors/id/M/MI/MIYAGAWA/Plack-0.9990.tar.gz
+ cpanm https://cpan.metacpan.org/authors/id/M/MI/MIYAGAWA/Plack-0.9990.tar.gz
cpanm git://github.com/plack/Plack.git
Additionally, you can use the notation using C<~> and C<@> to specify
@@ -214,7 +214,7 @@ the behaviour from before version 1.7023
=item --mirror
Specifies the base URL for the CPAN mirror to use, such as
-C (you can omit the trailing slash). You
+C (you can omit the trailing slash). You
can specify multiple mirror URLs by repeating the command line option.
You can use a local directory that has a CPAN mirror structure
@@ -225,7 +225,7 @@ scheme), it is considered as a file scheme as well.
cpanm --mirror file:///path/to/mirror
cpanm --mirror ~/minicpan # Because shell expands ~ to /home/user
-Defaults to C.
+Defaults to C.
=item --mirror-only
@@ -257,7 +257,7 @@ B It might be useful if you name these options with your shell
aliases, like:
alias minicpanm='cpanm --from ~/minicpan'
- alias darkpan='cpanm --from http://mycompany.example.com/DPAN'
+ alias darkpan='cpanm --from https://mycompany.example.com/DPAN'
=item --mirror-index
@@ -546,9 +546,16 @@ Defaults to true (man pages generated) unless C<-L|--local-lib-contained>
option is supplied in which case it's set to false. You can disable
it with C<--no-man-pages>.
+=item --insecure
+
+By default, cpanm only uses HTTPS. If your environment lacks TLS
+support, you can consider at your own risk to use HTTP instead by
+using the C<--insecure> flag.
+Be aware that when using that argument all requests will use HTTP.
+
=item --lwp
-Uses L module to download stuff over HTTP. Defaults to true, and
+Uses L module to download stuff over HTTPS. Defaults to true, and
you can say C<--no-lwp> to disable using LWP, when you want to upgrade
LWP from CPAN on some broken perl systems.