sub sockname ($) {
my ($s) = @_;
- my $n = getsockname($s) or return;
- my ($port, $addr);
- if (length($n) >= 28) {
+ my $addr = getsockname($s) or return;
+ my ($host, $port) = host_with_port($addr);
+ "$host:$port";
+}
+
+sub host_with_port ($) {
+ my ($addr) = @_;
+ my ($port, $host);
+ if (length($addr) >= 28) {
require Socket6;
- ($port, $addr) = Socket6::unpack_sockaddr_in6($n);
- } else {
- ($port, $addr) = Socket::sockaddr_in($n);
- }
- if (length($addr) == 4) {
- $n = Socket::inet_ntoa($addr)
+ ($port, $host) = Socket6::unpack_sockaddr_in6($addr);
+ $host = '['.Socket6::inet_ntop(Socket6::AF_INET6(), $host).']';
} else {
- $n = '['.Socket6::inet_ntop(Socket6::AF_INET6(), $addr).']';
+ ($port, $host) = Socket::sockaddr_in($addr);
+ $host = Socket::inet_ntoa($host);
}
- $n .= ":$port";
+ ($host, $port);
}
sub inherit () {
use strict;
use warnings;
use base qw(Danga::Socket);
-use fields qw(httpd env rbuf input_left);
+use fields qw(httpd env rbuf input_left remote_addr remote_port);
use Fcntl qw(:seek);
use HTTP::Parser::XS qw(parse_http_request); # supports pure Perl fallback
use HTTP::Status qw(status_message);
$self->SUPER::new($sock);
$self->{httpd} = $httpd;
$self->{rbuf} = '';
+ ($self->{remote_addr}, $self->{remote_port}) =
+ PublicInbox::Daemon::host_with_port($addr);
$self->watch_read(1);
$self;
}
my ($self) = @_;
$self->watch_read(0);
my $env = $self->{env};
- $env->{REMOTE_ADDR} = $self->peer_ip_string; # Danga::Socket
- $env->{REMOTE_PORT} = $self->{peer_port}; # set by peer_ip_string
+ $env->{REMOTE_ADDR} = $self->{remote_addr};
+ $env->{REMOTE_PORT} = $self->{remote_port};
if (my $host = $env->{HTTP_HOST}) {
$host =~ s/:(\d+)\z// and $env->{SERVER_PORT} = $1;
$env->{SERVER_NAME} = $host;
sub new {
my ($class, $sock, $app) = @_;
my $n = getsockname($sock) or die "not a socket: $sock $!\n";
- my ($port, $addr);
- if (length($n) >= 28) {
- require Socket6;
- ($port, $addr) = Socket6::unpack_sockaddr_in6($n);
- } else {
- ($port, $addr) = Socket::unpack_sockaddr_in($n);
- }
+ my ($host, $port) = PublicInbox::Daemon::host_with_port($n);
my %env = (
- REMOTE_HOST => '',
- REMOTE_PORT => 0,
- SERVER_NAME => $addr,
+ SERVER_NAME => $host,
SERVER_PORT => $port,
SCRIPT_NAME => '',
'psgi.version' => [ 1, 1 ],
$fh->close;
};
}
+ } elsif ($path eq '/host-port') {
+ $code = 200;
+ push @$body, "$env->{REMOTE_ADDR}:$env->{REMOTE_PORT}";
}
[ $code, $h, $body ]
return $conn;
}
+{
+ my $conn = conn_for($sock, 'host-port');
+ $conn->write("GET /host-port HTTP/1.0\r\n\r\n");
+ $conn->read(my $buf, 4096);
+ my ($head, $body) = split(/\r\n\r\n/, $buf);
+ my ($addr, $port) = split(/:/, $body);
+ is($addr, $conn->sockhost, 'host matches addr');
+ is($port, $conn->sockport, 'port matches');
+}
+
# graceful termination
{
my $conn = conn_for($sock, 'graceful termination via slow header');