X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FNetReader.pm;h=236e824cd26d48ec2326b97455b139d0b5841a65;hb=67fe4d8d90ac77419c8fc41457c849aa7d366a9d;hp=f0f56431282312c37840809be755cac0007ba51e;hpb=9d11ed460ce113dd10cd098e2dfa814fcfbddde9;p=public-inbox.git diff --git a/lib/PublicInbox/NetReader.pm b/lib/PublicInbox/NetReader.pm index f0f56431..236e824c 100644 --- a/lib/PublicInbox/NetReader.pm +++ b/lib/PublicInbox/NetReader.pm @@ -35,6 +35,7 @@ sub socks_args ($) { eval { require IO::Socket::Socks } or die < $h, ProxyPort => $p }; } die "$val not understood (only socks5h:// is supported)\n"; @@ -42,20 +43,54 @@ EOM sub mic_new ($$$$) { my ($self, $mic_arg, $sec, $uri) = @_; - my %mic_arg = %$mic_arg; + my %mic_arg = (%$mic_arg, Keepalive => 1); my $sa = $self->{cfg_opt}->{$sec}->{-proxy_cfg} || $self->{-proxy_cli}; if ($sa) { - my %opt = %$sa; + # this `require' needed for worker[1..Inf], since socks_args + # only got called in worker[0] + require IO::Socket::Socks; + my %opt = (%$sa, Keepalive => 1); + $opt{SocksDebug} = 1 if $mic_arg{Debug}; $opt{ConnectAddr} = delete $mic_arg{Server}; $opt{ConnectPort} = delete $mic_arg{Port}; - $mic_arg{Socket} = IO::Socket::Socks->new(%opt) or die - "E: <$$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR'); + my $s = IO::Socket::Socks->new(%opt) or die + "E: <$uri> ".eval('$IO::Socket::Socks::SOCKS_ERROR'); + if ($mic_arg->{Ssl}) { # for imaps:// + require IO::Socket::SSL; + $s = IO::Socket::SSL->start_SSL($s) or die + "E: <$uri> ".(IO::Socket::SSL->errstr // ''); + } + $mic_arg{Socket} = $s; } - PublicInbox::IMAPClient->new(%mic_arg, Keepalive => 1); + PublicInbox::IMAPClient->new(%mic_arg); } sub auth_anon_cb { '' }; # for Mail::IMAPClient::Authcallback +sub onion_hint ($$) { + my ($lei, $uri) = @_; + $uri->host =~ /\.onion\z/i or return "\n"; + my $t = $uri->isa('PublicInbox::URIimap') ? 'imap' : 'nntp'; + my $url = PublicInbox::Config::squote_maybe(uri_section($uri)); + my $set_cfg = 'lei config'; + if (!$lei) { # public-inbox-watch + my $f = PublicInbox::Config::squote_maybe( + $ENV{PI_CONFIG} || '~/.public-inbox/config'); + $set_cfg = "git config -f $f"; + } + my $dq = substr($url, 0, 1) eq "'" ? '"' : ''; + < $uri->port, Server => $host, - Ssl => $uri->scheme eq 'imaps', %$common, # may set Starttls, Compress, Debug .... }; $mic_arg->{Ssl} = 1 if $uri->scheme eq 'imaps'; require PublicInbox::IMAPClient; - my $mic = mic_new($self, $mic_arg, $sec, $uri) or - die "E: <$uri> new: $@\n"; + my $mic = mic_new($self, $mic_arg, $sec, $uri); + ($mic && $mic->IsConnected) or + die "E: <$uri> new: $@".onion_hint($lei, $uri); + # default to using STARTTLS if it's available, but allow # it to be disabled since I usually connect to localhost if (!$mic_arg->{Ssl} && !defined($mic_arg->{Starttls}) && @@ -142,11 +178,13 @@ sub nn_new ($$$) { my $nn; if (defined $nn_arg->{ProxyAddr}) { require PublicInbox::NetNNTPSocks; + $nn_arg->{SocksDebug} = 1 if $nn_arg->{Debug}; 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"; + $nn = Net::NNTP->new(%$nn_arg) or return; } + setsockopt($nn, Socket::SOL_SOCKET(), Socket::SO_KEEPALIVE(), 1); # default to using STARTTLS if it's available, but allow # it to be disabled for localhost/VPN users @@ -202,7 +240,8 @@ sub nn_for ($$$$) { # nn = Net::NNTP $nn_arg->{SSL} = 1 if $uri->secure; # snews == nntps my $sa = $self->{-proxy_cli}; %$nn_arg = (%$nn_arg, %$sa) if $sa; - my $nn = nn_new($nn_arg, $nntp_cfg, $uri); + my $nn = nn_new($nn_arg, $nntp_cfg, $uri) or + die "E: <$uri> new: $@".onion_hint($lei, $uri); if ($cred) { $cred->fill($lei) unless defined($p); # may prompt user here if ($nn->authinfo($u, $p)) { @@ -686,21 +725,24 @@ sub _nntp_fetch_all ($$$) { my $msg = ndump($nn->message); return "E: GROUP $group <$sec> $msg"; } + (defined($num_a) && defined($num_b) && $num_a > $num_b) and + return "E: $uri: backwards range: $num_a > $num_b"; # IMAPTracker is also used for tracking NNTP, UID == article number # LIST.ACTIVE can get the equivalent of UIDVALIDITY, but that's # expensive. So we assume newsgroups don't change: my ($itrk, $l_art) = itrk_last($self, $uri); - # allow users to specify articles to refetch - # cf. https://tools.ietf.org/id/draft-gilman-news-url-01.txt - # nntp://example.com/inbox.foo/$num_a-$num_b - $beg = $num_a if defined($num_a) && $num_a < $beg; - $end = $num_b if defined($num_b) && $num_b < $end; - if (defined $l_art) { + if (defined($l_art) && !defined($num_a)) { return if $l_art >= $end; # nothing to do $beg = $l_art + 1; } + # allow users to specify articles to refetch + # cf. https://tools.ietf.org/id/draft-gilman-news-url-01.txt + # nntp://example.com/inbox.foo/$num_a-$num_b + $beg = $num_a if defined($num_a) && $num_a > $beg && $num_a <= $end; + $end = $num_b if defined($num_b) && $num_b >= $beg && $num_b < $end; + $end = $beg if defined($num_a) && !defined($num_b); my ($err, $art, $last_art, $kw); # kw stays undef, no keywords in NNTP unless ($self->{quiet}) { warn "# $uri fetching ARTICLE $beg..$end\n";