]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1399713 - ensure existing production redirects work in a cloud hosted environment
authorDylan William Hardison <dylan@hardison.net>
Thu, 22 Mar 2018 03:17:12 +0000 (23:17 -0400)
committerGitHub <noreply@github.com>
Thu, 22 Mar 2018 03:17:12 +0000 (23:17 -0400)
.htaccess
Bugzilla/ModPerl.pm
Bugzilla/ModPerl/Hostage.pm [new file with mode: 0644]
Makefile.PL
helper.psgi [new file with mode: 0644]

index 745c57536c3144a943b0b0660c89c8b8fda7def2..fd14518bc9a0e8e6b58ec92656429bfd5ea65e3b 100644 (file)
--- a/.htaccess
+++ b/.htaccess
@@ -27,6 +27,8 @@ RewriteRule ^__version__$ version.json [L]
 # heartbeat.cgi returns 200 if the DB and memcached are both working, and 500 otherwise.
 RewriteRule ^__heartbeat__$ heartbeat.cgi [L]
 
+RewriteRule ^(\d+|quicksearch\.html|bugwritinghelp\.html)$ /helper/$1 [L]
+
 RewriteRule ^static/v\d{4}\d{2}\d{2}\.\d+/(.+\.(?:js|css|woff2?|png|jpe?g|gif|ico|svg))$ $1 [NC,E=IMMUTABLE:1,L]
 Header set Cache-Control "public, max-age=31536000" env=REDIRECT_IMMUTABLE
 
index a5c8408971596c5ab856c8486cb43818ba24c3fa..120dd82102185bf419136f3b8cc726be188b6120 100644 (file)
@@ -20,6 +20,7 @@ use Carp ();
 use Template ();
 
 use Bugzilla::ModPerl::BlockIP;
+use Bugzilla::ModPerl::Hostage;
 
 sub apache_config {
     my ($class, $cgi_path) = @_;
@@ -74,6 +75,7 @@ __DATA__
 # the built-in rand(), even though we never use it in Bugzilla itself,
 # so we need to srand() both of them.)
 PerlChildInitHandler "sub { Bugzilla::RNG::srand(); srand(); }"
+PerlInitHandler Bugzilla::ModPerl::Hostage
 PerlAccessHandler Bugzilla::ModPerl::BlockIP
 
 # It is important to specify ErrorDocuments outside of all directories.
@@ -84,6 +86,12 @@ ErrorDocument 403 /errors/403.html
 ErrorDocument 404 /errors/404.html
 ErrorDocument 500 /errors/500.html
 
+<Location /helper>
+    SetHandler perl-script
+    PerlResponseHandler Plack::Handler::Apache2
+    PerlSetVar psgi_app [% cgi_path %]/helper.psgi
+</Location>
+
 <Directory "[% cgi_path %]">
     AddHandler perl-script .cgi
     # No need to PerlModule these because they're already defined in mod_perl.pl
diff --git a/Bugzilla/ModPerl/Hostage.pm b/Bugzilla/ModPerl/Hostage.pm
new file mode 100644 (file)
index 0000000..a3bdfac
--- /dev/null
@@ -0,0 +1,71 @@
+package Bugzilla::ModPerl::Hostage;
+use 5.10.1;
+use strict;
+use warnings;
+
+use Apache2::Const qw(:common); ## no critic (Freenode::ModPerl)
+
+sub _attachment_root {
+    my ($base) = @_;
+    return undef unless $base;
+    return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)}
+        ? $1
+        : undef;
+}
+
+sub _attachment_host_regex {
+    my ($base) = @_;
+    return undef unless $base;
+    my $val   = $base;
+    $val =~ s{^https?://}{}s;
+    $val =~ s{/$}{}s;
+    my $regex = quotemeta $val;
+    $regex =~ s/\\\%bugid\\\%/\\d+/g;
+    return qr/^$regex$/s;
+}
+
+sub handler {
+    my $r = shift;
+    state $urlbase               = Bugzilla->localconfig->{urlbase};
+    state $urlbase_uri           = URI->new($urlbase);
+    state $urlbase_host          = $urlbase_uri->host;
+    state $urlbase_host_regex    = qr/^bug(\d+)\.\Q$urlbase_host\E$/;
+    state $attachment_base       = Bugzilla->localconfig->{attachment_base};
+    state $attachment_root       = _attachment_root($attachment_base);
+    state $attachment_host_regex = _attachment_host_regex($attachment_base);
+
+    my $hostname  = $r->hostname;
+    return OK if $hostname eq $urlbase_host;
+
+    my $path = $r->uri;
+    return OK if $path eq '/__lbheartbeat__';
+
+    if ($attachment_base && $hostname eq $attachment_root) {
+        $r->headers_out->set(Location => $urlbase);
+        return REDIRECT;
+    }
+    elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
+        if ($path =~ m{^/attachment\.cgi}s) {
+            return OK;
+        } else {
+            my $new_uri = URI->new($r->unparsed_uri);
+            $new_uri->scheme($urlbase_uri->scheme);
+            $new_uri->host($urlbase_host);
+            $r->headers_out->set(Location => $new_uri);
+            return REDIRECT;
+        }
+    }
+    elsif (my ($id) = $hostname =~ $urlbase_host_regex) {
+        my $new_uri = $urlbase_uri->clone;
+        $new_uri->path('/show_bug.cgi');
+        $new_uri->query_form(id => $id);
+        $r->headers_out->set(Location => $new_uri);
+        return REDIRECT;
+    }
+    else {
+        $r->headers_out->set(Location => $urlbase);
+        return REDIRECT;
+    }
+}
+
+1;
\ No newline at end of file
index ceb0fc97c9e9aa36d1c0067ec7d2dbb0a8ff9d00..f7b62ea5c9dca967204cda62a1bd1932139760ec 100755 (executable)
@@ -271,6 +271,7 @@ my %optional_features = (
                 requires => {
                     'mod_perl2'          => '1.999022',
                     'Apache2::SizeLimit' => '0.96',
+                    'Plack::Handler::Apache2' => 0,
                 }
             }
         }
diff --git a/helper.psgi b/helper.psgi
new file mode 100644 (file)
index 0000000..cc8c648
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
+
+use 5.10.1;
+use strict;
+use warnings;
+use Plack::Request;
+use Plack::Response;
+
+my $app = sub {
+    my $env     = shift;
+    my $req     = Plack::Request->new($env);
+    my $res     = Plack::Response->new(404);
+    my $urlbase = Bugzilla->localconfig->{urlbase};
+    my $path    = $req->path;
+
+    if ( $path eq '/quicksearch.html' ) {
+        $res->redirect( $urlbase . 'page.cgi?id=quicksearch.html', 301 );
+    }
+    elsif ( $path eq '/bugwritinghelp.html') {
+        $res->redirect( $urlbase . 'page.cgi?id=bug-writing.html', 301 );
+    }
+    elsif ( $path =~ m{^/(\d+)$}s ) {
+        $res->redirect( $urlbase . "show_bug.cgi?id=$1", 301 );
+    }
+    else {
+        $res->body('not found');
+    }
+    return $res->finalize;
+};
\ No newline at end of file