X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst.pm;h=5b2472aa2228d24c66aafaffb6489aa5eac56e34;hb=645c3f0b7ac9db50149e7a220e784ecf8cfaae69;hp=9ac29efee55d98632df50e762e11dc53d2e103b1;hpb=551068cfd29b252658de18655ac4bc193ccd5b56;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 9ac29ef..5b2472a 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -41,7 +41,6 @@ use Plack::Middleware::IIS6ScriptNameFix; use Plack::Middleware::IIS7KeepAliveFix; use Plack::Middleware::LighttpdScriptNameFix; use Plack::Util; -use Class::Load; BEGIN { require 5.008003; } @@ -106,7 +105,7 @@ our $GO = Catalyst::Exception::Go->new; __PACKAGE__->mk_classdata($_) for qw/components arguments dispatcher engine log dispatcher_class engine_loader context_class request_class response_class stats_class - setup_finished _psgi_app loading_psgi_file run_options/; + setup_finished _psgi_app loading_psgi_file run_options _psgi_middleware/; __PACKAGE__->dispatcher_class('Catalyst::Dispatcher'); __PACKAGE__->request_class('Catalyst::Request'); @@ -115,7 +114,7 @@ __PACKAGE__->stats_class('Catalyst::Stats'); # Remember to update this in Catalyst::Runtime as well! -our $VERSION = '5.90042'; +our $VERSION = '5.90049_001'; sub import { my ( $class, @arguments ) = @_; @@ -1110,6 +1109,7 @@ sub setup { $class->setup_log( delete $flags->{log} ); $class->setup_plugins( delete $flags->{plugins} ); + $class->setup_middleware(); $class->setup_dispatcher( delete $flags->{dispatcher} ); if (my $engine = delete $flags->{engine}) { $class->log->warn("Specifying the engine in ->setup is no longer supported, see Catalyst::Upgrading"); @@ -1151,6 +1151,16 @@ EOF $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" ); } + my @middleware = map { ref $_ eq 'CODE' ? "Inline Coderef" : (ref($_) .' '. $_->VERSION || '') } + $class->registered_middlewares; + + if (@middleware) { + my $column_width = Catalyst::Utils::term_width() - 6; + my $t = Text::SimpleTable->new($column_width); + $t->row($_) for @middleware; + $class->log->debug( "Loaded PSGI Middleware:\n" . $t->draw . "\n" ); + } + my $dispatcher = $class->dispatcher; my $engine = $class->engine; my $home = $class->config->{home}; @@ -2860,7 +2870,8 @@ reference of your Catalyst application for use in F<.psgi> files. sub psgi_app { my ($app) = @_; - return $app->engine->build_psgi_app($app); + my $psgi = $app->engine->build_psgi_app($app); + return $app->Catalyst::Utils::apply_registered_middleware($psgi); } =head2 $c->setup_home @@ -3044,25 +3055,23 @@ the plugin name does not begin with C. $class => @roles ) if @roles; } -} +} -has '_registered_middlewares' => ( - traits => ['Array'], - is => 'bare', - isa => 'ArrayRef[Object|CodeRef]', - default => sub { [] }, - handles => { - registered_middlewares => 'elements', - _register_middleware => 'push', - }); - +=head2 registered_middlewares + +Read only accessor that returns an array of all the middleware in the order +that they were added (which is the REVERSE of the order they will be applied). -=head2 setup_middleware +The values returned will be either instances of L or of a +compatible interface, or a coderef, which is assumed to be inlined middleware + +=head2 setup_middleware (?@middleware) -Read configuration information stored in configuration key 'psgi_middleware' -and invoke L for each middleware prototype found. See -under L information regarding L and how to -use it to enable L +Read configuration information stored in configuration key C or +from passed @args. + +See under L information regarding C and how +to use it to enable L This method is automatically called during 'setup' of your application, so you really don't need to invoke it. @@ -3072,107 +3081,43 @@ which sounds odd but is likely how you expect it to work if you have prior experience with L or if you previously used the plugin L (which is now considered deprecated) -=head2 register_middleware (@args) - -Given @args that represent the definition of some L or -middleware with a compatible interface, register it with your L -application. - -This is called by L. the behaior of invoking it yourself -at runtime is currently undefined, and anything that works or doesn't work -as a result of doing so is considered a side effect subject to change. - -=head2 _register_middleware (@args) - -Internal details of how registered middleware is stored by the application. - -=head2 _build_middleware_from_args (@args) - -Internal application that converts a single middleware definition (see -L) into an actual instance of middleware. - -=head2 registered_middlewares - -Read only accessor that returns an array of all the middleware in the order -that they were added (which is the REVERSE of the order they will be applied). - -The values returned will be either instances of L or of a -compatible interface, or a coderef, which is assumed to be inlined middleware - -=head2 apply_registered_middleware ($psgi) - -Given a $psgi reference, wrap all the L around it and -return the wrapped version. - =cut +sub registered_middlewares { + my $class = shift; + if(my $middleware = $class->_psgi_middleware) { + return @$middleware; + } else { + die "You cannot call ->registered_middlewares until middleware has been setup"; + } +} + sub setup_middleware { - my ($self) = @_; - my @middleware_definitions = reverse - @{$self->config->{'psgi_middleware'}||[]}; + my ($class, @middleware_definitions) = @_; + push @middleware_definitions, reverse( + @{$class->config->{'psgi_middleware'}||[]}); + my @middleware = (); while(my $next = shift(@middleware_definitions)) { if(ref $next) { if(Scalar::Util::blessed $next && $next->can('wrap')) { - $self->register_middleware($next); + push @middleware, $next; } elsif(ref $next eq 'CODE') { - $self->register_middleware($next); + push @middleware, $next; } elsif(ref $next eq 'HASH') { my $namespace = shift @middleware_definitions; - $self->register_middleware($namespace, %$next); + my $mw = $class->Catalyst::Utils::build_middleware($namespace, %$next); + push @middleware, $mw; } else { - $self->register_middleware($next); - } - } - } -} - -sub register_middleware { - my($self, @args) = @_; - my $middleware = $self->_build_middleware_from_args(@args); - $self->_register_middleware($middleware); - return $middleware; -} - -sub _build_middleware_from_args { - my ($self, $proto, @args) = @_; - - if(ref $proto) { ## Either an object or coderef - if(Scalar::Util::blessed $proto && $proto->can('wrap')) { ## Its already an instance of middleware - return $proto; - } elsif(ref $proto eq 'CODE') { ## Its inlined coderef - return $proto; - } - } else { ## We assume its a string aiming to load Plack Middleware - my $class = ref($self) || $self; - if( - $proto =~s/^\+// || - $proto =~/^Plack::Middleware/ || - $proto =~/^$class/ - ) { ## the string is a full namespace - require "$proto"; - return $proto->new(@args); - } else { ## the string is a partial namespace - if(Class::Load::try_load_class("Plack::Middleware::$proto")) { ## Act like Plack::Builder - return "Plack::Middleware::$proto"->new(@args); - } elsif(Class::Load::try_load_class("$class::$proto")) { ## Load Middleware from Project namespace - return "$class::$proto"->new(@args); + die "I can't handle middleware definition ${\ref $next}"; } + } else { + my $mw = $class->Catalyst::Utils::build_middleware($next); + push @middleware, $mw; } } - die "I don't know how to build $proto into valid Plack Middleware"; -} - -sub apply_registered_middleware { - my ($self, $psgi) = @_; - my $new_psgi = $psgi; - foreach my $middleware ($self->registered_middlewares) { - $new_psgi = Scalar::Util::blessed $middleware ? - $middleware->wrap($new_psgi) : - $middleware->($new_psgi); - } - return $new_psgi; + $class->_psgi_middleware(\@middleware); } =head2 $c->stack @@ -3497,7 +3442,7 @@ So the general form is: Where C<@middleware> is one or more of the following, applied in the REVERSE of the order listed (to make it function similarly to L: -=over4 +=over 4 =item Middleware Object