now better support for legacy psgi (Catalyst::Engine::PSGI) running with plackup...
[catagits/Catalyst-Runtime.git] / lib / Catalyst / EngineLoader.pm
1 package Catalyst::EngineLoader;
2 use Moose;
3 use Catalyst::Exception;
4 use Catalyst::Utils;
5 use namespace::autoclean;
6
7 extends 'Plack::Loader';
8
9 has application_name => (
10     isa => 'Str',
11     is => 'ro',
12     required => 1,
13 );
14
15 has requested_engine => (
16     is        => 'ro',
17     isa       => 'Str',
18     predicate => 'has_requested_engine',
19 );
20
21 sub needs_psgi_engine_compat_hack {
22     my ($self) = @_;
23     return $self->has_requested_engine
24         && $self->requested_engine eq 'PSGI';
25 }
26
27 has catalyst_engine_class => (
28     isa => 'Str',
29     is => 'rw',
30     lazy => 1,
31     builder => '_guess_catalyst_engine_class',
32 );
33
34 sub _guess_catalyst_engine_class {
35     my $self = shift;
36     my $old_engine = $self->has_requested_engine
37         ? $self->requested_engine
38         : Catalyst::Utils::env_value($self->application_name, 'ENGINE');
39     if (!defined $old_engine) {
40         return 'Catalyst::Engine';
41     }
42     elsif ($old_engine eq 'PSGI') {
43         ## If we are running under plackup let the Catalyst::Engine::PSGI
44         ## continue to run, but warn.
45         warn <<"EOW";
46 You are running Catalyst::Engine::PSGI, which is considered a legacy engine for
47 this version of Catalyst.  We will continue running and use your existing psgi
48 file, but it is recommended to perform the trivial upgrade process, which will
49 leave you with less code and a forward path.
50
51 Please review Catalyst::Upgrading
52 EOW
53         return 'Catalyst::Engine::' . $old_engine;
54     }
55     elsif ($old_engine =~ /^(CGI|FastCGI|HTTP|Apache.*)$/) {
56         return 'Catalyst::Engine';
57     }
58     else {
59         return 'Catalyst::Engine::' . $old_engine;
60     }
61 }
62
63 around guess => sub {
64     my ($orig, $self) = (shift, shift);
65     my $engine = $self->$orig(@_);
66     if ($engine eq 'Standalone') {
67         if ( $ENV{MOD_PERL} ) {
68             my ( $software, $version ) =
69               $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
70             $version =~ s/_//g;
71             $version =~ s/(\.[^.]+)\./$1/g;
72
73             if ( $software eq 'mod_perl' ) {
74                 if ( $version >= 1.99922 ) {
75                     $engine = 'Apache2';
76                 }
77
78                 elsif ( $version >= 1.9901 ) {
79                     Catalyst::Exception->throw( message => 'Plack does not have a mod_perl 1.99 handler' );
80                     $engine = 'Apache2::MP19';
81                 }
82
83                 elsif ( $version >= 1.24 ) {
84                     $engine = 'Apache1';
85                 }
86
87                 else {
88                     Catalyst::Exception->throw( message =>
89                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
90                 }
91             }
92         }
93     }
94
95     my $old_engine = Catalyst::Utils::env_value($self->application_name, 'ENGINE');
96     if (!defined $old_engine) { # Not overridden
97     }
98     elsif ($old_engine =~ /^(PSGI|CGI|Apache.*)$/) {
99         # Trust autodetect
100     }
101     elsif ($old_engine eq 'HTTP') {
102         $engine = 'Standalone';
103     }
104     elsif ($old_engine eq 'FastCGI') {
105         $engine = 'FCGI';
106     }
107     elsif ($old_engine eq "HTTP::Prefork") { # Too bad if you're customising, we don't handle options
108                                              # write yourself a script to collect and pass in the options
109         $engine = "Starman";
110     }
111     elsif ($old_engine eq "HTTP::POE") {
112         Catalyst::Exception->throw("HTTP::POE engine no longer works, recommend you use Twiggy instead");
113     }
114     elsif ($old_engine eq "Zeus") {
115         Catalyst::Exception->throw("Zeus engine no longer works");
116     }
117     else {
118         warn("You asked for an unrecognised engine '$old_engine' which is no longer supported, this has been ignored.\n");
119     }
120
121     return $engine;
122 };
123
124 # Force constructor inlining
125 __PACKAGE__->meta->make_immutable( replace_constructor => 1 );
126
127 1;
128
129 __END__
130
131 =head1 NAME
132
133 Catalyst::EngineLoader - The Catalyst Engine Loader
134
135 =head1 SYNOPSIS
136
137 See L<Catalyst>.
138
139 =head1 DESCRIPTION
140
141 Wrapper on L<Plack::Loader> which resets the ::Engine if you are using some
142 version of mod_perl.
143
144 =head1 AUTHORS
145
146 Catalyst Contributors, see Catalyst.pm
147
148 =head1 COPYRIGHT
149
150 This library is free software. You can redistribute it and/or modify it under
151 the same terms as Perl itself.
152
153 =begin Pod::Coverage
154
155 needs_psgi_engine_compat_hack
156
157 =end Pod::Coverage
158
159 =cut