fix $c->req->hostname empty for IPv6 clients (RT#75731)
Alexander Hartmaier [Mon, 18 Jan 2016 12:57:10 +0000 (13:57 +0100)]
use Socket directly instead of IO::Socket
Socket version 1.96 was chosen because of the NIx_NOSERV flag

Changes
Makefile.PL
lib/Catalyst/Request.pm

diff --git a/Changes b/Changes
index 8014ea8..4245398 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,7 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+  - Fix $c->req->hostname empty for IPv6 clients (RT#75731)
+
 5.90114 - 2016-12-19
   - Fixed regression introduced in the last version (5.90113) which caused 
     application to hang when the action private name contained a string
index 68dd556..493cab9 100644 (file)
@@ -50,6 +50,7 @@ requires 'HTTP::Request::AsCGI' => '1.0';
 requires 'Module::Pluggable' => '4.7';
 requires 'Path::Class' => '0.09';
 requires 'Scalar::Util';
+requires 'Socket' => '1.96';
 requires 'Sub::Exporter';
 requires 'Text::SimpleTable' => '0.03';
 requires 'Time::HiRes';
index 1306b94..19e7331 100644 (file)
@@ -1,6 +1,6 @@
 package Catalyst::Request;
 
-use IO::Socket qw[AF_INET inet_aton];
+use Socket qw( getaddrinfo getnameinfo AI_NUMERICHOST NI_DGRAM NIx_NOSERV );
 use Carp;
 use utf8;
 use URI::http;
@@ -436,7 +436,20 @@ has hostname => (
   lazy      => 1,
   default   => sub {
     my ($self) = @_;
-    gethostbyaddr( inet_aton( $self->address ), AF_INET ) || $self->address
+    my ( $err, $sockaddr ) = getaddrinfo(
+        $self->address,
+        # no service
+        '',
+        { flags => AI_NUMERICHOST }
+    );
+    return $self->address
+        if $err;
+    ( $err, my $hostname ) = getnameinfo(
+        $sockaddr->{addr},
+        # we are only interested in the hostname, not the servicename
+        NI_DGRAM|NIx_NOSERV
+    );
+    return $err ? $self->address : $hostname;
   },
 );