about summary refs log tree commit homepage
path: root/lib/PublicInbox/GitHTTPBackend.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/GitHTTPBackend.pm')
-rw-r--r--lib/PublicInbox/GitHTTPBackend.pm32
1 files changed, 14 insertions, 18 deletions
diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm
index 1eb51f27..396aa783 100644
--- a/lib/PublicInbox/GitHTTPBackend.pm
+++ b/lib/PublicInbox/GitHTTPBackend.pm
@@ -9,13 +9,14 @@ use v5.10.1;
 use Fcntl qw(:seek);
 use IO::Handle; # ->flush
 use HTTP::Date qw(time2str);
+use PublicInbox::Limiter;
 use PublicInbox::Qspawn;
 use PublicInbox::Tmpfile;
 use PublicInbox::WwwStatic qw(r @NO_CACHE);
 use Carp ();
 
 # 32 is same as the git-daemon connection limit
-my $default_limiter = PublicInbox::Qspawn::Limiter->new(32);
+my $default_limiter = PublicInbox::Limiter->new(32);
 
 # n.b. serving "description" and "cloneurl" should be innocuous enough to
 # not cause problems.  serving "config" might...
@@ -78,10 +79,10 @@ sub serve_dumb {
         PublicInbox::WwwStatic::response($env, $h, $path, $type);
 }
 
-sub git_parse_hdr { # {parse_hdr} for Qspawn
-        my ($r, $bref, $dumb_args) = @_;
+sub ghb_parse_hdr { # header parser for Qspawn
+        my ($r, $bref, @dumb_args) = @_;
         my $res = parse_cgi_headers($r, $bref) or return; # incomplete
-        $res->[0] == 403 ? serve_dumb(@$dumb_args) : $res;
+        $res->[0] == 403 ? serve_dumb(@dumb_args) : $res;
 }
 
 # returns undef if 403 so it falls back to dumb HTTP
@@ -104,8 +105,9 @@ sub serve_smart {
         $env{GIT_HTTP_EXPORT_ALL} = '1';
         $env{PATH_TRANSLATED} = "$git->{git_dir}/$path";
         my $rdr = input_prepare($env) or return r(500);
+        $rdr->{quiet} = 1;
         my $qsp = PublicInbox::Qspawn->new([qw(git http-backend)], \%env, $rdr);
-        $qsp->psgi_return($env, $limiter, \&git_parse_hdr, [$env, $git, $path]);
+        $qsp->psgi_yield($env, $limiter, \&ghb_parse_hdr, $env, $git, $path);
 }
 
 sub input_prepare {
@@ -128,7 +130,7 @@ sub input_prepare {
         { 0 => $in };
 }
 
-sub parse_cgi_headers {
+sub parse_cgi_headers { # {parse_hdr} for Qspawn
         my ($r, $bref, $ctx) = @_;
         return r(500) unless defined $r && $r >= 0;
         $$bref =~ s/\A(.*?)\r?\n\r?\n//s or return $r == 0 ? r(500) : undef;
@@ -144,20 +146,14 @@ sub parse_cgi_headers {
                 }
         }
 
-        # fallback to WwwCoderepo if cgit 404s.  Duplicating $ctx prevents
-        # ->finalize from the current Qspawn from using qspawn.wcb
+        # fallback to WwwCoderepo if cgit 404s
         if ($code == 404 && $ctx->{www} && !$ctx->{_coderepo_tried}++) {
-                my %ctx = %$ctx;
-                $ctx{env} = +{ %{$ctx->{env}} };
-                delete $ctx->{env}->{'qspawn.wcb'};
+                my $wcb = delete $ctx->{env}->{'qspawn.wcb'};
                 $ctx->{env}->{'plack.skip-deflater'} = 1; # prevent 2x gzip
-                my $res = $ctx->{www}->coderepo->srv(\%ctx);
-                if (ref($res) eq 'CODE') {
-                        $res->(delete $ctx{env}->{'qspawn.wcb'});
-                } else { # ref($res) eq 'ARRAY'
-                        $ctx->{env}->{'qspawn.wcb'} = $ctx{env}->{'qspawn.wcb'};
-                }
-                $res; # non ARRAY ref for ->psgi_return_init_cb
+                $ctx->{env}->{'qspawn.fallback'} = $code;
+                my $res = $ctx->{www}->coderepo->srv($ctx);
+                $ctx->{env}->{'qspawn.wcb'} = $wcb;
+                $res; # CODE or ARRAY ref
         } else {
                 [ $code, \@h ]
         }