about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-04-28 01:56:07 +0000
committerEric Wong <e@80x24.org>2016-04-28 02:00:53 +0000
commit6e88eec854e125520b67735df6e4b0de52201383 (patch)
treec3e65635a68b5936f10fef5a692a99ae99d2a62f
parente983376326eab20daac9c2bfbb65b88c4fd248a2 (diff)
downloadpublic-inbox-6e88eec854e125520b67735df6e4b0de52201383.tar.gz
Using http.getanyfile still keeps the http-backend process
alive, so it's better to break out of that process and
handle serving entirely within the HTTP server.
-rw-r--r--lib/PublicInbox/GitHTTPBackend.pm40
-rw-r--r--t/httpd.t9
2 files changed, 34 insertions, 15 deletions
diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm
index 2c81d4c8..c44c67d5 100644
--- a/lib/PublicInbox/GitHTTPBackend.pm
+++ b/lib/PublicInbox/GitHTTPBackend.pm
@@ -37,6 +37,12 @@ sub serve {
                 return $ok if $ok;
         }
 
+        serve_dumb($cgi, $git, $path);
+}
+
+sub serve_dumb {
+        my ($cgi, $git, $path) = @_;
+
         my $type;
         if ($path =~ /\A(?:$BIN)\z/o) {
                 $type = 'application/octet-stream';
@@ -141,11 +147,11 @@ sub serve_smart {
         }
         my ($rpipe, $wpipe);
         unless (pipe($rpipe, $wpipe)) {
-                $err->print("error creating pipe: $!\n");
-                return r(500);
+                $err->print("error creating pipe: $! - going static\n");
+                return;
         }
         my %env = %ENV;
-        # GIT_HTTP_EXPORT_ALL, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL
+        # GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL
         # may be set in the server-process and are passed as-is
         foreach my $name (qw(QUERY_STRING
                                 REMOTE_USER REMOTE_ADDR
@@ -162,8 +168,8 @@ sub serve_smart {
         my %rdr = ( 0 => fileno($in), 1 => fileno($wpipe) );
         my $pid = spawn([qw(git http-backend)], \%env, \%rdr);
         unless (defined $pid) {
-                $err->print("error spawning: $!\n");
-                return r(500);
+                $err->print("error spawning: $! - going static\n");
+                return;
         }
         $wpipe = $in = undef;
         $buf = '';
@@ -172,19 +178,19 @@ sub serve_smart {
                 if ($fh) {
                         $fh->close;
                         $fh = undef;
-                } else {
-                        $res->(r(500)) if $res;
                 }
                 if ($rpipe) {
                         $rpipe->close; # _may_ be Danga::Socket::close
                         $rpipe = undef;
                 }
-                if (defined $pid) {
-                        my $wpid = $pid;
-                        $pid = undef;
-                        return if $wpid == waitpid($wpid, 0);
+                if (defined $pid && $pid != waitpid($pid, 0)) {
                         $err->print("git http-backend ($git_dir): $?\n");
+                } else {
+                        $pid = undef;
                 }
+                return unless $res;
+                my $dumb = serve_dumb($cgi, $git, $path);
+                ref($dumb) eq 'ARRAY' ? $res->($dumb) : $dumb->($res);
         };
         my $fail = sub {
                 my ($e) = @_;
@@ -215,10 +221,14 @@ sub serve_smart {
                                         push @h, $k, $v;
                                 }
                         }
-                        # write response header:
-                        $fh = $res->([ $code, \@h ]);
-                        $res = undef;
-                        $fh->write($buf);
+                        if ($code == 403) {
+                                # smart cloning disabled, serve dumbly
+                                # in $end since we never undef $res in here
+                        } else { # write response header:
+                                $fh = $res->([ $code, \@h ]);
+                                $res = undef;
+                                $fh->write($buf);
+                        }
                         $buf = '';
                 } # else { keep reading ... }
         };
diff --git a/t/httpd.t b/t/httpd.t
index 28f507db..03790311 100644
--- a/t/httpd.t
+++ b/t/httpd.t
@@ -105,6 +105,15 @@ EOF
         is(system(qw(git clone -q --mirror),
                         "http://$host:$port/$group", "$tmpdir/clone.git"),
                 0, 'clone successful');
+
+        # ensure dumb cloning works, too:
+        is(system('git', "--git-dir=$maindir",
+                qw(config http.uploadpack false)),
+                0, 'disable http.uploadpack');
+        is(system(qw(git clone -q --mirror),
+                        "http://$host:$port/$group", "$tmpdir/dumb.git"),
+                0, 'clone successful');
+
         ok(kill('TERM', $pid), 'killed httpd');
         $pid = undef;
         waitpid(-1, 0);