Explicitly document the wrong Engine::PSGI thing.
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index 9f25c7e..71b1b74 100644 (file)
@@ -16,7 +16,6 @@ use Catalyst::Utils;
 use Catalyst::Controller;
 use Data::OptList;
 use Devel::InnerPackage ();
-use File::stat;
 use Module::Pluggable::Object ();
 use Text::SimpleTable ();
 use Path::Class::Dir ();
@@ -36,6 +35,7 @@ use Carp qw/croak carp shortmess/;
 use Try::Tiny;
 use Plack::Middleware::Conditional;
 use Plack::Middleware::ReverseProxy;
+use Plack::Middleware::IIS6ScriptNameFix;
 
 BEGIN { require 5.008004; }
 
@@ -1871,9 +1871,9 @@ sub finalize_headers {
         # get the length from a filehandle
         if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' )
         {
-            my $stat = stat $response->body;
-            if ( $stat && $stat->size > 0 ) {
-                $response->content_length( $stat->size );
+            my $size = -s $response->body;
+            if ( $size ) {
+                $response->content_length( $size );
             }
             else {
                 $c->log->warn('Serving filehandle without a content-length');
@@ -2599,9 +2599,18 @@ sub engine_class {
 }
 
 sub setup_engine {
-    my ($class) = @_;
-
-    $class->engine_loader(Catalyst::EngineLoader->new(application_name => $class));
+    my ($class, $compat_requested_engine) = @_;
+
+    $class->engine_loader(
+        Catalyst::EngineLoader->new({
+            application_name => $class,
+            (!defined $compat_requested_engine
+                 ? ()
+                 : (compat_options => {
+                     requested_engine => $compat_requested_engine,
+                 })),
+        }),
+    );
 
     my $engine = $class->engine_class;
     Class::MOP::load_class($engine);
@@ -2635,13 +2644,27 @@ sub _finalized_psgi_app {
 sub _setup_psgi_app {
     my ($app) = @_;
 
-    if (my $home = Path::Class::Dir->new($app->config->{home})) {
+    for my $home (Path::Class::Dir->new($app->config->{home})) {
         my $psgi_file = $home->file(
             Catalyst::Utils::appprefix($app) . '.psgi',
         );
 
-        return Plack::Util::load_psgi($psgi_file)
-            if -e $psgi_file;
+        next unless -e $psgi_file;
+        my $psgi_app = Plack::Util::load_psgi($psgi_file);
+
+        return $psgi_app
+            unless $app->engine_loader->needs_psgi_engine_compat_hack;
+
+        # load_psgi ran a .psgi file doing ->setup_engine('PSGI'). That's what
+        # .psgi files generated by the old Engine::PSGI do. Those return an app
+        # coderef calling into MyApp->run, which doesn't work anymore, so we're
+        # just ignoring it and use the wrapped legacy psgi app
+        warn <<"EOW";
+Found a legacy Catalyst::Engine::PSGI .psgi file at ${psgi_file}.
+
+Its content has been ignored. Please consult the Catalyst::Upgrading
+documentation on how to upgrade from Catalyst::Engine::PSGI.
+EOW
     }
 
     return $app->_wrapped_legacy_psgi_app($app->psgi_app);
@@ -2665,6 +2688,16 @@ sub _wrapped_legacy_psgi_app {
         },
     );
 
+    my $server_matches = sub {
+        my ($re) = @_;
+        return sub {
+            my ($env) = @_;
+            my $server = $env->{SERVER_SOFTWARE};
+            return unless $server;
+            return $server =~ $re ? 1 : 0;
+        };
+    };
+
     # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME
     # http://lists.scsys.co.uk/pipermail/catalyst/2006-June/008361.html
     # Thanks to Mark Blythe for this fix
@@ -2674,7 +2707,8 @@ sub _wrapped_legacy_psgi_app {
     # we can.
     $psgi_app = Plack::Middleware::Conditional->wrap(
         $psgi_app,
-        builder => sub {
+        condition => $server_matches->(qr/lighttpd/),
+        builder   => sub {
             my ($to_wrap) = @_;
             return sub {
                 my ($env) = @_;
@@ -2682,14 +2716,27 @@ sub _wrapped_legacy_psgi_app {
                 return $to_wrap->($env);
             };
         },
-        condition => sub {
-            my ($env) = @_;
-            my $server = $env->{SERVER_SOFTWARE};
-            return unless $server;
-            return $server =~ /lighttpd/ ? 1 : 0;
+    );
+
+    $psgi_app = Plack::Middleware::Conditional->wrap(
+        $psgi_app,
+        condition => $server_matches->(qr/^nginx/),
+        builder   => sub {
+            my ($to_wrap) = @_;
+            return sub {
+                my ($env) = @_;
+                my $script_name = $env->{SCRIPT_NAME};
+                $env->{PATH_INFO} =~ s/^$script_name//g;
+                return $to_wrap->($env);
+            };
         },
     );
 
+    # we're applying this unconditionally as the middleware itself already makes
+    # sure it doesn't fuck things up if it's not running under one of the right
+    # IIS versions
+    $psgi_app = Plack::Middleware::IIS6ScriptNameFix->wrap($psgi_app);
+
     return $psgi_app;
 }