]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Qspawn.pm
www: make coderepo URL generation more consistent
[public-inbox.git] / lib / PublicInbox / Qspawn.pm
index 9ca6b3dbbcc98c6a761e34fe4cc7e94f4a94ccd4..ab0ef25c5611f3e645a4f4e593ae143ee94291a6 100644 (file)
@@ -40,7 +40,7 @@ my $def_limiter;
 # $cmd_env is the environ for the child process (not PSGI env)
 # $opt can include redirects and perhaps other process spawning options
 # {qsp_err} is an optional error buffer callers may access themselves
-sub new ($$$;) {
+sub new {
        my ($class, $cmd, $cmd_env, $opt) = @_;
        bless { args => [ $cmd, $cmd_env, $opt ] }, $class;
 }
@@ -106,6 +106,7 @@ sub finalize ($$) {
                return unless $@;
                warn "E: $@"; # hope qspawn.wcb can handle it
        }
+       return if $self->{passed}; # another command chained it
        if (my $wcb = delete $env->{'qspawn.wcb'}) {
                # have we started writing, yet?
                require PublicInbox::WwwStatic;
@@ -225,7 +226,12 @@ sub psgi_return_init_cb {
        my ($self) = @_;
        my $r = rd_hdr($self) or return;
        my $env = $self->{psgi_env};
-       my $filter = delete($env->{'qspawn.filter'}) // (ref($r) eq 'ARRAY' ?
+       my $filter;
+       if (ref($r) eq 'ARRAY' && Scalar::Util::blessed($r->[2]) &&
+                       $r->[2]->can('attach')) {
+               $filter = pop @$r;
+       }
+       $filter //= delete($env->{'qspawn.filter'}) // (ref($r) eq 'ARRAY' ?
                PublicInbox::GzipFilter::qsp_maybe($r->[1], $env) : undef);
 
        my $wcb = delete $env->{'qspawn.wcb'};
@@ -233,14 +239,16 @@ sub psgi_return_init_cb {
        if (ref($r) ne 'ARRAY' || scalar(@$r) == 3) { # error
                if ($async) { # calls rpipe->close && ->event_step
                        $async->close; # PublicInbox::HTTPD::Async::close
-               } else {
-                       $self->{rpipe}->close;
+               } else { # generic PSGI:
+                       delete($self->{rpipe})->close;
                        event_step($self);
+                       waitpid_err($self);
                }
                if (ref($r) eq 'ARRAY') { # error
                        $wcb->($r)
                } elsif (ref($r) eq 'CODE') { # chain another command
-                       $r->($wcb)
+                       $r->($wcb);
+                       $self->{passed} = 1;
                }
                # else do nothing
        } elsif ($async) {