diff options
author | Eric Wong <e@80x24.org> | 2016-03-07 08:10:55 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-04-05 18:58:27 +0000 |
commit | 2722ba03b74a782c0f64c7a6b1d09b7b82ff5478 (patch) | |
tree | ed04fb3c8dda099ae3d20c2a3c7cda3bfdddea14 /lib/PublicInbox | |
parent | 4e49ab58f0ea6b32e9610a990c5bfe21900dc73b (diff) | |
download | public-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/PublicInbox')
-rw-r--r-- | lib/PublicInbox/Repobrowse.pm | 2 | ||||
-rw-r--r-- | lib/PublicInbox/RepobrowseGitFallback.pm | 71 |
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; |