LWP-Protocol-https-6.06/0002755004041600001440000000000012324255067014603 5ustar mschilliusersLWP-Protocol-https-6.06/lib/0002755004041600001440000000000012324255067015351 5ustar mschilliusersLWP-Protocol-https-6.06/lib/LWP/0002755004041600001440000000000012324255067016013 5ustar mschilliusersLWP-Protocol-https-6.06/lib/LWP/Protocol/0002755004041600001440000000000012324255067017614 5ustar mschilliusersLWP-Protocol-https-6.06/lib/LWP/Protocol/https.pm0000644004041600001440000001462512324251726021320 0ustar mschilliuserspackage LWP::Protocol::https; use strict; our $VERSION = "6.06"; require LWP::Protocol::http; our @ISA = qw(LWP::Protocol::http); require Net::HTTPS; sub socket_type { return "https"; } sub _extra_sock_opts { my $self = shift; my %ssl_opts = %{$self->{ua}{ssl_opts} || {}}; if (delete $ssl_opts{verify_hostname}) { $ssl_opts{SSL_verify_mode} ||= 1; $ssl_opts{SSL_verifycn_scheme} = 'www'; } else { $ssl_opts{SSL_verify_mode} = 0; } if ($ssl_opts{SSL_verify_mode}) { unless (exists $ssl_opts{SSL_ca_file} || exists $ssl_opts{SSL_ca_path}) { eval { require Mozilla::CA; }; if ($@) { if ($@ =! /^Can't locate Mozilla\/CA\.pm/) { $@ = <<'EOT'; Can't verify SSL peers without knowing which Certificate Authorities to trust This problem can be fixed by either setting the PERL_LWP_SSL_CA_FILE environment variable or by installing the Mozilla::CA module. To disable verification of SSL peers set the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0. If you do this you can't be sure that you communicate with the expected peer. EOT } die $@; } $ssl_opts{SSL_ca_file} = Mozilla::CA::SSL_ca_file(); } } $self->{ssl_opts} = \%ssl_opts; return (%ssl_opts, $self->SUPER::_extra_sock_opts); } #------------------------------------------------------------ # _cn_match($common_name, $san_name) # common_name: an IA5String # san_name: subjectAltName # initially we were only concerned with the dNSName # and the 'left-most' only wildcard as noted in # https://tools.ietf.org/html/rfc6125#section-6.4.3 # this method does not match any wildcarding in the # domain name as listed in section-6.4.3.3 # sub _cn_match { my( $me, $common_name, $san_name ) = @_; # /CN has a '*.' prefix # MUST be an FQDN -- fishing? return 0 if( $common_name =~ /^\*\./ ); my $re = q{}; # empty string # turn a leading "*." into a regex if( $san_name =~ /^\*\./ ) { $san_name =~ s/\*//; $re = "[^.]+"; } # quotemeta the rest and match anchored if( $common_name =~ /^$re\Q$san_name\E$/ ) { return 1; } return 0; } #------------------------------------------------------- # _in_san( cn, cert ) # 'cn' of the form /CN=host_to_check ( "Common Name" form ) # 'cert' any object that implements a peer_certificate('subjectAltNames') method # which will return an array of ( type-id, value ) pairings per # http://tools.ietf.org/html/rfc5280#section-4.2.1.6 # if there is no subjectAltNames there is nothing more to do. # currently we have a _cn_match() that will allow for simple compare. sub _in_san { my($me, $cn, $cert) = @_; # we can return early if there are no SAN options. my @sans = $cert->peer_certificate('subjectAltNames'); return unless scalar @sans; (my $common_name = $cn) =~ s/.*=//; # strip off the prefix. # get the ( type-id, value ) pairwise # currently only the basic CN to san_name check while( my ( $type_id, $value ) = splice( @sans, 0, 2 ) ) { return 'ok' if $me->_cn_match($common_name,$value); } return; } sub _check_sock { my($self, $req, $sock) = @_; my $check = $req->header("If-SSL-Cert-Subject"); if (defined $check) { my $cert = $sock->get_peer_certificate || die "Missing SSL certificate"; my $subject = $cert->subject_name; unless ( $subject =~ /$check/ ) { my $ok = $self->_in_san( $check, $cert); die "Bad SSL certificate subject: '$subject' !~ /$check/" unless $ok; } $req->remove_header("If-SSL-Cert-Subject"); # don't pass it on } } sub _get_sock_info { my $self = shift; $self->SUPER::_get_sock_info(@_); my($res, $sock) = @_; $res->header("Client-SSL-Cipher" => $sock->get_cipher); my $cert = $sock->get_peer_certificate; if ($cert) { $res->header("Client-SSL-Cert-Subject" => $cert->subject_name); $res->header("Client-SSL-Cert-Issuer" => $cert->issuer_name); } if (!$self->{ssl_opts}{SSL_verify_mode}) { $res->push_header("Client-SSL-Warning" => "Peer certificate not verified"); } elsif (!$self->{ssl_opts}{SSL_verifycn_scheme}) { $res->push_header("Client-SSL-Warning" => "Peer hostname match with certificate not verified"); } $res->header("Client-SSL-Socket-Class" => $Net::HTTPS::SSL_SOCKET_CLASS); } # upgrade plain socket to SSL, used for CONNECT tunnel when proxying https # will only work if the underlying socket class of Net::HTTPS is # IO::Socket::SSL, but code will only be called in this case if ( $Net::HTTPS::SSL_SOCKET_CLASS->can('start_SSL')) { *_upgrade_sock = sub { my ($self,$sock,$url) = @_; $sock = LWP::Protocol::https::Socket->start_SSL( $sock, SSL_verifycn_name => $url->host, $self->_extra_sock_opts, ); $@ = LWP::Protocol::https::Socket->errstr if ! $sock; return $sock; } } #----------------------------------------------------------- package LWP::Protocol::https::Socket; our @ISA = qw(Net::HTTPS LWP::Protocol::http::SocketMethods); 1; __END__ =head1 NAME LWP::Protocol::https - Provide https support for LWP::UserAgent =head1 SYNOPSIS use LWP::UserAgent; $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 }); $res = $ua->get("https://www.example.com"); =head1 DESCRIPTION The LWP::Protocol::https module provides support for using https schemed URLs with LWP. This module is a plug-in to the LWP protocol handling, so you don't use it directly. Once the module is installed LWP is able to access sites using HTTP over SSL/TLS. If hostname verification is requested by LWP::UserAgent's C, and neither C nor C is set, then C is implied to be the one provided by Mozilla::CA. If the Mozilla::CA module isn't available SSL requests will fail. Either install this module, set up an alternative C or disable hostname verification. This module used to be bundled with the libwww-perl, but it was unbundled in v6.02 in order to be able to declare its dependencies properly for the CPAN tool-chain. Applications that need https support can just declare their dependency on LWP::Protocol::https and will no longer need to know what underlying modules to install. =head1 SEE ALSO L, L, L =head1 COPYRIGHT Copyright 1997-2011 Gisle Aas. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. LWP-Protocol-https-6.06/t/0002755004041600001440000000000012324255067015046 5ustar mschilliusersLWP-Protocol-https-6.06/t/https_proxy.t0000644004041600001440000002347412324250406017636 0ustar mschilliusers#!/usr/bin/perl # to run test with Net::SSL as backend set environment # PERL_NET_HTTPS_SSL_SOCKET_CLASS=Net::SSL use strict; use warnings; use Test::More; use File::Temp 'tempfile'; use IO::Socket::INET; use IO::Select; use Socket 'MSG_PEEK'; use LWP::UserAgent; use LWP::Protocol::https; plan skip_all => "fork not implemented on this platform" if grep { $^O =~m{$_} } qw( MacOS VOS vmesa riscos amigaos ); eval { require IO::Socket::SSL } and $IO::Socket::SSL::VERSION >= 1.953 and eval { require IO::Socket::SSL::Utils } or plan skip_all => "no recent version of IO::Socket::SSL::Utils"; IO::Socket::SSL::Utils->import; # create CA ------------------------------------------------------------- my ($cacert,$cakey) = CERT_create( CA => 1 ); my $cafile = do { my ($fh,$fname) = tempfile( CLEANUP => 1 ); print $fh PEM_cert2string($cacert); $fname }; # create two web servers ------------------------------------------------ my (@server,@saddr); for my $i (0,1) { my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, # let system pick port Listen => 10 ) or die "failed to create INET listener"; my $saddr = $server->sockhost.':'.$server->sockport; $server[$i] = $server; $saddr[$i] = $saddr; } my @childs; END { kill 9,@childs if @childs }; defined( my $pid = fork()) or die "fork failed: $!"; # child process runs _server and exits if ( ! $pid ) { @childs = (); exit( _server()); } # parent continues with closed server sockets push @childs,$pid; @server = (); # check which SSL implementation Net::HTTPS uses # Net::SSL behaves different than the default IO::Socket::SSL my $netssl = $Net::HTTPS::SSL_SOCKET_CLASS eq 'Net::SSL'; # do some tests ---------------------------------------------------------- my %ua; $ua{noproxy} = LWP::UserAgent->new( keep_alive => 10, # size of connection cache # server does not know the expected name and returns generic certificate ssl_opts => { verify_hostname => 0 } ); $ua{proxy} = LWP::UserAgent->new( keep_alive => 10, # size of connection cache ssl_opts => { # Net::SSL cannot verify hostnames :( verify_hostname => $netssl ? 0: 1, SSL_ca_file => $cafile } ); $ua{proxy_nokeepalive} = LWP::UserAgent->new( keep_alive => 0, ssl_opts => { # Net::SSL cannot verify hostnames :( verify_hostname => $netssl ? 0: 1, SSL_ca_file => $cafile } ); $ENV{http_proxy} = $ENV{https_proxy} = "http://foo:bar\@$saddr[0]"; $ua{proxy}->env_proxy; $ua{proxy_nokeepalive}->env_proxy; if ($netssl) { # Net::SSL cannot get user/pass from proxy url $ENV{HTTPS_PROXY_USERNAME} = 'foo'; $ENV{HTTPS_PROXY_PASSWORD} = 'bar'; } my @tests = ( # the expected ids are connid.reqid[tunnel_auth][req_auth]@sslhost # because we run different sets of test depending on the SSL class # used by Net::HTTPS we replace connid with a letter and later # match it to a number # keep-alive for non-proxy http # requests to same target use same connection, even if intermixed [ 'noproxy', "http://$saddr[0]/foo",'A.1@nossl' ], [ 'noproxy', "http://$saddr[0]/bar",'A.2@nossl' ], # reuse conn#1 [ 'noproxy', "http://$saddr[1]/foo",'B.1@nossl' ], [ 'noproxy', "http://$saddr[1]/bar",'B.2@nossl' ], # reuse conn#2 [ 'noproxy', "http://$saddr[0]/tor",'A.3@nossl' ], # reuse conn#1 again [ 'noproxy', "http://$saddr[1]/tor",'B.3@nossl' ], # reuse conn#2 again # keep-alive for proxy http # use the same proxy connection for all even if the target host differs [ 'proxy', "http://foo/foo",'C.1.auth@nossl' ], [ 'proxy', "http://foo/bar",'C.2.auth@nossl' ], [ 'proxy', "http://bar/foo",'C.3.auth@nossl' ], [ 'proxy', "http://bar/bar",'C.4.auth@nossl' ], [ 'proxy', "http://foo/tor",'C.5.auth@nossl' ], [ 'proxy', "http://bar/tor",'C.6.auth@nossl' ], # keep-alive for non-proxy https # requests to same target use same connection, even if intermixed [ 'noproxy', "https://$saddr[0]/foo",'D.1@direct.ssl.access' ], [ 'noproxy', "https://$saddr[0]/bar",'D.2@direct.ssl.access' ], [ 'noproxy', "https://$saddr[1]/foo",'E.1@direct.ssl.access' ], [ 'noproxy', "https://$saddr[1]/bar",'E.2@direct.ssl.access' ], [ 'noproxy', "https://$saddr[0]/tor",'D.3@direct.ssl.access' ], [ 'noproxy', "https://$saddr[1]/tor",'E.3@direct.ssl.access' ], # keep-alive for proxy https ! $netssl ? ( # note that we reuse proxy conn#C in first request. Although the last id # from this conn was C.6 the new one is C.8, because request C.7 was the # socket upgrade via CONNECT request [ 'proxy', "https://foo/foo",'C.8.Tauth@foo' ], [ 'proxy', "https://foo/bar",'C.9.Tauth@foo' ], # if the target of the tunnel is different we need another connection # note that it starts with F.2, because F.1 is the CONNECT request which # established the tunnel [ 'proxy', "https://bar/foo",'F.2.Tauth@bar' ], [ 'proxy', "https://bar/bar",'F.3.Tauth@bar' ], [ 'proxy', "https://foo/tor",'C.10.Tauth@foo' ], [ 'proxy', "https://bar/tor",'F.4.Tauth@bar' ], ):( # Net::SSL will cannot reuse socket for CONNECT, but once inside tunnel # keep-alive is possible [ 'proxy', "https://foo/foo",'G.2.Tauth@foo' ], [ 'proxy', "https://foo/bar",'G.3.Tauth@foo' ], [ 'proxy', "https://bar/foo",'F.2.Tauth@bar' ], [ 'proxy', "https://bar/bar",'F.3.Tauth@bar' ], [ 'proxy', "https://foo/tor",'G.4.Tauth@foo' ], [ 'proxy', "https://bar/tor",'F.4.Tauth@bar' ], ), # non-keep alive for proxy https [ 'proxy_nokeepalive', "https://foo/foo",'H.2.Tauth@foo' ], [ 'proxy_nokeepalive', "https://foo/bar",'I.2.Tauth@foo' ], [ 'proxy_nokeepalive', "https://bar/foo",'J.2.Tauth@bar' ], [ 'proxy_nokeepalive', "https://bar/bar",'K.2.Tauth@bar' ], ); plan tests => 2*@tests; my (%conn2id,%id2conn); for my $test (@tests) { my ($uatype,$url,$expect_id) = @$test; my $ua = $ua{$uatype} or die "no such ua: $uatype"; # Net::SSL uses only the environment to decide about proxy, so we need the # proxy/non-proxy environment for each request if ( $netssl && $url =~m{^https://} ) { $ENV{https_proxy} = $uatype =~m{^proxy} ? "http://$saddr[0]":"" } my $response = $ua->get($url) or die "no response"; if ( $response->is_success and ( my $body = $response->content()) =~m{^ID: *(\d+)\.(\S+)}m ) { my $id = [ $1,$2 ]; my $xid = [ $expect_id =~m{(\w+)\.(\S+)} ]; if ( my $x = $id2conn{$id->[0]} ) { $id->[0] = $x; } elsif ( ! $conn2id{$xid->[0]} ) { $conn2id{ $xid->[0] } = $id->[0]; $id2conn{ $id->[0] } = $xid->[0]; $id->[0] = $xid->[0]; } is("$id->[0].$id->[1]",$expect_id,"$uatype $url -> $expect_id") or diag($response->as_string); # inside proxy tunnel and for non-proxy there should be only absolute # URI in request w/o scheme my $expect_rqurl = $url; $expect_rqurl =~s{^\w+://[^/]+}{} if $uatype eq 'noproxy' or $url =~m{^https://}; my ($rqurl) = $body =~m{^GET (\S+) HTTP/}m; is($rqurl,$expect_rqurl,"URL in request -> $expect_rqurl"); } else { die "unexpected response: ".$response->as_string } } # ------------------------------------------------------------------------ # simple web server with keep alive and SSL, which can also simulate proxy # ------------------------------------------------------------------------ sub _server { my $connid = 0; my %certs; # generated certificates ACCEPT: my ($server) = IO::Select->new(@server)->can_read(); my $cl = $server->accept or goto ACCEPT; # peek into socket to determine if this is direct SSL or not # minimal request is "GET / HTTP/1.1\n\n" my $buf = ''; while (length($buf)<15) { my $lbuf; if ( ! IO::Select->new($cl)->can_read(30) or ! defined recv($cl,$lbuf,20,MSG_PEEK)) { warn "not enough data for request ($buf): $!"; goto ACCEPT; } $buf .= $lbuf; } my $ssl_host = ''; if ( $buf !~m{\A[A-Z]{3,} } ) { # does not look like HTTP, assume direct SSL $ssl_host = "direct.ssl.access"; } $connid++; defined( my $pid = fork()) or die "failed to fork: $!"; if ( $pid ) { push @childs,$pid; goto ACCEPT; # wait for next connection } # child handles requests @server = (); my $reqid = 0; my $tunnel_auth = ''; SSL_UPGRADE: if ( $ssl_host ) { my ($cert,$key) = @{ $certs{$ssl_host} ||= do { diag("creating cert for $ssl_host"); my ($c,$k) = CERT_create( subject => { commonName => $ssl_host }, issuer_cert => $cacert, issuer_key => $cakey, # just reuse cakey as key for certificate key => $cakey, ); [ $c,$k ]; }; }; IO::Socket::SSL->start_SSL( $cl, SSL_server => 1, SSL_cert => $cert, SSL_key => $key, ) or do { diag("SSL handshake failed: ".IO::Socket::SSL->errstr); exit(1); }; } REQUEST: # read header my $req = ''; while (<$cl>) { $_ eq "\r\n" and last; $req .= $_; } $reqid++; my $req_auth = $req =~m{^Proxy-Authorization:}mi ? '.auth':''; if ( $req =~m{\ACONNECT ([^\s:]+)} ) { if ( $ssl_host ) { diag("CONNECT inside SSL tunnel"); exit(1); } $ssl_host = $1; $tunnel_auth = $req_auth ? '.Tauth':''; #diag($req); # simulate proxy and establish SSL tunnel print $cl "HTTP/1.0 200 ok\r\n\r\n"; goto SSL_UPGRADE; } if ( $req =~m{^Content-length: *(\d+)}mi ) { read($cl,my $buf,$1) or die "eof while reading request body"; } my $keep_alive = $req =~m{^(?:Proxy-)?Connection: *(?:(keep-alive)|close)}mi ? $1 : $req =~m{\A.*HTTP/1\.1} ? 1 : 0; # just echo request back, including connid and reqid my $body = "ID: $connid.$reqid$tunnel_auth$req_auth\@" . ( $ssl_host || 'nossl' )."\n" . "---------\n$req"; print $cl "HTTP/1.1 200 ok\r\nContent-type: text/plain\r\n" . "Connection: ".( $keep_alive ? 'keep-alive':'close' )."\r\n" . "Content-length: ".length($body)."\r\n" . "\r\n" . $body; goto REQUEST if $keep_alive; exit(0); # done handling requests } LWP-Protocol-https-6.06/t/apache.t0000644004041600001440000000127612324250406016450 0ustar mschilliusers#!perl -w use strict; use Test::More; use LWP::UserAgent; my $ua = LWP::UserAgent->new(); plan skip_all => "Not online" unless $ua->is_online; plan tests => 5; my $res = $ua->simple_request(HTTP::Request->new(GET => "https://www.apache.org")); ok($res->is_success); my $h = $res->header( 'X-Died' ); is($h, undef, "no X-Died header"); like($res->content, qr/Apache Software Foundation/); # test for RT #81948 my $warn = ''; $SIG{__WARN__} = sub { $warn = shift }; $ua = LWP::UserAgent->new( ssl_opts => {verify_hostname => 0} ); $res = $ua->simple_request(HTTP::Request->new(GET => "https://www.apache.org")); ok($res->is_success); is($warn, '', "no warning seen"); $res->dump(prefix => "# "); LWP-Protocol-https-6.06/README0000644004041600001440000000315012324251750015453 0ustar mschilliusers###################################################################### LWP::Protocol::https 6.06 ###################################################################### NAME LWP::Protocol::https - Provide https support for LWP::UserAgent SYNOPSIS use LWP::UserAgent; $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 }); $res = $ua->get("https://www.example.com"); DESCRIPTION The LWP::Protocol::https module provides support for using https schemed URLs with LWP. This module is a plug-in to the LWP protocol handling, so you don't use it directly. Once the module is installed LWP is able to access sites using HTTP over SSL/TLS. If hostname verification is requested by LWP::UserAgent's "ssl_opts", and neither "SSL_ca_file" nor "SSL_ca_path" is set, then "SSL_ca_file" is implied to be the one provided by Mozilla::CA. If the Mozilla::CA module isn't available SSL requests will fail. Either install this module, set up an alternative "SSL_ca_file" or disable hostname verification. This module used to be bundled with the libwww-perl, but it was unbundled in v6.02 in order to be able to declare its dependencies properly for the CPAN tool-chain. Applications that need https support can just declare their dependency on LWP::Protocol::https and will no longer need to know what underlying modules to install. SEE ALSO IO::Socket::SSL, Crypt::SSLeay, Mozilla::CA COPYRIGHT Copyright 1997-2011 Gisle Aas. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. LWP-Protocol-https-6.06/Makefile.PL0000644004041600001440000000230112324251132016534 0ustar mschilliusers#!perl -w require 5.008001; use strict; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'LWP::Protocol::https', VERSION_FROM => 'lib/LWP/Protocol/https.pm', ABSTRACT_FROM => 'lib/LWP/Protocol/https.pm', AUTHOR => 'Gisle Aas ', LICENSE => "perl", MIN_PERL_VERSION => 5.008001, PREREQ_PM => { 'LWP::UserAgent' => '6.06', 'Net::HTTPS' => 6, 'IO::Socket::SSL' => "1.54", 'Mozilla::CA' => "20110101", }, META_MERGE => { resources => { repository => 'http://github.com/libwww-perl/lwp-protocol-https', MailingList => 'mailto:libwww@perl.org', } }, ); BEGIN { # compatibility with older versions of MakeMaker my $developer = -f ".gitignore"; my %mm_req = ( LICENCE => 6.31, META_MERGE => 6.45, META_ADD => 6.45, MIN_PERL_VERSION => 6.48, ); undef(*WriteMakefile); *WriteMakefile = sub { my %arg = @_; for (keys %mm_req) { unless (eval { ExtUtils::MakeMaker->VERSION($mm_req{$_}) }) { warn "$_ $@" if $developer; delete $arg{$_}; } } ExtUtils::MakeMaker::WriteMakefile(%arg); }; } LWP-Protocol-https-6.06/MANIFEST0000644004041600001440000000041312324255067015730 0ustar mschilliusersChanges History of this package MANIFEST This file Makefile.PL Makefile generator README lib/LWP/Protocol/https.pm Access with HTTP/1.1 protocol over SSL t/apache.t t/https_proxy.t META.yml Module meta-data (added by MakeMaker) LWP-Protocol-https-6.06/Changes0000644004041600001440000000352312324252430016066 0ustar mschilliusers_______________________________________________________________________________ 2014-04-18 LWP-Protocol-https 6.06 Mike Schilli (3): Merge pull request #12 from drieux/subjectAltName Merge pull request #9 from chorny/master Updated libwww requirement to 6.06 to fix failing t/proxy.t test cases. Gisle Aas (2): Getopt::Long isn't actually used Merge pull request #7 from noxxi/master Alexandr Ciornii (1): better diagnostics in case of failures in apache.t Karen Etheridge (1): Merge pull request #8 from cpansprout/patch-1 Steffen Ullrich (1): correct behavior for https_proxy, this goes together with change to libwww-perl cb80c2ddb7, new method _upgrade_sock in LWP::Protocol::https cpansprout (1): Typo fix: envirionment =~ s/io/o/ drieux (1): support for subjectAltName _______________________________________________________________________________ 2013-04-29 LWP-Protocol-https 6.04 Fix IO::Socket::SSL warnings when not verifying hostname. Doc spelling fix. _______________________________________________________________________________ 2012-02-18 LWP-Protocol-https 6.03 Skip test if offline [RT#74163] Typo fixes Restore perl-5.8.1 compatibility. _______________________________________________________________________________ 2011-03-27 LWP-Protocol-https 6.02 Initial release of LWP-Protocol-https as a separate distribution. There are no code changes besides setting the version number since libwww-perl-6.01. The LWP::Protocol::https module used to be bundled with the libwww-perl distribution, but it was unbundled in v6.02 in order to be able to declare its dependencies properly for the CPAN tool chain. Applications that need https support can just declare their dependency on LWP::Protocol::https and will no longer need to know what underlying modules to install. LWP-Protocol-https-6.06/META.yml0000644004041600001440000000144312324255067016054 0ustar mschilliusers--- #YAML:1.0 name: LWP-Protocol-https version: 6.06 abstract: Provide https support for LWP::UserAgent author: - Gisle Aas license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: IO::Socket::SSL: 1.54 LWP::UserAgent: 6.06 Mozilla::CA: 20110101 Net::HTTPS: 6 perl: 5.008001 resources: MailingList: mailto:libwww@perl.org repository: http://github.com/libwww-perl/lwp-protocol-https no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.56 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4