use v5.10.1;
use parent qw(Exporter PublicInbox::IPC);
use PublicInbox::Eml;
+use PublicInbox::Config;
our %IMAPflags2kw = map {; "\\\u$_" => $_ } qw(seen answered flagged draft);
$IMAPflags2kw{'$Forwarded'} = 'forwarded'; # RFC 5550
sub auth_anon_cb { '' }; # for Mail::IMAPClient::Authcallback
# mic_for may prompt the user and store auth info, prepares mic_get
-sub mic_for { # mic = Mail::IMAPClient
+sub mic_for ($$$$) { # mic = Mail::IMAPClient
my ($self, $url, $mic_args, $lei) = @_;
require PublicInbox::URIimap;
my $uri = PublicInbox::URIimap->new($url);
%$common, # may set Starttls, Compress, Debug ....
};
require PublicInbox::IMAPClient;
- my $mic = PublicInbox::IMAPClient->new(%$mic_arg) or
+ my %socks;
+ if ($lei && $lei->{socks5h}) {
+ my %opt = %{$lei->{socks5h}};
+ $opt{ConnectAddr} = delete $mic_arg->{Server};
+ $opt{ConnectPort} = delete $mic_arg->{Port};
+ $socks{Socket} = IO::Socket::Socks->new(%opt) or die
+ "E: <$url> ".eval('$IO::Socket::Socks::SOCKS_ERROR');
+ $self->{mic_socks5h} = \%opt;
+ }
+ my $mic = PublicInbox::IMAPClient->new(%$mic_arg, %socks) or
die "E: <$url> new: $@\n";
# default to using STARTTLS if it's available, but allow
sub nn_new ($$$) {
my ($nn_arg, $nntp_opt, $uri) = @_;
- my $nn = Net::NNTP->new(%$nn_arg) or die "E: <$uri> new: $!\n";
+ my $nn;
+ if (defined $nn_arg->{ProxyAddr}) {
+ eval { $nn = PublicInbox::NetNNTPSocks->new_socks(%$nn_arg) };
+ die "E: <$uri> $@\n" if $@;
+ } else {
+ $nn = Net::NNTP->new(%$nn_arg) or die "E: <$uri> new: $!\n";
+ }
# default to using STARTTLS if it's available, but allow
# it to be disabled for localhost/VPN users
$nn;
}
-sub nn_for ($$$;$) { # nn = Net::NNTP
+sub nn_for ($$$$) { # nn = Net::NNTP
my ($self, $uri, $nn_args, $lei) = @_;
my $sec = uri_section($uri);
my $nntp_opt = $self->{nntp_opt}->{$sec} //= {};
SSL => $uri->secure, # snews == nntps
%$common, # may Debug ....
};
+ if ($lei && $lei->{socks5h}) {
+ require PublicInbox::NetNNTPSocks;
+ %$nn_arg = (%$nn_arg, %{$lei->{socks5h}});
+ }
my $nn = nn_new($nn_arg, $nntp_opt, $uri);
if ($cred) {
$cred->fill($lei); # may prompt user here
}
sub errors {
- my ($self) = @_;
+ my ($self, $lei) = @_;
if (my $u = $self->{unsupported_url}) {
return "Unsupported URL(s): @$u";
}
eval { require Net::NNTP } or
die "Net::NNTP is required for NNTP:\n$@\n";
}
+ if ($lei && (($lei->{opt}->{proxy}//'') =~ m!\Asocks5h://
+ (?: \[ ([^\]]+) \] | ([^:/]+) )
+ (?::([0-9]+))?/?(?:,|\z)!ix)) {
+ my ($h, $p) = ($1 // $2, $3 + 0);
+ $h = '127.0.0.1' if $h eq '0';
+ eval { require IO::Socket::Socks } or die <<EOM;
+IO::Socket::Socks missing for socks5h://$h:$p
+EOM
+ $lei->{socks5h} = { ProxyAddr => $h, ProxyPort => $p };
+ }
undef;
}
$mic_arg->{Authcallback} = $self->can($cb_name);
}
}
- my $mic = PublicInbox::IMAPClient->new(%$mic_arg);
+ my %socks;
+ if (my $s5h = $self->{mic_socks5h}) {
+ $socks{Socket} = IO::Socket::Socks->new(%$s5h) or die
+ "E: <$$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR');
+ }
+ my $mic = PublicInbox::IMAPClient->new(%$mic_arg, %socks);
$cached //= {}; # invalid placeholder if no cache enabled
$mic && $mic->IsConnected ? ($cached->{$sec} = $mic) : undef;
}