sub html_start {
my ($self, $req, $title_html, $opts) = @_;
my $desc = $req->{repo_info}->{desc_html};
- my $meta;
+ my $meta = '';
if ($opts) {
my @robots;
"</head><body><pre><b>$desc</b>";
}
+sub r {
+ my ($self, $status, $req, @extra) = @_;
+ my @h;
+
+ my $body = '';
+ if ($status == 301 || $status == 302) {
+ # The goal is to be able to make redirects like we make
+ # <a href=> tags with '../'
+ my $cgi = $req->{cgi};
+ my $base;
+ $base = ref($cgi) eq 'CGI' ? $cgi->url(-base).'/' : $cgi->base;
+ my ($redir) = @extra;
+ if ($redir =~ m!\A\.\./!) { # relative redirect
+ my @orig = split(m!/+!, $cgi->path_info, -1);
+ shift @orig; # drop leading '/'
+ my @dest = split(m!/+!, $redir);
+
+ while ($dest[0] eq '..') {
+ pop @orig;
+ shift @dest;
+ }
+ my $end = '';
+ $end = pop @dest if $dest[-1] =~ /\A[#\?]/;
+ $redir = $base . join('/', @orig, @dest) . $end;
+ } else {
+ $redir = $base . '/' . $redir;
+ }
+ push @h, qw(Content-Type text/plain Location), $redir;
+
+ # mainly for curl (no-'-L') users:
+ $body = "Redirecting to $redir\n";
+ } else {
+ die "not implemented, yet: $status";
+ }
+
+ [ $status, \@h, [ $body ] ]
+}
+
1;
my $q = PublicInbox::RepobrowseGitQuery->new($req->{cgi});
my $id = $q->{id};
$id eq '' and $id = 'HEAD';
+
+ my $expath = $req->{expath};
+ if ($expath ne '') {
+ my $relup = join('', map { '../' } @{$req->{extra}});
+ my $qs = $q->qs;
+ return $self->r(301, $req, "$relup$qs#".to_attr($expath));
+ }
+
my $git = $req->{repo_info}->{git};
my @cmd = (qw(show -z --numstat -p --encoding=UTF-8
--no-notes --no-color -c), $git->abbrev);
- my @path;
-
- # kill trailing slash
- my $extra = $req->{extra};
- if (@$extra) {
- pop @$extra if $extra->[-1] eq '';
- @path = (join('/', @$extra));
- push @cmd, '--follow';
- }
- my $log = $git->popen(@cmd, GIT_FMT, $id, '--', @path);
+ my $log = $git->popen(@cmd, GIT_FMT, $id, '--');
my $H = <$log>;
# maybe the path didn't exist, yet, zip them back up
- return git_commit_404($req, $q, $path[0]) unless defined $H;
+ return git_commit_404($req, $q) unless defined $H;
sub {
my ($res) = @_; # Plack callback
my $fh = $res->([200, ['Content-Type'=>'text/html']]);
}
sub git_commit_404 {
- my ($req, $q, $path) = @_;
+ my ($req, $q) = @_;
my $x = 'Missing commit or path';
my $pfx = "$req->{relcmd}commit";
- # print STDERR "path: $path\n";
my $try = 'try';
$x = "<html><head><title>$x</title></head><body><pre><b>$x</b>\n\n";
- if (defined $path) {
- my $qs = $q->qs;
- $x .= "<a\nhref=\"$pfx$qs\">" .
- "try without the path <s>$path</s></a>\n";
- $try = 'or';
- }
my $qs = $q->qs(id => '');
$x .= "<a\nhref=\"$pfx$qs\">$try the latest commit in HEAD</a>\n";
$x .= '</pre></body>';
--- /dev/null
+# Copyright (C) 2016 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+use strict;
+use warnings;
+
+my $test = require './t/repobrowse_common_git.perl';
+test_psgi($test->{app}, sub {
+ my ($cb) = @_;
+ my $path = '/path/to/something';
+ my $req = 'http://example.com/test.git/commit';
+ my $res = $cb->(GET($req . $path));
+ is($res->code, 301, 'got 301 to anchor');
+ is($res->header('Location'), "$req#path:to:something",
+ 'redirected to anchor from path');
+
+ my $q = '?id=deadbeef';
+ $res = $cb->(GET($req . $path . $q));
+ is($res->code, 301, 'got 301 with query string');
+ is($res->header('Location'), "$req$q#path:to:something",
+ 'redirected to anchor from path with query');
+});
+
+done_testing();