]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/GitHTTPBackend.pm
git-http-backend: favor sysread for regular files
[public-inbox.git] / lib / PublicInbox / GitHTTPBackend.pm
index 6e8ad955d7af9a7deb112366e178e6811b2f4d8c..50bb4331f5aaaa017b21d846fdbd040d32d0ca79 100644 (file)
@@ -73,7 +73,7 @@ sub serve {
                my $n = 8192;
                while ($len > 0) {
                        $n = $len if $len < $n;
-                       my $r = read($in, $buf, $n);
+                       my $r = sysread($in, $buf, $n);
                        last if (!defined($r) || $r <= 0);
                        $len -= $r;
                        $fh->write($buf);
@@ -132,9 +132,10 @@ sub serve_smart {
        my $buf;
        my $in;
        my $err = $env->{'psgi.errors'};
-       if (fileno($input) >= 0) {
+       my $fd = eval { fileno($input) };
+       if (defined $fd && $fd >= 0) {
                $in = $input;
-       } else { # FIXME untested
+       } else {
                $in = input_to_file($env) or return r(500);
        }
        my ($rpipe, $wpipe);
@@ -201,14 +202,14 @@ sub serve_smart {
                if ($fh) { # stream body from git-http-backend to HTTP client
                        $fh->write($buf);
                        $buf = '';
-               } elsif ($buf =~ s/\A(.*?)\r?\n\r?\n//s) { # parse headers
+               } elsif ($buf =~ s/\A(.*?)\r\n\r\n//s) { # parse headers
                        my $h = $1;
                        my $code = 200;
                        my @h;
-                       foreach my $l (split(/\r?\n/, $h)) {
+                       foreach my $l (split(/\r\n/, $h)) {
                                my ($k, $v) = split(/:\s*/, $l, 2);
                                if ($k =~ /\AStatus\z/i) {
-                                       $code = int($v);
+                                       ($code) = ($v =~ /\b(\d+)\b/);
                                } else {
                                        push @h, $k, $v;
                                }
@@ -223,7 +224,7 @@ sub serve_smart {
        if (my $async = $env->{'pi-httpd.async'}) {
                $rpipe = $async->($rpipe, $cb);
                sub { ($res) = @_ } # let Danga::Socket handle the rest.
-       } else { # synchronous loop
+       } else { # synchronous loop for other PSGI servers
                $vin = '';
                vec($vin, fileno($rpipe), 1) = 1;
                sub {
@@ -233,7 +234,6 @@ sub serve_smart {
        }
 }
 
-# FIXME: untested, our -httpd _always_ gives a real file handle
 sub input_to_file {
        my ($env) = @_;
        my $in = IO::File->new_tmpfile;