about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-03-07 08:10:55 +0000
committerEric Wong <e@80x24.org>2016-04-05 18:58:27 +0000
commit2722ba03b74a782c0f64c7a6b1d09b7b82ff5478 (patch)
treeed04fb3c8dda099ae3d20c2a3c7cda3bfdddea14 /lib
parent4e49ab58f0ea6b32e9610a990c5bfe21900dc73b (diff)
downloadpublic-inbox-2722ba03b74a782c0f64c7a6b1d09b7b82ff5478.tar.gz
We can reuse the existing code for cloning ssoma repositories
to serve normal git repos for repobrowse.

Also, this finally adds a test to fallback to dumb cloning when
http.uploadPack is disabled for the git repository to save
CPU/memory on the host machine.
Diffstat (limited to 'lib')
-rw-r--r--lib/PublicInbox/Repobrowse.pm2
-rw-r--r--lib/PublicInbox/RepobrowseGitFallback.pm71
2 files changed, 4 insertions, 69 deletions
diff --git a/lib/PublicInbox/Repobrowse.pm b/lib/PublicInbox/Repobrowse.pm
index 82d38f90..51ec14c8 100644
--- a/lib/PublicInbox/Repobrowse.pm
+++ b/lib/PublicInbox/Repobrowse.pm
@@ -68,7 +68,7 @@ sub root_index {
 
 sub run {
         my ($self, $cgi, $method) = @_;
-        return r(405, 'Method Not Allowed') if ($method !~ /\AGET|HEAD\z/);
+        return r(405, 'Method Not Allowed') if ($method !~ /\AGET|HEAD|POST\z/);
 
         # URL syntax: / repo [ / cmd [ / path ] ]
         # cmd: log | commit | diff | tree | view | blob | snapshot
diff --git a/lib/PublicInbox/RepobrowseGitFallback.pm b/lib/PublicInbox/RepobrowseGitFallback.pm
index 79cc2fe4..696e5b94 100644
--- a/lib/PublicInbox/RepobrowseGitFallback.pm
+++ b/lib/PublicInbox/RepobrowseGitFallback.pm
@@ -7,81 +7,16 @@ package PublicInbox::RepobrowseGitFallback;
 use strict;
 use warnings;
 use base qw(PublicInbox::RepobrowseBase);
-use Fcntl qw(:seek);
+use PublicInbox::GitHTTPBackend;
 
 # overrides PublicInbox::RepobrowseBase::call
 sub call {
         my ($self, undef, $req) = @_;
         my $expath = $req->{expath};
         return if index($expath, '..') >= 0; # prevent path traversal
-
         my $git = $req->{repo_info}->{git};
-        my $f = "$git->{git_dir}/$expath";
-        return unless -f $f && -r _;
-        my @st = stat(_);
-        my ($size, $mtime) = ($st[7], $st[9]);
-        # TODO: if-modified-since and last-modified...
-        open my $in, '<', $f or return;
-        my $code = 200;
-        my $len = $size;
-        my @h;
-
-        # FIXME: this is Plack-only
-        my $range = eval { $req->{cgi}->{env}->{HTTP_RANGE} };
-        if (defined $range && $range =~ /\bbytes=(\d*)-(\d*)\z/) {
-                ($code, $len) = prepare_range($req, $in, \@h, $1, $2, $size);
-        }
-
-        # we use the unsafe variant since we assume the server admin
-        # would not place untrusted HTML/JS/CSS in the git directory
-        my $type = $self->mime_type_unsafe($expath) || 'text/plain';
-        push @h, 'Content-Type', $type, 'Content-Length', $len;
-        sub {
-                my ($res) = @_; # Plack callback
-                my $fh = $res->([ $code, \@h ]);
-                my $buf;
-                my $n = 8192;
-                while ($size > 0) {
-                        $n = $size if $size < $n;
-                        my $r = read($in, $buf, $n);
-                        last if (!defined($r) || $r <= 0);
-                        $fh->write($buf);
-                }
-                $fh->close;
-        }
-}
-
-sub bad_range { [ 416, [], [] ] }
-
-sub prepare_range {
-        my ($req, $in, $h, $beg, $end, $size) = @_;
-        my $code = 200;
-        my $len = $size;
-        if ($beg eq '') {
-                if ($end ne '') { # last N bytes
-                        $beg = $size - $end;
-                        $beg = 0 if $beg < 0;
-                        $end = $size - 1;
-                        $code = 206;
-                }
-        } else {
-                if ($end eq '' || $end >= $size) {
-                        $end = $size - 1;
-                        $code = 206;
-                } elsif ($end < $size) {
-                        $code = 206;
-                }
-        }
-        if ($code == 206) {
-                $len = $end - $beg + 1;
-                seek($in, $beg, SEEK_SET) or return [ 500, [], [] ];
-                push @$h, qw(Accept-Ranges bytes),
-                                'Content-Range', "bytes $beg-$end/$size";
-
-                # FIXME: Plack::Middleware::Deflater bug?
-                $req->{cgi}->{env}->{'psgix.no-compress'} = 1;
-        }
-        ($code, $len);
+        my $cgi = $req->{cgi};
+        PublicInbox::GitHTTPBackend::serve($cgi, $git, $expath);
 }
 
 1;