diff options
-rw-r--r-- | .htaccess | 2 | ||||
-rw-r--r-- | Bugzilla/ModPerl.pm | 8 | ||||
-rw-r--r-- | Bugzilla/ModPerl/Hostage.pm | 71 | ||||
-rwxr-xr-x | Makefile.PL | 1 | ||||
-rw-r--r-- | helper.psgi | 35 |
5 files changed, 117 insertions, 0 deletions
@@ -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 diff --git a/Bugzilla/ModPerl.pm b/Bugzilla/ModPerl.pm index a5c840897..120dd8210 100644 --- a/Bugzilla/ModPerl.pm +++ b/Bugzilla/ModPerl.pm @@ -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 index 000000000..a3bdfac58 --- /dev/null +++ b/Bugzilla/ModPerl/Hostage.pm @@ -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 diff --git a/Makefile.PL b/Makefile.PL index ceb0fc97c..f7b62ea5c 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -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 index 000000000..cc8c648a8 --- /dev/null +++ b/helper.psgi @@ -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 |