about summary refs log tree commit homepage
path: root/lib/PublicInbox/Repobrowse.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/PublicInbox/Repobrowse.pm')
-rw-r--r--lib/PublicInbox/Repobrowse.pm47
1 files changed, 39 insertions, 8 deletions
diff --git a/lib/PublicInbox/Repobrowse.pm b/lib/PublicInbox/Repobrowse.pm
index 9e97593b..f344e0f8 100644
--- a/lib/PublicInbox/Repobrowse.pm
+++ b/lib/PublicInbox/Repobrowse.pm
@@ -35,6 +35,32 @@ sub new {
 # simple response for errors
 sub r { [ $_[0], ['Content-Type' => 'text/plain'], [ join(' ', @_, "\n") ] ] }
 
+# Remove trailing slash in URLs which regular humans are likely to read
+# in an attempt to improve cache hit ratios.  Do not redirect
+# plain|patch|blob|fallback endpoints since those could be using
+# automated tools which may not follow redirects automatically
+# (e.g. curl does not follow 301 unless given "-L")
+my %NO_TSLASH = map { $_ => 1 } qw(Log Commit Tree Summary Tag);
+sub no_tslash {
+        my ($cgi) = @_;
+        my ($base, $uri);
+        if (ref($cgi) eq 'CGI') {
+                $base = $cgi->url(-base);
+                $uri = $ENV{REQUEST_URI};
+        } else { # Plack::Request
+                $base = $cgi->base;
+                $base =~ s!/+\z!!;
+                $uri = $cgi->request_uri;
+        }
+        if ($uri !~ s!/+\z!!) {
+                warn "W: buggy redirect? base=$base request_uri=$uri\n";
+        }
+        my $url = $base . $uri;
+        [ 301,
+          [ Location => $url, 'Content-Type' => 'text/plain' ],
+          [ "Redirecting to $url\n" ] ]
+}
+
 sub run {
         my ($self, $cgi, $method) = @_;
         return r(405, 'Method Not Allowed') if ($method !~ /\AGET|HEAD\z/);
@@ -59,9 +85,8 @@ sub run {
                 extra => \@extra, # path
                 cgi => $cgi,
                 rconfig => $rconfig,
-                tslash => 0,
         };
-
+        my $tslash = 0;
         my $cmd = shift @extra;
         my $vcs_lc = $repo_info->{vcs};
         my $vcs = $VCS{$vcs_lc} or return r404();
@@ -77,8 +102,7 @@ sub run {
                 $mod = 'Summary';
                 $cmd = 'summary';
                 if ($path_info =~ m!/\z!) {
-                        $req->{tslash} = $path_info =~ tr!/!!;
-                        $req->{relcmd} = '';
+                        $tslash = $path_info =~ tr!/!!;
                 } else {
                         my @repo = split('/', $repo_path);
                         if (@repo > 1) {
@@ -88,13 +112,20 @@ sub run {
                         }
                 }
         }
-        $mod = load_once("PublicInbox::Repobrowse$vcs$mod");
-        $vcs = load_once("PublicInbox::$vcs");
-        $repo_info->{$vcs_lc} ||= $vcs->new($repo_info->{path});
         while (@extra && $extra[-1] eq '') {
                 pop @extra;
-                ++$req->{tslash};
+                ++$tslash;
         }
+
+        if ($tslash && $path_info ne '/' && $NO_TSLASH{$mod}) {
+                return no_tslash($cgi);
+        }
+
+        $req->{tslash} = $tslash;
+        $mod = load_once("PublicInbox::Repobrowse$vcs$mod");
+        $vcs = load_once("PublicInbox::$vcs");
+        $repo_info->{$vcs_lc} ||= $vcs->new($repo_info->{path});
+
         $req->{expath} = join('/', @extra);
         my $rv = eval { $mod->new->call($cmd, $req) }; # RepobrowseBase::call
         $rv || r404();