about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/PublicInbox/Git.pm5
-rw-r--r--lib/PublicInbox/GitAsync.pm3
-rw-r--r--lib/PublicInbox/RepoGitRaw.pm20
-rw-r--r--lib/PublicInbox/RepoGitSrc.pm21
-rw-r--r--t/git_async.t4
5 files changed, 30 insertions, 23 deletions
diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index 6a7b109f..893df71e 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -253,10 +253,10 @@ sub cat_async_compat ($$$) {
         $self->{out}->print($obj."\n") or fail($self, "write error: $!");
         my $in = $self->{in};
         my $info = async_info_compat($in);
+        my (undef, $type, $left) = @$info;
         $cb->($info);
-        return if scalar(@$info) != 3; # missing
+        return if $info->[1] eq 'missing';
         my $max = 8192;
-        my $left = $info->[2];
         my ($buf, $r);
         while ($left > 0) {
                 $r = read($in, $buf, $left > $max ? $max : $left);
@@ -267,6 +267,7 @@ sub cat_async_compat ($$$) {
         $r = read($in, $buf, 1);
         defined($r) or fail($self, "read failed: $!");
         fail($self, 'newline missing after blob') if ($r != 1 || $buf ne "\n");
+        $cb->(0);
 }
 
 sub check_async {
diff --git a/lib/PublicInbox/GitAsync.pm b/lib/PublicInbox/GitAsync.pm
index 8369978c..24e0bf3b 100644
--- a/lib/PublicInbox/GitAsync.pm
+++ b/lib/PublicInbox/GitAsync.pm
@@ -65,7 +65,7 @@ take_job:
                 }
                 $cb->($info); # $info may 0 (EOF, or undef, $cb will see $!)
                 return $self->close unless $info;
-                if ($check || (scalar(@$info) != 3)) {
+                if ($check || $info->[1] eq 'missing') {
                         # do not monopolize the event loop if we're drained:
                         return if ${$self->{rbuf}} eq '';
                         goto take_job;
@@ -89,6 +89,7 @@ final_hunk:
                 my $lf = chop $$rbuf;
                 $lf eq "\n" or die "BUG: missing LF (got $lf)";
                 $cb->($rbuf);
+                $cb->(0);
 
                 return if $buf eq '';
                 goto take_job;
diff --git a/lib/PublicInbox/RepoGitRaw.pm b/lib/PublicInbox/RepoGitRaw.pm
index 858034a3..717ca71f 100644
--- a/lib/PublicInbox/RepoGitRaw.pm
+++ b/lib/PublicInbox/RepoGitRaw.pm
@@ -36,15 +36,17 @@ sub git_raw_check_res ($$$) {
                 my $buf = '';
                 $req->{-repo}->{git}->cat_async($req->{env}, $hex, sub {
                         my ($r) = @_;
-                        return if ref($r) ne 'SCALAR';
-                        $buf .= $$r;
-                        return if bytes::length($buf) < $size;
-                        $ct ||= index($buf, "\0") >= 0 ?
-                                        'application/octet-stream' :
-                                        'text/plain; charset=UTF-8';
-                        $res->([200, ['Content-Type', $ct,
-                                        'Content-Length', $size ],
-                                [ $buf ]]);
+                        if (ref($r) eq 'SCALAR') {
+                                $buf .= $$r;
+                        } elsif ($r == 0) {
+                                return if bytes::length($buf) < $size;
+                                $ct ||= index($buf, "\0") >= 0 ?
+                                                'application/octet-stream' :
+                                                'text/plain; charset=UTF-8';
+                                $res->([200, ['Content-Type', $ct,
+                                                'Content-Length', $size ],
+                                        [ $buf ]]);
+                        }
                 });
         }
 }
diff --git a/lib/PublicInbox/RepoGitSrc.pm b/lib/PublicInbox/RepoGitSrc.pm
index 67de86ee..51048773 100644
--- a/lib/PublicInbox/RepoGitSrc.pm
+++ b/lib/PublicInbox/RepoGitSrc.pm
@@ -154,18 +154,17 @@ sub git_blob_show {
                 return if $ref eq 'ARRAY'; # redundant info
                 if ($ref eq 'SCALAR') {
                         $buf .= $$r;
-                        if (bytes::length($buf) == $size) {
-                                my $fh = $res->($self->rt(200, 'html'));
-                                my $sed = git_blob_sed($req, $hex, $size);
-                                $fh->write($sed->($buf));
-                                $fh->write($sed->(undef));
-                                $fh->close;
-                        }
-                        return;
+                } elsif (!defined $r) {
+                        my $cb = $res or return;
+                        $res = undef;
+                        $cb->($self->rt(500, 'plain', "Error\n"));
+                } elsif ($r == 0) {
+                        my $fh = $res->($self->rt(200, 'html'));
+                        my $sed = git_blob_sed($req, $hex, $size);
+                        $fh->write($sed->($buf));
+                        $fh->write($sed->(undef));
+                        $fh->close;
                 }
-                my $cb = $res or return;
-                $res = undef;
-                $cb->($self->rt(500, 'plain', "Error\n"));
         });
 }
 
diff --git a/t/git_async.t b/t/git_async.t
index 4f7e4ebe..ffe2b1a2 100644
--- a/t/git_async.t
+++ b/t/git_async.t
@@ -117,6 +117,7 @@ my $dir = "$tmpdir/git.git";
         }
         my @info;
         my $str = '';
+        my $eof_seen = 0;
         $git->cat_async_compat('HEAD:foo.txt', sub {
                 my $ref = $_[0];
                 my $t = ref $ref;
@@ -124,10 +125,13 @@ my $dir = "$tmpdir/git.git";
                         push @info, $ref;
                 } elsif ($t eq 'SCALAR') {
                         $str .= $$ref;
+                } elsif ($ref == 0) {
+                        $eof_seen++;
                 } else {
                         fail "fail type: $t";
                 }
         });
+        is($eof_seen, 1, 'EOF seen once');
         is_deeply(\@info, [ [ 'bf4f17855632367a160bef055fc8ba4675d10e6b',
                                'blob', 18 ]], 'info matches compat');
         is($str, "-----\nhello\nworld\n", 'data matches compat');