# Copyright (C) all contributors # License: AGPL-3.0+ # wrap Net::NNTP client with SOCKS support. Convoluted, but AFAIK this # is the only way to get SOCKS working with Net::NNTP w/o LD_PRELOAD. package PublicInbox::NetNNTPSocks; use v5.12; use Net::NNTP; our %OPT; # used to pass options between ->new_socks and our ->new our @ISA = qw(IO::Socket::Socks); # use this instead of Net::NNTP->new if using Proxy* sub new_socks { my (undef, %opt) = @_; require IO::Socket::Socks; local @Net::NNTP::ISA = (qw(Net::Cmd), __PACKAGE__); local %OPT = map {; defined($opt{$_}) ? ($_ => $opt{$_}) : () } qw(ProxyAddr ProxyPort SocksVersion SocksDebug SocksResolve); no warnings 'uninitialized'; # needed for $SOCKS_ERROR my $ret = Net::NNTP->new(%opt); # calls PublicInbox::NetNNTPSocks::new return $ret if $ret || $!{EINTR}; $ret // die "errors: \$!=$! SOCKS=", eval('$IO::Socket::Socks::SOCKS_ERROR // ""'), ', SSL=', (eval('IO::Socket::SSL->errstr') // ''), "\n"; } # called by Net::NNTP->new sub new { my ($self, %opt) = @_; @OPT{qw(ConnectAddr ConnectPort)} = @opt{qw(PeerAddr PeerPort)}; $self->SUPER::new(%OPT); } 1;