-# Copyright (C) 2016-2018 all contributors <meta@public-inbox.org>
+# Copyright (C) 2016-2019 all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# when no endpoints match, fallback to this and serve a static file
use HTTP::Status qw(status_message);
use Plack::Util;
use PublicInbox::Qspawn;
+use PublicInbox::Tmpfile;
# 32 is same as the git-daemon connection limit
my $default_limiter = PublicInbox::Qspawn::Limiter->new(32);
$env{PATH_TRANSLATED} = "$git->{git_dir}/$path";
my $rdr = input_prepare($env) or return r(500);
my $qsp = PublicInbox::Qspawn->new([qw(git http-backend)], \%env, $rdr);
- $qsp->psgi_return($env, $limiter, sub {
+ $qsp->psgi_return($env, $limiter, sub { # parse_hdr
my ($r, $bref) = @_;
my $res = parse_cgi_headers($r, $bref) or return; # incomplete
$res->[0] == 403 ? serve_dumb($env, $git, $path) : $res;
if (defined $fd && $fd >= 0) {
return { 0 => $fd };
}
- open(my $in, '+>', undef);
+ my $id = "git-http.input.$env->{REMOTE_ADDR}:$env->{REMOTE_PORT}";
+ my $in = tmpfile($id);
unless (defined $in) {
err($env, "could not open temporary file: $!");
return;
return;
}
last if $r == 0;
- my $off = 0;
- while ($r > 0) {
- my $w = syswrite($in, $buf, $r, $off);
- if (defined $w) {
- $r -= $w;
- $off += $w;
- } else {
- err($env, "error writing temporary file: $!");
- return;
- }
+ unless (print $in $buf) {
+ err($env, "error writing temporary file: $!");
+ return;
}
}
+ # ensure it's visible to git-http-backend(1):
+ unless ($in->flush) {
+ err($env, "error writing temporary file: $!");
+ return;
+ }
unless (defined(sysseek($in, 0, SEEK_SET))) {
err($env, "error seeking temporary file: $!");
return;