4 use Moose::Meta::Class ();
5 extends 'Catalyst::Component';
6 use Moose::Util qw/find_meta/;
7 use B::Hooks::EndOfScope ();
8 use Catalyst::Exception;
9 use Catalyst::Exception::Detach;
10 use Catalyst::Exception::Go;
12 use Catalyst::Request;
13 use Catalyst::Request::Upload;
14 use Catalyst::Response;
16 use Catalyst::Controller;
19 use Module::Pluggable::Object ();
20 use Text::SimpleTable ();
21 use Path::Class::Dir ();
22 use Path::Class::File ();
26 use Tree::Simple qw/use_weak_refs/;
27 use Tree::Simple::Visitor::FindByUID;
28 use Class::C3::Adopt::NEXT;
29 use List::MoreUtils qw/uniq/;
32 use Carp qw/croak carp shortmess/;
34 BEGIN { require 5.008004; }
36 has stack => (is => 'ro', default => sub { [] });
37 has stash => (is => 'rw', default => sub { {} });
38 has state => (is => 'rw', default => 0);
39 has stats => (is => 'rw');
40 has action => (is => 'rw');
41 has counter => (is => 'rw', default => sub { {} });
42 has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
43 has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
44 has namespace => (is => 'rw');
46 sub depth { scalar @{ shift->stack || [] }; }
47 sub comp { shift->component(@_) }
50 my $self = shift; return $self->request(@_);
53 my $self = shift; return $self->response(@_);
56 # For backwards compatibility
57 sub finalize_output { shift->finalize_body(@_) };
62 our $RECURSION = 1000;
63 our $DETACH = Catalyst::Exception::Detach->new;
64 our $GO = Catalyst::Exception::Go->new;
66 #I imagine that very few of these really need to be class variables. if any.
67 #maybe we should just make them attributes with a default?
68 __PACKAGE__->mk_classdata($_)
69 for qw/container arguments dispatcher engine log dispatcher_class
70 engine_class context_class request_class response_class stats_class
73 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
74 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
75 __PACKAGE__->request_class('Catalyst::Request');
76 __PACKAGE__->response_class('Catalyst::Response');
77 __PACKAGE__->stats_class('Catalyst::Stats');
79 # Remember to update this in Catalyst::Runtime as well!
81 our $VERSION = '5.80033';
84 my ( $class, @arguments ) = @_;
86 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
88 return unless $class eq 'Catalyst';
90 my $caller = caller();
91 return if $caller eq 'main';
93 my $meta = Moose::Meta::Class->initialize($caller);
95 unless ( $caller->isa('Catalyst') ) { # XXX - Remove!
96 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Component'); # XXX - Remove!
97 $meta->superclasses(@superclasses); # XXX - Remove!
100 # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
101 $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
103 unless( $meta->has_method('meta') ){
104 if ($Moose::VERSION >= 1.15) {
105 $meta->_add_meta_method('meta');
108 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
112 $caller->arguments( [@arguments] );
116 sub MODIFY_CODE_ATTRIBUTES {
117 Catalyst::Exception->throw(
118 "Catalyst applications (aka MyApp) cannot be controllers anymore. " .
119 "That has been deprecated and removed. You should create a " .
120 "controller class called Root.pm, and move relevant code to that class."
125 sub _application { $_[0] }
129 Catalyst - The Elegant MVC Web Application Framework
133 See the L<Catalyst::Manual> distribution for comprehensive
134 documentation and tutorials.
136 # Install Catalyst::Devel for helpers and other development tools
137 # use the helper to create a new application
140 # add models, views, controllers
141 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
142 script/myapp_create.pl view MyTemplate TT
143 script/myapp_create.pl controller Search
145 # built in testserver -- use -r to restart automatically on changes
146 # --help to see all available options
147 script/myapp_server.pl
149 # command line testing interface
150 script/myapp_test.pl /yada
153 use Catalyst qw/-Debug/; # include plugins here as well
155 ### In lib/MyApp/Controller/Root.pm (autocreated)
156 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
157 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
158 $c->stash->{template} = 'foo.tt'; # set the template
159 # lookup something from db -- stash vars are passed to TT
161 $c->model('Database::Foo')->search( { country => $args[0] } );
162 if ( $c->req->params->{bar} ) { # access GET or POST parameters
163 $c->forward( 'bar' ); # process another action
164 # do something else after forward returns
168 # The foo.tt TT template can use the stash data from the database
169 [% WHILE (item = data.next) %]
173 # called for /bar/of/soap, /bar/of/soap/10, etc.
174 sub bar : Path('/bar/of/soap') { ... }
176 # called for all actions, from the top-most controller downwards
178 my ( $self, $c ) = @_;
179 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
180 $c->res->redirect( '/login' ); # require login
181 return 0; # abort request and go immediately to end()
183 return 1; # success; carry on to next action
186 # called after all actions are finished
188 my ( $self, $c ) = @_;
189 if ( scalar @{ $c->error } ) { ... } # handle errors
190 return if $c->res->body; # already have a response
191 $c->forward( 'MyApp::View::TT' ); # render template
194 ### in MyApp/Controller/Foo.pm
195 # called for /foo/bar
196 sub bar : Local { ... }
198 # called for /blargle
199 sub blargle : Global { ... }
201 # an index action matches /foo, but not /foo/1, etc.
202 sub index : Private { ... }
204 ### in MyApp/Controller/Foo/Bar.pm
205 # called for /foo/bar/baz
206 sub baz : Local { ... }
208 # first Root auto is called, then Foo auto, then this
209 sub auto : Private { ... }
211 # powerful regular expression paths are also possible
212 sub details : Regex('^product/(\w+)/details$') {
213 my ( $self, $c ) = @_;
214 # extract the (\w+) from the URI
215 my $product = $c->req->captures->[0];
218 See L<Catalyst::Manual::Intro> for additional information.
222 Catalyst is a modern framework for making web applications without the
223 pain usually associated with this process. This document is a reference
224 to the main Catalyst application. If you are a new user, we suggest you
225 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
227 See L<Catalyst::Manual> for more documentation.
229 Catalyst plugins can be loaded by naming them as arguments to the "use
230 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
231 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
234 use Catalyst qw/My::Module/;
236 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
237 fully qualify the name by using a unary plus:
241 +Fully::Qualified::Plugin::Name
244 Special flags like C<-Debug> and C<-Engine> can also be specified as
245 arguments when Catalyst is loaded:
247 use Catalyst qw/-Debug My::Module/;
249 The position of plugins and flags in the chain is important, because
250 they are loaded in the order in which they appear.
252 The following flags are supported:
256 Enables debug output. You can also force this setting from the system
257 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
258 settings override the application, with <MYAPP>_DEBUG having the highest
261 This sets the log level to 'debug' and enables full debug output on the
262 error screen. If you only want the latter, see L<< $c->debug >>.
266 Forces Catalyst to use a specific engine. Omit the
267 C<Catalyst::Engine::> prefix of the engine name, i.e.:
269 use Catalyst qw/-Engine=CGI/;
273 Forces Catalyst to use a specific home directory, e.g.:
275 use Catalyst qw[-Home=/usr/mst];
277 This can also be done in the shell environment by setting either the
278 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
279 is replaced with the uppercased name of your application, any "::" in
280 the name will be replaced with underscores, e.g. MyApp::Web should use
281 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
283 If none of these are set, Catalyst will attempt to automatically detect the
284 home directory. If you are working in a development envirnoment, Catalyst
285 will try and find the directory containing either Makefile.PL, Build.PL or
286 dist.ini. If the application has been installed into the system (i.e.
287 you have done C<make install>), then Catalyst will use the path to your
288 application module, without the .pm extension (ie, /foo/MyApp if your
289 application was installed at /foo/MyApp.pm)
293 use Catalyst '-Log=warn,fatal,error';
295 Specifies a comma-delimited list of log levels.
299 Enables statistics collection and reporting.
301 use Catalyst qw/-Stats=1/;
303 You can also force this setting from the system environment with CATALYST_STATS
304 or <MYAPP>_STATS. The environment settings override the application, with
305 <MYAPP>_STATS having the highest priority.
307 Stats are also enabled if L<< debugging |/"-Debug" >> is enabled.
311 =head2 INFORMATION ABOUT THE CURRENT REQUEST
315 Returns a L<Catalyst::Action> object for the current action, which
316 stringifies to the action name. See L<Catalyst::Action>.
320 Returns the namespace of the current action, i.e., the URI prefix
321 corresponding to the controller of the current action. For example:
323 # in Controller::Foo::Bar
324 $c->namespace; # returns 'foo/bar';
330 Returns the current L<Catalyst::Request> object, giving access to
331 information about the current client request (including parameters,
332 cookies, HTTP headers, etc.). See L<Catalyst::Request>.
334 =head2 REQUEST FLOW HANDLING
336 =head2 $c->forward( $action [, \@arguments ] )
338 =head2 $c->forward( $class, $method, [, \@arguments ] )
340 Forwards processing to another action, by its private name. If you give a
341 class name but no method, C<process()> is called. You may also optionally
342 pass arguments in an arrayref. The action will receive the arguments in
343 C<@_> and C<< $c->req->args >>. Upon returning from the function,
344 C<< $c->req->args >> will be restored to the previous values.
346 Any data C<return>ed from the action forwarded to, will be returned by the
349 my $foodata = $c->forward('/foo');
350 $c->forward('index');
351 $c->forward(qw/Model::DBIC::Foo do_stuff/);
352 $c->forward('View::TT');
354 Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
355 an C<< eval { } >> around the call (actually
356 L<< execute|/"$c->execute( $class, $coderef )" >> does), thus de-fatalizing
357 all 'dies' within the called action. If you want C<die> to propagate you
358 need to do something like:
361 die join "\n", @{ $c->error } if @{ $c->error };
363 Or make sure to always return true values from your actions and write
366 $c->forward('foo') || return;
368 Another note is that C<< $c->forward >> always returns a scalar because it
369 actually returns $c->state which operates in a scalar context.
370 Thus, something like:
374 in an action that is forwarded to is going to return a scalar,
375 i.e. how many items are in that array, which is probably not what you want.
376 If you need to return an array then return a reference to it,
379 $c->stash->{array} = \@array;
381 and access it from the stash.
383 Keep in mind that the C<end> method used is that of the caller action. So a C<$c-E<gt>detach> inside a forwarded action would run the C<end> method from the original action requested.
387 sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
389 =head2 $c->detach( $action [, \@arguments ] )
391 =head2 $c->detach( $class, $method, [, \@arguments ] )
395 The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
396 doesn't return to the previous action when processing is finished.
398 When called with no arguments it escapes the processing chain entirely.
402 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
404 =head2 $c->visit( $action [, \@captures, \@arguments ] )
406 =head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
408 Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
409 but does a full dispatch, instead of just calling the new C<$action> /
410 C<< $class->$method >>. This means that C<begin>, C<auto> and the method
411 you go to are called, just like a new request.
413 In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
414 This means, for example, that C<< $c->action >> methods such as
415 L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
416 L<reverse|Catalyst::Action/reverse> return information for the visited action
417 when they are invoked within the visited action. This is different from the
418 behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which
419 continues to use the $c->action object from the caller action even when
420 invoked from the callee.
422 C<< $c->stash >> is kept unchanged.
424 In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
425 allows you to "wrap" another action, just as it would have been called by
426 dispatching from a URL, while the analogous
427 L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
428 transfer control to another action as if it had been reached directly from a URL.
432 sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
434 =head2 $c->go( $action [, \@captures, \@arguments ] )
436 =head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
438 The relationship between C<go> and
439 L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
440 the relationship between
441 L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and
442 L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>,
443 C<< $c->go >> will perform a full dispatch on the specified action or method,
444 with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>,
445 C<go> escapes the processing of the current request chain on completion, and
446 does not return to its caller.
448 @arguments are arguments to the final destination of $action. @captures are
449 arguments to the intermediate steps, if any, on the way to the final sub of
454 sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
460 Returns the current L<Catalyst::Response> object, see there for details.
464 Returns a hashref to the stash, which may be used to store data and pass
465 it between components during a request. You can also set hash keys by
466 passing arguments. The stash is automatically sent to the view. The
467 stash is cleared at the end of a request; it cannot be used for
468 persistent storage (for this you must use a session; see
469 L<Catalyst::Plugin::Session> for a complete system integrated with
472 $c->stash->{foo} = $bar;
473 $c->stash( { moose => 'majestic', qux => 0 } );
474 $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
476 # stash is automatically passed to the view for use in a template
477 $c->forward( 'MyApp::View::TT' );
481 around stash => sub {
484 my $stash = $orig->($c);
486 my $new_stash = @_ > 1 ? {@_} : $_[0];
487 croak('stash takes a hash or hashref') unless ref $new_stash;
488 foreach my $key ( keys %$new_stash ) {
489 $stash->{$key} = $new_stash->{$key};
499 =head2 $c->error($error, ...)
501 =head2 $c->error($arrayref)
503 Returns an arrayref containing error messages. If Catalyst encounters an
504 error while processing a request, it stores the error in $c->error. This
505 method should only be used to store fatal error messages.
507 my @error = @{ $c->error };
511 $c->error('Something bad happened');
518 my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
519 croak @$error unless ref $c;
520 push @{ $c->{error} }, @$error;
522 elsif ( defined $_[0] ) { $c->{error} = undef }
523 return $c->{error} || [];
529 Contains the return value of the last executed action.
530 Note that << $c->state >> operates in a scalar context which means that all
531 values it returns are scalar.
533 =head2 $c->clear_errors
535 Clear errors. You probably don't want to clear the errors unless you are
536 implementing a custom error screen.
538 This is equivalent to running
549 =head2 COMPONENT ACCESSORS
551 =head2 $c->controller($name)
553 Gets a L<Catalyst::Controller> instance by name.
555 $c->controller('Foo')->do_stuff;
557 If the name is omitted, will return the controller for the dispatched
560 If you want to search for controllers, pass in a regexp as the argument.
562 # find all controllers that start with Foo
563 my @foo_controllers = $c->controller(qr{^Foo});
569 my ( $c, $name, @args ) = @_;
571 $name ||= Catalyst::Utils::class2classshortsuffix( $c->action->class );
573 return $c->container->get_component_from_sub_container( 'controller', $name, $c, @args);
576 =head2 $c->model($name)
578 Gets a L<Catalyst::Model> instance by name.
580 $c->model('Foo')->do_stuff;
582 Any extra arguments are directly passed to ACCEPT_CONTEXT.
584 If the name is omitted, it will look for
585 - a model object in $c->stash->{current_model_instance}, then
586 - a model name in $c->stash->{current_model}, then
587 - a config setting 'default_model', or
588 - check if there is only one model, and return it if that's the case.
590 If you want to search for models, pass in a regexp as the argument.
592 # find all models that start with Foo
593 my @foo_models = $c->model(qr{^Foo});
598 my ( $c, $name, @args ) = @_;
600 if (ref $c && !$name) {
601 return $c->stash->{current_model_instance}
602 if $c->stash->{current_model_instance};
604 $name = $c->stash->{current_model}
605 if $c->stash->{current_model};
608 return $c->container->get_component_from_sub_container( 'model', $name, $c, @args);
612 =head2 $c->view($name)
614 Gets a L<Catalyst::View> instance by name.
616 $c->view('Foo')->do_stuff;
618 Any extra arguments are directly passed to ACCEPT_CONTEXT.
620 If the name is omitted, it will look for
621 - a view object in $c->stash->{current_view_instance}, then
622 - a view name in $c->stash->{current_view}, then
623 - a config setting 'default_view', or
624 - check if there is only one view, and return it if that's the case.
626 If you want to search for views, pass in a regexp as the argument.
628 # find all views that start with Foo
629 my @foo_views = $c->view(qr{^Foo});
634 my ( $c, $name, @args ) = @_;
636 if (ref $c && !$name) {
637 return $c->stash->{current_view_instance}
638 if $c->stash->{current_view_instance};
640 $name = $c->stash->{current_view}
641 if $c->stash->{current_view};
644 return $c->container->get_component_from_sub_container( 'view', $name, $c, @args);
647 =head2 $c->controllers
649 Returns the available names which can be passed to $c->controller
655 return $c->container->get_sub_container('controller')->get_service_list;
660 Returns the available names which can be passed to $c->model
666 return $c->container->get_sub_container('model')->get_service_list;
672 Returns the available names which can be passed to $c->view
678 return $c->container->get_sub_container('view')->get_service_list;
681 =head2 $c->comp($name)
683 =head2 $c->component($name)
685 Gets a component object by name. This method is not recommended,
686 unless you want to get a specific component by full
687 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
688 should be used instead.
690 If C<$name> is a regexp, a list of components matched against the full
691 component name will be returned.
696 my ( $c, $component, @args ) = @_;
698 unless ($component) {
699 $c->log->warn('Calling $c->component with no args is deprecated and ');
700 $c->log->warn('will be removed in a future release.');
701 $c->log->warn('Use $c->component_list instead.');
702 return $c->component_list;
705 my @result = $c->container->find_component( $component, $c, @args );
707 # list context for regexp searches
708 return @result if ref $component;
710 # only one component (if it's found) for string searches
711 return shift @result if @result;
713 if (ref $c eq $component) {
714 $c->log->warn('You are calling $c->comp("MyApp"). This behaviour is');
715 $c->log->warn('deprecated, and will be removed in a future release.');
719 $c->log->warn("Looking for '$component', but nothing was found.");
721 # I would expect to return an empty list here, but that breaks back-compat
722 $c->log->warn('Component not found, returning the list of existing');
723 $c->log->warn('components. This behavior is deprecated and will be');
724 $c->log->warn('removed in a future release. Use $c->component_list');
725 $c->log->warn('instead.');
727 return $c->component_list;
730 =head2 $c->component_list
732 Returns the sorted list of the component names of the application.
736 sub component_list { sort keys %{ shift->components } }
738 =head2 CLASS DATA AND HELPER CLASSES
742 Returns or takes a hashref containing the application's configuration.
744 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
746 You can also use a C<YAML>, C<XML> or L<Config::General> config file
747 like C<myapp.conf> in your applications home directory. See
748 L<Catalyst::Plugin::ConfigLoader>.
750 =head3 Cascading configuration
752 The config method is present on all Catalyst components, and configuration
753 will be merged when an application is started. Configuration loaded with
754 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
755 followed by configuration in your top level C<MyApp> class. These two
756 configurations are merged, and then configuration data whose hash key matches a
757 component name is merged with configuration for that component.
759 The configuration for a component is then passed to the C<new> method when a
760 component is constructed.
764 MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
765 MyApp::Model::Foo->config({ quux => 'frob', overrides => 'this' });
767 will mean that C<MyApp::Model::Foo> receives the following data when
770 MyApp::Model::Foo->new({
776 It's common practice to use a Moose attribute
777 on the receiving component to access the config value.
779 package MyApp::Model::Foo;
783 # this attr will receive 'baz' at construction time
789 You can then get the value 'baz' by calling $c->model('Foo')->bar
790 (or $self->bar inside code in the model).
792 B<NOTE:> you MUST NOT call C<< $self->config >> or C<< __PACKAGE__->config >>
793 as a way of reading config within your code, as this B<will not> give you the
794 correctly merged config back. You B<MUST> take the config values supplied to
795 the constructor and use those instead.
799 around config => sub {
803 croak('Setting config after setup has been run is not allowed.')
804 if ( @_ and $c->setup_finished );
811 Returns the logging object instance. Unless it is already set, Catalyst
812 sets this up with a L<Catalyst::Log> object. To use your own log class,
813 set the logger with the C<< __PACKAGE__->log >> method prior to calling
814 C<< __PACKAGE__->setup >>.
816 __PACKAGE__->log( MyLogger->new );
821 $c->log->info( 'Now logging with my own logger!' );
823 Your log class should implement the methods described in
829 Returns 1 if debug mode is enabled, 0 otherwise.
831 You can enable debug mode in several ways:
835 =item By calling myapp_server.pl with the -d flag
837 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
839 =item The -Debug option in your MyApp.pm
841 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
845 The first three also set the log level to 'debug'.
847 Calling C<< $c->debug(1) >> has no effect.
853 =head2 $c->dispatcher
855 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
859 Returns the engine instance. See L<Catalyst::Engine>.
862 =head2 UTILITY METHODS
864 =head2 $c->path_to(@path)
866 Merges C<@path> with C<< $c->config->{home} >> and returns a
867 L<Path::Class::Dir> object. Note you can usually use this object as
868 a filename, but sometimes you will have to explicitly stringify it
869 yourself by calling the C<< ->stringify >> method.
873 $c->path_to( 'db', 'sqlite.db' );
878 my ( $c, @path ) = @_;
879 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
880 if ( -d $path ) { return $path }
881 else { return Path::Class::File->new( $c->config->{home}, @path ) }
884 =head2 $c->plugin( $name, $class, @args )
886 Helper method for plugins. It creates a class data accessor/mutator and
887 loads and instantiates the given class.
889 MyApp->plugin( 'prototype', 'HTML::Prototype' );
891 $c->prototype->define_javascript_functions;
893 B<Note:> This method of adding plugins is deprecated. The ability
894 to add plugins like this B<will be removed> in a Catalyst 5.81.
895 Please do not use this functionality in new code.
900 my ( $class, $name, $plugin, @args ) = @_;
902 # See block comment in t/aggregate/unit_core_plugin.t
903 $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
905 $class->_register_plugin( $plugin, 1 );
907 eval { $plugin->import };
908 $class->mk_classdata($name);
910 eval { $obj = $plugin->new(@args) };
913 Catalyst::Exception->throw( message =>
914 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
918 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
924 Initializes the dispatcher and engine, loads any plugins, and loads the
925 model, view, and controller components. You may also specify an array
926 of plugins to load here, if you choose to not load them in the C<use
930 MyApp->setup( qw/-Debug/ );
935 my ( $class, @arguments ) = @_;
936 croak('Running setup more than once')
937 if ( $class->setup_finished );
939 unless ( $class->isa('Catalyst') ) {
941 Catalyst::Exception->throw(
942 message => qq/'$class' does not inherit from Catalyst/ );
945 if ( $class->arguments ) {
946 @arguments = ( @arguments, @{ $class->arguments } );
952 foreach (@arguments) {
956 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
958 elsif (/^-(\w+)=?(.*)$/) {
959 $flags->{ lc $1 } = $2;
962 push @{ $flags->{plugins} }, $_;
966 $class->setup_config();
967 $class->setup_home( delete $flags->{home} );
969 $class->setup_log( delete $flags->{log} );
970 $class->setup_plugins( delete $flags->{plugins} );
971 $class->setup_dispatcher( delete $flags->{dispatcher} );
972 $class->setup_engine( delete $flags->{engine} );
973 $class->setup_stats( delete $flags->{stats} );
975 for my $flag ( sort keys %{$flags} ) {
977 if ( my $code = $class->can( 'setup_' . $flag ) ) {
978 &$code( $class, delete $flags->{$flag} );
981 $class->log->warn(qq/Unknown flag "$flag"/);
985 eval { require Catalyst::Devel; };
986 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
987 $class->log->warn(<<"EOF");
988 You are running an old script!
990 Please update by running (this will overwrite existing files):
991 catalyst.pl -force -scripts $class
993 or (this will not overwrite existing files):
994 catalyst.pl -scripts $class
999 if ( $class->debug ) {
1000 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
1003 my $column_width = Catalyst::Utils::term_width() - 6;
1004 my $t = Text::SimpleTable->new($column_width);
1005 $t->row($_) for @plugins;
1006 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
1009 my $dispatcher = $class->dispatcher;
1010 my $engine = $class->engine;
1011 my $home = $class->config->{home};
1013 $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
1014 $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
1018 ? $class->log->debug(qq/Found home "$home"/)
1019 : $class->log->debug(qq/Home "$home" doesn't exist/)
1020 : $class->log->debug(q/Couldn't find home/);
1023 # Call plugins setup, this is stupid and evil.
1024 # Also screws C3 badly on 5.10, hack to avoid.
1026 no warnings qw/redefine/;
1027 local *setup = sub { };
1028 $class->setup unless $Catalyst::__AM_RESTARTING;
1031 $class->setup_components;
1035 my @comps_types = $class->container->get_components_types
1037 my $column_width = Catalyst::Utils::term_width() - 8 - 9;
1038 my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
1039 $t->row( @$_ ) for @comps_types;
1041 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" );
1044 $class->setup_actions;
1046 if ( $class->debug ) {
1047 my $name = $class->config->{name} || 'Application';
1048 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
1051 # Make sure that the application class becomes immutable at this point,
1052 B::Hooks::EndOfScope::on_scope_end {
1054 my $meta = Class::MOP::get_metaclass_by_name($class);
1057 && ! { $meta->immutable_options }->{replace_constructor}
1059 $class->isa('Class::Accessor::Fast')
1060 || $class->isa('Class::Accessor')
1063 warn "You made your application class ($class) immutable, "
1064 . "but did not inline the\nconstructor. "
1065 . "This will break catalyst, as your app \@ISA "
1066 . "Class::Accessor(::Fast)?\nPlease pass "
1067 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
1069 $meta->make_immutable(
1070 replace_constructor => 1,
1071 ) unless $meta->is_immutable;
1074 if ($class->config->{case_sensitive}) {
1075 $class->log->warn($class . "->config->{case_sensitive} is set.");
1076 $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81.");
1079 $class->setup_finalize;
1080 # Should be the last thing we do so that user things hooking
1081 # setup_finalize can log..
1082 $class->log->_flush() if $class->log->can('_flush');
1083 return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
1086 =head2 $app->setup_finalize
1088 A hook to attach modifiers to. This method does not do anything except set the
1089 C<setup_finished> accessor.
1091 Applying method modifiers to the C<setup> method doesn't work, because of quirky things done for plugin setup.
1095 after setup_finalize => sub {
1103 sub setup_finalize {
1105 $class->setup_finished(1);
1108 =head2 $c->uri_for( $path?, @args?, \%query_values? )
1110 =head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
1112 Constructs an absolute L<URI> object based on the application root, the
1113 provided path, and the additional arguments and query parameters provided.
1114 When used as a string, provides a textual URI. If you need more flexibility
1115 than this (i.e. the option to provide relative URIs etc.) see
1116 L<Catalyst::Plugin::SmartURI>.
1118 If no arguments are provided, the URI for the current action is returned.
1119 To return the current action and also provide @args, use
1120 C<< $c->uri_for( $c->action, @args ) >>.
1122 If the first argument is a string, it is taken as a public URI path relative
1123 to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
1124 relative to the application root (if it does). It is then merged with
1125 C<< $c->request->base >>; any C<@args> are appended as additional path
1126 components; and any C<%query_values> are appended as C<?foo=bar> parameters.
1128 If the first argument is a L<Catalyst::Action> it represents an action which
1129 will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
1130 optional C<\@captures> argument (an arrayref) allows passing the captured
1131 variables that are needed to fill in the paths of Chained and Regex actions;
1132 once the path is resolved, C<uri_for> continues as though a path was
1133 provided, appending any arguments or parameters and creating an absolute
1136 The captures for the current request can be found in
1137 C<< $c->request->captures >>, and actions can be resolved using
1138 C<< Catalyst::Controller->action_for($name) >>. If you have a private action
1139 path, use C<< $c->uri_for_action >> instead.
1141 # Equivalent to $c->req->uri
1142 $c->uri_for($c->action, $c->req->captures,
1143 @{ $c->req->args }, $c->req->params);
1145 # For the Foo action in the Bar controller
1146 $c->uri_for($c->controller('Bar')->action_for('Foo'));
1148 # Path to a static resource
1149 $c->uri_for('/static/images/logo.png');
1154 my ( $c, $path, @args ) = @_;
1156 if (blessed($path) && $path->isa('Catalyst::Controller')) {
1157 $path = $path->path_prefix;
1162 undef($path) if (defined $path && $path eq '');
1165 ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
1167 carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
1168 foreach my $arg (@args) {
1169 utf8::encode($arg) if utf8::is_utf8($arg);
1170 $arg =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1173 if ( blessed($path) ) { # action object
1174 s|/|%2F|g for @args;
1175 my $captures = [ map { s|/|%2F|g; $_; }
1176 ( scalar @args && ref $args[0] eq 'ARRAY'
1180 foreach my $capture (@$captures) {
1181 utf8::encode($capture) if utf8::is_utf8($capture);
1182 $capture =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1186 $path = $c->dispatcher->uri_for_action($action, $captures);
1187 if (not defined $path) {
1188 $c->log->debug(qq/Can't find uri_for action '$action' @$captures/)
1192 $path = '/' if $path eq '';
1195 unshift(@args, $path);
1197 unless (defined $path && $path =~ s!^/!!) { # in-place strip
1198 my $namespace = $c->namespace;
1199 if (defined $path) { # cheesy hack to handle path '../foo'
1200 $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
1202 unshift(@args, $namespace || '');
1205 # join args with '/', or a blank string
1206 my $args = join('/', grep { defined($_) } @args);
1207 $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
1209 my $base = $c->req->base;
1210 my $class = ref($base);
1211 $base =~ s{(?<!/)$}{/};
1215 if (my @keys = keys %$params) {
1216 # somewhat lifted from URI::_query's query_form
1217 $query = '?'.join('&', map {
1218 my $val = $params->{$_};
1219 s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1222 $val = '' unless defined $val;
1225 utf8::encode( $param ) if utf8::is_utf8($param);
1226 # using the URI::Escape pattern here so utf8 chars survive
1227 $param =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1229 "${key}=$param"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1233 my $res = bless(\"${base}${args}${query}", $class);
1237 =head2 $c->uri_for_action( $path, \@captures?, @args?, \%query_values? )
1239 =head2 $c->uri_for_action( $action, \@captures?, @args?, \%query_values? )
1245 A private path to the Catalyst action you want to create a URI for.
1247 This is a shortcut for calling C<< $c->dispatcher->get_action_by_path($path)
1248 >> and passing the resulting C<$action> and the remaining arguments to C<<
1251 You can also pass in a Catalyst::Action object, in which case it is passed to
1254 Note that although the path looks like a URI that dispatches to the wanted action, it is not a URI, but an internal path to that action.
1256 For example, if the action looks like:
1258 package MyApp::Controller::Users;
1260 sub lst : Path('the-list') {}
1264 $c->uri_for_action('/users/lst')
1266 and it will create the URI /users/the-list.
1272 sub uri_for_action {
1273 my ( $c, $path, @args ) = @_;
1274 my $action = blessed($path)
1276 : $c->dispatcher->get_action_by_path($path);
1277 unless (defined $action) {
1278 croak "Can't find action for path '$path'";
1280 return $c->uri_for( $action, @args );
1283 =head2 $c->welcome_message
1285 Returns the Catalyst welcome HTML page.
1289 sub welcome_message {
1291 my $name = $c->config->{name};
1292 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
1293 my $prefix = Catalyst::Utils::appprefix( ref $c );
1294 $c->response->content_type('text/html; charset=utf-8');
1296 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1297 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1298 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1300 <meta http-equiv="Content-Language" content="en" />
1301 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1302 <title>$name on Catalyst $VERSION</title>
1303 <style type="text/css">
1306 background-color: #eee;
1313 margin-bottom: 10px;
1315 background-color: #ccc;
1316 border: 1px solid #aaa;
1321 font-family: verdana, tahoma, sans-serif;
1324 font-family: verdana, tahoma, sans-serif;
1327 text-decoration: none;
1329 border-bottom: 1px dotted #bbb;
1331 :link:hover, :visited:hover {
1344 background-color: #fff;
1345 border: 1px solid #aaa;
1349 font-weight: normal;
1371 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1376 <img src="$logo" alt="Catalyst Logo" />
1378 <p>Welcome to the world of Catalyst.
1379 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1380 framework will make web development something you had
1381 never expected it to be: Fun, rewarding, and quick.</p>
1382 <h2>What to do now?</h2>
1383 <p>That really depends on what <b>you</b> want to do.
1384 We do, however, provide you with a few starting points.</p>
1385 <p>If you want to jump right into web development with Catalyst
1386 you might want to start with a tutorial.</p>
1387 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1389 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1391 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1392 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1394 <h2>What to do next?</h2>
1395 <p>Next it's time to write an actual application. Use the
1396 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
1397 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
1398 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
1399 they can save you a lot of work.</p>
1400 <pre><code>script/${prefix}_create.pl --help</code></pre>
1401 <p>Also, be sure to check out the vast and growing
1402 collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
1403 you are likely to find what you need there.
1407 <p>Catalyst has a very active community. Here are the main places to
1408 get in touch with us.</p>
1411 <a href="http://dev.catalyst.perl.org">Wiki</a>
1414 <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
1417 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1420 <h2>In conclusion</h2>
1421 <p>The Catalyst team hopes you will enjoy using Catalyst as much
1422 as we enjoyed making it. Please contact us if you have ideas
1423 for improvement or other feedback.</p>
1431 =head1 INTERNAL METHODS
1433 These methods are not meant to be used by end users.
1435 =head2 $c->components
1437 Returns a hash of components.
1442 my ( $class, $comps ) = @_;
1444 # people create components calling this sub directly, before setup
1445 $class->setup_config unless $class->container;
1447 my $container = $class->container;
1450 $container->add_component(
1455 return $container->get_all_components();
1458 =head2 $c->context_class
1460 Returns or sets the context class.
1464 Returns a hashref containing coderefs and execution counts (needed for
1465 deep recursion detection).
1469 Returns the number of actions on the current internal execution stack.
1473 Dispatches a request to actions.
1477 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1479 =head2 $c->dispatcher_class
1481 Returns or sets the dispatcher class.
1483 =head2 $c->dump_these
1485 Returns a list of 2-element array references (name, structure) pairs
1486 that will be dumped on the error page in debug mode.
1492 [ Request => $c->req ],
1493 [ Response => $c->res ],
1494 [ Stash => $c->stash ],
1495 [ Config => $c->config ];
1498 =head2 $c->engine_class
1500 Returns or sets the engine class.
1502 =head2 $c->execute( $class, $coderef )
1504 Execute a coderef in given class and catch exceptions. Errors are available
1510 my ( $c, $class, $code ) = @_;
1511 $class = $c->component($class) || $class;
1514 if ( $c->depth >= $RECURSION ) {
1515 my $action = $code->reverse();
1516 $action = "/$action" unless $action =~ /->/;
1517 my $error = qq/Deep recursion detected calling "${action}"/;
1518 $c->log->error($error);
1524 my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1526 push( @{ $c->stack }, $code );
1528 no warnings 'recursion';
1529 # N.B. This used to be combined, but I have seen $c get clobbered if so, and
1530 # I have no idea how, ergo $ret (which appears to fix the issue)
1531 eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) };
1533 $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1535 my $last = pop( @{ $c->stack } );
1537 if ( my $error = $@ ) {
1538 if ( blessed($error) and $error->isa('Catalyst::Exception::Detach') ) {
1539 $error->rethrow if $c->depth > 1;
1541 elsif ( blessed($error) and $error->isa('Catalyst::Exception::Go') ) {
1542 $error->rethrow if $c->depth > 0;
1545 unless ( ref $error ) {
1546 no warnings 'uninitialized';
1548 my $class = $last->class;
1549 my $name = $last->name;
1550 $error = qq/Caught exception in $class->$name "$error"/;
1559 sub _stats_start_execute {
1560 my ( $c, $code ) = @_;
1561 my $appclass = ref($c) || $c;
1562 return if ( ( $code->name =~ /^_.*/ )
1563 && ( !$appclass->config->{show_internal_actions} ) );
1565 my $action_name = $code->reverse();
1566 $c->counter->{$action_name}++;
1568 my $action = $action_name;
1569 $action = "/$action" unless $action =~ /->/;
1571 # determine if the call was the result of a forward
1572 # this is done by walking up the call stack and looking for a calling
1573 # sub of Catalyst::forward before the eval
1575 for my $index ( 2 .. 11 ) {
1577 if ( ( caller($index) )[0] eq 'Catalyst'
1578 && ( caller($index) )[3] eq '(eval)' );
1580 if ( ( caller($index) )[3] =~ /forward$/ ) {
1581 $callsub = ( caller($index) )[3];
1582 $action = "-> $action";
1587 my $uid = $action_name . $c->counter->{$action_name};
1589 # is this a root-level call or a forwarded call?
1590 if ( $callsub =~ /forward$/ ) {
1591 my $parent = $c->stack->[-1];
1593 # forward, locate the caller
1594 if ( defined $parent && exists $c->counter->{"$parent"} ) {
1597 parent => "$parent" . $c->counter->{"$parent"},
1603 # forward with no caller may come from a plugin
1622 sub _stats_finish_execute {
1623 my ( $c, $info ) = @_;
1624 $c->stats->profile( end => $info );
1629 Finalizes the request.
1636 for my $error ( @{ $c->error } ) {
1637 $c->log->error($error);
1640 # Allow engine to handle finalize flow (for POE)
1641 my $engine = $c->engine;
1642 if ( my $code = $engine->can('finalize') ) {
1647 $c->finalize_uploads;
1650 if ( $#{ $c->error } >= 0 ) {
1654 $c->finalize_headers;
1657 if ( $c->request->method eq 'HEAD' ) {
1658 $c->response->body('');
1666 if ($c->use_stats) {
1667 my $elapsed = sprintf '%f', $c->stats->elapsed;
1668 my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1670 "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
1673 return $c->response->status;
1676 =head2 $c->finalize_body
1682 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1684 =head2 $c->finalize_cookies
1690 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1692 =head2 $c->finalize_error
1698 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1700 =head2 $c->finalize_headers
1706 sub finalize_headers {
1709 my $response = $c->response; #accessor calls can add up?
1711 # Check if we already finalized headers
1712 return if $response->finalized_headers;
1715 if ( my $location = $response->redirect ) {
1716 $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1717 $response->header( Location => $location );
1719 if ( !$response->has_body ) {
1720 # Add a default body if none is already present
1722 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1728 if ( defined $response->body && length $response->body && !$response->content_length ) {
1730 # get the length from a filehandle
1731 if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' )
1733 my $stat = stat $response->body;
1734 if ( $stat && $stat->size > 0 ) {
1735 $response->content_length( $stat->size );
1738 $c->log->warn('Serving filehandle without a content-length');
1742 # everything should be bytes at this point, but just in case
1743 $response->content_length( length( $response->body ) );
1748 if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1749 $response->headers->remove_header("Content-Length");
1750 $response->body('');
1753 $c->finalize_cookies;
1755 $c->engine->finalize_headers( $c, @_ );
1758 $response->finalized_headers(1);
1761 =head2 $c->finalize_output
1763 An alias for finalize_body.
1765 =head2 $c->finalize_read
1767 Finalizes the input after reading is complete.
1771 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1773 =head2 $c->finalize_uploads
1775 Finalizes uploads. Cleans up any temporary files.
1779 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1781 =head2 $c->get_action( $action, $namespace )
1783 Gets an action in a given namespace.
1787 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1789 =head2 $c->get_actions( $action, $namespace )
1791 Gets all actions of a given name in a namespace and all parent
1796 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1798 =head2 $app->handle_request( @arguments )
1800 Called to handle each HTTP request.
1804 sub handle_request {
1805 my ( $class, @arguments ) = @_;
1807 # Always expect worst case!
1810 if ($class->debug) {
1811 my $secs = time - $START || 1;
1812 my $av = sprintf '%.3f', $COUNT / $secs;
1813 my $time = localtime time;
1814 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1817 my $c = $class->prepare(@arguments);
1819 $status = $c->finalize;
1822 if ( my $error = $@ ) {
1824 $class->log->error(qq/Caught exception in engine "$error"/);
1829 if(my $coderef = $class->log->can('_flush')){
1830 $class->log->$coderef();
1835 =head2 $c->prepare( @arguments )
1837 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1843 my ( $class, @arguments ) = @_;
1846 # After the app/ctxt split, this should become an attribute based on something passed
1847 # into the application.
1848 $class->context_class( ref $class || $class ) unless $class->context_class;
1850 my $c = $class->context_class->new({});
1852 # For on-demand data
1853 $c->request->_context($c);
1854 $c->response->_context($c);
1856 #surely this is not the most efficient way to do things...
1857 $c->stats($class->stats_class->new)->enable($c->use_stats);
1858 if ( $c->debug || $c->config->{enable_catalyst_header} ) {
1859 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1862 #XXX reuse coderef from can
1863 # Allow engine to direct the prepare flow (for POE)
1864 if ( $c->engine->can('prepare') ) {
1865 $c->engine->prepare( $c, @arguments );
1868 $c->prepare_request(@arguments);
1869 $c->prepare_connection;
1870 $c->prepare_query_parameters;
1871 $c->prepare_headers;
1872 $c->prepare_cookies;
1875 # Prepare the body for reading, either by prepare_body
1876 # or the user, if they are using $c->read
1879 # Parse the body unless the user wants it on-demand
1880 unless ( ref($c)->config->{parse_on_demand} ) {
1885 my $method = $c->req->method || '';
1886 my $path = $c->req->path;
1887 $path = '/' unless length $path;
1888 my $address = $c->req->address || '';
1897 =head2 $c->prepare_action
1899 Prepares action. See L<Catalyst::Dispatcher>.
1903 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1905 =head2 $c->prepare_body
1907 Prepares message body.
1914 return if $c->request->_has_body;
1916 # Initialize on-demand data
1917 $c->engine->prepare_body( $c, @_ );
1918 $c->prepare_parameters;
1919 $c->prepare_uploads;
1922 =head2 $c->prepare_body_chunk( $chunk )
1924 Prepares a chunk of data before sending it to L<HTTP::Body>.
1926 See L<Catalyst::Engine>.
1930 sub prepare_body_chunk {
1932 $c->engine->prepare_body_chunk( $c, @_ );
1935 =head2 $c->prepare_body_parameters
1937 Prepares body parameters.
1941 sub prepare_body_parameters {
1943 $c->engine->prepare_body_parameters( $c, @_ );
1946 =head2 $c->prepare_connection
1948 Prepares connection.
1952 sub prepare_connection {
1954 $c->engine->prepare_connection( $c, @_ );
1957 =head2 $c->prepare_cookies
1963 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1965 =head2 $c->prepare_headers
1971 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1973 =head2 $c->prepare_parameters
1975 Prepares parameters.
1979 sub prepare_parameters {
1981 $c->prepare_body_parameters;
1982 $c->engine->prepare_parameters( $c, @_ );
1985 =head2 $c->prepare_path
1987 Prepares path and base.
1991 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1993 =head2 $c->prepare_query_parameters
1995 Prepares query parameters.
1999 sub prepare_query_parameters {
2002 $c->engine->prepare_query_parameters( $c, @_ );
2005 =head2 $c->log_request
2007 Writes information about the request to the debug logs. This includes:
2011 =item * Request method, path, and remote IP address
2013 =item * Query keywords (see L<Catalyst::Request/query_keywords>)
2015 =item * Request parameters
2017 =item * File uploads
2026 return unless $c->debug;
2028 my($dump) = grep {$_->[0] eq 'Request' } $c->dump_these;
2029 my $request = $dump->[1];
2031 my ( $method, $path, $address ) = ( $request->method, $request->path, $request->address );
2033 $path = '/' unless length $path;
2035 $c->log->debug(qq/"$method" request for "$path" from "$address"/);
2037 $c->log_request_headers($request->headers);
2039 if ( my $keywords = $request->query_keywords ) {
2040 $c->log->debug("Query keywords are: $keywords");
2043 $c->log_request_parameters( query => $request->query_parameters, $request->_has_body ? (body => $request->body_parameters) : () );
2045 $c->log_request_uploads($request);
2048 =head2 $c->log_response
2050 Writes information about the response to the debug logs by calling
2051 C<< $c->log_response_status_line >> and C<< $c->log_response_headers >>.
2058 return unless $c->debug;
2060 my($dump) = grep {$_->[0] eq 'Response' } $c->dump_these;
2061 my $response = $dump->[1];
2063 $c->log_response_status_line($response);
2064 $c->log_response_headers($response->headers);
2067 =head2 $c->log_response_status_line($response)
2069 Writes one line of information about the response to the debug logs. This includes:
2073 =item * Response status code
2075 =item * Content-Type header (if present)
2077 =item * Content-Length header (if present)
2083 sub log_response_status_line {
2084 my ($c, $response) = @_;
2088 'Response Code: %s; Content-Type: %s; Content-Length: %s',
2089 $response->status || 'unknown',
2090 $response->headers->header('Content-Type') || 'unknown',
2091 $response->headers->header('Content-Length') || 'unknown'
2096 =head2 $c->log_response_headers($headers);
2098 Hook method which can be wrapped by plugins to log the responseheaders.
2099 No-op in the default implementation.
2103 sub log_response_headers {}
2105 =head2 $c->log_request_parameters( query => {}, body => {} )
2107 Logs request parameters to debug logs
2111 sub log_request_parameters {
2113 my %all_params = @_;
2115 return unless $c->debug;
2117 my $column_width = Catalyst::Utils::term_width() - 44;
2118 foreach my $type (qw(query body)) {
2119 my $params = $all_params{$type};
2120 next if ! keys %$params;
2121 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] );
2122 for my $key ( sort keys %$params ) {
2123 my $param = $params->{$key};
2124 my $value = defined($param) ? $param : '';
2125 $t->row( $key, ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
2127 $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw );
2131 =head2 $c->log_request_uploads
2133 Logs file uploads included in the request to the debug logs.
2134 The parameter name, filename, file type, and file size are all included in
2139 sub log_request_uploads {
2141 my $request = shift;
2142 return unless $c->debug;
2143 my $uploads = $request->uploads;
2144 if ( keys %$uploads ) {
2145 my $t = Text::SimpleTable->new(
2146 [ 12, 'Parameter' ],
2151 for my $key ( sort keys %$uploads ) {
2152 my $upload = $uploads->{$key};
2153 for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
2154 $t->row( $key, $u->filename, $u->type, $u->size );
2157 $c->log->debug( "File Uploads are:\n" . $t->draw );
2161 =head2 $c->log_request_headers($headers);
2163 Hook method which can be wrapped by plugins to log the request headers.
2164 No-op in the default implementation.
2168 sub log_request_headers {}
2170 =head2 $c->log_headers($type => $headers)
2172 Logs L<HTTP::Headers> (either request or response) to the debug logs.
2179 my $headers = shift; # an HTTP::Headers instance
2181 return unless $c->debug;
2183 my $column_width = Catalyst::Utils::term_width() - 28;
2184 my $t = Text::SimpleTable->new( [ 15, 'Header Name' ], [ $column_width, 'Value' ] );
2187 my ( $name, $value ) = @_;
2188 $t->row( $name, $value );
2191 $c->log->debug( ucfirst($type) . " Headers:\n" . $t->draw );
2195 =head2 $c->prepare_read
2197 Prepares the input for reading.
2201 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
2203 =head2 $c->prepare_request
2205 Prepares the engine request.
2209 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
2211 =head2 $c->prepare_uploads
2217 sub prepare_uploads {
2220 $c->engine->prepare_uploads( $c, @_ );
2223 =head2 $c->prepare_write
2225 Prepares the output for writing.
2229 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
2231 =head2 $c->request_class
2233 Returns or sets the request class. Defaults to L<Catalyst::Request>.
2235 =head2 $c->response_class
2237 Returns or sets the response class. Defaults to L<Catalyst::Response>.
2239 =head2 $c->read( [$maxlength] )
2241 Reads a chunk of data from the request body. This method is designed to
2242 be used in a while loop, reading C<$maxlength> bytes on every call.
2243 C<$maxlength> defaults to the size of the request if not specified.
2245 You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this
2248 Warning: If you use read(), Catalyst will not process the body,
2249 so you will not be able to access POST parameters or file uploads via
2250 $c->request. You must handle all body parsing yourself.
2254 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
2262 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
2264 =head2 $c->set_action( $action, $code, $namespace, $attrs )
2266 Sets an action in a given namespace.
2270 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
2272 =head2 $c->setup_actions($component)
2274 Sets up actions for a component.
2278 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
2280 =head2 $c->setup_config
2287 my %args = %{ $class->config || {} };
2289 my @container_classes = ( "${class}::Container", 'Catalyst::IOC::Container');
2290 unshift @container_classes, delete $args{container_class} if exists $args{container_class};
2292 my $container_class = Class::MOP::load_first_existing_class(@container_classes);
2294 my $container = $container_class->new( %args, name => "$class" );
2295 $class->container($container);
2297 my $config = $container->resolve(service => 'config');
2298 $class->config($config);
2299 $class->finalize_config; # back-compat
2302 =head2 $c->finalize_config
2306 sub finalize_config { }
2308 =head2 $c->setup_components
2310 This method is called internally to set up the application's components.
2312 It finds modules by calling the L<locate_components> method, expands them to
2313 package names with the $container->expand_component_module method, and then
2314 installs each component into the application.
2316 The C<setup_components> config option is passed to both of the above methods.
2320 sub setup_components {
2323 my $config = $class->config->{ setup_components };
2325 Catalyst::Exception->throw(
2326 qq{You are using search_extra config option. That option is\n} .
2327 qq{deprecated, please refer to the documentation for\n} .
2328 qq{other ways of achieving the same results.\n}
2329 ) if delete $config->{ search_extra };
2331 my @comps = $class->locate_components($config);
2332 my %comps = map { $_ => 1 } @comps;
2334 my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
2335 $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2336 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2337 ) if $deprecatedcatalyst_component_names;
2339 for my $component ( @comps ) {
2341 # We pass ignore_loaded here so that overlay files for (e.g.)
2342 # Model::DBI::Schema sub-classes are loaded - if it's in @comps
2343 # we know M::P::O found a file on disk so this is safe
2345 Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
2348 my $container = $class->container;
2350 for my $component (@comps) {
2351 $container->add_component( $component, $class );
2352 # FIXME - $instance->expand_modules() is broken
2353 my @expanded_components = $container->expand_component_module( $component );
2354 for my $component (@expanded_components) {
2355 next if $comps{$component};
2357 # FIXME - Why is it inside the for loop? It makes no sense
2358 $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @expanded_components;
2359 $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2360 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2361 ) if $deprecatedcatalyst_component_names;
2363 $container->add_component( $component, $class );
2367 $container->get_sub_container('model')->make_single_default;
2368 $container->get_sub_container('view')->make_single_default;
2372 =head2 $c->locate_components( $setup_component_config )
2374 This method is meant to provide a list of component modules that should be
2375 setup for the application. By default, it will use L<Module::Pluggable>.
2377 Specify a C<setup_components> config option to pass additional options directly
2378 to L<Module::Pluggable>.
2382 sub locate_components {
2386 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
2388 my $locator = Module::Pluggable::Object->new(
2389 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
2393 # XXX think about ditching this sort entirely
2394 my @comps = sort { length $a <=> length $b } $locator->plugins;
2399 =head2 $c->setup_dispatcher
2405 sub setup_dispatcher {
2406 my ( $class, $dispatcher ) = @_;
2409 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2412 if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2413 $dispatcher = 'Catalyst::Dispatcher::' . $env;
2416 unless ($dispatcher) {
2417 $dispatcher = $class->dispatcher_class;
2420 Class::MOP::load_class($dispatcher);
2422 # dispatcher instance
2423 $class->dispatcher( $dispatcher->new );
2426 =head2 $c->setup_engine
2433 my ( $class, $engine ) = @_;
2436 $engine = 'Catalyst::Engine::' . $engine;
2439 if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2440 $engine = 'Catalyst::Engine::' . $env;
2443 if ( $ENV{MOD_PERL} ) {
2444 my $meta = Class::MOP::get_metaclass_by_name($class);
2446 # create the apache method
2447 $meta->add_method('apache' => sub { shift->engine->apache });
2449 my ( $software, $version ) =
2450 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2453 $version =~ s/(\.[^.]+)\./$1/g;
2455 if ( $software eq 'mod_perl' ) {
2459 if ( $version >= 1.99922 ) {
2460 $engine = 'Catalyst::Engine::Apache2::MP20';
2463 elsif ( $version >= 1.9901 ) {
2464 $engine = 'Catalyst::Engine::Apache2::MP19';
2467 elsif ( $version >= 1.24 ) {
2468 $engine = 'Catalyst::Engine::Apache::MP13';
2472 Catalyst::Exception->throw( message =>
2473 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2478 # install the correct mod_perl handler
2479 if ( $version >= 1.9901 ) {
2480 *handler = sub : method {
2481 shift->handle_request(@_);
2485 *handler = sub ($$) { shift->handle_request(@_) };
2490 elsif ( $software eq 'Zeus-Perl' ) {
2491 $engine = 'Catalyst::Engine::Zeus';
2495 Catalyst::Exception->throw(
2496 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2501 $engine = $class->engine_class;
2504 Class::MOP::load_class($engine);
2506 # check for old engines that are no longer compatible
2508 if ( $engine->isa('Catalyst::Engine::Apache')
2509 && !Catalyst::Engine::Apache->VERSION )
2514 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2515 && Catalyst::Engine::Server->VERSION le '0.02' )
2520 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2521 && $engine->VERSION eq '0.01' )
2526 elsif ($engine->isa('Catalyst::Engine::Zeus')
2527 && $engine->VERSION eq '0.01' )
2533 Catalyst::Exception->throw( message =>
2534 qq/Engine "$engine" is not supported by this version of Catalyst/
2539 $class->engine( $engine->new );
2542 =head2 $c->setup_home
2544 Sets up the home directory.
2549 my ( $class, $home ) = @_;
2551 if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2555 $home ||= Catalyst::Utils::home($class);
2558 #I remember recently being scolded for assigning config values like this
2559 $class->config->{home} ||= $home;
2560 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2564 =head2 $c->setup_log
2566 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
2567 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
2570 This method also installs a C<debug> method that returns a true value into the
2571 catalyst subclass if the "debug" level is passed in the comma-delimited list,
2572 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
2574 Note that if the log has already been setup, by either a previous call to
2575 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
2576 that this method won't actually set up the log object.
2581 my ( $class, $levels ) = @_;
2584 $levels =~ s/^\s+//;
2585 $levels =~ s/\s+$//;
2586 my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
2588 my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2589 if ( defined $env_debug ) {
2590 $levels{debug} = 1 if $env_debug; # Ugly!
2591 delete($levels{debug}) unless $env_debug;
2594 unless ( $class->log ) {
2595 $class->log( Catalyst::Log->new(keys %levels) );
2598 if ( $levels{debug} ) {
2599 Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
2600 $class->log->debug('Debug messages enabled');
2604 =head2 $c->setup_plugins
2610 =head2 $c->setup_stats
2612 Sets up timing statistics class.
2617 my ( $class, $stats ) = @_;
2619 Catalyst::Utils::ensure_class_loaded($class->stats_class);
2621 my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2622 if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2623 Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
2624 $class->log->debug('Statistics enabled');
2629 =head2 $c->registered_plugins
2631 Returns a sorted list of the plugins which have either been stated in the
2632 import list or which have been added via C<< MyApp->plugin(@args); >>.
2634 If passed a given plugin name, it will report a boolean value indicating
2635 whether or not that plugin is loaded. A fully qualified name is required if
2636 the plugin name does not begin with C<Catalyst::Plugin::>.
2638 if ($c->registered_plugins('Some::Plugin')) {
2646 sub registered_plugins {
2648 return sort keys %{ $proto->_plugins } unless @_;
2650 return 1 if exists $proto->_plugins->{$plugin};
2651 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2654 sub _register_plugin {
2655 my ( $proto, $plugin, $instant ) = @_;
2656 my $class = ref $proto || $proto;
2658 Class::MOP::load_class( $plugin );
2659 $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is deprecated and will not work in 5.81" )
2660 if $plugin->isa( 'Catalyst::Component' );
2661 $proto->_plugins->{$plugin} = 1;
2663 my $meta = Class::MOP::get_metaclass_by_name($class);
2664 $meta->superclasses($plugin, $meta->superclasses);
2670 my ( $class, $plugins ) = @_;
2672 $class->_plugins( {} ) unless $class->_plugins;
2673 $plugins = Data::OptList::mkopt($plugins || []);
2676 [ Catalyst::Utils::resolve_namespace(
2677 $class . '::Plugin',
2678 'Catalyst::Plugin', $_->[0]
2684 for my $plugin ( reverse @plugins ) {
2685 Class::MOP::load_class($plugin->[0], $plugin->[1]);
2686 my $meta = find_meta($plugin->[0]);
2687 next if $meta && $meta->isa('Moose::Meta::Role');
2689 $class->_register_plugin($plugin->[0]);
2693 map { $_->[0]->name, $_->[1] }
2694 grep { blessed($_->[0]) && $_->[0]->isa('Moose::Meta::Role') }
2695 map { [find_meta($_->[0]), $_->[1]] }
2698 Moose::Util::apply_all_roles(
2706 Returns an arrayref of the internal execution stack (actions that are
2707 currently executing).
2711 Returns the current timing statistics object. By default Catalyst uses
2712 L<Catalyst::Stats|Catalyst::Stats>, but can be set otherwise with
2713 L<< stats_class|/"$c->stats_class" >>.
2715 Even if L<< -Stats|/"-Stats" >> is not enabled, the stats object is still
2716 available. By enabling it with C< $c->stats->enabled(1) >, it can be used to
2717 profile explicitly, although MyApp.pm still won't profile nor output anything
2720 =head2 $c->stats_class
2722 Returns or sets the stats (timing statistics) class. L<Catalyst::Stats|Catalyst::Stats> is used by default.
2724 =head2 $c->use_stats
2726 Returns 1 when L<< stats collection|/"-Stats" >> is enabled.
2728 Note that this is a static method, not an accessor and should be overridden
2729 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
2736 =head2 $c->write( $data )
2738 Writes $data to the output stream. When using this method directly, you
2739 will need to manually set the C<Content-Length> header to the length of
2740 your output data, if known.
2747 # Finalize headers if someone manually writes output
2748 $c->finalize_headers;
2750 return $c->engine->write( $c, @_ );
2755 Returns the Catalyst version number. Mostly useful for "powered by"
2756 messages in template systems.
2760 sub version { return $Catalyst::VERSION }
2762 =head1 CONFIGURATION
2764 There are a number of 'base' config variables which can be set:
2770 C<default_model> - The default model picked if you say C<< $c->model >>. See L<< /$c->model($name) >>.
2774 C<default_view> - The default view to be rendered or returned when C<< $c->view >> is called. See L<< /$c->view($name) >>.
2778 C<home> - The application home directory. In an uninstalled application,
2779 this is the top level application directory. In an installed application,
2780 this will be the directory containing C<< MyApp.pm >>.
2784 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
2788 C<name> - The name of the application in debug messages and the debug and
2793 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
2794 until it is accessed. This allows you to (for example) check authentication (and reject
2795 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
2799 C<root> - The root directory for templates. Usually this is just a
2800 subdirectory of the home directory, but you can set it to change the
2801 templates to a different directory.
2805 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
2806 to be shown in hit debug tables in the test server.
2810 C<use_request_uri_for_path> - Controlls if the C<REQUEST_URI> or C<PATH_INFO> environment
2811 variable should be used for determining the request path. See L<Catalyst::Engine::CGI/PATH DECODING>
2812 for more information.
2816 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
2820 =head1 INTERNAL ACTIONS
2822 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2823 C<_ACTION>, and C<_END>. These are by default not shown in the private
2824 action table, but you can make them visible with a config parameter.
2826 MyApp->config(show_internal_actions => 1);
2828 =head1 ON-DEMAND PARSER
2830 The request body is usually parsed at the beginning of a request,
2831 but if you want to handle input yourself, you can enable on-demand
2832 parsing with a config parameter.
2834 MyApp->config(parse_on_demand => 1);
2836 =head1 PROXY SUPPORT
2838 Many production servers operate using the common double-server approach,
2839 with a lightweight frontend web server passing requests to a larger
2840 backend server. An application running on the backend server must deal
2841 with two problems: the remote user always appears to be C<127.0.0.1> and
2842 the server's hostname will appear to be C<localhost> regardless of the
2843 virtual host that the user connected through.
2845 Catalyst will automatically detect this situation when you are running
2846 the frontend and backend servers on the same machine. The following
2847 changes are made to the request.
2849 $c->req->address is set to the user's real IP address, as read from
2850 the HTTP X-Forwarded-For header.
2852 The host value for $c->req->base and $c->req->uri is set to the real
2853 host, as read from the HTTP X-Forwarded-Host header.
2855 Additionally, you may be running your backend application on an insecure
2856 connection (port 80) while your frontend proxy is running under SSL. If there
2857 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
2858 tell Catalyst what port the frontend listens on. This will allow all URIs to
2859 be created properly.
2861 In the case of passing in:
2863 X-Forwarded-Port: 443
2865 All calls to C<uri_for> will result in an https link, as is expected.
2867 Obviously, your web server must support these headers for this to work.
2869 In a more complex server farm environment where you may have your
2870 frontend proxy server(s) on different machines, you will need to set a
2871 configuration option to tell Catalyst to read the proxied data from the
2874 MyApp->config(using_frontend_proxy => 1);
2876 If you do not wish to use the proxy support at all, you may set:
2878 MyApp->config(ignore_frontend_proxy => 1);
2880 =head1 THREAD SAFETY
2882 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2883 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2884 believe the Catalyst core to be thread-safe.
2886 If you plan to operate in a threaded environment, remember that all other
2887 modules you are using must also be thread-safe. Some modules, most notably
2888 L<DBD::SQLite>, are not thread-safe.
2894 Join #catalyst on irc.perl.org.
2898 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
2899 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
2903 http://catalyst.perl.org
2907 http://dev.catalyst.perl.org
2911 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2913 =head2 L<Catalyst::Manual> - The Catalyst Manual
2915 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
2917 =head2 L<Catalyst::Engine> - Core engine
2919 =head2 L<Catalyst::Log> - Log class.
2921 =head2 L<Catalyst::Request> - Request object
2923 =head2 L<Catalyst::Response> - Response object
2925 =head2 L<Catalyst::Test> - The test suite.
2927 =head1 PROJECT FOUNDER
2929 sri: Sebastian Riedel <sri@cpan.org>
2935 acme: Leon Brocard <leon@astray.com>
2937 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
2941 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
2947 andyg: Andy Grundman <andy@hybridized.org>
2949 audreyt: Audrey Tang
2951 bricas: Brian Cassidy <bricas@cpan.org>
2953 Caelum: Rafael Kitover <rkitover@io.com>
2955 chansen: Christian Hansen
2957 chicks: Christopher Hicks
2959 Chisel Wright C<pause@herlpacker.co.uk>
2961 Danijel Milicevic C<me@danijel.de>
2963 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
2965 David Naughton, C<naughton@umn.edu>
2969 dhoss: Devin Austin <dhoss@cpan.org>
2971 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
2975 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
2977 esskar: Sascha Kiefer
2979 fireartist: Carl Franks <cfranks@cpan.org>
2981 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
2983 gabb: Danijel Milicevic
2987 Gavin Henry C<ghenry@perl.me.uk>
2991 groditi: Guillermo Roditi <groditi@gmail.com>
2993 hobbs: Andrew Rodland <andrew@cleverdomain.org>
2995 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
2997 jcamacho: Juan Camacho
2999 jester: Jesse Sheidlower C<jester@panix.com>
3001 jhannah: Jay Hannah <jay@jays.net>
3007 jon: Jon Schutz <jjschutz@cpan.org>
3009 Jonathan Rockway C<< <jrockway@cpan.org> >>
3011 Kieren Diment C<kd@totaldatasolution.com>
3013 konobi: Scott McWhirter <konobi@cpan.org>
3015 marcus: Marcus Ramberg <mramberg@cpan.org>
3017 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
3019 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
3023 naughton: David Naughton
3025 ningu: David Kamholz <dkamholz@cpan.org>
3027 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
3029 numa: Dan Sully <daniel@cpan.org>
3035 omega: Andreas Marienborg
3037 Oleg Kostyuk <cub.uanic@gmail.com>
3039 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
3041 rafl: Florian Ragwitz <rafl@debian.org>
3043 random: Roland Lammel <lammel@cpan.org>
3045 Robert Sedlacek C<< <rs@474.at> >>
3047 SpiceMan: Marcel Montes
3051 szbalint: Balint Szilakszi <szbalint@cpan.org>
3053 t0m: Tomas Doran <bobtfish@bobtfish.net>
3057 Viljo Marrandi C<vilts@yahoo.com>
3059 Will Hawes C<info@whawes.co.uk>
3061 willert: Sebastian Willert <willert@cpan.org>
3063 wreis: Wallace Reis <wallace@reis.org.br>
3065 Yuval Kogman, C<nothingmuch@woobling.org>
3067 rainboxx: Matthias Dietrich, C<perl@rainboxx.de>
3069 dd070: Dhaval Dhanani <dhaval070@gmail.com>
3073 Copyright (c) 2005, the above named PROJECT FOUNDER and CONTRIBUTORS.
3077 This library is free software. You can redistribute it and/or modify it under
3078 the same terms as Perl itself.
3084 __PACKAGE__->meta->make_immutable;