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: X-Spam-Status: No, score=-2.8 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: meta@public-inbox.org Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id D129F63381A for ; Thu, 25 Feb 2016 04:02:41 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 1/3] use pipe for git-http-backend output Date: Thu, 25 Feb 2016 04:02:35 +0000 Message-Id: <20160225040237.29014-2-e@80x24.org> In-Reply-To: <20160225040237.29014-1-e@80x24.org> References: <20160225040237.29014-1-e@80x24.org> List-Id: This allows us to stream the output to the client without buffering everything up-front. Next, we'll let Danga::Socket (or AE in the future) wait for readability. --- lib/PublicInbox/GitHTTPBackend.pm | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm index 562c290..cba025e 100644 --- a/lib/PublicInbox/GitHTTPBackend.pm +++ b/lib/PublicInbox/GitHTTPBackend.pm @@ -132,9 +132,9 @@ sub serve_smart { my $buf; my $in; my $err = $env->{'psgi.errors'}; - if (fileno($input) >= 0) { # FIXME untested + if (fileno($input) >= 0) { $in = $input; - } else { + } else { # FIXME untested $in = IO::File->new_tmpfile; while (1) { my $r = $input->read($buf, 8192); @@ -148,7 +148,11 @@ sub serve_smart { $in->flush; $in->sysseek(0, SEEK_SET); } - my $out = IO::File->new_tmpfile; + my ($rpipe, $wpipe); + unless (pipe($rpipe, $wpipe)) { + $err->print('error creating pipe', $!, "\n"); + return r(500); + } my $pid = fork; # TODO: vfork under Linux... unless (defined $pid) { $err->print('error forking: ', $!, "\n"); @@ -170,22 +174,17 @@ sub serve_smart { $ENV{GIT_HTTP_EXPORT_ALL} = '1'; $ENV{PATH_TRANSLATED} = "$git->{git_dir}/$path"; dup2(fileno($in), 0) or die "redirect stdin failed: $!\n"; - dup2(fileno($out), 1) or die "redirect stdout failed: $!\n"; + dup2(fileno($wpipe), 1) or die "redirect stdout failed: $!\n"; my @cmd = qw(git http-backend); exec(@cmd) or die 'exec `' . join(' ', @cmd). "' failed: $!\n"; } - - if (waitpid($pid, 0) != $pid) { - $err->print("git http-backend ($git->{git_dir}): ", $?, "\n"); - return r(500); - } + $wpipe = undef; $in = undef; - $out->seek(0, SEEK_SET); my @h; my $code = 200; { local $/ = "\r\n"; - while (defined(my $line = <$out>)) { + while (defined(my $line = <$rpipe>)) { if ($line =~ /\AStatus:\s*(\d+)/) { $code = $1; } else { @@ -200,7 +199,7 @@ sub serve_smart { my ($cb) = @_; my $fh = $cb->([ $code, \@h ]); while (1) { - my $r = $out->read($buf, 8192); + my $r = sysread($rpipe, $buf, 8192); die "$!\n" unless defined $r; last if ($r == 0); $fh->write($buf); -- EW