File add-ipv6-support.patch of Package perl-Net-HTTP
From 8109c5e85bc7178b1244b12c1033eecff1203df8 Mon Sep 17 00:00:00 2001
From: Jason A Fesler <jfesler@badamount-lm.corp.yahoo.com>
Date: Tue, 22 Jul 2014 14:19:11 -0700
Subject: [PATCH] Adds IPv6 support [RT#75618]
---
Changes | 5 +++++
Makefile.PL | 1 +
lib/Net/HTTP.pm | 25 +++++++++++++++++++------
lib/Net/HTTP/Methods.pm | 39 +++++++++++++++++++++++++--------------
4 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/Changes b/Changes
index 5a2a0e6..da0549a 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,8 @@
+
+Jason Fesler:
+ Opportunistically use IO::Socket::IP or IO::Socket::INET6.
+ Properly parse IPv6 literal addreses with optional port numbers. [RT#75618]
+
_______________________________________________________________________________
2013-03-10 Net-HTTP 6.06
diff --git a/Makefile.PL b/Makefile.PL
index d7c7437..bb064c3 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -26,6 +26,7 @@ WriteMakefile(
'IO::Select' => 0,
'Compress::Raw::Zlib' => 0,
'IO::Compress::Gzip' => 0,
+ 'URI' => 0,
},
META_MERGE => {
recommends => {
diff --git a/lib/Net/HTTP.pm b/lib/Net/HTTP.pm
index 919e591..016163b 100644
--- a/lib/Net/HTTP.pm
+++ b/lib/Net/HTTP.pm
@@ -5,8 +5,17 @@ use vars qw($VERSION @ISA $SOCKET_CLASS);
$VERSION = "6.06";
unless ($SOCKET_CLASS) {
- eval { require IO::Socket::INET } || require IO::Socket;
- $SOCKET_CLASS = "IO::Socket::INET";
+ # Try several, in order of capability and preference
+ if (eval { require IO::Socket::IP }) {
+ $SOCKET_CLASS = "IO::Socket::IP"; # IPv4+IPv6
+ } elsif (eval { require IO::Socket::INET6 }) {
+ $SOCKET_CLASS = "IO::Socket::INET6"; # IPv4+IPv6
+ } elsif (eval { require IO::Socket::INET }) {
+ $SOCKET_CLASS = "IO::Socket::INET"; # IPv4 only
+ } else {
+ require IO::Socket;
+ $SOCKET_CLASS = "IO::Socket::INET";
+ }
}
require Net::HTTP::Methods;
require Carp;
@@ -59,10 +68,11 @@ C<Net::HTTP> class represents a connection to an HTTP server. The
HTTP protocol is described in RFC 2616. The C<Net::HTTP> class
supports C<HTTP/1.0> and C<HTTP/1.1>.
-C<Net::HTTP> is a sub-class of C<IO::Socket::INET>. You can mix the
-methods described below with reading and writing from the socket
-directly. This is not necessary a good idea, unless you know what you
-are doing.
+C<Net::HTTP> is a sub-class of one of C<IO::Socket::IP> (IPv6+IPv4),
+C<IO::Socket::INET6> (IPv6+IPv4), or C<IO::Socket::INET> (IPv4 only).
+You can mix the methods described below with reading and writing from the
+socket directly. This is not necessary a good idea, unless you know what
+you are doing.
The following methods are provided (in addition to those of
C<IO::Socket::INET>):
@@ -84,6 +94,9 @@ C<IO::Socket::INET>'s as well as these:
The C<Host> option is also the default for C<IO::Socket::INET>'s
C<PeerAddr>. The C<PeerPort> defaults to 80 if not provided.
+The C<PeerPort> specification can also be embedded in the C<PeerAddr>
+by preceding it with a ":", and closing the IPv6 address on bracktes "[]" if
+necessary: "192.0.2.1:80","[2001:db8::1]:80","any.example.com:80".
The C<Listen> option provided by C<IO::Socket::INET>'s constructor
method is not allowed.
diff --git a/lib/Net/HTTP/Methods.pm b/lib/Net/HTTP/Methods.pm
index 98b58c5..649f3cc 100644
--- a/lib/Net/HTTP/Methods.pm
+++ b/lib/Net/HTTP/Methods.pm
@@ -4,6 +4,7 @@ require 5.005; # 4-arg substr
use strict;
use vars qw($VERSION);
+use URI;
$VERSION = "6.06";
@@ -44,20 +45,30 @@ sub http_configure {
$cnf->{PeerAddr} = $peer = $host;
}
- if ($peer =~ s,:(\d+)$,,) {
- $cnf->{PeerPort} = int($1); # always override
- }
- if (!$cnf->{PeerPort}) {
- $cnf->{PeerPort} = $self->http_default_port;
- }
-
- if (!$explict_host) {
- $host = $peer;
- $host =~ s/:.*//;
- }
- if ($host && $host !~ /:/) {
- my $p = $cnf->{PeerPort};
- $host .= ":$p" if $p != $self->http_default_port;
+ # CONNECTIONS
+ # PREFER: port number from PeerAddr, then PeerPort, then http_default_port
+ my $peer_uri = URI->new("http://$peer");
+ $cnf->{"PeerPort"} = $peer_uri->_port || $cnf->{PeerPort} || $self->http_default_port;
+ $cnf->{"PeerAddr"} = $peer_uri->host;
+
+ # HOST header:
+ # If specified but blank, ignore.
+ # If specified with a value, add the port number
+ # If not specified, set to PeerAddr and port number
+ # ALWAYS: If IPv6 address, use [brackets] (thanks to the URI package)
+ # ALWAYS: omit port number if http_default_port
+ if (($host) || (! $explict_host)) {
+ my $uri = ($explict_host) ? URI->new("http://$host") : $peer_uri->clone;
+ if (!$uri->_port) {
+ # Always use *our* $self->http_default_port instead of URI's (Covers HTTP, HTTPS)
+ $uri->port( $cnf->{PeerPort} || $self->http_default_port);
+ }
+ my $host_port = $uri->host_port; # Returns host:port or [ipv6]:port
+ my $remove = ":" . $self->http_default_port; # we want to remove the default port number
+ if (substr($host_port,0-length($remove)) eq $remove) {
+ substr($host_port,0-length($remove)) = "";
+ }
+ $host = $host_port;
}
$cnf->{Proto} = 'tcp';