]> Sergey Matveev's repositories - public-inbox.git/commitdiff
cgi: 301 for list-indices without trailing slash
authorEric Wong <e@80x24.org>
Mon, 14 Apr 2014 07:53:53 +0000 (07:53 +0000)
committerEric Wong <e@80x24.org>
Mon, 14 Apr 2014 08:04:12 +0000 (08:04 +0000)
It is common to type upper-level URLs without the slash,
redirect users to the correct page for usability.

public-inbox.cgi
t/cgi.t

index 1765cf4549bc51b334ee5061e2176df0a3038040..17eb5b7beb4e0626c7bf6e135f5587cbce0d48a5 100755 (executable)
@@ -46,6 +46,12 @@ if (@ARGV && $ARGV[0] eq 'static') {
 # private functions below
 
 sub main {
+       # some servers (Ruby webrick) include scheme://host[:port] here,
+       # which confuses CGI.pm when generating self_url.
+       # RFC 3875 does not mention REQUEST_URI at all,
+       # so nuke it since CGI.pm functions without it.
+       delete $ENV{REQUEST_URI};
+
        my $cgi = CGI->new;
        my %ctx;
        if ($cgi->request_method !~ /\AGET|HEAD\z/) {
@@ -77,6 +83,8 @@ sub main {
        } elsif ($path_info =~ m!$LISTNAME_RE/f/(\S+)\z!o) {
                redirect_mid_html($cgi, $1, $2);
 
+       } elsif ($path_info =~ m!$LISTNAME_RE\z!o) {
+               invalid_list(\%ctx, $1) || redirect_list_index(\%ctx, $cgi);
        } else {
                r404();
        }
@@ -182,6 +190,19 @@ sub get_full_html {
                PublicInbox::View->as_html(Email::MIME->new($$x))];
 }
 
+sub redirect_list_index {
+       my ($ctx, $cgi) = @_;
+       do_redirect($cgi->self_url . "/");
+}
+
+sub do_redirect {
+       my ($url) = @_;
+       [ '301 Moved Permanently',
+         { Location => $url, 'Content-Type' => 'text/plain' },
+         "Redirecting to $url\n"
+       ]
+}
+
 # only used for CGI and static file generation modes
 sub set_binmode {
        my ($headers) = @_;
diff --git a/t/cgi.t b/t/cgi.t
index ae7cc730e7203ea1c1c5991233d52a7dff7597ea..c8755541211ffd3757480ba8b519a851a17e0831 100644 (file)
--- a/t/cgi.t
+++ b/t/cgi.t
@@ -181,6 +181,14 @@ EOF
                "slashy URL generated correctly");
 }
 
+# redirect list-name-only URLs
+{
+       local $ENV{HOME} = $home;
+       my $res = cgi_run("/test");
+       like($res->{head}, qr/Status: 301 Moved/, "redirected status");
+       like($res->{head}, qr!/test/!, "redirected with slash");
+}
+
 done_testing();
 
 sub run_with_env {