From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS43350 77.247.176.0/21 X-Spam-Status: No, score=-1.5 required=3.0 tests=AWL,BAYES_00,RCVD_IN_XBL, SPF_FAIL,SPF_HELO_FAIL shortcircuit=no autolearn=no version=3.3.2 X-Original-To: meta@public-inbox.org Received: from 80x24.org (politkovskaja.torservers.net [77.247.181.165]) by dcvr.yhbt.net (Postfix) with ESMTP id 60D3020A47 for ; Thu, 28 Apr 2016 01:56:16 +0000 (UTC) From: Eric Wong 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 Message-Id: <20160428015608.23091-2-e@80x24.org> In-Reply-To: <20160428015608.23091-1-e@80x24.org> References: <20160428015608.23091-1-e@80x24.org> List-Id: 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