+sub socks_args ($) {
+ my ($val) = @_;
+ return if ($val // '') eq '';
+ if ($val =~ 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
+ # for IO::Socket::Socks
+ return { ProxyAddr => $h, ProxyPort => $p };
+ }
+ die "$val not understood (only socks5h:// is supported)\n";
+}
+
+sub mic_new ($$$$) {
+ my ($self, $mic_arg, $sec, $uri) = @_;
+ my %mic_arg = (%$mic_arg, Keepalive => 1);
+ my $sa = $self->{cfg_opt}->{$sec}->{-proxy_cfg} || $self->{-proxy_cli};
+ if ($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};
+ 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);
+}
+