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 0953b79..039abe0 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.90122 - 2018-11-03
   - releasing as stable
 
index 8289765..8b366c6 100644 (file)
@@ -50,6 +50,7 @@ my %META = (
         'Tree::Simple::Visitor::FindByUID' => 0,
         'Try::Tiny'             => '0.17',
         'Safe::Isa'             => 0,
+        'Socket'                => '1.96',
         'Task::Weaken'          => 0,
         'Text::Balanced'        => 0, # core in 5.8.x but mentioned for completeness
         'MRO::Compat'           => 0,
index 52314f3..e937fb1 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_NAMEREQD NIx_NOSERV );
 use Carp;
 use utf8;
 use URI::http;
@@ -439,7 +439,21 @@ 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},
+        NI_NAMEREQD,
+        # we are only interested in the hostname, not the servicename
+        NIx_NOSERV
+    );
+    return $err ? $self->address : $hostname;
   },
 );