# Copyright (C) 2015-2016 all contributors # License: AGPL-3.0+ package PublicInbox::RepoGitRaw; use strict; use warnings; use base qw(PublicInbox::RepoBase); use PublicInbox::Hval qw(utf8_html); use PublicInbox::Qspawn; my $MAX_ASYNC = 65536; my $BIN_DETECT = 8000; sub git_raw_check_res ($$$) { my ($self, $req, $res) = @_; sub { my ($info) = @_; my ($hex, $type, $size) = @$info; if (!defined $type || $type eq 'missing') { return $res->($self->rt(404, 'plain', 'Not Found')); } my $ct; if ($type eq 'blob') { my $base = $req->{extra}->[-1]; $ct = $self->mime_type($base) if defined $base; $ct ||= 'text/plain; charset=UTF-8' if !$size; } elsif ($type eq 'commit' || $type eq 'tag') { $ct = 'text/plain; charset=UTF-8'; } elsif ($type eq 'tree') { return git_tree_raw($self, $req, $res, $hex); } else { $ct = 'application/octet-stream'; } $size > $MAX_ASYNC and return show_big($self, $req, $res, $ct, $info); # buffer small files in full 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 ]]); }); } } sub call_git_raw { my ($self, $req) = @_; my $repo = $req->{-repo}; my $obj = $req->{tip} || $repo->tip; my $expath = $req->{expath}; $obj .= ":$expath" if $expath ne ''; sub { my ($res) = @_; $repo->{git}->check_async($req->{env}, $obj, git_raw_check_res($self, $req, $res)); } } sub git_tree_sed ($) { my ($req) = @_; my $buf = ''; my $end = ''; my $pfx = $req->{tpfx}; sub { # $_[0] = buffer or undef my $dst = delete $req->{tstart} || ''; my @files; if (defined $_[0]) { @files = split(/\0/, $buf .= $_[0]); $buf = pop @files if scalar @files; } else { @files = split(/\0/, $buf); $end = ''; } foreach my $n (@files) { $n = PublicInbox::Hval->utf8($n); my $ref = $n->as_path; $dst .= qq(
  • ); $dst .= $n->as_html; $dst .= '
  • '; } $dst .= $end; } } sub git_tree_raw { my ($self, $req, $res, $hex) = @_; my @ex = @{$req->{extra}}; my $rel = $req->{relcmd}; my $title = utf8_html(join('/', '', @ex, '')); my $repo = $req->{-repo}; my $pfx = ($req->{tip} || $repo->tip) . '/'; my $t = "

    $title