X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst.pm;h=083c0affaaec73093fe1f3b1b7d51a70b10fc267;hp=dcc8c2b5bc176c72b5d9eabdd63cc3cc5ec395a3;hb=0c6352ff331d7d1c43931d24e1fd8efb21b6d902;hpb=00fa37d0e9385f660b2e013ac41e00d3f13a8122 diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index dcc8c2b..083c0af 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -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,8 @@ use Carp qw/croak carp shortmess/; use Try::Tiny; use Plack::Middleware::Conditional; use Plack::Middleware::ReverseProxy; +use Plack::Middleware::IIS6ScriptNameFix; +use Plack::Middleware::LighttpdScriptNameFix; BEGIN { require 5.008004; } @@ -865,6 +866,9 @@ sub component { return $c->_filter_component( $comp, @args ) if $comp; } + return + if $c->config->{disable_component_resolution_regex_fallback}; + # This is here so $c->comp( '::M::' ) works my $query = ref $name ? $name : qr{$name}i; @@ -1248,7 +1252,7 @@ EOF A hook to attach modifiers to. This method does not do anything except set the C accessor. -Applying method modifiers to the C method doesn't work, because of quirky thingsdone for plugin setup. +Applying method modifiers to the C method doesn't work, because of quirky things done for plugin setup. Example: @@ -1691,8 +1695,8 @@ sub execute { $error = qq/Caught exception in $class->$name "$error"/; } $c->error($error); - $c->state(0); } + $c->state(0); } return $c->state; } @@ -1871,9 +1875,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'); @@ -2409,7 +2413,12 @@ Starts the engine. =cut -sub run { my $c = shift; return $c->engine->run( $c, $c->_finalized_psgi_app, @_ ) } +sub run { + my $app = shift; + $app->engine_loader->needs_psgi_engine_compat_hack ? + $app->engine->run($app, @_) : + $app->engine->run( $app, $app->_finalized_psgi_app, @_ ); +} =head2 $c->set_action( $action, $code, $namespace, $attrs ) @@ -2599,9 +2608,15 @@ sub engine_class { } sub setup_engine { - my ($class) = @_; - - $class->engine_loader(Catalyst::EngineLoader->new(application_name => $class)); + my ($class, $requested_engine) = @_; + + $class->engine_loader( + Catalyst::EngineLoader->new({ + application_name => $class, + (defined $requested_engine + ? (requested_engine => $requested_engine) : ()), + }), + ); my $engine = $class->engine_class; Class::MOP::load_class($engine); @@ -2635,23 +2650,63 @@ 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 + + $app->engine(undef); + $app->setup_engine; + + # ^^ We need to do this because even though we are discarded $psgi_app, the + # fact that it was loaded above means that Catalyst Engine now has the + # wrong value (PSGI), which persists due to the singleton nature of all + # this stuff. This solution is probably a lame hack but did work for all + # the cases we know about. Hopefully we can pull out this crap soon + # Please note that if the fact that the psgi file was loaded started to set + # values in areas outside Engine this hack will probably fail. + + 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); + return $app->apply_default_middlewares($app->psgi_app); } -# 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. -sub _wrapped_legacy_psgi_app { +=head2 $c->apply_default_middlewares + +Adds the following L middlewares to your application, since they are +useful and commonly needed: + +L, (conditionally added based on the status +of your $ENV{REMOTE_ADDR}, and can be forced on with C +or forced off with C), L +(if you are using Lighttpd), L (always +applied since this middleware is smart enough to conditionally apply itself). + +Additionally if we detect we are using Nginx, we add a bit of custom middleware +to solve some problems with the way that server handles $ENV{PATH_INFO} and +$ENV{SCRIPT_NAME} + +=cut + + +sub apply_default_middlewares { my ($app, $psgi_app) = @_; $psgi_app = Plack::Middleware::Conditional->wrap( @@ -2677,23 +2732,7 @@ sub _wrapped_legacy_psgi_app { # 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 - # - # Note that this has probably the same effect as - # Plack::Middleware::LighttpdScriptNameFix and we should switch to that if - # we can. - $psgi_app = Plack::Middleware::Conditional->wrap( - $psgi_app, - condition => $server_matches->(qr/lighttpd/), - builder => sub { - my ($to_wrap) = @_; - return sub { - my ($env) = @_; - $env->{PATH_INFO} ||= delete $env->{SCRIPT_NAME}; - return $to_wrap->($env); - }; - }, - ); + $psgi_app = Plack::Middleware::LighttpdScriptNameFix->wrap($psgi_app); $psgi_app = Plack::Middleware::Conditional->wrap( $psgi_app, @@ -2709,32 +2748,10 @@ sub _wrapped_legacy_psgi_app { }, ); - $psgi_app = Plack::Middleware::Conditional->wrap( - $psgi_app, - condition => $server_matches->(qr/IIS\/[6-9]\.[0-9]/), - builder => sub { - my ($to_wrap) = @_; - return sub { - my ($env) = @_; - - my @script_name = split(m!/!, $env->{PATH_INFO}); - my @path_translated = split(m!/|\\\\?!, $env->{PATH_TRANSLATED}); - my @path_info; - - while ($script_name[$#script_name] eq $path_translated[$#path_translated]) { - pop(@path_translated); - unshift(@path_info, pop(@script_name)); - } - - unshift(@path_info, '', ''); - - $env->{PATH_INFO} = join('/', @path_info); - $env->{SCRIPT_NAME} = join('/', @script_name); - - 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; } @@ -2872,7 +2889,7 @@ the plugin name does not begin with C. my $class = ref $proto || $proto; Class::MOP::load_class( $plugin ); - $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is decated and will not work in 5.81" ) + $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is deprecated and will not work in 5.81" ) if $plugin->isa( 'Catalyst::Component' ); $proto->_plugins->{$plugin} = 1; unless ($instant) { @@ -3296,6 +3313,10 @@ rainboxx: Matthias Dietrich, C dd070: Dhaval Dhanani +=head1 COPYRIGHT + +Copyright (c) 2005, the above named PROJECT FOUNDER and CONTRIBUTORS. + =head1 LICENSE This library is free software. You can redistribute it and/or modify it under