making unit_core_component.t work
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use Moose;
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;
11 use Catalyst::Log;
12 use Catalyst::Request;
13 use Catalyst::Request::Upload;
14 use Catalyst::Response;
15 use Catalyst::Utils;
16 use Catalyst::Controller;
17 use Data::OptList;
18 use Devel::InnerPackage ();
19 use File::stat;
20 use Module::Pluggable::Object ();
21 use Text::SimpleTable ();
22 use Path::Class::Dir ();
23 use Path::Class::File ();
24 use URI ();
25 use URI::http;
26 use URI::https;
27 use Tree::Simple qw/use_weak_refs/;
28 use Tree::Simple::Visitor::FindByUID;
29 use Class::C3::Adopt::NEXT;
30 use List::Util qw/first/;
31 use List::MoreUtils qw/uniq/;
32 use attributes;
33 use utf8;
34 use Carp qw/croak carp shortmess/;
35
36 BEGIN { require 5.008004; }
37
38 has stack => (is => 'ro', default => sub { [] });
39 has stash => (is => 'rw', default => sub { {} });
40 has state => (is => 'rw', default => 0);
41 has stats => (is => 'rw');
42 has action => (is => 'rw');
43 has counter => (is => 'rw', default => sub { {} });
44 has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
45 has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
46 has namespace => (is => 'rw');
47
48 sub depth { scalar @{ shift->stack || [] }; }
49 sub comp { shift->component(@_) }
50
51 sub req {
52     my $self = shift; return $self->request(@_);
53 }
54 sub res {
55     my $self = shift; return $self->response(@_);
56 }
57
58 # For backwards compatibility
59 sub finalize_output { shift->finalize_body(@_) };
60
61 # For statistics
62 our $COUNT     = 1;
63 our $START     = time;
64 our $RECURSION = 1000;
65 our $DETACH    = Catalyst::Exception::Detach->new;
66 our $GO        = Catalyst::Exception::Go->new;
67
68 #I imagine that very few of these really need to be class variables. if any.
69 #maybe we should just make them attributes with a default?
70 __PACKAGE__->mk_classdata($_)
71   for qw/container components arguments dispatcher engine log dispatcher_class
72   engine_class context_class request_class response_class stats_class
73   setup_finished/;
74
75 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
76 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
77 __PACKAGE__->request_class('Catalyst::Request');
78 __PACKAGE__->response_class('Catalyst::Response');
79 __PACKAGE__->stats_class('Catalyst::Stats');
80
81 # Remember to update this in Catalyst::Runtime as well!
82
83 our $VERSION = '5.80032';
84
85 sub import {
86     my ( $class, @arguments ) = @_;
87
88     # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
89     # callers @ISA.
90     return unless $class eq 'Catalyst';
91
92     my $caller = caller();
93     return if $caller eq 'main';
94
95     my $meta = Moose::Meta::Class->initialize($caller);
96     unless ( $caller->isa('Catalyst') ) {
97         my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
98         $meta->superclasses(@superclasses);
99     }
100     # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
101     $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
102
103     unless( $meta->has_method('meta') ){
104         if ($Moose::VERSION >= 1.15) {
105             $meta->_add_meta_method('meta');
106         }
107         else {
108             $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
109         }
110     }
111
112     $caller->arguments( [@arguments] );
113     $caller->setup_home;
114 }
115
116 sub _application { $_[0] }
117
118 =head1 NAME
119
120 Catalyst - The Elegant MVC Web Application Framework
121
122 =head1 SYNOPSIS
123
124 See the L<Catalyst::Manual> distribution for comprehensive
125 documentation and tutorials.
126
127     # Install Catalyst::Devel for helpers and other development tools
128     # use the helper to create a new application
129     catalyst.pl MyApp
130
131     # add models, views, controllers
132     script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
133     script/myapp_create.pl view MyTemplate TT
134     script/myapp_create.pl controller Search
135
136     # built in testserver -- use -r to restart automatically on changes
137     # --help to see all available options
138     script/myapp_server.pl
139
140     # command line testing interface
141     script/myapp_test.pl /yada
142
143     ### in lib/MyApp.pm
144     use Catalyst qw/-Debug/; # include plugins here as well
145
146     ### In lib/MyApp/Controller/Root.pm (autocreated)
147     sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
148         my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
149         $c->stash->{template} = 'foo.tt'; # set the template
150         # lookup something from db -- stash vars are passed to TT
151         $c->stash->{data} =
152           $c->model('Database::Foo')->search( { country => $args[0] } );
153         if ( $c->req->params->{bar} ) { # access GET or POST parameters
154             $c->forward( 'bar' ); # process another action
155             # do something else after forward returns
156         }
157     }
158
159     # The foo.tt TT template can use the stash data from the database
160     [% WHILE (item = data.next) %]
161         [% item.foo %]
162     [% END %]
163
164     # called for /bar/of/soap, /bar/of/soap/10, etc.
165     sub bar : Path('/bar/of/soap') { ... }
166
167     # called for all actions, from the top-most controller downwards
168     sub auto : Private {
169         my ( $self, $c ) = @_;
170         if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
171             $c->res->redirect( '/login' ); # require login
172             return 0; # abort request and go immediately to end()
173         }
174         return 1; # success; carry on to next action
175     }
176
177     # called after all actions are finished
178     sub end : Private {
179         my ( $self, $c ) = @_;
180         if ( scalar @{ $c->error } ) { ... } # handle errors
181         return if $c->res->body; # already have a response
182         $c->forward( 'MyApp::View::TT' ); # render template
183     }
184
185     ### in MyApp/Controller/Foo.pm
186     # called for /foo/bar
187     sub bar : Local { ... }
188
189     # called for /blargle
190     sub blargle : Global { ... }
191
192     # an index action matches /foo, but not /foo/1, etc.
193     sub index : Private { ... }
194
195     ### in MyApp/Controller/Foo/Bar.pm
196     # called for /foo/bar/baz
197     sub baz : Local { ... }
198
199     # first Root auto is called, then Foo auto, then this
200     sub auto : Private { ... }
201
202     # powerful regular expression paths are also possible
203     sub details : Regex('^product/(\w+)/details$') {
204         my ( $self, $c ) = @_;
205         # extract the (\w+) from the URI
206         my $product = $c->req->captures->[0];
207     }
208
209 See L<Catalyst::Manual::Intro> for additional information.
210
211 =head1 DESCRIPTION
212
213 Catalyst is a modern framework for making web applications without the
214 pain usually associated with this process. This document is a reference
215 to the main Catalyst application. If you are a new user, we suggest you
216 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
217
218 See L<Catalyst::Manual> for more documentation.
219
220 Catalyst plugins can be loaded by naming them as arguments to the "use
221 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
222 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
223 C<My::Module>.
224
225     use Catalyst qw/My::Module/;
226
227 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
228 fully qualify the name by using a unary plus:
229
230     use Catalyst qw/
231         My::Module
232         +Fully::Qualified::Plugin::Name
233     /;
234
235 Special flags like C<-Debug> and C<-Engine> can also be specified as
236 arguments when Catalyst is loaded:
237
238     use Catalyst qw/-Debug My::Module/;
239
240 The position of plugins and flags in the chain is important, because
241 they are loaded in the order in which they appear.
242
243 The following flags are supported:
244
245 =head2 -Debug
246
247 Enables debug output. You can also force this setting from the system
248 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
249 settings override the application, with <MYAPP>_DEBUG having the highest
250 priority.
251
252 This sets the log level to 'debug' and enables full debug output on the
253 error screen. If you only want the latter, see L<< $c->debug >>.
254
255 =head2 -Engine
256
257 Forces Catalyst to use a specific engine. Omit the
258 C<Catalyst::Engine::> prefix of the engine name, i.e.:
259
260     use Catalyst qw/-Engine=CGI/;
261
262 =head2 -Home
263
264 Forces Catalyst to use a specific home directory, e.g.:
265
266     use Catalyst qw[-Home=/usr/mst];
267
268 This can also be done in the shell environment by setting either the
269 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
270 is replaced with the uppercased name of your application, any "::" in
271 the name will be replaced with underscores, e.g. MyApp::Web should use
272 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
273
274 If none of these are set, Catalyst will attempt to automatically detect the
275 home directory. If you are working in a development envirnoment, Catalyst
276 will try and find the directory containing either Makefile.PL, Build.PL or
277 dist.ini. If the application has been installed into the system (i.e.
278 you have done C<make install>), then Catalyst will use the path to your
279 application module, without the .pm extension (ie, /foo/MyApp if your
280 application was installed at /foo/MyApp.pm)
281
282 =head2 -Log
283
284     use Catalyst '-Log=warn,fatal,error';
285
286 Specifies a comma-delimited list of log levels.
287
288 =head2 -Stats
289
290 Enables statistics collection and reporting.
291
292    use Catalyst qw/-Stats=1/;
293
294 You can also force this setting from the system environment with CATALYST_STATS
295 or <MYAPP>_STATS. The environment settings override the application, with
296 <MYAPP>_STATS having the highest priority.
297
298 Stats are also enabled if L<< debugging |/"-Debug" >> is enabled.
299
300 =head1 METHODS
301
302 =head2 INFORMATION ABOUT THE CURRENT REQUEST
303
304 =head2 $c->action
305
306 Returns a L<Catalyst::Action> object for the current action, which
307 stringifies to the action name. See L<Catalyst::Action>.
308
309 =head2 $c->namespace
310
311 Returns the namespace of the current action, i.e., the URI prefix
312 corresponding to the controller of the current action. For example:
313
314     # in Controller::Foo::Bar
315     $c->namespace; # returns 'foo/bar';
316
317 =head2 $c->request
318
319 =head2 $c->req
320
321 Returns the current L<Catalyst::Request> object, giving access to
322 information about the current client request (including parameters,
323 cookies, HTTP headers, etc.). See L<Catalyst::Request>.
324
325 =head2 REQUEST FLOW HANDLING
326
327 =head2 $c->forward( $action [, \@arguments ] )
328
329 =head2 $c->forward( $class, $method, [, \@arguments ] )
330
331 Forwards processing to another action, by its private name. If you give a
332 class name but no method, C<process()> is called. You may also optionally
333 pass arguments in an arrayref. The action will receive the arguments in
334 C<@_> and C<< $c->req->args >>. Upon returning from the function,
335 C<< $c->req->args >> will be restored to the previous values.
336
337 Any data C<return>ed from the action forwarded to, will be returned by the
338 call to forward.
339
340     my $foodata = $c->forward('/foo');
341     $c->forward('index');
342     $c->forward(qw/Model::DBIC::Foo do_stuff/);
343     $c->forward('View::TT');
344
345 Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
346 an C<< eval { } >> around the call (actually
347 L<< execute|/"$c->execute( $class, $coderef )" >> does), thus de-fatalizing
348 all 'dies' within the called action. If you want C<die> to propagate you
349 need to do something like:
350
351     $c->forward('foo');
352     die join "\n", @{ $c->error } if @{ $c->error };
353
354 Or make sure to always return true values from your actions and write
355 your code like this:
356
357     $c->forward('foo') || return;
358
359 Another note is that C<< $c->forward >> always returns a scalar because it
360 actually returns $c->state which operates in a scalar context.
361 Thus, something like:
362
363     return @array;
364
365 in an action that is forwarded to is going to return a scalar,
366 i.e. how many items are in that array, which is probably not what you want.
367 If you need to return an array then return a reference to it,
368 or stash it like so:
369
370     $c->stash->{array} = \@array;
371
372 and access it from the stash.
373
374 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.
375
376 =cut
377
378 sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
379
380 =head2 $c->detach( $action [, \@arguments ] )
381
382 =head2 $c->detach( $class, $method, [, \@arguments ] )
383
384 =head2 $c->detach()
385
386 The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
387 doesn't return to the previous action when processing is finished.
388
389 When called with no arguments it escapes the processing chain entirely.
390
391 =cut
392
393 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
394
395 =head2 $c->visit( $action [, \@captures, \@arguments ] )
396
397 =head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
398
399 Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
400 but does a full dispatch, instead of just calling the new C<$action> /
401 C<< $class->$method >>. This means that C<begin>, C<auto> and the method
402 you go to are called, just like a new request.
403
404 In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
405 This means, for example, that C<< $c->action >> methods such as
406 L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
407 L<reverse|Catalyst::Action/reverse> return information for the visited action
408 when they are invoked within the visited action.  This is different from the
409 behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which
410 continues to use the $c->action object from the caller action even when
411 invoked from the callee.
412
413 C<< $c->stash >> is kept unchanged.
414
415 In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
416 allows you to "wrap" another action, just as it would have been called by
417 dispatching from a URL, while the analogous
418 L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
419 transfer control to another action as if it had been reached directly from a URL.
420
421 =cut
422
423 sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
424
425 =head2 $c->go( $action [, \@captures, \@arguments ] )
426
427 =head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
428
429 The relationship between C<go> and
430 L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
431 the relationship between
432 L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and
433 L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>,
434 C<< $c->go >> will perform a full dispatch on the specified action or method,
435 with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>,
436 C<go> escapes the processing of the current request chain on completion, and
437 does not return to its caller.
438
439 @arguments are arguments to the final destination of $action. @captures are
440 arguments to the intermediate steps, if any, on the way to the final sub of
441 $action.
442
443 =cut
444
445 sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
446
447 =head2 $c->response
448
449 =head2 $c->res
450
451 Returns the current L<Catalyst::Response> object, see there for details.
452
453 =head2 $c->stash
454
455 Returns a hashref to the stash, which may be used to store data and pass
456 it between components during a request. You can also set hash keys by
457 passing arguments. The stash is automatically sent to the view. The
458 stash is cleared at the end of a request; it cannot be used for
459 persistent storage (for this you must use a session; see
460 L<Catalyst::Plugin::Session> for a complete system integrated with
461 Catalyst).
462
463     $c->stash->{foo} = $bar;
464     $c->stash( { moose => 'majestic', qux => 0 } );
465     $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
466
467     # stash is automatically passed to the view for use in a template
468     $c->forward( 'MyApp::View::TT' );
469
470 =cut
471
472 around stash => sub {
473     my $orig = shift;
474     my $c = shift;
475     my $stash = $orig->($c);
476     if (@_) {
477         my $new_stash = @_ > 1 ? {@_} : $_[0];
478         croak('stash takes a hash or hashref') unless ref $new_stash;
479         foreach my $key ( keys %$new_stash ) {
480           $stash->{$key} = $new_stash->{$key};
481         }
482     }
483
484     return $stash;
485 };
486
487
488 =head2 $c->error
489
490 =head2 $c->error($error, ...)
491
492 =head2 $c->error($arrayref)
493
494 Returns an arrayref containing error messages.  If Catalyst encounters an
495 error while processing a request, it stores the error in $c->error.  This
496 method should only be used to store fatal error messages.
497
498     my @error = @{ $c->error };
499
500 Add a new error.
501
502     $c->error('Something bad happened');
503
504 =cut
505
506 sub error {
507     my $c = shift;
508     if ( $_[0] ) {
509         my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
510         croak @$error unless ref $c;
511         push @{ $c->{error} }, @$error;
512     }
513     elsif ( defined $_[0] ) { $c->{error} = undef }
514     return $c->{error} || [];
515 }
516
517
518 =head2 $c->state
519
520 Contains the return value of the last executed action.
521 Note that << $c->state >> operates in a scalar context which means that all
522 values it returns are scalar.
523
524 =head2 $c->clear_errors
525
526 Clear errors.  You probably don't want to clear the errors unless you are
527 implementing a custom error screen.
528
529 This is equivalent to running
530
531     $c->error(0);
532
533 =cut
534
535 sub clear_errors {
536     my $c = shift;
537     $c->error(0);
538 }
539
540 =head2 COMPONENT ACCESSORS
541
542 =head2 $c->controller($name)
543
544 Gets a L<Catalyst::Controller> instance by name.
545
546     $c->controller('Foo')->do_stuff;
547
548 If the name is omitted, will return the controller for the dispatched
549 action.
550
551 If you want to search for controllers, pass in a regexp as the argument.
552
553     # find all controllers that start with Foo
554     my @foo_controllers = $c->controller(qr{^Foo});
555
556
557 =cut
558
559 sub controller {
560     my ( $c, $name, @args ) = @_;
561
562 # FIXME: should this be a Catalyst::Utils method?
563     if (!$name) {
564         my $class  = $c->action->class;
565
566         my $prefix = length Catalyst::Utils::class2classprefix($class);
567
568         # MyApp::Controller::Foo becomes Foo
569         # the + 2 is because of the ::
570         $name = substr $class, $prefix + 2;
571     }
572
573     return $c->container->get_component_from_sub_container( 'controller', $name, $c, @args);
574 }
575
576 =head2 $c->model($name)
577
578 Gets a L<Catalyst::Model> instance by name.
579
580     $c->model('Foo')->do_stuff;
581
582 Any extra arguments are directly passed to ACCEPT_CONTEXT.
583
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.
589
590 If you want to search for models, pass in a regexp as the argument.
591
592     # find all models that start with Foo
593     my @foo_models = $c->model(qr{^Foo});
594
595 =cut
596
597 sub model {
598     my ( $c, $name, @args ) = @_;
599
600     if (ref $c && !$name) {
601         return $c->stash->{current_model_instance}
602             if $c->stash->{current_model_instance};
603
604         $name = $c->stash->{current_model}
605             if $c->stash->{current_model};
606     }
607
608     return $c->container->get_component_from_sub_container( 'model', $name, $c, @args);
609 }
610
611
612 =head2 $c->view($name)
613
614 Gets a L<Catalyst::View> instance by name.
615
616     $c->view('Foo')->do_stuff;
617
618 Any extra arguments are directly passed to ACCEPT_CONTEXT.
619
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.
625
626 If you want to search for views, pass in a regexp as the argument.
627
628     # find all views that start with Foo
629     my @foo_views = $c->view(qr{^Foo});
630
631 =cut
632
633 sub view {
634     my ( $c, $name, @args ) = @_;
635
636     if (ref $c && !$name) {
637         return $c->stash->{current_view_instance}
638             if $c->stash->{current_view_instance};
639
640         $name = $c->stash->{current_view}
641             if $c->stash->{current_view};
642     }
643
644     return $c->container->get_component_from_sub_container( 'view', $name, $c, @args);
645 }
646
647 =head2 $c->controllers
648
649 Returns the available names which can be passed to $c->controller
650
651 =cut
652
653 sub controllers {
654     my ( $c ) = @_;
655     return $c->container->get_sub_container('controller')->get_service_list;
656 }
657
658 =head2 $c->models
659
660 Returns the available names which can be passed to $c->model
661
662 =cut
663
664 sub models {
665     my ( $c ) = @_;
666     return $c->container->get_sub_container('model')->get_service_list;
667 }
668
669
670 =head2 $c->views
671
672 Returns the available names which can be passed to $c->view
673
674 =cut
675
676 sub views {
677     my ( $c ) = @_;
678     return $c->container->get_sub_container('view')->get_service_list;
679 }
680
681 =head2 $c->comp($name)
682
683 =head2 $c->component($name)
684
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.
689
690 If C<$name> is a regexp, a list of components matched against the full
691 component name will be returned.
692
693 =cut
694
695 sub component {
696     my ( $c, $component, @args ) = @_;
697
698     if ( $component ) {
699         if (ref $component) {
700             my @result;
701             for my $subcontainer_name (qw/model view controller/) {
702                 my $subcontainer = $c->container->get_sub_container($subcontainer_name);
703                 my @components   = $subcontainer->get_service_list;
704                 @result          = grep { m{$component} } @components;
705
706                 return map { $subcontainer->get_component( $_, $c, @args ) } @result
707                     if @result;
708             }
709
710             # it expects an empty list on failed searches
711             return @result;
712         }
713         else {
714             my ($type, $name) = _get_component_type_name($component);
715
716             if ($type && $c->container->has_sub_container($type)) {
717                 my $container = $c->container->get_sub_container($type);
718
719                 if ( !ref $component && $container->has_service($name) ) {
720                     return $container->get_component( $name, $c, @args );
721                 }
722
723                 return $container->get_component_regexp( $name, $c, @args );
724             }
725             else {
726                 for my $subcontainer_name (qw/model view controller/) {
727                     my $subcontainer = $c->container->get_sub_container($subcontainer_name);
728                     my @components   = $subcontainer->get_service_list;
729                     my $result       = first { $_ eq $component } @components;
730
731                     return $subcontainer->get_component( $result, $c, @args )
732                         if $result;
733                 }
734             }
735         }
736
737         # FIXME: I probably shouldn't be doing this
738         # I'm keeping it temporarily for things like $c->comp('MyApp')
739         return $c->components->{$component}
740             if exists $c->components->{$component} and !@args;
741
742         $c->log->warn("Looking for '$component', but nothing was found.");
743
744         # I would expect to return an empty list here, but that breaks back-compat
745     }
746
747     # fallback
748     return sort keys %{ $c->components };
749 }
750
751 =head2 CLASS DATA AND HELPER CLASSES
752
753 =head2 $c->config
754
755 Returns or takes a hashref containing the application's configuration.
756
757     __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
758
759 You can also use a C<YAML>, C<XML> or L<Config::General> config file
760 like C<myapp.conf> in your applications home directory. See
761 L<Catalyst::Plugin::ConfigLoader>.
762
763 =head3 Cascading configuration
764
765 The config method is present on all Catalyst components, and configuration
766 will be merged when an application is started. Configuration loaded with
767 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
768 followed by configuration in your top level C<MyApp> class. These two
769 configurations are merged, and then configuration data whose hash key matches a
770 component name is merged with configuration for that component.
771
772 The configuration for a component is then passed to the C<new> method when a
773 component is constructed.
774
775 For example:
776
777     MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
778     MyApp::Model::Foo->config({ quux => 'frob', overrides => 'this' });
779
780 will mean that C<MyApp::Model::Foo> receives the following data when
781 constructed:
782
783     MyApp::Model::Foo->new({
784         bar => 'baz',
785         quux => 'frob',
786         overrides => 'me',
787     });
788
789 It's common practice to use a Moose attribute
790 on the receiving component to access the config value.
791
792     package MyApp::Model::Foo;
793
794     use Moose;
795
796     # this attr will receive 'baz' at construction time
797     has 'bar' => (
798         is  => 'rw',
799         isa => 'Str',
800     );
801
802 You can then get the value 'baz' by calling $c->model('Foo')->bar
803 (or $self->bar inside code in the model).
804
805 B<NOTE:> you MUST NOT call C<< $self->config >> or C<< __PACKAGE__->config >>
806 as a way of reading config within your code, as this B<will not> give you the
807 correctly merged config back. You B<MUST> take the config values supplied to
808 the constructor and use those instead.
809
810 =cut
811
812 around config => sub {
813     my $orig = shift;
814     my $c = shift;
815
816     croak('Setting config after setup has been run is not allowed.')
817         if ( @_ and $c->setup_finished );
818
819     $c->$orig(@_);
820 };
821
822 =head2 $c->log
823
824 Returns the logging object instance. Unless it is already set, Catalyst
825 sets this up with a L<Catalyst::Log> object. To use your own log class,
826 set the logger with the C<< __PACKAGE__->log >> method prior to calling
827 C<< __PACKAGE__->setup >>.
828
829  __PACKAGE__->log( MyLogger->new );
830  __PACKAGE__->setup;
831
832 And later:
833
834     $c->log->info( 'Now logging with my own logger!' );
835
836 Your log class should implement the methods described in
837 L<Catalyst::Log>.
838
839
840 =head2 $c->debug
841
842 Returns 1 if debug mode is enabled, 0 otherwise.
843
844 You can enable debug mode in several ways:
845
846 =over
847
848 =item By calling myapp_server.pl with the -d flag
849
850 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
851
852 =item The -Debug option in your MyApp.pm
853
854 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
855
856 =back
857
858 The first three also set the log level to 'debug'.
859
860 Calling C<< $c->debug(1) >> has no effect.
861
862 =cut
863
864 sub debug { 0 }
865
866 =head2 $c->dispatcher
867
868 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
869
870 =head2 $c->engine
871
872 Returns the engine instance. See L<Catalyst::Engine>.
873
874
875 =head2 UTILITY METHODS
876
877 =head2 $c->path_to(@path)
878
879 Merges C<@path> with C<< $c->config->{home} >> and returns a
880 L<Path::Class::Dir> object. Note you can usually use this object as
881 a filename, but sometimes you will have to explicitly stringify it
882 yourself by calling the C<< ->stringify >> method.
883
884 For example:
885
886     $c->path_to( 'db', 'sqlite.db' );
887
888 =cut
889
890 sub path_to {
891     my ( $c, @path ) = @_;
892     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
893     if ( -d $path ) { return $path }
894     else { return Path::Class::File->new( $c->config->{home}, @path ) }
895 }
896
897 =head2 $c->plugin( $name, $class, @args )
898
899 Helper method for plugins. It creates a class data accessor/mutator and
900 loads and instantiates the given class.
901
902     MyApp->plugin( 'prototype', 'HTML::Prototype' );
903
904     $c->prototype->define_javascript_functions;
905
906 B<Note:> This method of adding plugins is deprecated. The ability
907 to add plugins like this B<will be removed> in a Catalyst 5.81.
908 Please do not use this functionality in new code.
909
910 =cut
911
912 sub plugin {
913     my ( $class, $name, $plugin, @args ) = @_;
914
915     # See block comment in t/unit_core_plugin.t
916     $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
917
918     $class->_register_plugin( $plugin, 1 );
919
920     eval { $plugin->import };
921     $class->mk_classdata($name);
922     my $obj;
923     eval { $obj = $plugin->new(@args) };
924
925     if ($@) {
926         Catalyst::Exception->throw( message =>
927               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
928     }
929
930     $class->$name($obj);
931     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
932       if $class->debug;
933 }
934
935 =head2 MyApp->setup
936
937 Initializes the dispatcher and engine, loads any plugins, and loads the
938 model, view, and controller components. You may also specify an array
939 of plugins to load here, if you choose to not load them in the C<use
940 Catalyst> line.
941
942     MyApp->setup;
943     MyApp->setup( qw/-Debug/ );
944
945 =cut
946
947 sub setup {
948     my ( $class, @arguments ) = @_;
949     croak('Running setup more than once')
950         if ( $class->setup_finished );
951
952     unless ( $class->isa('Catalyst') ) {
953
954         Catalyst::Exception->throw(
955             message => qq/'$class' does not inherit from Catalyst/ );
956     }
957
958     if ( $class->arguments ) {
959         @arguments = ( @arguments, @{ $class->arguments } );
960     }
961
962     # Process options
963     my $flags = {};
964
965     foreach (@arguments) {
966
967         if (/^-Debug$/) {
968             $flags->{log} =
969               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
970         }
971         elsif (/^-(\w+)=?(.*)$/) {
972             $flags->{ lc $1 } = $2;
973         }
974         else {
975             push @{ $flags->{plugins} }, $_;
976         }
977     }
978
979     $class->setup_config();
980     $class->setup_home( delete $flags->{home} );
981
982     $class->setup_log( delete $flags->{log} );
983     $class->setup_plugins( delete $flags->{plugins} );
984     $class->setup_dispatcher( delete $flags->{dispatcher} );
985     $class->setup_engine( delete $flags->{engine} );
986     $class->setup_stats( delete $flags->{stats} );
987
988     for my $flag ( sort keys %{$flags} ) {
989
990         if ( my $code = $class->can( 'setup_' . $flag ) ) {
991             &$code( $class, delete $flags->{$flag} );
992         }
993         else {
994             $class->log->warn(qq/Unknown flag "$flag"/);
995         }
996     }
997
998     eval { require Catalyst::Devel; };
999     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
1000         $class->log->warn(<<"EOF");
1001 You are running an old script!
1002
1003   Please update by running (this will overwrite existing files):
1004     catalyst.pl -force -scripts $class
1005
1006   or (this will not overwrite existing files):
1007     catalyst.pl -scripts $class
1008
1009 EOF
1010     }
1011
1012     if ( $class->debug ) {
1013         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
1014
1015         if (@plugins) {
1016             my $column_width = Catalyst::Utils::term_width() - 6;
1017             my $t = Text::SimpleTable->new($column_width);
1018             $t->row($_) for @plugins;
1019             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
1020         }
1021
1022         my $dispatcher = $class->dispatcher;
1023         my $engine     = $class->engine;
1024         my $home       = $class->config->{home};
1025
1026         $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
1027         $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
1028
1029         $home
1030           ? ( -d $home )
1031           ? $class->log->debug(qq/Found home "$home"/)
1032           : $class->log->debug(qq/Home "$home" doesn't exist/)
1033           : $class->log->debug(q/Couldn't find home/);
1034     }
1035
1036     # Call plugins setup, this is stupid and evil.
1037     # Also screws C3 badly on 5.10, hack to avoid.
1038     {
1039         no warnings qw/redefine/;
1040         local *setup = sub { };
1041         $class->setup unless $Catalyst::__AM_RESTARTING;
1042     }
1043
1044     # Initialize our data structure
1045     $class->components( {} );
1046
1047     $class->setup_components;
1048
1049     if ( $class->debug ) {
1050         my $column_width = Catalyst::Utils::term_width() - 8 - 9;
1051         my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
1052         for my $comp ( sort keys %{ $class->components } ) {
1053             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
1054             $t->row( $comp, $type );
1055         }
1056         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
1057           if ( keys %{ $class->components } );
1058     }
1059
1060     # Add our self to components, since we are also a component
1061     if( $class->isa('Catalyst::Controller') ){
1062       $class->components->{$class} = $class;
1063     }
1064
1065     $class->setup_actions;
1066
1067     if ( $class->debug ) {
1068         my $name = $class->config->{name} || 'Application';
1069         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
1070     }
1071
1072     # Make sure that the application class becomes immutable at this point,
1073     B::Hooks::EndOfScope::on_scope_end {
1074         return if $@;
1075         my $meta = Class::MOP::get_metaclass_by_name($class);
1076         if (
1077             $meta->is_immutable
1078             && ! { $meta->immutable_options }->{replace_constructor}
1079             && (
1080                    $class->isa('Class::Accessor::Fast')
1081                 || $class->isa('Class::Accessor')
1082             )
1083         ) {
1084             warn "You made your application class ($class) immutable, "
1085                 . "but did not inline the\nconstructor. "
1086                 . "This will break catalyst, as your app \@ISA "
1087                 . "Class::Accessor(::Fast)?\nPlease pass "
1088                 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
1089         }
1090         $meta->make_immutable(
1091             replace_constructor => 1,
1092         ) unless $meta->is_immutable;
1093     };
1094
1095     if ($class->config->{case_sensitive}) {
1096         $class->log->warn($class . "->config->{case_sensitive} is set.");
1097         $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81.");
1098     }
1099
1100     $class->setup_finalize;
1101     # Should be the last thing we do so that user things hooking
1102     # setup_finalize can log..
1103     $class->log->_flush() if $class->log->can('_flush');
1104     return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
1105 }
1106
1107 =head2 $app->setup_finalize
1108
1109 A hook to attach modifiers to. This method does not do anything except set the
1110 C<setup_finished> accessor.
1111
1112 Applying method modifiers to the C<setup> method doesn't work, because of quirky things done for plugin setup.
1113
1114 Example:
1115
1116     after setup_finalize => sub {
1117         my $app = shift;
1118
1119         ## do stuff here..
1120     };
1121
1122 =cut
1123
1124 sub setup_finalize {
1125     my ($class) = @_;
1126     $class->setup_finished(1);
1127 }
1128
1129 =head2 $c->uri_for( $path?, @args?, \%query_values? )
1130
1131 =head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
1132
1133 Constructs an absolute L<URI> object based on the application root, the
1134 provided path, and the additional arguments and query parameters provided.
1135 When used as a string, provides a textual URI.  If you need more flexibility
1136 than this (i.e. the option to provide relative URIs etc.) see
1137 L<Catalyst::Plugin::SmartURI>.
1138
1139 If no arguments are provided, the URI for the current action is returned.
1140 To return the current action and also provide @args, use
1141 C<< $c->uri_for( $c->action, @args ) >>.
1142
1143 If the first argument is a string, it is taken as a public URI path relative
1144 to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
1145 relative to the application root (if it does). It is then merged with
1146 C<< $c->request->base >>; any C<@args> are appended as additional path
1147 components; and any C<%query_values> are appended as C<?foo=bar> parameters.
1148
1149 If the first argument is a L<Catalyst::Action> it represents an action which
1150 will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
1151 optional C<\@captures> argument (an arrayref) allows passing the captured
1152 variables that are needed to fill in the paths of Chained and Regex actions;
1153 once the path is resolved, C<uri_for> continues as though a path was
1154 provided, appending any arguments or parameters and creating an absolute
1155 URI.
1156
1157 The captures for the current request can be found in
1158 C<< $c->request->captures >>, and actions can be resolved using
1159 C<< Catalyst::Controller->action_for($name) >>. If you have a private action
1160 path, use C<< $c->uri_for_action >> instead.
1161
1162   # Equivalent to $c->req->uri
1163   $c->uri_for($c->action, $c->req->captures,
1164       @{ $c->req->args }, $c->req->params);
1165
1166   # For the Foo action in the Bar controller
1167   $c->uri_for($c->controller('Bar')->action_for('Foo'));
1168
1169   # Path to a static resource
1170   $c->uri_for('/static/images/logo.png');
1171
1172 =cut
1173
1174 sub uri_for {
1175     my ( $c, $path, @args ) = @_;
1176
1177     if (blessed($path) && $path->isa('Catalyst::Controller')) {
1178         $path = $path->path_prefix;
1179         $path =~ s{/+\z}{};
1180         $path .= '/';
1181     }
1182
1183     undef($path) if (defined $path && $path eq '');
1184
1185     my $params =
1186       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
1187
1188     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
1189     foreach my $arg (@args) {
1190         utf8::encode($arg) if utf8::is_utf8($arg);
1191         $arg =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1192     }
1193
1194     if ( blessed($path) ) { # action object
1195         s|/|%2F|g for @args;
1196         my $captures = [ map { s|/|%2F|g; $_; }
1197                         ( scalar @args && ref $args[0] eq 'ARRAY'
1198                          ? @{ shift(@args) }
1199                          : ()) ];
1200
1201         foreach my $capture (@$captures) {
1202             utf8::encode($capture) if utf8::is_utf8($capture);
1203             $capture =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1204         }
1205
1206         my $action = $path;
1207         $path = $c->dispatcher->uri_for_action($action, $captures);
1208         if (not defined $path) {
1209             $c->log->debug(qq/Can't find uri_for action '$action' @$captures/)
1210                 if $c->debug;
1211             return undef;
1212         }
1213         $path = '/' if $path eq '';
1214     }
1215
1216     unshift(@args, $path);
1217
1218     unless (defined $path && $path =~ s!^/!!) { # in-place strip
1219         my $namespace = $c->namespace;
1220         if (defined $path) { # cheesy hack to handle path '../foo'
1221            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
1222         }
1223         unshift(@args, $namespace || '');
1224     }
1225
1226     # join args with '/', or a blank string
1227     my $args = join('/', grep { defined($_) } @args);
1228     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
1229     $args =~ s!^/+!!;
1230     my $base = $c->req->base;
1231     my $class = ref($base);
1232     $base =~ s{(?<!/)$}{/};
1233
1234     my $query = '';
1235
1236     if (my @keys = keys %$params) {
1237       # somewhat lifted from URI::_query's query_form
1238       $query = '?'.join('&', map {
1239           my $val = $params->{$_};
1240           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1241           s/ /+/g;
1242           my $key = $_;
1243           $val = '' unless defined $val;
1244           (map {
1245               my $param = "$_";
1246               utf8::encode( $param ) if utf8::is_utf8($param);
1247               # using the URI::Escape pattern here so utf8 chars survive
1248               $param =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1249               $param =~ s/ /+/g;
1250               "${key}=$param"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1251       } @keys);
1252     }
1253
1254     my $res = bless(\"${base}${args}${query}", $class);
1255     $res;
1256 }
1257
1258 =head2 $c->uri_for_action( $path, \@captures?, @args?, \%query_values? )
1259
1260 =head2 $c->uri_for_action( $action, \@captures?, @args?, \%query_values? )
1261
1262 =over
1263
1264 =item $path
1265
1266 A private path to the Catalyst action you want to create a URI for.
1267
1268 This is a shortcut for calling C<< $c->dispatcher->get_action_by_path($path)
1269 >> and passing the resulting C<$action> and the remaining arguments to C<<
1270 $c->uri_for >>.
1271
1272 You can also pass in a Catalyst::Action object, in which case it is passed to
1273 C<< $c->uri_for >>.
1274
1275 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.
1276
1277 For example, if the action looks like:
1278
1279  package MyApp::Controller::Users;
1280
1281  sub lst : Path('the-list') {}
1282
1283 You can use:
1284
1285  $c->uri_for_action('/users/lst')
1286
1287 and it will create the URI /users/the-list.
1288
1289 =back
1290
1291 =cut
1292
1293 sub uri_for_action {
1294     my ( $c, $path, @args ) = @_;
1295     my $action = blessed($path)
1296       ? $path
1297       : $c->dispatcher->get_action_by_path($path);
1298     unless (defined $action) {
1299       croak "Can't find action for path '$path'";
1300     }
1301     return $c->uri_for( $action, @args );
1302 }
1303
1304 =head2 $c->welcome_message
1305
1306 Returns the Catalyst welcome HTML page.
1307
1308 =cut
1309
1310 sub welcome_message {
1311     my $c      = shift;
1312     my $name   = $c->config->{name};
1313     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1314     my $prefix = Catalyst::Utils::appprefix( ref $c );
1315     $c->response->content_type('text/html; charset=utf-8');
1316     return <<"EOF";
1317 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1318     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1319 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1320     <head>
1321     <meta http-equiv="Content-Language" content="en" />
1322     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1323         <title>$name on Catalyst $VERSION</title>
1324         <style type="text/css">
1325             body {
1326                 color: #000;
1327                 background-color: #eee;
1328             }
1329             div#content {
1330                 width: 640px;
1331                 margin-left: auto;
1332                 margin-right: auto;
1333                 margin-top: 10px;
1334                 margin-bottom: 10px;
1335                 text-align: left;
1336                 background-color: #ccc;
1337                 border: 1px solid #aaa;
1338             }
1339             p, h1, h2 {
1340                 margin-left: 20px;
1341                 margin-right: 20px;
1342                 font-family: verdana, tahoma, sans-serif;
1343             }
1344             a {
1345                 font-family: verdana, tahoma, sans-serif;
1346             }
1347             :link, :visited {
1348                     text-decoration: none;
1349                     color: #b00;
1350                     border-bottom: 1px dotted #bbb;
1351             }
1352             :link:hover, :visited:hover {
1353                     color: #555;
1354             }
1355             div#topbar {
1356                 margin: 0px;
1357             }
1358             pre {
1359                 margin: 10px;
1360                 padding: 8px;
1361             }
1362             div#answers {
1363                 padding: 8px;
1364                 margin: 10px;
1365                 background-color: #fff;
1366                 border: 1px solid #aaa;
1367             }
1368             h1 {
1369                 font-size: 0.9em;
1370                 font-weight: normal;
1371                 text-align: center;
1372             }
1373             h2 {
1374                 font-size: 1.0em;
1375             }
1376             p {
1377                 font-size: 0.9em;
1378             }
1379             p img {
1380                 float: right;
1381                 margin-left: 10px;
1382             }
1383             span#appname {
1384                 font-weight: bold;
1385                 font-size: 1.6em;
1386             }
1387         </style>
1388     </head>
1389     <body>
1390         <div id="content">
1391             <div id="topbar">
1392                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1393                     $VERSION</h1>
1394              </div>
1395              <div id="answers">
1396                  <p>
1397                  <img src="$logo" alt="Catalyst Logo" />
1398                  </p>
1399                  <p>Welcome to the  world of Catalyst.
1400                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1401                     framework will make web development something you had
1402                     never expected it to be: Fun, rewarding, and quick.</p>
1403                  <h2>What to do now?</h2>
1404                  <p>That really depends  on what <b>you</b> want to do.
1405                     We do, however, provide you with a few starting points.</p>
1406                  <p>If you want to jump right into web development with Catalyst
1407                     you might want to start with a tutorial.</p>
1408 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1409 </pre>
1410 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1411 <pre>
1412 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1413 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1414 </code></pre>
1415                  <h2>What to do next?</h2>
1416                  <p>Next it's time to write an actual application. Use the
1417                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1418                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1419                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1420                     they can save you a lot of work.</p>
1421                     <pre><code>script/${prefix}_create.pl --help</code></pre>
1422                     <p>Also, be sure to check out the vast and growing
1423                     collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
1424                     you are likely to find what you need there.
1425                     </p>
1426
1427                  <h2>Need help?</h2>
1428                  <p>Catalyst has a very active community. Here are the main places to
1429                     get in touch with us.</p>
1430                  <ul>
1431                      <li>
1432                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1433                      </li>
1434                      <li>
1435                          <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
1436                      </li>
1437                      <li>
1438                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1439                      </li>
1440                  </ul>
1441                  <h2>In conclusion</h2>
1442                  <p>The Catalyst team hopes you will enjoy using Catalyst as much
1443                     as we enjoyed making it. Please contact us if you have ideas
1444                     for improvement or other feedback.</p>
1445              </div>
1446          </div>
1447     </body>
1448 </html>
1449 EOF
1450 }
1451
1452 =head1 INTERNAL METHODS
1453
1454 These methods are not meant to be used by end users.
1455
1456 =head2 $c->components
1457
1458 Returns a hash of components.
1459
1460 =cut
1461
1462 around components => sub {
1463     my $orig  = shift;
1464     my $class = shift;
1465     my $comps = shift;
1466
1467     return $class->$orig if ( !$comps );
1468
1469 # FIXME: should this ugly kludge exist?
1470     $class->setup_config unless defined $class->container;
1471
1472 # FIXME: should there be a warning here, not to use this accessor to create the components?
1473     my $components = {};
1474
1475     my $containers;
1476     $containers->{$_} = $class->container->get_sub_container($_) for qw(model view controller);
1477
1478     for my $component ( keys %$comps ) {
1479         $components->{ $component } = $comps->{$component};
1480
1481         my ($type, $name) = _get_component_type_name($component);
1482
1483         $containers->{$type}->add_service(Catalyst::IOC::BlockInjection->new( name => $name, block => sub { return $class->setup_component($component) } ));
1484     }
1485
1486     return $class->$orig($components);
1487 };
1488
1489 =head2 $c->context_class
1490
1491 Returns or sets the context class.
1492
1493 =head2 $c->counter
1494
1495 Returns a hashref containing coderefs and execution counts (needed for
1496 deep recursion detection).
1497
1498 =head2 $c->depth
1499
1500 Returns the number of actions on the current internal execution stack.
1501
1502 =head2 $c->dispatch
1503
1504 Dispatches a request to actions.
1505
1506 =cut
1507
1508 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1509
1510 =head2 $c->dispatcher_class
1511
1512 Returns or sets the dispatcher class.
1513
1514 =head2 $c->dump_these
1515
1516 Returns a list of 2-element array references (name, structure) pairs
1517 that will be dumped on the error page in debug mode.
1518
1519 =cut
1520
1521 sub dump_these {
1522     my $c = shift;
1523     [ Request => $c->req ],
1524     [ Response => $c->res ],
1525     [ Stash => $c->stash ],
1526     [ Config => $c->config ];
1527 }
1528
1529 =head2 $c->engine_class
1530
1531 Returns or sets the engine class.
1532
1533 =head2 $c->execute( $class, $coderef )
1534
1535 Execute a coderef in given class and catch exceptions. Errors are available
1536 via $c->error.
1537
1538 =cut
1539
1540 sub execute {
1541     my ( $c, $class, $code ) = @_;
1542     $class = $c->component($class) || $class;
1543     $c->state(0);
1544
1545     if ( $c->depth >= $RECURSION ) {
1546         my $action = $code->reverse();
1547         $action = "/$action" unless $action =~ /->/;
1548         my $error = qq/Deep recursion detected calling "${action}"/;
1549         $c->log->error($error);
1550         $c->error($error);
1551         $c->state(0);
1552         return $c->state;
1553     }
1554
1555     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1556
1557     push( @{ $c->stack }, $code );
1558
1559     no warnings 'recursion';
1560     # N.B. This used to be combined, but I have seen $c get clobbered if so, and
1561     #      I have no idea how, ergo $ret (which appears to fix the issue)
1562     eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) };
1563
1564     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1565
1566     my $last = pop( @{ $c->stack } );
1567
1568     if ( my $error = $@ ) {
1569         if ( blessed($error) and $error->isa('Catalyst::Exception::Detach') ) {
1570             $error->rethrow if $c->depth > 1;
1571         }
1572         elsif ( blessed($error) and $error->isa('Catalyst::Exception::Go') ) {
1573             $error->rethrow if $c->depth > 0;
1574         }
1575         else {
1576             unless ( ref $error ) {
1577                 no warnings 'uninitialized';
1578                 chomp $error;
1579                 my $class = $last->class;
1580                 my $name  = $last->name;
1581                 $error = qq/Caught exception in $class->$name "$error"/;
1582             }
1583             $c->error($error);
1584         }
1585         $c->state(0);
1586     }
1587     return $c->state;
1588 }
1589
1590 sub _stats_start_execute {
1591     my ( $c, $code ) = @_;
1592     my $appclass = ref($c) || $c;
1593     return if ( ( $code->name =~ /^_.*/ )
1594         && ( !$appclass->config->{show_internal_actions} ) );
1595
1596     my $action_name = $code->reverse();
1597     $c->counter->{$action_name}++;
1598
1599     my $action = $action_name;
1600     $action = "/$action" unless $action =~ /->/;
1601
1602     # determine if the call was the result of a forward
1603     # this is done by walking up the call stack and looking for a calling
1604     # sub of Catalyst::forward before the eval
1605     my $callsub = q{};
1606     for my $index ( 2 .. 11 ) {
1607         last
1608         if ( ( caller($index) )[0] eq 'Catalyst'
1609             && ( caller($index) )[3] eq '(eval)' );
1610
1611         if ( ( caller($index) )[3] =~ /forward$/ ) {
1612             $callsub = ( caller($index) )[3];
1613             $action  = "-> $action";
1614             last;
1615         }
1616     }
1617
1618     my $uid = $action_name . $c->counter->{$action_name};
1619
1620     # is this a root-level call or a forwarded call?
1621     if ( $callsub =~ /forward$/ ) {
1622         my $parent = $c->stack->[-1];
1623
1624         # forward, locate the caller
1625         if ( defined $parent && exists $c->counter->{"$parent"} ) {
1626             $c->stats->profile(
1627                 begin  => $action,
1628                 parent => "$parent" . $c->counter->{"$parent"},
1629                 uid    => $uid,
1630             );
1631         }
1632         else {
1633
1634             # forward with no caller may come from a plugin
1635             $c->stats->profile(
1636                 begin => $action,
1637                 uid   => $uid,
1638             );
1639         }
1640     }
1641     else {
1642
1643         # root-level call
1644         $c->stats->profile(
1645             begin => $action,
1646             uid   => $uid,
1647         );
1648     }
1649     return $action;
1650
1651 }
1652
1653 sub _stats_finish_execute {
1654     my ( $c, $info ) = @_;
1655     $c->stats->profile( end => $info );
1656 }
1657
1658 =head2 $c->finalize
1659
1660 Finalizes the request.
1661
1662 =cut
1663
1664 sub finalize {
1665     my $c = shift;
1666
1667     for my $error ( @{ $c->error } ) {
1668         $c->log->error($error);
1669     }
1670
1671     # Allow engine to handle finalize flow (for POE)
1672     my $engine = $c->engine;
1673     if ( my $code = $engine->can('finalize') ) {
1674         $engine->$code($c);
1675     }
1676     else {
1677
1678         $c->finalize_uploads;
1679
1680         # Error
1681         if ( $#{ $c->error } >= 0 ) {
1682             $c->finalize_error;
1683         }
1684
1685         $c->finalize_headers;
1686
1687         # HEAD request
1688         if ( $c->request->method eq 'HEAD' ) {
1689             $c->response->body('');
1690         }
1691
1692         $c->finalize_body;
1693     }
1694
1695     $c->log_response;
1696
1697     if ($c->use_stats) {
1698         my $elapsed = sprintf '%f', $c->stats->elapsed;
1699         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1700         $c->log->info(
1701             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
1702     }
1703
1704     return $c->response->status;
1705 }
1706
1707 =head2 $c->finalize_body
1708
1709 Finalizes body.
1710
1711 =cut
1712
1713 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1714
1715 =head2 $c->finalize_cookies
1716
1717 Finalizes cookies.
1718
1719 =cut
1720
1721 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1722
1723 =head2 $c->finalize_error
1724
1725 Finalizes error.
1726
1727 =cut
1728
1729 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1730
1731 =head2 $c->finalize_headers
1732
1733 Finalizes headers.
1734
1735 =cut
1736
1737 sub finalize_headers {
1738     my $c = shift;
1739
1740     my $response = $c->response; #accessor calls can add up?
1741
1742     # Check if we already finalized headers
1743     return if $response->finalized_headers;
1744
1745     # Handle redirects
1746     if ( my $location = $response->redirect ) {
1747         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1748         $response->header( Location => $location );
1749
1750         if ( !$response->has_body ) {
1751             # Add a default body if none is already present
1752             $response->body(
1753                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1754             );
1755         }
1756     }
1757
1758     # Content-Length
1759     if ( defined $response->body && length $response->body && !$response->content_length ) {
1760
1761         # get the length from a filehandle
1762         if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' )
1763         {
1764             my $stat = stat $response->body;
1765             if ( $stat && $stat->size > 0 ) {
1766                 $response->content_length( $stat->size );
1767             }
1768             else {
1769                 $c->log->warn('Serving filehandle without a content-length');
1770             }
1771         }
1772         else {
1773             # everything should be bytes at this point, but just in case
1774             $response->content_length( length( $response->body ) );
1775         }
1776     }
1777
1778     # Errors
1779     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1780         $response->headers->remove_header("Content-Length");
1781         $response->body('');
1782     }
1783
1784     $c->finalize_cookies;
1785
1786     $c->engine->finalize_headers( $c, @_ );
1787
1788     # Done
1789     $response->finalized_headers(1);
1790 }
1791
1792 =head2 $c->finalize_output
1793
1794 An alias for finalize_body.
1795
1796 =head2 $c->finalize_read
1797
1798 Finalizes the input after reading is complete.
1799
1800 =cut
1801
1802 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1803
1804 =head2 $c->finalize_uploads
1805
1806 Finalizes uploads. Cleans up any temporary files.
1807
1808 =cut
1809
1810 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1811
1812 =head2 $c->get_action( $action, $namespace )
1813
1814 Gets an action in a given namespace.
1815
1816 =cut
1817
1818 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1819
1820 =head2 $c->get_actions( $action, $namespace )
1821
1822 Gets all actions of a given name in a namespace and all parent
1823 namespaces.
1824
1825 =cut
1826
1827 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1828
1829 =head2 $app->handle_request( @arguments )
1830
1831 Called to handle each HTTP request.
1832
1833 =cut
1834
1835 sub handle_request {
1836     my ( $class, @arguments ) = @_;
1837
1838     # Always expect worst case!
1839     my $status = -1;
1840     eval {
1841         if ($class->debug) {
1842             my $secs = time - $START || 1;
1843             my $av = sprintf '%.3f', $COUNT / $secs;
1844             my $time = localtime time;
1845             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1846         }
1847
1848         my $c = $class->prepare(@arguments);
1849         $c->dispatch;
1850         $status = $c->finalize;
1851     };
1852
1853     if ( my $error = $@ ) {
1854         chomp $error;
1855         $class->log->error(qq/Caught exception in engine "$error"/);
1856     }
1857
1858     $COUNT++;
1859
1860     if(my $coderef = $class->log->can('_flush')){
1861         $class->log->$coderef();
1862     }
1863     return $status;
1864 }
1865
1866 =head2 $c->prepare( @arguments )
1867
1868 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1869 etc.).
1870
1871 =cut
1872
1873 sub prepare {
1874     my ( $class, @arguments ) = @_;
1875
1876     # XXX
1877     # After the app/ctxt split, this should become an attribute based on something passed
1878     # into the application.
1879     $class->context_class( ref $class || $class ) unless $class->context_class;
1880
1881     my $c = $class->context_class->new({});
1882
1883     # For on-demand data
1884     $c->request->_context($c);
1885     $c->response->_context($c);
1886
1887     #surely this is not the most efficient way to do things...
1888     $c->stats($class->stats_class->new)->enable($c->use_stats);
1889     if ( $c->debug || $c->config->{enable_catalyst_header} ) {
1890         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1891     }
1892
1893     #XXX reuse coderef from can
1894     # Allow engine to direct the prepare flow (for POE)
1895     if ( $c->engine->can('prepare') ) {
1896         $c->engine->prepare( $c, @arguments );
1897     }
1898     else {
1899         $c->prepare_request(@arguments);
1900         $c->prepare_connection;
1901         $c->prepare_query_parameters;
1902         $c->prepare_headers;
1903         $c->prepare_cookies;
1904         $c->prepare_path;
1905
1906         # Prepare the body for reading, either by prepare_body
1907         # or the user, if they are using $c->read
1908         $c->prepare_read;
1909
1910         # Parse the body unless the user wants it on-demand
1911         unless ( ref($c)->config->{parse_on_demand} ) {
1912             $c->prepare_body;
1913         }
1914     }
1915
1916     my $method  = $c->req->method  || '';
1917     my $path    = $c->req->path;
1918     $path       = '/' unless length $path;
1919     my $address = $c->req->address || '';
1920
1921     $c->log_request;
1922
1923     $c->prepare_action;
1924
1925     return $c;
1926 }
1927
1928 =head2 $c->prepare_action
1929
1930 Prepares action. See L<Catalyst::Dispatcher>.
1931
1932 =cut
1933
1934 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1935
1936 =head2 $c->prepare_body
1937
1938 Prepares message body.
1939
1940 =cut
1941
1942 sub prepare_body {
1943     my $c = shift;
1944
1945     return if $c->request->_has_body;
1946
1947     # Initialize on-demand data
1948     $c->engine->prepare_body( $c, @_ );
1949     $c->prepare_parameters;
1950     $c->prepare_uploads;
1951 }
1952
1953 =head2 $c->prepare_body_chunk( $chunk )
1954
1955 Prepares a chunk of data before sending it to L<HTTP::Body>.
1956
1957 See L<Catalyst::Engine>.
1958
1959 =cut
1960
1961 sub prepare_body_chunk {
1962     my $c = shift;
1963     $c->engine->prepare_body_chunk( $c, @_ );
1964 }
1965
1966 =head2 $c->prepare_body_parameters
1967
1968 Prepares body parameters.
1969
1970 =cut
1971
1972 sub prepare_body_parameters {
1973     my $c = shift;
1974     $c->engine->prepare_body_parameters( $c, @_ );
1975 }
1976
1977 =head2 $c->prepare_connection
1978
1979 Prepares connection.
1980
1981 =cut
1982
1983 sub prepare_connection {
1984     my $c = shift;
1985     $c->engine->prepare_connection( $c, @_ );
1986 }
1987
1988 =head2 $c->prepare_cookies
1989
1990 Prepares cookies.
1991
1992 =cut
1993
1994 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1995
1996 =head2 $c->prepare_headers
1997
1998 Prepares headers.
1999
2000 =cut
2001
2002 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
2003
2004 =head2 $c->prepare_parameters
2005
2006 Prepares parameters.
2007
2008 =cut
2009
2010 sub prepare_parameters {
2011     my $c = shift;
2012     $c->prepare_body_parameters;
2013     $c->engine->prepare_parameters( $c, @_ );
2014 }
2015
2016 =head2 $c->prepare_path
2017
2018 Prepares path and base.
2019
2020 =cut
2021
2022 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
2023
2024 =head2 $c->prepare_query_parameters
2025
2026 Prepares query parameters.
2027
2028 =cut
2029
2030 sub prepare_query_parameters {
2031     my $c = shift;
2032
2033     $c->engine->prepare_query_parameters( $c, @_ );
2034 }
2035
2036 =head2 $c->log_request
2037
2038 Writes information about the request to the debug logs.  This includes:
2039
2040 =over 4
2041
2042 =item * Request method, path, and remote IP address
2043
2044 =item * Query keywords (see L<Catalyst::Request/query_keywords>)
2045
2046 =item * Request parameters
2047
2048 =item * File uploads
2049
2050 =back
2051
2052 =cut
2053
2054 sub log_request {
2055     my $c = shift;
2056
2057     return unless $c->debug;
2058
2059     my($dump) = grep {$_->[0] eq 'Request' } $c->dump_these;
2060     my $request = $dump->[1];
2061
2062     my ( $method, $path, $address ) = ( $request->method, $request->path, $request->address );
2063     $method ||= '';
2064     $path = '/' unless length $path;
2065     $address ||= '';
2066     $c->log->debug(qq/"$method" request for "$path" from "$address"/);
2067
2068     $c->log_request_headers($request->headers);
2069
2070     if ( my $keywords = $request->query_keywords ) {
2071         $c->log->debug("Query keywords are: $keywords");
2072     }
2073
2074     $c->log_request_parameters( query => $request->query_parameters, $request->_has_body ? (body => $request->body_parameters) : () );
2075
2076     $c->log_request_uploads($request);
2077 }
2078
2079 =head2 $c->log_response
2080
2081 Writes information about the response to the debug logs by calling
2082 C<< $c->log_response_status_line >> and C<< $c->log_response_headers >>.
2083
2084 =cut
2085
2086 sub log_response {
2087     my $c = shift;
2088
2089     return unless $c->debug;
2090
2091     my($dump) = grep {$_->[0] eq 'Response' } $c->dump_these;
2092     my $response = $dump->[1];
2093
2094     $c->log_response_status_line($response);
2095     $c->log_response_headers($response->headers);
2096 }
2097
2098 =head2 $c->log_response_status_line($response)
2099
2100 Writes one line of information about the response to the debug logs.  This includes:
2101
2102 =over 4
2103
2104 =item * Response status code
2105
2106 =item * Content-Type header (if present)
2107
2108 =item * Content-Length header (if present)
2109
2110 =back
2111
2112 =cut
2113
2114 sub log_response_status_line {
2115     my ($c, $response) = @_;
2116
2117     $c->log->debug(
2118         sprintf(
2119             'Response Code: %s; Content-Type: %s; Content-Length: %s',
2120             $response->status                            || 'unknown',
2121             $response->headers->header('Content-Type')   || 'unknown',
2122             $response->headers->header('Content-Length') || 'unknown'
2123         )
2124     );
2125 }
2126
2127 =head2 $c->log_response_headers($headers);
2128
2129 Hook method which can be wrapped by plugins to log the responseheaders.
2130 No-op in the default implementation.
2131
2132 =cut
2133
2134 sub log_response_headers {}
2135
2136 =head2 $c->log_request_parameters( query => {}, body => {} )
2137
2138 Logs request parameters to debug logs
2139
2140 =cut
2141
2142 sub log_request_parameters {
2143     my $c          = shift;
2144     my %all_params = @_;
2145
2146     return unless $c->debug;
2147
2148     my $column_width = Catalyst::Utils::term_width() - 44;
2149     foreach my $type (qw(query body)) {
2150         my $params = $all_params{$type};
2151         next if ! keys %$params;
2152         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] );
2153         for my $key ( sort keys %$params ) {
2154             my $param = $params->{$key};
2155             my $value = defined($param) ? $param : '';
2156             $t->row( $key, ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
2157         }
2158         $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw );
2159     }
2160 }
2161
2162 =head2 $c->log_request_uploads
2163
2164 Logs file uploads included in the request to the debug logs.
2165 The parameter name, filename, file type, and file size are all included in
2166 the debug logs.
2167
2168 =cut
2169
2170 sub log_request_uploads {
2171     my $c = shift;
2172     my $request = shift;
2173     return unless $c->debug;
2174     my $uploads = $request->uploads;
2175     if ( keys %$uploads ) {
2176         my $t = Text::SimpleTable->new(
2177             [ 12, 'Parameter' ],
2178             [ 26, 'Filename' ],
2179             [ 18, 'Type' ],
2180             [ 9,  'Size' ]
2181         );
2182         for my $key ( sort keys %$uploads ) {
2183             my $upload = $uploads->{$key};
2184             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
2185                 $t->row( $key, $u->filename, $u->type, $u->size );
2186             }
2187         }
2188         $c->log->debug( "File Uploads are:\n" . $t->draw );
2189     }
2190 }
2191
2192 =head2 $c->log_request_headers($headers);
2193
2194 Hook method which can be wrapped by plugins to log the request headers.
2195 No-op in the default implementation.
2196
2197 =cut
2198
2199 sub log_request_headers {}
2200
2201 =head2 $c->log_headers($type => $headers)
2202
2203 Logs L<HTTP::Headers> (either request or response) to the debug logs.
2204
2205 =cut
2206
2207 sub log_headers {
2208     my $c       = shift;
2209     my $type    = shift;
2210     my $headers = shift;    # an HTTP::Headers instance
2211
2212     return unless $c->debug;
2213
2214     my $column_width = Catalyst::Utils::term_width() - 28;
2215     my $t = Text::SimpleTable->new( [ 15, 'Header Name' ], [ $column_width, 'Value' ] );
2216     $headers->scan(
2217         sub {
2218             my ( $name, $value ) = @_;
2219             $t->row( $name, $value );
2220         }
2221     );
2222     $c->log->debug( ucfirst($type) . " Headers:\n" . $t->draw );
2223 }
2224
2225
2226 =head2 $c->prepare_read
2227
2228 Prepares the input for reading.
2229
2230 =cut
2231
2232 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
2233
2234 =head2 $c->prepare_request
2235
2236 Prepares the engine request.
2237
2238 =cut
2239
2240 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
2241
2242 =head2 $c->prepare_uploads
2243
2244 Prepares uploads.
2245
2246 =cut
2247
2248 sub prepare_uploads {
2249     my $c = shift;
2250
2251     $c->engine->prepare_uploads( $c, @_ );
2252 }
2253
2254 =head2 $c->prepare_write
2255
2256 Prepares the output for writing.
2257
2258 =cut
2259
2260 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
2261
2262 =head2 $c->request_class
2263
2264 Returns or sets the request class. Defaults to L<Catalyst::Request>.
2265
2266 =head2 $c->response_class
2267
2268 Returns or sets the response class. Defaults to L<Catalyst::Response>.
2269
2270 =head2 $c->read( [$maxlength] )
2271
2272 Reads a chunk of data from the request body. This method is designed to
2273 be used in a while loop, reading C<$maxlength> bytes on every call.
2274 C<$maxlength> defaults to the size of the request if not specified.
2275
2276 You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this
2277 directly.
2278
2279 Warning: If you use read(), Catalyst will not process the body,
2280 so you will not be able to access POST parameters or file uploads via
2281 $c->request.  You must handle all body parsing yourself.
2282
2283 =cut
2284
2285 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
2286
2287 =head2 $c->run
2288
2289 Starts the engine.
2290
2291 =cut
2292
2293 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
2294
2295 =head2 $c->set_action( $action, $code, $namespace, $attrs )
2296
2297 Sets an action in a given namespace.
2298
2299 =cut
2300
2301 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
2302
2303 =head2 $c->setup_actions($component)
2304
2305 Sets up actions for a component.
2306
2307 =cut
2308
2309 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
2310
2311 =head2 $c->setup_config
2312
2313 =cut
2314
2315 sub setup_config {
2316     my $class = shift;
2317
2318     my %args = %{ $class->config || {} };
2319
2320     my @container_classes = ( "${class}::Container", 'Catalyst::IOC::Container');
2321     unshift @container_classes, delete $args{container_class} if exists $args{container_class};
2322
2323     my $container_class = Class::MOP::load_first_existing_class(@container_classes);
2324
2325     my $container = $container_class->new( %args, name => "$class" );
2326     $class->container($container);
2327
2328     my $config = $container->resolve(service => 'config');
2329     $class->config($config);
2330     $class->finalize_config; # back-compat
2331 }
2332
2333 =head2 $c->finalize_config
2334
2335 =cut
2336
2337 sub finalize_config { }
2338
2339 =head2 $c->setup_components
2340
2341 This method is called internally to set up the application's components.
2342
2343 It finds modules by calling the L<locate_components> method, expands them to
2344 package names with the L<expand_component_module> method, and then installs
2345 each component into the application.
2346
2347 The C<setup_components> config option is passed to both of the above methods.
2348
2349 Installation of each component is performed by the L<setup_component> method,
2350 below.
2351
2352 =cut
2353
2354 sub setup_components {
2355     my $class = shift;
2356
2357     my $config  = $class->config->{ setup_components };
2358
2359     my @comps = $class->locate_components($config);
2360     my %comps = map { $_ => 1 } @comps;
2361
2362     my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
2363     $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2364         qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2365     ) if $deprecatedcatalyst_component_names;
2366
2367     for my $component ( @comps ) {
2368
2369         # We pass ignore_loaded here so that overlay files for (e.g.)
2370         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
2371         # we know M::P::O found a file on disk so this is safe
2372
2373         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
2374     }
2375
2376     my $containers;
2377     $containers->{$_} = $class->container->get_sub_container($_) for qw(model view controller);
2378
2379     for my $component (@comps) {
2380         my $instance = $class->components->{ $component } = $class->setup_component($component);
2381         if ( my ($type, $name) = _get_component_type_name($component) ) {
2382             $containers->{$type}->add_service(Catalyst::IOC::BlockInjection->new( name => $name, block => sub { return $instance } ));
2383         }
2384         my @expanded_components = $instance->can('expand_modules')
2385             ? $instance->expand_modules( $component, $config )
2386             : $class->expand_component_module( $component, $config );
2387         for my $component (@expanded_components) {
2388             next if $comps{$component};
2389
2390             $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @expanded_components;
2391             $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2392                 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2393             ) if $deprecatedcatalyst_component_names;
2394
2395             if (my ($type, $name) = _get_component_type_name($component)) {
2396                 $containers->{$type}->add_service(Catalyst::IOC::BlockInjection->new( name => $name, block => sub { return $class->setup_component($component) } ));
2397             }
2398
2399             $class->components->{ $component } = $class->setup_component($component);
2400         }
2401     }
2402
2403     $containers->{model}->make_single_default;
2404     $containers->{view}->make_single_default;
2405 }
2406
2407 # FIXME: should this sub exist?
2408 # should it be moved to Catalyst::Utils,
2409 # or replaced by something already existing there?
2410 sub _get_component_type_name {
2411     my $component = shift;
2412     my @parts     = split /::/, $component;
2413
2414     if (scalar @parts == 1) {
2415         return (undef, $component);
2416     }
2417
2418     while (my $type = shift @parts) {
2419         return ('controller', join '::', @parts)
2420             if $type =~ /^(c|controller)$/i;
2421
2422         return ('model', join '::', @parts)
2423             if $type =~ /^(m|model)$/i;
2424
2425         return ('view', join '::', @parts)
2426             if $type =~ /^(v|view)$/i;
2427     }
2428 }
2429
2430 =head2 $c->locate_components( $setup_component_config )
2431
2432 This method is meant to provide a list of component modules that should be
2433 setup for the application.  By default, it will use L<Module::Pluggable>.
2434
2435 Specify a C<setup_components> config option to pass additional options directly
2436 to L<Module::Pluggable>. To add additional search paths, specify a key named
2437 C<search_extra> as an array reference. Items in the array beginning with C<::>
2438 will have the application class name prepended to them.
2439
2440 =cut
2441
2442 sub locate_components {
2443     my $class  = shift;
2444     my $config = shift;
2445
2446     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
2447     my $extra   = delete $config->{ search_extra } || [];
2448
2449     push @paths, @$extra;
2450
2451     my $locator = Module::Pluggable::Object->new(
2452         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
2453         %$config
2454     );
2455
2456     # XXX think about ditching this sort entirely
2457     my @comps = sort { length $a <=> length $b } $locator->plugins;
2458
2459     return @comps;
2460 }
2461
2462 =head2 $c->expand_component_module( $component, $setup_component_config )
2463
2464 Components found by C<locate_components> will be passed to this method, which
2465 is expected to return a list of component (package) names to be set up.
2466
2467 =cut
2468
2469 sub expand_component_module {
2470     my ($class, $module) = @_;
2471     return Devel::InnerPackage::list_packages( $module );
2472 }
2473
2474 =head2 $c->setup_component
2475
2476 =cut
2477
2478 sub setup_component {
2479     my( $class, $component ) = @_;
2480
2481     unless ( $component->can( 'COMPONENT' ) ) {
2482         return $component;
2483     }
2484
2485     my $suffix = Catalyst::Utils::class2classsuffix( $component );
2486     my $config = $class->config->{ $suffix } || {};
2487     # Stash catalyst_component_name in the config here, so that custom COMPONENT
2488     # methods also pass it. local to avoid pointlessly shitting in config
2489     # for the debug screen, as $component is already the key name.
2490     local $config->{catalyst_component_name} = $component;
2491
2492     my $instance = eval { $component->COMPONENT( $class, $config ); };
2493
2494     if ( my $error = $@ ) {
2495         chomp $error;
2496         Catalyst::Exception->throw(
2497             message => qq/Couldn't instantiate component "$component", "$error"/
2498         );
2499     }
2500     elsif (!blessed $instance) {
2501         my $metaclass = Moose::Util::find_meta($component);
2502         my $method_meta = $metaclass->find_method_by_name('COMPONENT');
2503         my $component_method_from = $method_meta->associated_metaclass->name;
2504         my $value = defined($instance) ? $instance : 'undef';
2505         Catalyst::Exception->throw(
2506             message =>
2507             qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
2508         );
2509     }
2510
2511     return $instance;
2512 }
2513
2514 =head2 $c->setup_dispatcher
2515
2516 Sets up dispatcher.
2517
2518 =cut
2519
2520 sub setup_dispatcher {
2521     my ( $class, $dispatcher ) = @_;
2522
2523     if ($dispatcher) {
2524         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2525     }
2526
2527     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2528         $dispatcher = 'Catalyst::Dispatcher::' . $env;
2529     }
2530
2531     unless ($dispatcher) {
2532         $dispatcher = $class->dispatcher_class;
2533     }
2534
2535     Class::MOP::load_class($dispatcher);
2536
2537     # dispatcher instance
2538     $class->dispatcher( $dispatcher->new );
2539 }
2540
2541 =head2 $c->setup_engine
2542
2543 Sets up engine.
2544
2545 =cut
2546
2547 sub setup_engine {
2548     my ( $class, $engine ) = @_;
2549
2550     if ($engine) {
2551         $engine = 'Catalyst::Engine::' . $engine;
2552     }
2553
2554     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2555         $engine = 'Catalyst::Engine::' . $env;
2556     }
2557
2558     if ( $ENV{MOD_PERL} ) {
2559         my $meta = Class::MOP::get_metaclass_by_name($class);
2560
2561         # create the apache method
2562         $meta->add_method('apache' => sub { shift->engine->apache });
2563
2564         my ( $software, $version ) =
2565           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2566
2567         $version =~ s/_//g;
2568         $version =~ s/(\.[^.]+)\./$1/g;
2569
2570         if ( $software eq 'mod_perl' ) {
2571
2572             if ( !$engine ) {
2573
2574                 if ( $version >= 1.99922 ) {
2575                     $engine = 'Catalyst::Engine::Apache2::MP20';
2576                 }
2577
2578                 elsif ( $version >= 1.9901 ) {
2579                     $engine = 'Catalyst::Engine::Apache2::MP19';
2580                 }
2581
2582                 elsif ( $version >= 1.24 ) {
2583                     $engine = 'Catalyst::Engine::Apache::MP13';
2584                 }
2585
2586                 else {
2587                     Catalyst::Exception->throw( message =>
2588                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2589                 }
2590
2591             }
2592
2593             # install the correct mod_perl handler
2594             if ( $version >= 1.9901 ) {
2595                 *handler = sub  : method {
2596                     shift->handle_request(@_);
2597                 };
2598             }
2599             else {
2600                 *handler = sub ($$) { shift->handle_request(@_) };
2601             }
2602
2603         }
2604
2605         elsif ( $software eq 'Zeus-Perl' ) {
2606             $engine = 'Catalyst::Engine::Zeus';
2607         }
2608
2609         else {
2610             Catalyst::Exception->throw(
2611                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2612         }
2613     }
2614
2615     unless ($engine) {
2616         $engine = $class->engine_class;
2617     }
2618
2619     Class::MOP::load_class($engine);
2620
2621     # check for old engines that are no longer compatible
2622     my $old_engine;
2623     if ( $engine->isa('Catalyst::Engine::Apache')
2624         && !Catalyst::Engine::Apache->VERSION )
2625     {
2626         $old_engine = 1;
2627     }
2628
2629     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2630         && Catalyst::Engine::Server->VERSION le '0.02' )
2631     {
2632         $old_engine = 1;
2633     }
2634
2635     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2636         && $engine->VERSION eq '0.01' )
2637     {
2638         $old_engine = 1;
2639     }
2640
2641     elsif ($engine->isa('Catalyst::Engine::Zeus')
2642         && $engine->VERSION eq '0.01' )
2643     {
2644         $old_engine = 1;
2645     }
2646
2647     if ($old_engine) {
2648         Catalyst::Exception->throw( message =>
2649               qq/Engine "$engine" is not supported by this version of Catalyst/
2650         );
2651     }
2652
2653     # engine instance
2654     $class->engine( $engine->new );
2655 }
2656
2657 =head2 $c->setup_home
2658
2659 Sets up the home directory.
2660
2661 =cut
2662
2663 sub setup_home {
2664     my ( $class, $home ) = @_;
2665
2666     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2667         $home = $env;
2668     }
2669
2670     $home ||= Catalyst::Utils::home($class);
2671
2672     if ($home) {
2673         #I remember recently being scolded for assigning config values like this
2674         $class->config->{home} ||= $home;
2675         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2676     }
2677 }
2678
2679 =head2 $c->setup_log
2680
2681 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
2682 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
2683 log to.
2684
2685 This method also installs a C<debug> method that returns a true value into the
2686 catalyst subclass if the "debug" level is passed in the comma-delimited list,
2687 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
2688
2689 Note that if the log has already been setup, by either a previous call to
2690 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
2691 that this method won't actually set up the log object.
2692
2693 =cut
2694
2695 sub setup_log {
2696     my ( $class, $levels ) = @_;
2697
2698     $levels ||= '';
2699     $levels =~ s/^\s+//;
2700     $levels =~ s/\s+$//;
2701     my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
2702
2703     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2704     if ( defined $env_debug ) {
2705         $levels{debug} = 1 if $env_debug; # Ugly!
2706         delete($levels{debug}) unless $env_debug;
2707     }
2708
2709     unless ( $class->log ) {
2710         $class->log( Catalyst::Log->new(keys %levels) );
2711     }
2712
2713     if ( $levels{debug} ) {
2714         Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
2715         $class->log->debug('Debug messages enabled');
2716     }
2717 }
2718
2719 =head2 $c->setup_plugins
2720
2721 Sets up plugins.
2722
2723 =cut
2724
2725 =head2 $c->setup_stats
2726
2727 Sets up timing statistics class.
2728
2729 =cut
2730
2731 sub setup_stats {
2732     my ( $class, $stats ) = @_;
2733
2734     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2735
2736     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2737     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2738         Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
2739         $class->log->debug('Statistics enabled');
2740     }
2741 }
2742
2743
2744 =head2 $c->registered_plugins
2745
2746 Returns a sorted list of the plugins which have either been stated in the
2747 import list or which have been added via C<< MyApp->plugin(@args); >>.
2748
2749 If passed a given plugin name, it will report a boolean value indicating
2750 whether or not that plugin is loaded.  A fully qualified name is required if
2751 the plugin name does not begin with C<Catalyst::Plugin::>.
2752
2753  if ($c->registered_plugins('Some::Plugin')) {
2754      ...
2755  }
2756
2757 =cut
2758
2759 {
2760
2761     sub registered_plugins {
2762         my $proto = shift;
2763         return sort keys %{ $proto->_plugins } unless @_;
2764         my $plugin = shift;
2765         return 1 if exists $proto->_plugins->{$plugin};
2766         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2767     }
2768
2769     sub _register_plugin {
2770         my ( $proto, $plugin, $instant ) = @_;
2771         my $class = ref $proto || $proto;
2772
2773         Class::MOP::load_class( $plugin );
2774         $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is deprecated and will not work in 5.81" )
2775             if $plugin->isa( 'Catalyst::Component' );
2776         $proto->_plugins->{$plugin} = 1;
2777         unless ($instant) {
2778             my $meta = Class::MOP::get_metaclass_by_name($class);
2779             $meta->superclasses($plugin, $meta->superclasses);
2780         }
2781         return $class;
2782     }
2783
2784     sub setup_plugins {
2785         my ( $class, $plugins ) = @_;
2786
2787         $class->_plugins( {} ) unless $class->_plugins;
2788         $plugins = Data::OptList::mkopt($plugins || []);
2789
2790         my @plugins = map {
2791             [ Catalyst::Utils::resolve_namespace(
2792                   $class . '::Plugin',
2793                   'Catalyst::Plugin', $_->[0]
2794               ),
2795               $_->[1],
2796             ]
2797          } @{ $plugins };
2798
2799         for my $plugin ( reverse @plugins ) {
2800             Class::MOP::load_class($plugin->[0], $plugin->[1]);
2801             my $meta = find_meta($plugin->[0]);
2802             next if $meta && $meta->isa('Moose::Meta::Role');
2803
2804             $class->_register_plugin($plugin->[0]);
2805         }
2806
2807         my @roles =
2808             map  { $_->[0]->name, $_->[1] }
2809             grep { blessed($_->[0]) && $_->[0]->isa('Moose::Meta::Role') }
2810             map  { [find_meta($_->[0]), $_->[1]] }
2811             @plugins;
2812
2813         Moose::Util::apply_all_roles(
2814             $class => @roles
2815         ) if @roles;
2816     }
2817 }
2818
2819 =head2 $c->stack
2820
2821 Returns an arrayref of the internal execution stack (actions that are
2822 currently executing).
2823
2824 =head2 $c->stats
2825
2826 Returns the current timing statistics object. By default Catalyst uses
2827 L<Catalyst::Stats|Catalyst::Stats>, but can be set otherwise with
2828 L<< stats_class|/"$c->stats_class" >>.
2829
2830 Even if L<< -Stats|/"-Stats" >> is not enabled, the stats object is still
2831 available. By enabling it with C< $c->stats->enabled(1) >, it can be used to
2832 profile explicitly, although MyApp.pm still won't profile nor output anything
2833 by itself.
2834
2835 =head2 $c->stats_class
2836
2837 Returns or sets the stats (timing statistics) class. L<Catalyst::Stats|Catalyst::Stats> is used by default.
2838
2839 =head2 $c->use_stats
2840
2841 Returns 1 when L<< stats collection|/"-Stats" >> is enabled.
2842
2843 Note that this is a static method, not an accessor and should be overridden
2844 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
2845
2846 =cut
2847
2848 sub use_stats { 0 }
2849
2850
2851 =head2 $c->write( $data )
2852
2853 Writes $data to the output stream. When using this method directly, you
2854 will need to manually set the C<Content-Length> header to the length of
2855 your output data, if known.
2856
2857 =cut
2858
2859 sub write {
2860     my $c = shift;
2861
2862     # Finalize headers if someone manually writes output
2863     $c->finalize_headers;
2864
2865     return $c->engine->write( $c, @_ );
2866 }
2867
2868 =head2 version
2869
2870 Returns the Catalyst version number. Mostly useful for "powered by"
2871 messages in template systems.
2872
2873 =cut
2874
2875 sub version { return $Catalyst::VERSION }
2876
2877 =head1 CONFIGURATION
2878
2879 There are a number of 'base' config variables which can be set:
2880
2881 =over
2882
2883 =item *
2884
2885 C<default_model> - The default model picked if you say C<< $c->model >>. See L<< /$c->model($name) >>.
2886
2887 =item *
2888
2889 C<default_view> - The default view to be rendered or returned when C<< $c->view >> is called. See L<< /$c->view($name) >>.
2890
2891 =item *
2892
2893 C<home> - The application home directory. In an uninstalled application,
2894 this is the top level application directory. In an installed application,
2895 this will be the directory containing C<< MyApp.pm >>.
2896
2897 =item *
2898
2899 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
2900
2901 =item *
2902
2903 C<name> - The name of the application in debug messages and the debug and
2904 welcome screens
2905
2906 =item *
2907
2908 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
2909 until it is accessed. This allows you to (for example) check authentication (and reject
2910 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
2911
2912 =item *
2913
2914 C<root> - The root directory for templates. Usually this is just a
2915 subdirectory of the home directory, but you can set it to change the
2916 templates to a different directory.
2917
2918 =item *
2919
2920 C<search_extra> - Array reference passed to Module::Pluggable to for additional
2921 namespaces from which components will be loaded (and constructed and stored in
2922 C<< $c->components >>).
2923
2924 =item *
2925
2926 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
2927 to be shown in hit debug tables in the test server.
2928
2929 =item *
2930
2931 C<use_request_uri_for_path> - Controlls if the C<REQUEST_URI> or C<PATH_INFO> environment
2932 variable should be used for determining the request path. See L<Catalyst::Engine::CGI/PATH DECODING>
2933 for more information.
2934
2935 =item *
2936
2937 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
2938
2939 =back
2940
2941 =head1 INTERNAL ACTIONS
2942
2943 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2944 C<_ACTION>, and C<_END>. These are by default not shown in the private
2945 action table, but you can make them visible with a config parameter.
2946
2947     MyApp->config(show_internal_actions => 1);
2948
2949 =head1 ON-DEMAND PARSER
2950
2951 The request body is usually parsed at the beginning of a request,
2952 but if you want to handle input yourself, you can enable on-demand
2953 parsing with a config parameter.
2954
2955     MyApp->config(parse_on_demand => 1);
2956
2957 =head1 PROXY SUPPORT
2958
2959 Many production servers operate using the common double-server approach,
2960 with a lightweight frontend web server passing requests to a larger
2961 backend server. An application running on the backend server must deal
2962 with two problems: the remote user always appears to be C<127.0.0.1> and
2963 the server's hostname will appear to be C<localhost> regardless of the
2964 virtual host that the user connected through.
2965
2966 Catalyst will automatically detect this situation when you are running
2967 the frontend and backend servers on the same machine. The following
2968 changes are made to the request.
2969
2970     $c->req->address is set to the user's real IP address, as read from
2971     the HTTP X-Forwarded-For header.
2972
2973     The host value for $c->req->base and $c->req->uri is set to the real
2974     host, as read from the HTTP X-Forwarded-Host header.
2975
2976 Additionally, you may be running your backend application on an insecure
2977 connection (port 80) while your frontend proxy is running under SSL.  If there
2978 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
2979 tell Catalyst what port the frontend listens on.  This will allow all URIs to
2980 be created properly.
2981
2982 In the case of passing in:
2983
2984     X-Forwarded-Port: 443
2985
2986 All calls to C<uri_for> will result in an https link, as is expected.
2987
2988 Obviously, your web server must support these headers for this to work.
2989
2990 In a more complex server farm environment where you may have your
2991 frontend proxy server(s) on different machines, you will need to set a
2992 configuration option to tell Catalyst to read the proxied data from the
2993 headers.
2994
2995     MyApp->config(using_frontend_proxy => 1);
2996
2997 If you do not wish to use the proxy support at all, you may set:
2998
2999     MyApp->config(ignore_frontend_proxy => 1);
3000
3001 =head1 THREAD SAFETY
3002
3003 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
3004 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
3005 believe the Catalyst core to be thread-safe.
3006
3007 If you plan to operate in a threaded environment, remember that all other
3008 modules you are using must also be thread-safe. Some modules, most notably
3009 L<DBD::SQLite>, are not thread-safe.
3010
3011 =head1 SUPPORT
3012
3013 IRC:
3014
3015     Join #catalyst on irc.perl.org.
3016
3017 Mailing Lists:
3018
3019     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
3020     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
3021
3022 Web:
3023
3024     http://catalyst.perl.org
3025
3026 Wiki:
3027
3028     http://dev.catalyst.perl.org
3029
3030 =head1 SEE ALSO
3031
3032 =head2 L<Task::Catalyst> - All you need to start with Catalyst
3033
3034 =head2 L<Catalyst::Manual> - The Catalyst Manual
3035
3036 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
3037
3038 =head2 L<Catalyst::Engine> - Core engine
3039
3040 =head2 L<Catalyst::Log> - Log class.
3041
3042 =head2 L<Catalyst::Request> - Request object
3043
3044 =head2 L<Catalyst::Response> - Response object
3045
3046 =head2 L<Catalyst::Test> - The test suite.
3047
3048 =head1 PROJECT FOUNDER
3049
3050 sri: Sebastian Riedel <sri@cpan.org>
3051
3052 =head1 CONTRIBUTORS
3053
3054 abw: Andy Wardley
3055
3056 acme: Leon Brocard <leon@astray.com>
3057
3058 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
3059
3060 Andrew Bramble
3061
3062 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
3063
3064 Andrew Ruthven
3065
3066 André Walker
3067
3068 andyg: Andy Grundman <andy@hybridized.org>
3069
3070 audreyt: Audrey Tang
3071
3072 bricas: Brian Cassidy <bricas@cpan.org>
3073
3074 Caelum: Rafael Kitover <rkitover@io.com>
3075
3076 chansen: Christian Hansen
3077
3078 chicks: Christopher Hicks
3079
3080 Chisel Wright C<pause@herlpacker.co.uk>
3081
3082 Danijel Milicevic C<me@danijel.de>
3083
3084 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
3085
3086 David Naughton, C<naughton@umn.edu>
3087
3088 David E. Wheeler
3089
3090 dhoss: Devin Austin <dhoss@cpan.org>
3091
3092 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
3093
3094 Drew Taylor
3095
3096 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
3097
3098 esskar: Sascha Kiefer
3099
3100 fireartist: Carl Franks <cfranks@cpan.org>
3101
3102 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
3103
3104 gabb: Danijel Milicevic
3105
3106 Gary Ashton Jones
3107
3108 Gavin Henry C<ghenry@perl.me.uk>
3109
3110 Geoff Richards
3111
3112 groditi: Guillermo Roditi <groditi@gmail.com>
3113
3114 hobbs: Andrew Rodland <andrew@cleverdomain.org>
3115
3116 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
3117
3118 jcamacho: Juan Camacho
3119
3120 jester: Jesse Sheidlower C<jester@panix.com>
3121
3122 jhannah: Jay Hannah <jay@jays.net>
3123
3124 Jody Belka
3125
3126 Johan Lindstrom
3127
3128 jon: Jon Schutz <jjschutz@cpan.org>
3129
3130 Jonathan Rockway C<< <jrockway@cpan.org> >>
3131
3132 Kieren Diment C<kd@totaldatasolution.com>
3133
3134 konobi: Scott McWhirter <konobi@cpan.org>
3135
3136 marcus: Marcus Ramberg <mramberg@cpan.org>
3137
3138 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
3139
3140 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
3141
3142 mugwump: Sam Vilain
3143
3144 naughton: David Naughton
3145
3146 ningu: David Kamholz <dkamholz@cpan.org>
3147
3148 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
3149
3150 numa: Dan Sully <daniel@cpan.org>
3151
3152 obra: Jesse Vincent
3153
3154 Octavian Rasnita
3155
3156 omega: Andreas Marienborg
3157
3158 Oleg Kostyuk <cub.uanic@gmail.com>
3159
3160 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
3161
3162 rafl: Florian Ragwitz <rafl@debian.org>
3163
3164 random: Roland Lammel <lammel@cpan.org>
3165
3166 Robert Sedlacek C<< <rs@474.at> >>
3167
3168 SpiceMan: Marcel Montes
3169
3170 sky: Arthur Bergman
3171
3172 szbalint: Balint Szilakszi <szbalint@cpan.org>
3173
3174 t0m: Tomas Doran <bobtfish@bobtfish.net>
3175
3176 Ulf Edvinsson
3177
3178 Viljo Marrandi C<vilts@yahoo.com>
3179
3180 Will Hawes C<info@whawes.co.uk>
3181
3182 willert: Sebastian Willert <willert@cpan.org>
3183
3184 wreis: Wallace Reis <wallace@reis.org.br>
3185
3186 Yuval Kogman, C<nothingmuch@woobling.org>
3187
3188 rainboxx: Matthias Dietrich, C<perl@rainboxx.de>
3189
3190 dd070: Dhaval Dhanani <dhaval070@gmail.com>
3191
3192 =head1 COPYRIGHT
3193
3194 Copyright (c) 2005, the above named PROJECT FOUNDER and CONTRIBUTORS.
3195
3196 =head1 LICENSE
3197
3198 This library is free software. You can redistribute it and/or modify it under
3199 the same terms as Perl itself.
3200
3201 =cut
3202
3203 no Moose;
3204
3205 __PACKAGE__->meta->make_immutable;
3206
3207 1;