user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 1/2] githttpbackend: fall back to dumb if smart HTTP is off
Date: Thu, 28 Apr 2016 01:56:07 +0000	[thread overview]
Message-ID: <20160428015608.23091-2-e@80x24.org> (raw)
In-Reply-To: <20160428015608.23091-1-e@80x24.org>

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.
---
 lib/PublicInbox/GitHTTPBackend.pm | 40 ++++++++++++++++++++++++---------------
 t/httpd.t                         |  9 +++++++++
 2 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm
index 2c81d4c..c44c67d 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 28f507d..0379031 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);
-- 
EW


  reply	other threads:[~2016-04-28  1:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-28  1:56 [PATCH 0/2] githttpbackend: dumb HTTP fallbacks Eric Wong
2016-04-28  1:56 ` Eric Wong [this message]
2016-04-28  1:56 ` [PATCH 2/2] githttpbackend: clamp to one smart HTTP request at-a-time Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160428015608.23091-2-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).