]> Sergey Matveev's repositories - public-inbox.git/commitdiff
httpd/async: retry reads properly when parsing headers
authorEric Wong <e@80x24.org>
Fri, 6 Jan 2023 10:10:51 +0000 (10:10 +0000)
committerEric Wong <e@80x24.org>
Fri, 6 Jan 2023 10:24:15 +0000 (10:24 +0000)
While git-http-backend sends headers with one write syscall,
upstream cgit still trickles them out line-by-line and we need to
account for that and retry Qspawn {parse_hdr} callbacks.

lib/PublicInbox/HTTPD/Async.pm
lib/PublicInbox/Qspawn.pm

index e03daafac8d1a7994042fa52e94e4eac60f7ac4c..7bbab1e1cd65c22d2a895f5a99b5924fa172afd5 100644 (file)
@@ -14,7 +14,7 @@
 # arg: arg for {cb}
 # end_obj: CODE or object which responds to ->event_step when ->close is called
 package PublicInbox::HTTPD::Async;
-use strict;
+use v5.12;
 use parent qw(PublicInbox::DS);
 use Errno qw(EAGAIN);
 use PublicInbox::Syscall qw(EPOLLIN);
@@ -44,9 +44,9 @@ sub new {
 
 sub event_step {
        my ($self) = @_;
-       if (my $cb = delete $self->{cb}) {
+       if (defined $self->{cb}) {
                # this may call async_pass when headers are done
-               $cb->(my $refcnt_guard = delete $self->{arg});
+               $self->{cb}->($self->{arg});
        } elsif (my $sock = $self->{sock}) {
                # $http may be undef if discarding body output from cgit on 404
                my $http = $self->{http} or return $self->close;
@@ -76,6 +76,7 @@ sub event_step {
 # may be PublicInbox::GzipFilter or $PublicInbox::Qspawn::qx_fh
 sub async_pass {
        my ($self, $http, $ofh, $bref) = @_;
+       delete @$self{qw(cb arg)};
        # In case the client HTTP connection ($http) dies, it
        # will automatically close this ($self) object.
        $http->{forward} = $self;
@@ -94,6 +95,7 @@ sub async_pass {
 sub close {
        my $self = $_[0];
        $self->SUPER::close; # DS::close
+       delete @$self{qw(cb arg)};
 
        # we defer this to the next timer loop since close is deferred
        if (my $end_obj = delete $self->{end_obj}) {
index f8cbffcb359b74629a888119bcbba4237335d0ad..7984e35a80510ffdf09cbb7f5e325ecd9eb764a0 100644 (file)
@@ -134,7 +134,7 @@ sub start ($$$) {
        }
 }
 
-sub psgi_qx_init_cb {
+sub psgi_qx_init_cb { # this may be PublicInbox::HTTPD::Async {cb}
        my ($self) = @_;
        my $async = delete $self->{async}; # PublicInbox::HTTPD::Async
        my ($r, $buf);
@@ -223,7 +223,7 @@ sub rd_hdr ($) {
        $ret;
 }
 
-sub psgi_return_init_cb {
+sub psgi_return_init_cb { # this may be PublicInbox::HTTPD::Async {cb}
        my ($self) = @_;
        my $r = rd_hdr($self) or return;
        my $env = $self->{psgi_env};