Small docs and fixes
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index f91eb26..1d598dd 100644 (file)
@@ -71,7 +71,7 @@ our $GO        = Catalyst::Exception::Go->new;
 __PACKAGE__->mk_classdata($_)
   for qw/components arguments dispatcher engine log dispatcher_class
   engine_class context_class request_class response_class stats_class
-  setup_finished psgi_app/;
+  setup_finished _psgi_app/;
 
 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
 __PACKAGE__->engine_class('Catalyst::Engine');
@@ -81,7 +81,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80029';
+our $VERSION = '5.89000';
 
 sub import {
     my ( $class, @arguments ) = @_;
@@ -1116,7 +1116,10 @@ sub setup {
     $class->setup_log( delete $flags->{log} );
     $class->setup_plugins( delete $flags->{plugins} );
     $class->setup_dispatcher( delete $flags->{dispatcher} );
-    $class->setup_engine( delete $flags->{engine} );
+    if (my $engine = delete $flags->{engine}) {
+        $class->log->warn("Specifying the engine in ->setup is no longer supported, XXX FIXME");
+    }
+    $class->setup_engine();
     $class->setup_stats( delete $flags->{stats} );
 
     for my $flag ( sort keys %{$flags} ) {
@@ -1859,7 +1862,7 @@ sub finalize_headers {
     }
 
     # Content-Length
-    if ( $response->body && !$response->content_length ) {
+    if ( defined $response->body && length $response->body && !$response->content_length ) {
 
         # get the length from a filehandle
         if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' )
@@ -2373,11 +2376,11 @@ sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
 
 =head2 $c->request_class
 
-Returns or sets the request class.
+Returns or sets the request class. Defaults to L<Catalyst::Request>.
 
 =head2 $c->response_class
 
-Returns or sets the response class.
+Returns or sets the response class. Defaults to L<Catalyst::Response>.
 
 =head2 $c->read( [$maxlength] )
 
@@ -2402,7 +2405,7 @@ Starts the engine.
 
 =cut
 
-sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
+sub run { my $c = shift; return $c->engine->run( $c, $c->psgi_app, @_ ) }
 
 =head2 $c->set_action( $action, $code, $namespace, $attrs )
 
@@ -2587,51 +2590,11 @@ Sets up engine.
 =cut
 
 sub setup_engine {
-    my ($class, $engine) = @_;
-
-    unless ($engine) {
-        $engine = $class->engine_class;
-    }
-    else {
-        $engine = String::RewritePrefix->rewrite( { '' => 'Catalyst::Engine::', '+' => '' }, $engine );
-    }
-
-    $engine = 'Catalyst::Engine' if $engine eq 'Catalyst::Engine::HTTP';
+    my ($class) = @_;
 
+    my $engine = $class->engine_class;
     Class::MOP::load_class($engine);
 
-    # check for old engines that are no longer compatible
-    my $old_engine;
-    if ( $engine->isa('Catalyst::Engine::Apache')
-        && !Catalyst::Engine::Apache->VERSION )
-    {
-        $old_engine = 1;
-    }
-
-    elsif ( $engine->isa('Catalyst::Engine::Server::Base')
-        && Catalyst::Engine::Server->VERSION le '0.02' )
-    {
-        $old_engine = 1;
-    }
-
-    elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
-        && $engine->VERSION eq '0.01' )
-    {
-        $old_engine = 1;
-    }
-
-    elsif ($engine->isa('Catalyst::Engine::Zeus')
-        && $engine->VERSION eq '0.01' )
-    {
-        $old_engine = 1;
-    }
-
-    if ($old_engine) {
-        Catalyst::Exception->throw( message =>
-              qq/Engine "$engine" is not supported by this version of Catalyst/
-        );
-    }
-
     if ($ENV{MOD_PERL}) {
         require 'Catalyst/Engine/Loader.pm';
         my $apache = Catalyst::Engine::Loader->auto;
@@ -2644,8 +2607,87 @@ sub setup_engine {
     }
 
     $class->engine( $engine->new );
-    $class->psgi_app( $class->engine->build_psgi_app($class) );
 
+    return;
+}
+
+=head2 $c->psgi_app
+
+Builds a PSGI application coderef for the catalyst application C<$c> using
+L</"$c->setup_psgi_app">, stores it internally, and returns it. On the next call
+to this method, C<setup_psgi_app> won't be invoked again, but its persisted
+return value of it will be returned.
+
+This is the top-level entrypoint for things that need a full blown Catalyst PSGI
+app. If you only need the raw PSGI application, without any middlewares, use
+L</"$c->raw_psgi_app"> instead.
+
+=cut
+
+sub psgi_app {
+    my ($app) = @_;
+
+    unless ($app->_psgi_app) {
+        my $psgi_app = $app->setup_psgi_app;
+        $app->_psgi_app($psgi_app);
+    }
+
+    return $app->_psgi_app;
+}
+
+=head2 $c->setup_psgi_app
+
+Builds a PSGI application coderef for the catalyst application C<$c>.
+
+If we're able to locate a C<${myapp}.psgi> file in the applications home
+directory, we'll use that to obtain our code reference.
+
+Otherwise the raw psgi app, without any middlewares is created using
+C<raw_psgi_app> and wrapped into L<Plack::Middleware::ReverseProxy>
+conditionally. See L</"PROXY SUPPORT">.
+
+=cut
+
+sub setup_psgi_app {
+    my ($app) = @_;
+
+    if (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;
+    }
+
+    # Note - this is for back compatibility. Catalyst should not know
+    #        or care about how it's deployed. The recommended way of
+    #        configuring this is now to use the ReverseProxy middleware
+    #        yourself if you want it in a .psgi file.
+    return Plack::Middleware::Conditional->wrap(
+        $app->raw_psgi_app,
+        builder   => sub { Plack::Middleware::ReverseProxy->wrap($_[0]) },
+        condition => sub {
+            my ($env) = @_;
+            return if $app->config->{ignore_frontend_proxy};
+            return $env->{REMOTE_ADDR} eq '127.0.0.1'
+                || $app->config->{using_frontend_proxy};
+        },
+    );
+}
+
+=head2 $c->raw_psgi_app
+
+Returns a PSGI application code reference for the catalyst application
+C<$c>. This is the bare application without any middlewares
+applied. C<${myapp}.psgi> is not taken into account. See
+L</"$c->setup_psgi_app">.
+
+=cut
+
+sub raw_psgi_app {
+    my ($app) = @_;
+    return $app->engine->build_psgi_app($app);
 }
 
 =head2 $c->setup_home