]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Daemon.pm
daemon: use per-listener SIG{__WARN__} callbacks
[public-inbox.git] / lib / PublicInbox / Daemon.pm
index 67b26d2e8addee54a360073ecd07d2062790a320..bb140640c3219ec7f69b6cf9ab853039fc9fb893 100644 (file)
@@ -22,6 +22,7 @@ use PublicInbox::Sigfd;
 use PublicInbox::Git;
 use PublicInbox::GitAsyncCat;
 use PublicInbox::Eml;
+use PublicInbox::Config;
 our $SO_ACCEPTFILTER = 0x1000;
 my @CMD;
 my ($set_user, $oldset);
@@ -133,6 +134,8 @@ sub load_mod ($;$$) {
                $tlsd->{$f} = $logs{$p} //= open_log_path(my $fh, $p);
                warn "# $scheme://$addr $f=$p\n";
        }
+       my $err = $tlsd->{err};
+       $tlsd->{warn_cb} = sub { print $err @_ }; # for local $SIG{__WARN__}
        \%xn;
 }
 
@@ -191,20 +194,23 @@ EOF
 
        foreach my $l (@cfg_listen) {
                my $orig = $l;
-               my $scheme = '';
-               my $port;
-               if ($l =~ s!\A([^:]+)://!!) { $scheme = $1 }
+               my ($scheme, $port, $opt);
+
+               $l =~ s!\A([a-z0-9]+)://!! and $scheme = $1;
+               (!$scheme && ($default_listen // '') =~ m!\A([^:]+)://!) and
+                       $scheme = $1;
                if ($l =~ /\A(?:\[[^\]]+\]|[^:]+):([0-9]+)/) {
                        $port = $1 + 0;
-                       my $s = $KNOWN_TLS{$port} // $KNOWN_STARTTLS{$port};
-                       $scheme //= $s if defined $s;
-               } elsif (index($l, '/') != 0) { # unix socket
-                       $port //= $SCHEME2PORT{$scheme} if $scheme;
-                       $port // die "no port in listen=$l\n";
+                       $scheme //= $KNOWN_TLS{$port} // $KNOWN_STARTTLS{$port};
+               }
+               $scheme or die "unable to determine URL scheme of $orig\n";
+               if (!defined($port) && index($l, '/') != 0) { # unix socket
+                       $port = $SCHEME2PORT{$scheme} //
+                               die "no port in listen=$orig\n";
                        $l =~ s!\A([^/]+)!$1:$port! or
                                die "unable to add port=$port to $l\n";
                }
-               my $opt; # non-TLS options
+               $l =~ s!/\z!!; # chop one trailing slash
                if ($l =~ s!/?\?(.+)\z!!) {
                        $opt = listener_opt($1);
                        $tls_opt{"$scheme://$l"} = accept_tls_opt($opt);
@@ -213,10 +219,10 @@ EOF
                } elsif ($scheme =~ /\A(?:https|imaps|nntps|pop3s)\z/) {
                        die "$orig specified w/o cert=\n";
                }
-               $scheme =~ /\A(?:http|imap|nntp|pop3)/ and
+               if ($listener_names->{$l}) { # already inherited
                        $xnetd->{$l} = load_mod($scheme, $opt, $l);
-
-               next if $listener_names->{$l}; # already inherited
+                       next;
+               }
                my (%o, $sock_pkg);
                if (index($l, '/') == 0) {
                        $sock_pkg = 'IO::Socket::UNIX';
@@ -243,16 +249,16 @@ EOF
                }
                $o{Listen} = 1024;
                my $prev = umask 0000;
-               my $s = eval { $sock_pkg->new(%o) };
-               warn "error binding $l: $! ($@)\n" unless $s;
+               my $s = eval { $sock_pkg->new(%o) } or
+                       warn "error binding $l: $! ($@)\n";
                umask $prev;
-               if ($s) {
-                       $s->blocking(0);
-                       my $k = sockname($s);
-                       warn "# bound $scheme://$k\n";
-                       $listener_names->{$k} = $s;
-                       push @listeners, $s;
-               }
+               $s // next;
+               $s->blocking(0);
+               my $sockname = sockname($s);
+               warn "# bound $scheme://$sockname\n";
+               $xnetd->{$sockname} //= load_mod($scheme);
+               $listener_names->{$sockname} = $s;
+               push @listeners, $s;
        }
 
        # cert/key options in @cfg_listen takes precedence when inheriting,
@@ -261,10 +267,10 @@ EOF
        for my $sockname (@inherited_names) {
                $sockname =~ /:([0-9]+)\z/ or next;
                if (my $scheme = $KNOWN_TLS{$1}) {
-                       $xnetd->{$sockname} = load_mod($scheme);
+                       $xnetd->{$sockname} //= load_mod($scheme);
                        $tls_opt{"$scheme://$sockname"} ||= accept_tls_opt('');
                } elsif (($scheme = $KNOWN_STARTTLS{$1})) {
-                       $xnetd->{$sockname} = load_mod($scheme);
+                       $xnetd->{$sockname} //= load_mod($scheme);
                        $tls_opt{"$scheme://$sockname"} ||= accept_tls_opt('');
                        $tls_opt{''} ||= accept_tls_opt('');
                }
@@ -653,8 +659,10 @@ sub defer_accept ($$) {
 
 sub daemon_loop ($) {
        my ($xnetd) = @_;
+       local $PublicInbox::Config::DEDUPE = {}; # enable dedupe cache
        my $refresh = sub {
                my ($sig) = @_;
+               %$PublicInbox::Config::DEDUPE = (); # clear cache
                for my $xn (values %$xnetd) {
                        delete $xn->{tlsd}->{ssl_ctx}; # PublicInbox::TLS::start
                        eval { $xn->{refresh}->($sig) };