summaryrefslogtreecommitdiffstats
path: root/app.psgi
blob: 50e341f6ba9fac1a015b37bbafe27f6908ec3553 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/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.14.0;
use strict;
use warnings;

use File::Basename;
use File::Spec;

BEGIN {
    require lib;
    my $dir = File::Spec->rel2abs( dirname(__FILE__) );
    lib->import(
        $dir,
        File::Spec->catdir( $dir, "lib" ),
        File::Spec->catdir( $dir, qw(local lib perl5) )
    );

    # disable "use lib" from now on
    no warnings qw(redefine);
    *lib::import = sub { };
}

use Bugzilla::Constants ();

use Plack;
use Plack::Builder;
use Plack::App::URLMap;
use Plack::App::WrapCGI;
use Plack::Response;

use constant STATIC => qw(
    data/assets
    data/webdot
    docs
    extensions/[^/]+/web
    graphs
    images
    js
    skins
);

$ENV{BZ_PLACK} = 'Plack/' . Plack->VERSION;

my $app = builder {
    my $static_paths
        = join( '|', sort { length $b <=> length $a || $a cmp $b } STATIC );
    enable 'Static',
        path => qr{^/($static_paths)/},
        root => Bugzilla::Constants::bz_locations->{cgi_path};

    my $shutdown_app
        = Plack::App::WrapCGI->new( script => 'shutdown.cgi' )->to_app;
    my @scripts = glob('*.cgi');

    my %cgi_app;
    foreach my $script (@scripts) {
        my $base_name = basename($script);

        next if $base_name eq 'shutdown.cgi';
        my $app
            = eval { Plack::App::WrapCGI->new( script => $script )->to_app };

        # Some CGI scripts won't compile if not all optional Perl modules are
        # installed. That's expected.
        unless ($app) {
            warn "Cannot compile $script: $@\nSkipping!\n";
            next;
        }

        my $wrapper = sub {
            my $ret = Bugzilla::init_page();
            my $res
                = ( $ret eq '-1' && $script ne 'editparams.cgi' )
                ? $shutdown_app->(@_)
                : $app->(@_);
            Bugzilla::_cleanup();
            return $res;
        };
        $cgi_app{$base_name} = $wrapper;
    }

    foreach my $cgi_name ( keys %cgi_app ) {
        mount "/$cgi_name" => $cgi_app{$cgi_name};
    }

    # so mount / => $app will make *all* files redirect to the index.
    # instead we use an inline middleware to rewrite / to /index.cgi
    enable sub {
        my $app = shift;
        return sub {
            my $env = shift;
            $env->{PATH_INFO} = '/index.cgi' if $env->{PATH_INFO} eq '/';
            return $app->($env);
        };
    };

    mount "/rest" => $cgi_app{"rest.cgi"};

};

unless (caller) {
    require Plack::Runner;
    my $runner = Plack::Runner->new;
    $runner->parse_options(@ARGV);
    $runner->run($app);
    exit 0;
}

return $app;