c3ff12ce24c7412076966f83a24fb8b141f56624
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use Class::C3;
4 use Moose;
5 extends 'Catalyst::Component';
6 use bytes;
7 use Catalyst::Exception;
8 use Catalyst::Log;
9 use Catalyst::Request;
10 use Catalyst::Request::Upload;
11 use Catalyst::Response;
12 use Catalyst::Utils;
13 use Catalyst::Controller;
14 use Devel::InnerPackage ();
15 use File::stat;
16 use Module::Pluggable::Object ();
17 use Text::SimpleTable ();
18 use Path::Class::Dir ();
19 use Path::Class::File ();
20 use Time::HiRes qw/gettimeofday tv_interval/;
21 use URI ();
22 use URI::http;
23 use URI::https;
24 use Scalar::Util qw/weaken blessed/;
25 use Tree::Simple qw/use_weak_refs/;
26 use Tree::Simple::Visitor::FindByUID;
27 use attributes;
28 use utf8;
29 use Carp qw/croak carp/;
30
31 BEGIN { require 5.008001; }
32
33 has stack => (is => 'rw', default => sub { [] });
34 has stash => (is => 'rw', default => sub { {} });
35 has state => (is => 'rw', default => 0);
36 has stats => (is => 'rw');
37 has action => (is => 'rw');
38 has counter => (is => 'rw', default => sub { {} });
39 has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
40 has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
41 has namespace => (is => 'rw');
42
43 no Moose;
44
45 attributes->import( __PACKAGE__, \&namespace, 'lvalue' );
46
47 sub depth { scalar @{ shift->stack || [] }; }
48 sub comp { shift->component(@_) }
49
50 sub req {
51     # carp "the use of req() is deprecated in favour of request()";
52     my $self = shift; return $self->request(@_);
53 }
54 sub res {
55     # carp "the use of res() is deprecated in favour of response()";
56     my $self = shift; return $self->response(@_);
57 }
58
59 # For backwards compatibility
60 sub finalize_output { shift->finalize_body(@_) };
61
62 # For statistics
63 our $COUNT     = 1;
64 our $START     = time;
65 our $RECURSION = 1000;
66 our $DETACH    = "catalyst_detach\n";
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/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.7013';
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(0);
93
94     #why does called have to ISA Catalyst and ISA Controller ?
95     #Convert test suite to not use the behavior where Myapp ISA Controller
96     # after that is done we can eliminate that little mess.
97     unless ( $caller->isa('Catalyst') ) {
98         no strict 'refs';
99         if( $caller->can('meta') ){
100           my @superclasses = ($caller->meta->superclasses, $class, 'Catalyst::Controller');
101           #my @superclasses = ($caller->meta->superclasses, $class);
102           $caller->meta->superclasses(@superclasses);
103         } else {
104           push @{"$caller\::ISA"}, $class, 'Catalyst::Controller';
105           #push @{"$caller\::ISA"}, $class;
106         }
107     }
108
109     $caller->arguments( [@arguments] );
110     $caller->setup_home;
111 }
112
113 =head1 NAME
114
115 Catalyst - The Elegant MVC Web Application Framework
116
117 =head1 SYNOPSIS
118
119 See the L<Catalyst::Manual> distribution for comprehensive
120 documentation and tutorials.
121
122     # Install Catalyst::Devel for helpers and other development tools
123     # use the helper to create a new application
124     catalyst.pl MyApp
125
126     # add models, views, controllers
127     script/myapp_create.pl model MyDatabase DBIC::Schema create=dynamic dbi:SQLite:/path/to/db
128     script/myapp_create.pl view MyTemplate TT
129     script/myapp_create.pl controller Search
130
131     # built in testserver -- use -r to restart automatically on changes
132     # --help to see all available options
133     script/myapp_server.pl
134
135     # command line testing interface
136     script/myapp_test.pl /yada
137
138     ### in lib/MyApp.pm
139     use Catalyst qw/-Debug/; # include plugins here as well
140     
141     ### In lib/MyApp/Controller/Root.pm (autocreated)
142     sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
143         my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
144         $c->stash->{template} = 'foo.tt'; # set the template
145         # lookup something from db -- stash vars are passed to TT
146         $c->stash->{data} = 
147           $c->model('Database::Foo')->search( { country => $args[0] } );
148         if ( $c->req->params->{bar} ) { # access GET or POST parameters
149             $c->forward( 'bar' ); # process another action
150             # do something else after forward returns            
151         }
152     }
153     
154     # The foo.tt TT template can use the stash data from the database
155     [% WHILE (item = data.next) %]
156         [% item.foo %]
157     [% END %]
158     
159     # called for /bar/of/soap, /bar/of/soap/10, etc.
160     sub bar : Path('/bar/of/soap') { ... }
161
162     # called for all actions, from the top-most controller downwards
163     sub auto : Private { 
164         my ( $self, $c ) = @_;
165         if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
166             $c->res->redirect( '/login' ); # require login
167             return 0; # abort request and go immediately to end()
168         }
169         return 1; # success; carry on to next action
170     }
171     
172     # called after all actions are finished
173     sub end : Private { 
174         my ( $self, $c ) = @_;
175         if ( scalar @{ $c->error } ) { ... } # handle errors
176         return if $c->res->body; # already have a response
177         $c->forward( 'MyApp::View::TT' ); # render template
178     }
179
180     ### in MyApp/Controller/Foo.pm
181     # called for /foo/bar
182     sub bar : Local { ... }
183     
184     # called for /blargle
185     sub blargle : Global { ... }
186     
187     # an index action matches /foo, but not /foo/1, etc.
188     sub index : Private { ... }
189     
190     ### in MyApp/Controller/Foo/Bar.pm
191     # called for /foo/bar/baz
192     sub baz : Local { ... }
193     
194     # first Root auto is called, then Foo auto, then this
195     sub auto : Private { ... }
196     
197     # powerful regular expression paths are also possible
198     sub details : Regex('^product/(\w+)/details$') {
199         my ( $self, $c ) = @_;
200         # extract the (\w+) from the URI
201         my $product = $c->req->captures->[0];
202     }
203
204 See L<Catalyst::Manual::Intro> for additional information.
205
206 =head1 DESCRIPTION
207
208 Catalyst is a modern framework for making web applications without the
209 pain usually associated with this process. This document is a reference
210 to the main Catalyst application. If you are a new user, we suggest you
211 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
212
213 See L<Catalyst::Manual> for more documentation.
214
215 Catalyst plugins can be loaded by naming them as arguments to the "use
216 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
217 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
218 C<My::Module>.
219
220     use Catalyst qw/My::Module/;
221
222 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
223 fully qualify the name by using a unary plus:
224
225     use Catalyst qw/
226         My::Module
227         +Fully::Qualified::Plugin::Name
228     /;
229
230 Special flags like C<-Debug> and C<-Engine> can also be specified as
231 arguments when Catalyst is loaded:
232
233     use Catalyst qw/-Debug My::Module/;
234
235 The position of plugins and flags in the chain is important, because
236 they are loaded in the order in which they appear.
237
238 The following flags are supported:
239
240 =head2 -Debug
241
242 Enables debug output. You can also force this setting from the system
243 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
244 settings override the application, with <MYAPP>_DEBUG having the highest
245 priority.
246
247 =head2 -Engine
248
249 Forces Catalyst to use a specific engine. Omit the
250 C<Catalyst::Engine::> prefix of the engine name, i.e.:
251
252     use Catalyst qw/-Engine=CGI/;
253
254 =head2 -Home
255
256 Forces Catalyst to use a specific home directory, e.g.:
257
258     use Catalyst qw[-Home=/usr/mst];
259
260 This can also be done in the shell environment by setting either the
261 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
262 is replaced with the uppercased name of your application, any "::" in
263 the name will be replaced with underscores, e.g. MyApp::Web should use
264 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
265
266 =head2 -Log
267
268 Specifies log level.
269
270 =head2 -Stats
271
272 Enables statistics collection and reporting. You can also force this setting
273 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
274 environment settings override the application, with <MYAPP>_STATS having the
275 highest priority.
276
277 e.g. 
278
279    use Catalyst qw/-Stats=1/
280
281 =head1 METHODS
282
283 =head2 INFORMATION ABOUT THE CURRENT REQUEST
284
285 =head2 $c->action
286
287 Returns a L<Catalyst::Action> object for the current action, which
288 stringifies to the action name. See L<Catalyst::Action>.
289
290 =head2 $c->namespace
291
292 Returns the namespace of the current action, i.e., the URI prefix
293 corresponding to the controller of the current action. For example:
294
295     # in Controller::Foo::Bar
296     $c->namespace; # returns 'foo/bar';
297
298 =head2 $c->request
299
300 =head2 $c->req
301
302 Returns the current L<Catalyst::Request> object, giving access to
303 information about the current client request (including parameters,
304 cookies, HTTP headers, etc.). See L<Catalyst::Request>.
305
306 =head2 REQUEST FLOW HANDLING
307
308 =head2 $c->forward( $action [, \@arguments ] )
309
310 =head2 $c->forward( $class, $method, [, \@arguments ] )
311
312 Forwards processing to another action, by its private name. If you give a
313 class name but no method, C<process()> is called. You may also optionally
314 pass arguments in an arrayref. The action will receive the arguments in
315 C<@_> and C<< $c->req->args >>. Upon returning from the function,
316 C<< $c->req->args >> will be restored to the previous values.
317
318 Any data C<return>ed from the action forwarded to, will be returned by the
319 call to forward.
320
321     my $foodata = $c->forward('/foo');
322     $c->forward('index');
323     $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
324     $c->forward('MyApp::View::TT');
325
326 Note that forward implies an C<<eval { }>> around the call (actually
327 C<execute> does), thus de-fatalizing all 'dies' within the called
328 action. If you want C<die> to propagate you need to do something like:
329
330     $c->forward('foo');
331     die $c->error if $c->error;
332
333 Or make sure to always return true values from your actions and write
334 your code like this:
335
336     $c->forward('foo') || return;
337
338 =cut
339
340 sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
341
342 =head2 $c->detach( $action [, \@arguments ] )
343
344 =head2 $c->detach( $class, $method, [, \@arguments ] )
345
346 =head2 $c->detach()
347
348 The same as C<forward>, but doesn't return to the previous action when 
349 processing is finished. 
350
351 When called with no arguments it escapes the processing chain entirely.
352
353 =cut
354
355 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
356
357 =head2 $c->response
358
359 =head2 $c->res
360
361 Returns the current L<Catalyst::Response> object, see there for details.
362
363 =head2 $c->stash
364
365 Returns a hashref to the stash, which may be used to store data and pass
366 it between components during a request. You can also set hash keys by
367 passing arguments. The stash is automatically sent to the view. The
368 stash is cleared at the end of a request; it cannot be used for
369 persistent storage (for this you must use a session; see
370 L<Catalyst::Plugin::Session> for a complete system integrated with
371 Catalyst).
372
373     $c->stash->{foo} = $bar;
374     $c->stash( { moose => 'majestic', qux => 0 } );
375     $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
376     
377     # stash is automatically passed to the view for use in a template
378     $c->forward( 'MyApp::View::TT' );
379
380 =cut
381
382 sub stash {
383     my $c = shift;
384     if (@_) {
385         my $stash = @_ > 1 ? {@_} : $_[0];
386         croak('stash takes a hash or hashref') unless ref $stash;
387         foreach my $key ( keys %$stash ) {
388             #shouldn't we hold this in a var and save ourselves the subcall?
389             $c->next::method->{$key} = $stash->{$key};
390         }
391     }
392
393     return $c->next::method;
394 }
395
396
397 =head2 $c->error
398
399 =head2 $c->error($error, ...)
400
401 =head2 $c->error($arrayref)
402
403 Returns an arrayref containing error messages.  If Catalyst encounters an
404 error while processing a request, it stores the error in $c->error.  This
405 method should only be used to store fatal error messages.
406
407     my @error = @{ $c->error };
408
409 Add a new error.
410
411     $c->error('Something bad happened');
412
413 =cut
414
415 sub error {
416     my $c = shift;
417     if ( $_[0] ) {
418         my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
419         croak @$error unless ref $c;
420         push @{ $c->{error} }, @$error;
421     }
422     elsif ( defined $_[0] ) { $c->{error} = undef }
423     return $c->{error} || [];
424 }
425
426
427 =head2 $c->state
428
429 Contains the return value of the last executed action.
430
431 =head2 $c->clear_errors
432
433 Clear errors.  You probably don't want to clear the errors unless you are
434 implementing a custom error screen.
435
436 This is equivalent to running
437
438     $c->error(0);
439
440 =cut
441
442 sub clear_errors {
443     my $c = shift;
444     $c->error(0);
445 }
446
447
448 # search via regex
449 sub _comp_search {
450     my ( $c, @names ) = @_;
451
452     foreach my $name (@names) {
453         foreach my $component ( keys %{ $c->components } ) {
454             return $c->components->{$component} if $component =~ /$name/i;
455         }
456     }
457
458     return undef;
459 }
460
461 # try explicit component names
462 sub _comp_explicit {
463     my ( $c, @names ) = @_;
464
465     foreach my $try (@names) {
466         return $c->components->{$try} if ( exists $c->components->{$try} );
467     }
468
469     return undef;
470 }
471
472 # like component, but try just these prefixes before regex searching,
473 #  and do not try to return "sort keys %{ $c->components }"
474 sub _comp_prefixes {
475     my ( $c, $name, @prefixes ) = @_;
476
477     my $appclass = ref $c || $c;
478
479     my @names = map { "${appclass}::${_}::${name}" } @prefixes;
480
481     my $comp = $c->_comp_explicit(@names);
482     return $comp if defined($comp);
483     $comp = $c->_comp_search($name);
484     return $comp;
485 }
486
487 # Find possible names for a prefix 
488
489 sub _comp_names {
490     my ( $c, @prefixes ) = @_;
491
492     my $appclass = ref $c || $c;
493
494     my @pre = map { "${appclass}::${_}::" } @prefixes;
495
496     my @names;
497
498     COMPONENT: foreach my $comp ($c->component) {
499         foreach my $p (@pre) {
500             if ($comp =~ s/^$p//) {
501                 push(@names, $comp);
502                 next COMPONENT;
503             }
504         }
505     }
506
507     return @names;
508 }
509
510 # Return a component if only one matches.
511 sub _comp_singular {
512     my ( $c, @prefixes ) = @_;
513
514     my $appclass = ref $c || $c;
515
516     my ( $comp, $rest ) =
517       map { $c->_comp_search("^${appclass}::${_}::") } @prefixes;
518     return $comp unless $rest;
519 }
520
521 # Filter a component before returning by calling ACCEPT_CONTEXT if available
522 sub _filter_component {
523     my ( $c, $comp, @args ) = @_;
524     if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
525         return $comp->ACCEPT_CONTEXT( $c, @args );
526     }
527     else { return $comp }
528 }
529
530 =head2 COMPONENT ACCESSORS
531
532 =head2 $c->controller($name)
533
534 Gets a L<Catalyst::Controller> instance by name.
535
536     $c->controller('Foo')->do_stuff;
537
538 If the name is omitted, will return the controller for the dispatched
539 action.
540
541 =cut
542
543 sub controller {
544     my ( $c, $name, @args ) = @_;
545     return $c->_filter_component( $c->_comp_prefixes( $name, qw/Controller C/ ),
546         @args )
547       if ($name);
548     return $c->component( $c->action->class );
549 }
550
551 =head2 $c->model($name)
552
553 Gets a L<Catalyst::Model> instance by name.
554
555     $c->model('Foo')->do_stuff;
556
557 Any extra arguments are directly passed to ACCEPT_CONTEXT.
558
559 If the name is omitted, it will look for 
560  - a model object in $c->stash{current_model_instance}, then
561  - a model name in $c->stash->{current_model}, then
562  - a config setting 'default_model', or
563  - check if there is only one model, and return it if that's the case.
564
565 =cut
566
567 sub model {
568     my ( $c, $name, @args ) = @_;
569     return $c->_filter_component( $c->_comp_prefixes( $name, qw/Model M/ ),
570         @args )
571       if $name;
572     if (ref $c) {
573         return $c->stash->{current_model_instance} 
574           if $c->stash->{current_model_instance};
575         return $c->model( $c->stash->{current_model} )
576           if $c->stash->{current_model};
577     }
578     return $c->model( $c->config->{default_model} )
579       if $c->config->{default_model};
580     return $c->_filter_component( $c->_comp_singular(qw/Model M/) );
581
582 }
583
584 =head2 $c->controllers
585
586 Returns the available names which can be passed to $c->controller
587
588 =cut
589
590 sub controllers {
591     my ( $c ) = @_;
592     return $c->_comp_names(qw/Controller C/);
593 }
594
595
596 =head2 $c->view($name)
597
598 Gets a L<Catalyst::View> instance by name.
599
600     $c->view('Foo')->do_stuff;
601
602 Any extra arguments are directly passed to ACCEPT_CONTEXT.
603
604 If the name is omitted, it will look for 
605  - a view object in $c->stash{current_view_instance}, then
606  - a view name in $c->stash->{current_view}, then
607  - a config setting 'default_view', or
608  - check if there is only one view, and return it if that's the case.
609
610 =cut
611
612 sub view {
613     my ( $c, $name, @args ) = @_;
614     return $c->_filter_component( $c->_comp_prefixes( $name, qw/View V/ ),
615         @args )
616       if $name;
617     if (ref $c) {
618         return $c->stash->{current_view_instance} 
619           if $c->stash->{current_view_instance};
620         return $c->view( $c->stash->{current_view} )
621           if $c->stash->{current_view};
622     }
623     return $c->view( $c->config->{default_view} )
624       if $c->config->{default_view};
625     return $c->_filter_component( $c->_comp_singular(qw/View V/) );
626 }
627
628 =head2 $c->models
629
630 Returns the available names which can be passed to $c->model
631
632 =cut
633
634 sub models {
635     my ( $c ) = @_;
636     return $c->_comp_names(qw/Model M/);
637 }
638
639
640 =head2 $c->views
641
642 Returns the available names which can be passed to $c->view
643
644 =cut
645
646 sub views {
647     my ( $c ) = @_;
648     return $c->_comp_names(qw/View V/);
649 }
650
651 =head2 $c->comp($name)
652
653 =head2 $c->component($name)
654
655 Gets a component object by name. This method is not recommended,
656 unless you want to get a specific component by full
657 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
658 should be used instead.
659
660 =cut
661
662 sub component {
663     my $c = shift;
664
665     if (@_) {
666
667         my $name = shift;
668
669         my $appclass = ref $c || $c;
670
671         my @names = (
672             $name, "${appclass}::${name}",
673             map { "${appclass}::${_}::${name}" }
674               qw/Model M Controller C View V/
675         );
676
677         my $comp = $c->_comp_explicit(@names);
678         return $c->_filter_component( $comp, @_ ) if defined($comp);
679
680         $comp = $c->_comp_search($name);
681         return $c->_filter_component( $comp, @_ ) if defined($comp);
682     }
683
684     return sort keys %{ $c->components };
685 }
686
687
688
689 =head2 CLASS DATA AND HELPER CLASSES
690
691 =head2 $c->config
692
693 Returns or takes a hashref containing the application's configuration.
694
695     __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
696
697 You can also use a C<YAML>, C<XML> or C<Config::General> config file
698 like myapp.yml in your applications home directory. See
699 L<Catalyst::Plugin::ConfigLoader>.
700
701     ---
702     db: dsn:SQLite:foo.db
703
704
705 =cut
706
707 sub config {
708     my $c = shift;
709
710     $c->log->warn("Setting config after setup has been run is not a good idea.")
711       if ( @_ and $c->setup_finished );
712
713     $c->next::method(@_);
714 }
715
716 =head2 $c->log
717
718 Returns the logging object instance. Unless it is already set, Catalyst
719 sets this up with a L<Catalyst::Log> object. To use your own log class,
720 set the logger with the C<< __PACKAGE__->log >> method prior to calling
721 C<< __PACKAGE__->setup >>.
722
723  __PACKAGE__->log( MyLogger->new );
724  __PACKAGE__->setup;
725
726 And later:
727
728     $c->log->info( 'Now logging with my own logger!' );
729
730 Your log class should implement the methods described in
731 L<Catalyst::Log>.
732
733
734 =head2 $c->debug
735
736 Overload to enable debug messages (same as -Debug option).
737
738 Note that this is a static method, not an accessor and should be overloaded
739 by declaring "sub debug { 1 }" in your MyApp.pm, not by calling $c->debug(1).
740
741 =cut
742
743 sub debug { 0 }
744
745 =head2 $c->dispatcher
746
747 Returns the dispatcher instance. Stringifies to class name. See
748 L<Catalyst::Dispatcher>.
749
750 =head2 $c->engine
751
752 Returns the engine instance. Stringifies to the class name. See
753 L<Catalyst::Engine>.
754
755
756 =head2 UTILITY METHODS
757
758 =head2 $c->path_to(@path)
759
760 Merges C<@path> with C<< $c->config->{home} >> and returns a
761 L<Path::Class::Dir> object.
762
763 For example:
764
765     $c->path_to( 'db', 'sqlite.db' );
766
767 =cut
768
769 sub path_to {
770     my ( $c, @path ) = @_;
771     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
772     if ( -d $path ) { return $path }
773     else { return Path::Class::File->new( $c->config->{home}, @path ) }
774 }
775
776 =head2 $c->plugin( $name, $class, @args )
777
778 Helper method for plugins. It creates a classdata accessor/mutator and
779 loads and instantiates the given class.
780
781     MyApp->plugin( 'prototype', 'HTML::Prototype' );
782
783     $c->prototype->define_javascript_functions;
784
785 =cut
786
787 sub plugin {
788     my ( $class, $name, $plugin, @args ) = @_;
789     $class->_register_plugin( $plugin, 1 );
790
791     eval { $plugin->import };
792     $class->mk_classdata($name);
793     my $obj;
794     eval { $obj = $plugin->new(@args) };
795
796     if ($@) {
797         Catalyst::Exception->throw( message =>
798               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
799     }
800
801     $class->$name($obj);
802     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
803       if $class->debug;
804 }
805
806 =head2 MyApp->setup
807
808 Initializes the dispatcher and engine, loads any plugins, and loads the
809 model, view, and controller components. You may also specify an array
810 of plugins to load here, if you choose to not load them in the C<use
811 Catalyst> line.
812
813     MyApp->setup;
814     MyApp->setup( qw/-Debug/ );
815
816 =cut
817
818 sub setup {
819     my ( $class, @arguments ) = @_;
820
821     $class->log->warn("Running setup twice is not a good idea.")
822       if ( $class->setup_finished );
823
824     unless ( $class->isa('Catalyst') ) {
825
826         Catalyst::Exception->throw(
827             message => qq/'$class' does not inherit from Catalyst/ );
828     }
829
830     if ( $class->arguments ) {
831         @arguments = ( @arguments, @{ $class->arguments } );
832     }
833
834     # Process options
835     my $flags = {};
836
837     foreach (@arguments) {
838
839         if (/^-Debug$/) {
840             $flags->{log} =
841               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
842         }
843         elsif (/^-(\w+)=?(.*)$/) {
844             $flags->{ lc $1 } = $2;
845         }
846         else {
847             push @{ $flags->{plugins} }, $_;
848         }
849     }
850
851     $class->setup_home( delete $flags->{home} );
852
853     $class->setup_log( delete $flags->{log} );
854     $class->setup_plugins( delete $flags->{plugins} );
855     $class->setup_dispatcher( delete $flags->{dispatcher} );
856     $class->setup_engine( delete $flags->{engine} );
857     $class->setup_stats( delete $flags->{stats} );
858
859     for my $flag ( sort keys %{$flags} ) {
860
861         if ( my $code = $class->can( 'setup_' . $flag ) ) {
862             &$code( $class, delete $flags->{$flag} );
863         }
864         else {
865             $class->log->warn(qq/Unknown flag "$flag"/);
866         }
867     }
868
869     eval { require Catalyst::Devel; };
870     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
871         $class->log->warn(<<"EOF");
872 You are running an old script!
873
874   Please update by running (this will overwrite existing files):
875     catalyst.pl -force -scripts $class
876
877   or (this will not overwrite existing files):
878     catalyst.pl -scripts $class
879
880 EOF
881     }
882     
883     if ( $class->debug ) {
884         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
885
886         if (@plugins) {
887             my $t = Text::SimpleTable->new(74);
888             $t->row($_) for @plugins;
889             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
890         }
891
892         my $dispatcher = $class->dispatcher;
893         my $engine     = $class->engine;
894         my $home       = $class->config->{home};
895
896         $class->log->debug(qq/Loaded dispatcher "$dispatcher"/);
897         $class->log->debug(qq/Loaded engine "$engine"/);
898
899         $home
900           ? ( -d $home )
901           ? $class->log->debug(qq/Found home "$home"/)
902           : $class->log->debug(qq/Home "$home" doesn't exist/)
903           : $class->log->debug(q/Couldn't find home/);
904     }
905
906     # Call plugins setup
907     {
908         no warnings qw/redefine/;
909         local *setup = sub { };
910         $class->setup;
911     }
912
913     # Initialize our data structure
914     $class->components( {} );
915
916     $class->setup_components;
917
918     if ( $class->debug ) {
919         my $t = Text::SimpleTable->new( [ 63, 'Class' ], [ 8, 'Type' ] );
920         for my $comp ( sort keys %{ $class->components } ) {
921             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
922             $t->row( $comp, $type );
923         }
924         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
925           if ( keys %{ $class->components } );
926     }
927
928     # Add our self to components, since we are also a component
929     $class->components->{$class} = $class;
930
931     $class->setup_actions;
932
933     if ( $class->debug ) {
934         my $name = $class->config->{name} || 'Application';
935         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
936     }
937     $class->log->_flush() if $class->log->can('_flush');
938
939     $class->setup_finished(1);
940 }
941
942 =head2 $c->uri_for( $path, @args?, \%query_values? )
943
944 Merges path with C<< $c->request->base >> for absolute URIs and with
945 C<< $c->namespace >> for relative URIs, then returns a normalized L<URI>
946 object. If any args are passed, they are added at the end of the path.
947 If the last argument to C<uri_for> is a hash reference, it is assumed to
948 contain GET parameter key/value pairs, which will be appended to the URI
949 in standard fashion.
950
951 Note that uri_for is destructive to the passed hashref.  Subsequent calls
952 with the same hashref may have unintended results.
953
954 Instead of C<$path>, you can also optionally pass a C<$action> object
955 which will be resolved to a path using
956 C<< $c->dispatcher->uri_for_action >>; if the first element of
957 C<@args> is an arrayref it is treated as a list of captures to be passed
958 to C<uri_for_action>.
959
960 =cut
961
962 sub uri_for {
963     my ( $c, $path, @args ) = @_;
964
965     if ( Scalar::Util::blessed($path) ) { # action object
966         my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
967                          ? shift(@args)
968                          : [] );
969         $path = $c->dispatcher->uri_for_action($path, $captures);
970         return undef unless defined($path);
971         $path = '/' if $path eq '';
972     }
973
974     undef($path) if (defined $path && $path eq '');
975
976     my $params =
977       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
978
979     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
980     s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
981
982     unshift(@args, $path);
983
984     unless (defined $path && $path =~ s!^/!!) { # in-place strip
985         my $namespace = $c->namespace;
986         if (defined $path) { # cheesy hack to handle path '../foo'
987            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
988         }
989         unshift(@args, $namespace || '');
990     }
991     
992     # join args with '/', or a blank string
993     my $args = join('/', grep { defined($_) } @args);
994     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
995     $args =~ s!^/!!;
996     my $base = $c->req->base;
997     my $class = ref($base);
998     $base =~ s{(?<!/)$}{/};
999
1000     my $query = '';
1001
1002     if (my @keys = keys %$params) {
1003       # somewhat lifted from URI::_query's query_form
1004       $query = '?'.join('&', map {
1005           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1006           s/ /+/g;
1007           my $key = $_;
1008           my $val = $params->{$_};
1009           $val = '' unless defined $val;
1010           (map {
1011               $_ = "$_";
1012               utf8::encode( $_ ) if utf8::is_utf8($_);
1013               # using the URI::Escape pattern here so utf8 chars survive
1014               s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1015               s/ /+/g;
1016               "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1017       } @keys);
1018     }
1019
1020     my $res = bless(\"${base}${args}${query}", $class);
1021     $res;
1022 }
1023
1024 =head2 $c->welcome_message
1025
1026 Returns the Catalyst welcome HTML page.
1027
1028 =cut
1029
1030 sub welcome_message {
1031     my $c      = shift;
1032     my $name   = $c->config->{name};
1033     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1034     my $prefix = Catalyst::Utils::appprefix( ref $c );
1035     $c->response->content_type('text/html; charset=utf-8');
1036     return <<"EOF";
1037 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1038     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1039 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1040     <head>
1041     <meta http-equiv="Content-Language" content="en" />
1042     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1043         <title>$name on Catalyst $VERSION</title>
1044         <style type="text/css">
1045             body {
1046                 color: #000;
1047                 background-color: #eee;
1048             }
1049             div#content {
1050                 width: 640px;
1051                 margin-left: auto;
1052                 margin-right: auto;
1053                 margin-top: 10px;
1054                 margin-bottom: 10px;
1055                 text-align: left;
1056                 background-color: #ccc;
1057                 border: 1px solid #aaa;
1058             }
1059             p, h1, h2 {
1060                 margin-left: 20px;
1061                 margin-right: 20px;
1062                 font-family: verdana, tahoma, sans-serif;
1063             }
1064             a {
1065                 font-family: verdana, tahoma, sans-serif;
1066             }
1067             :link, :visited {
1068                     text-decoration: none;
1069                     color: #b00;
1070                     border-bottom: 1px dotted #bbb;
1071             }
1072             :link:hover, :visited:hover {
1073                     color: #555;
1074             }
1075             div#topbar {
1076                 margin: 0px;
1077             }
1078             pre {
1079                 margin: 10px;
1080                 padding: 8px;
1081             }
1082             div#answers {
1083                 padding: 8px;
1084                 margin: 10px;
1085                 background-color: #fff;
1086                 border: 1px solid #aaa;
1087             }
1088             h1 {
1089                 font-size: 0.9em;
1090                 font-weight: normal;
1091                 text-align: center;
1092             }
1093             h2 {
1094                 font-size: 1.0em;
1095             }
1096             p {
1097                 font-size: 0.9em;
1098             }
1099             p img {
1100                 float: right;
1101                 margin-left: 10px;
1102             }
1103             span#appname {
1104                 font-weight: bold;
1105                 font-size: 1.6em;
1106             }
1107         </style>
1108     </head>
1109     <body>
1110         <div id="content">
1111             <div id="topbar">
1112                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1113                     $VERSION</h1>
1114              </div>
1115              <div id="answers">
1116                  <p>
1117                  <img src="$logo" alt="Catalyst Logo" />
1118                  </p>
1119                  <p>Welcome to the  world of Catalyst.
1120                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1121                     framework will make web development something you had
1122                     never expected it to be: Fun, rewarding, and quick.</p>
1123                  <h2>What to do now?</h2>
1124                  <p>That really depends  on what <b>you</b> want to do.
1125                     We do, however, provide you with a few starting points.</p>
1126                  <p>If you want to jump right into web development with Catalyst
1127                     you might want want to start with a tutorial.</p>
1128 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1129 </pre>
1130 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1131 <pre>
1132 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1133 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1134 </code></pre>
1135                  <h2>What to do next?</h2>
1136                  <p>Next it's time to write an actual application. Use the
1137                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1138                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1139                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1140                     they can save you a lot of work.</p>
1141                     <pre><code>script/${prefix}_create.pl -help</code></pre>
1142                     <p>Also, be sure to check out the vast and growing
1143                     collection of <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3APlugin%3A%3A&amp;mode=all">plugins for Catalyst on CPAN</a>;
1144                     you are likely to find what you need there.
1145                     </p>
1146
1147                  <h2>Need help?</h2>
1148                  <p>Catalyst has a very active community. Here are the main places to
1149                     get in touch with us.</p>
1150                  <ul>
1151                      <li>
1152                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1153                      </li>
1154                      <li>
1155                          <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">Mailing-List</a>
1156                      </li>
1157                      <li>
1158                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1159                      </li>
1160                  </ul>
1161                  <h2>In conclusion</h2>
1162                  <p>The Catalyst team hopes you will enjoy using Catalyst as much 
1163                     as we enjoyed making it. Please contact us if you have ideas
1164                     for improvement or other feedback.</p>
1165              </div>
1166          </div>
1167     </body>
1168 </html>
1169 EOF
1170 }
1171
1172 =head1 INTERNAL METHODS
1173
1174 These methods are not meant to be used by end users.
1175
1176 =head2 $c->components
1177
1178 Returns a hash of components.
1179
1180 =head2 $c->context_class
1181
1182 Returns or sets the context class.
1183
1184 =head2 $c->counter
1185
1186 Returns a hashref containing coderefs and execution counts (needed for
1187 deep recursion detection).
1188
1189 =head2 $c->depth
1190
1191 Returns the number of actions on the current internal execution stack.
1192
1193 =head2 $c->dispatch
1194
1195 Dispatches a request to actions.
1196
1197 =cut
1198
1199 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1200
1201 =head2 $c->dispatcher_class
1202
1203 Returns or sets the dispatcher class.
1204
1205 =head2 $c->dump_these
1206
1207 Returns a list of 2-element array references (name, structure) pairs
1208 that will be dumped on the error page in debug mode.
1209
1210 =cut
1211
1212 sub dump_these {
1213     my $c = shift;
1214     [ Request => $c->req ], 
1215     [ Response => $c->res ], 
1216     [ Stash => $c->stash ],
1217     [ Config => $c->config ];
1218 }
1219
1220 =head2 $c->engine_class
1221
1222 Returns or sets the engine class.
1223
1224 =head2 $c->execute( $class, $coderef )
1225
1226 Execute a coderef in given class and catch exceptions. Errors are available
1227 via $c->error.
1228
1229 =cut
1230
1231 sub execute {
1232     my ( $c, $class, $code ) = @_;
1233     $class = $c->component($class) || $class;
1234     $c->state(0);
1235
1236     if ( $c->depth >= $RECURSION ) {
1237         my $action = "$code";
1238         $action = "/$action" unless $action =~ /->/;
1239         my $error = qq/Deep recursion detected calling "$action"/;
1240         $c->log->error($error);
1241         $c->error($error);
1242         $c->state(0);
1243         return $c->state;
1244     }
1245
1246     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1247
1248     push( @{ $c->stack }, $code );
1249     
1250     eval { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ) };
1251
1252     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1253     
1254     my $last = pop( @{ $c->stack } );
1255
1256     if ( my $error = $@ ) {
1257         if ( !ref($error) and $error eq $DETACH ) { die $DETACH if $c->depth > 1 }
1258         else {
1259             unless ( ref $error ) {
1260                 no warnings 'uninitialized';
1261                 chomp $error;
1262                 my $class = $last->class;
1263                 my $name  = $last->name;
1264                 $error = qq/Caught exception in $class->$name "$error"/;
1265             }
1266             $c->error($error);
1267             $c->state(0);
1268         }
1269     }
1270     return $c->state;
1271 }
1272
1273 sub _stats_start_execute {
1274     my ( $c, $code ) = @_;
1275
1276     return if ( ( $code->name =~ /^_.*/ )
1277         && ( !$c->config->{show_internal_actions} ) );
1278
1279     $c->counter->{"$code"}++;
1280
1281     my $action = "$code";
1282     $action = "/$action" unless $action =~ /->/;
1283
1284     # determine if the call was the result of a forward
1285     # this is done by walking up the call stack and looking for a calling
1286     # sub of Catalyst::forward before the eval
1287     my $callsub = q{};
1288     for my $index ( 2 .. 11 ) {
1289         last
1290         if ( ( caller($index) )[0] eq 'Catalyst'
1291             && ( caller($index) )[3] eq '(eval)' );
1292
1293         if ( ( caller($index) )[3] =~ /forward$/ ) {
1294             $callsub = ( caller($index) )[3];
1295             $action  = "-> $action";
1296             last;
1297         }
1298     }
1299
1300     my $uid = "$code" . $c->counter->{"$code"};
1301
1302     # is this a root-level call or a forwarded call?
1303     if ( $callsub =~ /forward$/ ) {
1304
1305         # forward, locate the caller
1306         if ( my $parent = $c->stack->[-1] ) {
1307             $c->stats->profile(
1308                 begin  => $action, 
1309                 parent => "$parent" . $c->counter->{"$parent"},
1310                 uid    => $uid,
1311             );
1312         }
1313         else {
1314
1315             # forward with no caller may come from a plugin
1316             $c->stats->profile(
1317                 begin => $action,
1318                 uid   => $uid,
1319             );
1320         }
1321     }
1322     else {
1323         
1324         # root-level call
1325         $c->stats->profile(
1326             begin => $action,
1327             uid   => $uid,
1328         );
1329     }
1330     return $action;
1331
1332 }
1333
1334 sub _stats_finish_execute {
1335     my ( $c, $info ) = @_;
1336     $c->stats->profile( end => $info );
1337 }
1338
1339 =head2 $c->_localize_fields( sub { }, \%keys );
1340
1341 =cut
1342
1343 #Why does this exist? This is no longer safe and WILL NOT WORK.
1344 # it doesnt seem to be used anywhere. can we remove it?
1345 sub _localize_fields {
1346     my ( $c, $localized, $code ) = ( @_ );
1347
1348     my $request = delete $localized->{request} || {};
1349     my $response = delete $localized->{response} || {};
1350     
1351     local @{ $c }{ keys %$localized } = values %$localized;
1352     local @{ $c->request }{ keys %$request } = values %$request;
1353     local @{ $c->response }{ keys %$response } = values %$response;
1354
1355     $code->();
1356 }
1357
1358 =head2 $c->finalize
1359
1360 Finalizes the request.
1361
1362 =cut
1363
1364 sub finalize {
1365     my $c = shift;
1366
1367     for my $error ( @{ $c->error } ) {
1368         $c->log->error($error);
1369     }
1370
1371     # Allow engine to handle finalize flow (for POE)
1372     my $engine = $c->engine;
1373     if ( my $code = $engine->can('finalize') ) {
1374         $engine->$code($c);
1375     }
1376     else {
1377
1378         $c->finalize_uploads;
1379
1380         # Error
1381         if ( $#{ $c->error } >= 0 ) {
1382             $c->finalize_error;
1383         }
1384
1385         $c->finalize_headers;
1386
1387         # HEAD request
1388         if ( $c->request->method eq 'HEAD' ) {
1389             $c->response->body('');
1390         }
1391
1392         $c->finalize_body;
1393     }
1394     
1395     if ($c->use_stats) {        
1396         my $elapsed = sprintf '%f', $c->stats->elapsed;
1397         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1398         $c->log->info(
1399             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );        
1400     }
1401
1402     return $c->response->status;
1403 }
1404
1405 =head2 $c->finalize_body
1406
1407 Finalizes body.
1408
1409 =cut
1410
1411 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1412
1413 =head2 $c->finalize_cookies
1414
1415 Finalizes cookies.
1416
1417 =cut
1418
1419 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1420
1421 =head2 $c->finalize_error
1422
1423 Finalizes error.
1424
1425 =cut
1426
1427 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1428
1429 =head2 $c->finalize_headers
1430
1431 Finalizes headers.
1432
1433 =cut
1434
1435 sub finalize_headers {
1436     my $c = shift;
1437
1438     my $response = $c->response; #accessor calls can add up?
1439
1440     # Check if we already finalized headers
1441     return if $response->finalized_headers;
1442
1443     # Handle redirects
1444     if ( my $location = $response->redirect ) {
1445         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1446         $response->header( Location => $location );
1447
1448         #Moose TODO: we should probably be using a predicate method here ?
1449         if ( !$response->body ) {
1450             # Add a default body if none is already present
1451             $response->body(
1452                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1453             );
1454         }
1455     }
1456
1457     # Content-Length
1458     if ( $response->body && !$response->content_length ) {
1459
1460         # get the length from a filehandle
1461         if ( blessed( $response->body ) && $response->body->can('read') )
1462         {
1463             my $stat = stat $response->body;
1464             if ( $stat && $stat->size > 0 ) {
1465                 $response->content_length( $stat->size );
1466             }
1467             else {
1468                 $c->log->warn('Serving filehandle without a content-length');
1469             }
1470         }
1471         else {
1472             # everything should be bytes at this point, but just in case
1473             $response->content_length( bytes::length( $response->body ) );
1474         }
1475     }
1476
1477     # Errors
1478     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1479         $response->headers->remove_header("Content-Length");
1480         $response->body('');
1481     }
1482
1483     $c->finalize_cookies;
1484
1485     $c->engine->finalize_headers( $c, @_ );
1486
1487     # Done
1488     $response->finalized_headers(1);
1489 }
1490
1491 =head2 $c->finalize_output
1492
1493 An alias for finalize_body.
1494
1495 =head2 $c->finalize_read
1496
1497 Finalizes the input after reading is complete.
1498
1499 =cut
1500
1501 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1502
1503 =head2 $c->finalize_uploads
1504
1505 Finalizes uploads. Cleans up any temporary files.
1506
1507 =cut
1508
1509 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1510
1511 =head2 $c->get_action( $action, $namespace )
1512
1513 Gets an action in a given namespace.
1514
1515 =cut
1516
1517 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1518
1519 =head2 $c->get_actions( $action, $namespace )
1520
1521 Gets all actions of a given name in a namespace and all parent
1522 namespaces.
1523
1524 =cut
1525
1526 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1527
1528 =head2 $c->handle_request( $class, @arguments )
1529
1530 Called to handle each HTTP request.
1531
1532 =cut
1533
1534 sub handle_request {
1535     my ( $class, @arguments ) = @_;
1536
1537     # Always expect worst case!
1538     my $status = -1;
1539     eval {
1540         if ($class->debug) {
1541             my $secs = time - $START || 1;
1542             my $av = sprintf '%.3f', $COUNT / $secs;
1543             my $time = localtime time;
1544             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1545         }
1546
1547         my $c = $class->prepare(@arguments);
1548         $c->dispatch;
1549         $status = $c->finalize;   
1550     };
1551
1552     if ( my $error = $@ ) {
1553         chomp $error;
1554         $class->log->error(qq/Caught exception in engine "$error"/);
1555     }
1556
1557     $COUNT++;
1558     
1559     if(my $coderef = $class->log->can('_flush')){
1560         $class->log->$coderef();
1561     }
1562     return $status;
1563 }
1564
1565 =head2 $c->prepare( @arguments )
1566
1567 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1568 etc.).
1569
1570 =cut
1571
1572 sub prepare {
1573     my ( $class, @arguments ) = @_;
1574
1575     # XXX
1576     # After the app/ctxt split, this should become an attribute based on something passed
1577     # into the application.
1578     $class->context_class( ref $class || $class ) unless $class->context_class;
1579    
1580     my $c = $class->context_class->new({});
1581
1582     # For on-demand data
1583     $c->request->_context($c);
1584     $c->response->_context($c);
1585
1586     #surely this is not the most efficient way to do things...
1587     $c->stats($class->stats_class->new)->enable($c->use_stats);
1588     if ( $c->debug ) {
1589         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );            
1590     }
1591
1592     #XXX reuse coderef from can
1593     # Allow engine to direct the prepare flow (for POE)
1594     if ( $c->engine->can('prepare') ) {
1595         $c->engine->prepare( $c, @arguments );
1596     }
1597     else {
1598         $c->prepare_request(@arguments);
1599         $c->prepare_connection;
1600         $c->prepare_query_parameters;
1601         $c->prepare_headers;
1602         $c->prepare_cookies;
1603         $c->prepare_path;
1604
1605         # Prepare the body for reading, either by prepare_body
1606         # or the user, if they are using $c->read
1607         $c->prepare_read;
1608         
1609         # Parse the body unless the user wants it on-demand
1610         unless ( $c->config->{parse_on_demand} ) {
1611             $c->prepare_body;
1612         }
1613     }
1614
1615     my $method  = $c->req->method  || '';
1616     my $path    = $c->req->path    || '/';
1617     my $address = $c->req->address || '';
1618
1619     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1620       if $c->debug;
1621
1622     $c->prepare_action;
1623
1624     return $c;
1625 }
1626
1627 =head2 $c->prepare_action
1628
1629 Prepares action. See L<Catalyst::Dispatcher>.
1630
1631 =cut
1632
1633 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1634
1635 =head2 $c->prepare_body
1636
1637 Prepares message body.
1638
1639 =cut
1640
1641 sub prepare_body {
1642     my $c = shift;
1643
1644     #Moose TODO: what is  _body ??
1645     # Do we run for the first time?
1646     return if defined $c->request->{_body};
1647
1648     # Initialize on-demand data
1649     $c->engine->prepare_body( $c, @_ );
1650     $c->prepare_parameters;
1651     $c->prepare_uploads;
1652
1653     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1654         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1655         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1656             my $param = $c->req->body_parameters->{$key};
1657             my $value = defined($param) ? $param : '';
1658             $t->row( $key,
1659                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1660         }
1661         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1662     }
1663 }
1664
1665 =head2 $c->prepare_body_chunk( $chunk )
1666
1667 Prepares a chunk of data before sending it to L<HTTP::Body>.
1668
1669 See L<Catalyst::Engine>.
1670
1671 =cut
1672
1673 sub prepare_body_chunk {
1674     my $c = shift;
1675     $c->engine->prepare_body_chunk( $c, @_ );
1676 }
1677
1678 =head2 $c->prepare_body_parameters
1679
1680 Prepares body parameters.
1681
1682 =cut
1683
1684 sub prepare_body_parameters {
1685     my $c = shift;
1686     $c->engine->prepare_body_parameters( $c, @_ );
1687 }
1688
1689 =head2 $c->prepare_connection
1690
1691 Prepares connection.
1692
1693 =cut
1694
1695 sub prepare_connection {
1696     my $c = shift;
1697     $c->engine->prepare_connection( $c, @_ );
1698 }
1699
1700 =head2 $c->prepare_cookies
1701
1702 Prepares cookies.
1703
1704 =cut
1705
1706 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1707
1708 =head2 $c->prepare_headers
1709
1710 Prepares headers.
1711
1712 =cut
1713
1714 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1715
1716 =head2 $c->prepare_parameters
1717
1718 Prepares parameters.
1719
1720 =cut
1721
1722 sub prepare_parameters {
1723     my $c = shift;
1724     $c->prepare_body_parameters;
1725     $c->engine->prepare_parameters( $c, @_ );
1726 }
1727
1728 =head2 $c->prepare_path
1729
1730 Prepares path and base.
1731
1732 =cut
1733
1734 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1735
1736 =head2 $c->prepare_query_parameters
1737
1738 Prepares query parameters.
1739
1740 =cut
1741
1742 sub prepare_query_parameters {
1743     my $c = shift;
1744
1745     $c->engine->prepare_query_parameters( $c, @_ );
1746
1747     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1748         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1749         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1750             my $param = $c->req->query_parameters->{$key};
1751             my $value = defined($param) ? $param : '';
1752             $t->row( $key,
1753                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1754         }
1755         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1756     }
1757 }
1758
1759 =head2 $c->prepare_read
1760
1761 Prepares the input for reading.
1762
1763 =cut
1764
1765 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1766
1767 =head2 $c->prepare_request
1768
1769 Prepares the engine request.
1770
1771 =cut
1772
1773 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1774
1775 =head2 $c->prepare_uploads
1776
1777 Prepares uploads.
1778
1779 =cut
1780
1781 sub prepare_uploads {
1782     my $c = shift;
1783
1784     $c->engine->prepare_uploads( $c, @_ );
1785
1786     if ( $c->debug && keys %{ $c->request->uploads } ) {
1787         my $t = Text::SimpleTable->new(
1788             [ 12, 'Parameter' ],
1789             [ 26, 'Filename' ],
1790             [ 18, 'Type' ],
1791             [ 9,  'Size' ]
1792         );
1793         for my $key ( sort keys %{ $c->request->uploads } ) {
1794             my $upload = $c->request->uploads->{$key};
1795             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1796                 $t->row( $key, $u->filename, $u->type, $u->size );
1797             }
1798         }
1799         $c->log->debug( "File Uploads are:\n" . $t->draw );
1800     }
1801 }
1802
1803 =head2 $c->prepare_write
1804
1805 Prepares the output for writing.
1806
1807 =cut
1808
1809 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1810
1811 =head2 $c->request_class
1812
1813 Returns or sets the request class.
1814
1815 =head2 $c->response_class
1816
1817 Returns or sets the response class.
1818
1819 =head2 $c->read( [$maxlength] )
1820
1821 Reads a chunk of data from the request body. This method is designed to
1822 be used in a while loop, reading C<$maxlength> bytes on every call.
1823 C<$maxlength> defaults to the size of the request if not specified.
1824
1825 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
1826 directly.
1827
1828 Warning: If you use read(), Catalyst will not process the body,
1829 so you will not be able to access POST parameters or file uploads via
1830 $c->request.  You must handle all body parsing yourself.
1831
1832 =cut
1833
1834 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1835
1836 =head2 $c->run
1837
1838 Starts the engine.
1839
1840 =cut
1841
1842 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1843
1844 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1845
1846 Sets an action in a given namespace.
1847
1848 =cut
1849
1850 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1851
1852 =head2 $c->setup_actions($component)
1853
1854 Sets up actions for a component.
1855
1856 =cut
1857
1858 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1859
1860 =head2 $c->setup_components
1861
1862 Sets up components. Specify a C<setup_components> config option to pass
1863 additional options directly to L<Module::Pluggable>. To add additional
1864 search paths, specify a key named C<search_extra> as an array
1865 reference. Items in the array beginning with C<::> will have the
1866 application class name prepended to them.
1867
1868 =cut
1869
1870 sub setup_components {
1871     my $class = shift;
1872
1873     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
1874     my $config  = $class->config->{ setup_components };
1875     my $extra   = delete $config->{ search_extra } || [];
1876     
1877     push @paths, @$extra;
1878         
1879     my $locator = Module::Pluggable::Object->new(
1880         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1881         %$config
1882     );
1883
1884     my @comps = sort { length $a <=> length $b } $locator->plugins;
1885     my %comps = map { $_ => 1 } @comps;
1886     
1887     for my $component ( @comps ) {
1888
1889         # We pass ignore_loaded here so that overlay files for (e.g.)
1890         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1891         # we know M::P::O found a file on disk so this is safe
1892
1893         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1894         #Class::MOP::load_class($component);
1895
1896         my $module  = $class->setup_component( $component );
1897         my %modules = (
1898             $component => $module,
1899             map {
1900                 $_ => $class->setup_component( $_ )
1901             } grep { 
1902               not exists $comps{$_}
1903             } Devel::InnerPackage::list_packages( $component )
1904         );
1905         
1906         for my $key ( keys %modules ) {
1907             $class->components->{ $key } = $modules{ $key };
1908         }
1909     }
1910 }
1911
1912 =head2 $c->setup_component
1913
1914 =cut
1915
1916 sub setup_component {
1917     my( $class, $component ) = @_;
1918
1919     unless ( $component->can( 'COMPONENT' ) ) {
1920         return $component;
1921     }
1922
1923     my $suffix = Catalyst::Utils::class2classsuffix( $component );
1924     my $config = $class->config->{ $suffix } || {};
1925
1926     my $instance = eval { $component->COMPONENT( $class, $config ); };
1927
1928     if ( my $error = $@ ) {
1929         chomp $error;
1930         Catalyst::Exception->throw(
1931             message => qq/Couldn't instantiate component "$component", "$error"/
1932         );
1933     }
1934
1935     Catalyst::Exception->throw(
1936         message =>
1937         qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
1938     ) unless eval { $instance->can( 'can' ) };
1939
1940     return $instance;
1941 }
1942
1943 =head2 $c->setup_dispatcher
1944
1945 Sets up dispatcher.
1946
1947 =cut
1948
1949 sub setup_dispatcher {
1950     my ( $class, $dispatcher ) = @_;
1951
1952     if ($dispatcher) {
1953         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1954     }
1955
1956     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1957         $dispatcher = 'Catalyst::Dispatcher::' . $env;
1958     }
1959
1960     unless ($dispatcher) {
1961         $dispatcher = $class->dispatcher_class;
1962     }
1963
1964     Class::MOP::load_class($dispatcher);
1965
1966     # dispatcher instance
1967     $class->dispatcher( $dispatcher->new );
1968 }
1969
1970 =head2 $c->setup_engine
1971
1972 Sets up engine.
1973
1974 =cut
1975
1976 sub setup_engine {
1977     my ( $class, $engine ) = @_;
1978
1979     if ($engine) {
1980         $engine = 'Catalyst::Engine::' . $engine;
1981     }
1982
1983     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1984         $engine = 'Catalyst::Engine::' . $env;
1985     }
1986
1987     if ( $ENV{MOD_PERL} ) {
1988
1989         # create the apache method
1990         {
1991             no strict 'refs';
1992             *{"$class\::apache"} = sub { shift->engine->apache };
1993         }
1994
1995         my ( $software, $version ) =
1996           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1997
1998         $version =~ s/_//g;
1999         $version =~ s/(\.[^.]+)\./$1/g;
2000
2001         if ( $software eq 'mod_perl' ) {
2002
2003             if ( !$engine ) {
2004
2005                 if ( $version >= 1.99922 ) {
2006                     $engine = 'Catalyst::Engine::Apache2::MP20';
2007                 }
2008
2009                 elsif ( $version >= 1.9901 ) {
2010                     $engine = 'Catalyst::Engine::Apache2::MP19';
2011                 }
2012
2013                 elsif ( $version >= 1.24 ) {
2014                     $engine = 'Catalyst::Engine::Apache::MP13';
2015                 }
2016
2017                 else {
2018                     Catalyst::Exception->throw( message =>
2019                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2020                 }
2021
2022             }
2023
2024             # install the correct mod_perl handler
2025             if ( $version >= 1.9901 ) {
2026                 *handler = sub  : method {
2027                     shift->handle_request(@_);
2028                 };
2029             }
2030             else {
2031                 *handler = sub ($$) { shift->handle_request(@_) };
2032             }
2033
2034         }
2035
2036         elsif ( $software eq 'Zeus-Perl' ) {
2037             $engine = 'Catalyst::Engine::Zeus';
2038         }
2039
2040         else {
2041             Catalyst::Exception->throw(
2042                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2043         }
2044     }
2045
2046     unless ($engine) {
2047         $engine = $class->engine_class;
2048     }
2049
2050     Class::MOP::load_class($engine);
2051     #unless (Class::Inspector->loaded($engine)) {
2052     #    require Class::Inspector->filename($engine);
2053     #}
2054
2055     # check for old engines that are no longer compatible
2056     my $old_engine;
2057     if ( $engine->isa('Catalyst::Engine::Apache')
2058         && !Catalyst::Engine::Apache->VERSION )
2059     {
2060         $old_engine = 1;
2061     }
2062
2063     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2064         && Catalyst::Engine::Server->VERSION le '0.02' )
2065     {
2066         $old_engine = 1;
2067     }
2068
2069     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2070         && $engine->VERSION eq '0.01' )
2071     {
2072         $old_engine = 1;
2073     }
2074
2075     elsif ($engine->isa('Catalyst::Engine::Zeus')
2076         && $engine->VERSION eq '0.01' )
2077     {
2078         $old_engine = 1;
2079     }
2080
2081     if ($old_engine) {
2082         Catalyst::Exception->throw( message =>
2083               qq/Engine "$engine" is not supported by this version of Catalyst/
2084         );
2085     }
2086
2087     # engine instance
2088     $class->engine( $engine->new );
2089 }
2090
2091 =head2 $c->setup_home
2092
2093 Sets up the home directory.
2094
2095 =cut
2096
2097 sub setup_home {
2098     my ( $class, $home ) = @_;
2099
2100     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2101         $home = $env;
2102     }
2103
2104     $home ||= Catalyst::Utils::home($class);
2105
2106     if ($home) {
2107         #I remember recently being scolded for assigning config values like this
2108         $class->config->{home} ||= $home;
2109         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2110     }
2111 }
2112
2113 =head2 $c->setup_log
2114
2115 Sets up log.
2116
2117 =cut
2118
2119 sub setup_log {
2120     my ( $class, $debug ) = @_;
2121
2122     unless ( $class->log ) {
2123         $class->log( Catalyst::Log->new );
2124     }
2125
2126     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2127     if ( defined($env_debug) ? $env_debug : $debug ) {
2128         no strict 'refs';
2129         #Moose todo: dying to be made a bool attribute
2130         *{"$class\::debug"} = sub { 1 };
2131         $class->log->debug('Debug messages enabled');
2132     }
2133 }
2134
2135 =head2 $c->setup_plugins
2136
2137 Sets up plugins.
2138
2139 =cut
2140
2141 =head2 $c->setup_stats
2142
2143 Sets up timing statistics class.
2144
2145 =cut
2146
2147 sub setup_stats {
2148     my ( $class, $stats ) = @_;
2149
2150     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2151
2152     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2153     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2154         no strict 'refs';
2155         #Moose todo: dying to be made a bool attribute
2156         *{"$class\::use_stats"} = sub { 1 };
2157         $class->log->debug('Statistics enabled');
2158     }
2159 }
2160
2161
2162 =head2 $c->registered_plugins 
2163
2164 Returns a sorted list of the plugins which have either been stated in the
2165 import list or which have been added via C<< MyApp->plugin(@args); >>.
2166
2167 If passed a given plugin name, it will report a boolean value indicating
2168 whether or not that plugin is loaded.  A fully qualified name is required if
2169 the plugin name does not begin with C<Catalyst::Plugin::>.
2170
2171  if ($c->registered_plugins('Some::Plugin')) {
2172      ...
2173  }
2174
2175 =cut
2176
2177 {
2178
2179     sub registered_plugins {
2180         my $proto = shift;
2181         return sort keys %{ $proto->_plugins } unless @_;
2182         my $plugin = shift;
2183         return 1 if exists $proto->_plugins->{$plugin};
2184         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2185     }
2186
2187     sub _register_plugin {
2188         my ( $proto, $plugin, $instant ) = @_;
2189         my $class = ref $proto || $proto;
2190
2191         # no ignore_loaded here, the plugin may already have been
2192         # defined in memory and we don't want to error on "no file" if so
2193
2194         Class::MOP::load_class( $plugin );
2195
2196         $proto->_plugins->{$plugin} = 1;
2197         unless ($instant) {
2198             no strict 'refs';
2199             if( $class->can('meta') ){
2200               my @superclasses = ($plugin, $class->meta->superclasses );
2201               $class->meta->superclasses(@superclasses);
2202             } else {
2203               unshift @{"$class\::ISA"}, $plugin;
2204             }
2205         }
2206         return $class;
2207     }
2208
2209     sub setup_plugins {
2210         my ( $class, $plugins ) = @_;
2211
2212         $class->_plugins( {} ) unless $class->_plugins;
2213         $plugins ||= [];
2214         for my $plugin ( reverse @$plugins ) {
2215
2216             unless ( $plugin =~ s/\A\+// ) {
2217                 $plugin = "Catalyst::Plugin::$plugin";
2218             }
2219
2220             $class->_register_plugin($plugin);
2221         }
2222     }
2223 }
2224
2225 =head2 $c->stack
2226
2227 Returns an arrayref of the internal execution stack (actions that are
2228 currently executing).
2229
2230 =head2 $c->stats_class
2231
2232 Returns or sets the stats (timing statistics) class.
2233
2234 =head2 $c->use_stats
2235
2236 Returns 1 when stats collection is enabled.  Stats collection is enabled
2237 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2238 environment variable is set.
2239
2240 Note that this is a static method, not an accessor and should be overloaded
2241 by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2242
2243 =cut
2244
2245 sub use_stats { 0 }
2246
2247
2248 =head2 $c->write( $data )
2249
2250 Writes $data to the output stream. When using this method directly, you
2251 will need to manually set the C<Content-Length> header to the length of
2252 your output data, if known.
2253
2254 =cut
2255
2256 sub write {
2257     my $c = shift;
2258
2259     # Finalize headers if someone manually writes output
2260     $c->finalize_headers;
2261
2262     return $c->engine->write( $c, @_ );
2263 }
2264
2265 =head2 version
2266
2267 Returns the Catalyst version number. Mostly useful for "powered by"
2268 messages in template systems.
2269
2270 =cut
2271
2272 sub version { return $Catalyst::VERSION }
2273
2274 =head1 INTERNAL ACTIONS
2275
2276 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2277 C<_ACTION>, and C<_END>. These are by default not shown in the private
2278 action table, but you can make them visible with a config parameter.
2279
2280     MyApp->config->{show_internal_actions} = 1;
2281
2282 =head1 CASE SENSITIVITY
2283
2284 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2285 mapped to C</foo/bar>. You can activate case sensitivity with a config
2286 parameter.
2287
2288     MyApp->config->{case_sensitive} = 1;
2289
2290 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2291
2292 =head1 ON-DEMAND PARSER
2293
2294 The request body is usually parsed at the beginning of a request,
2295 but if you want to handle input yourself, you can enable on-demand
2296 parsing with a config parameter.
2297
2298     MyApp->config->{parse_on_demand} = 1;
2299     
2300 =head1 PROXY SUPPORT
2301
2302 Many production servers operate using the common double-server approach,
2303 with a lightweight frontend web server passing requests to a larger
2304 backend server. An application running on the backend server must deal
2305 with two problems: the remote user always appears to be C<127.0.0.1> and
2306 the server's hostname will appear to be C<localhost> regardless of the
2307 virtual host that the user connected through.
2308
2309 Catalyst will automatically detect this situation when you are running
2310 the frontend and backend servers on the same machine. The following
2311 changes are made to the request.
2312
2313     $c->req->address is set to the user's real IP address, as read from 
2314     the HTTP X-Forwarded-For header.
2315     
2316     The host value for $c->req->base and $c->req->uri is set to the real
2317     host, as read from the HTTP X-Forwarded-Host header.
2318
2319 Obviously, your web server must support these headers for this to work.
2320
2321 In a more complex server farm environment where you may have your
2322 frontend proxy server(s) on different machines, you will need to set a
2323 configuration option to tell Catalyst to read the proxied data from the
2324 headers.
2325
2326     MyApp->config->{using_frontend_proxy} = 1;
2327     
2328 If you do not wish to use the proxy support at all, you may set:
2329
2330     MyApp->config->{ignore_frontend_proxy} = 1;
2331
2332 =head1 THREAD SAFETY
2333
2334 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2335 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2336 believe the Catalyst core to be thread-safe.
2337
2338 If you plan to operate in a threaded environment, remember that all other
2339 modules you are using must also be thread-safe. Some modules, most notably
2340 L<DBD::SQLite>, are not thread-safe.
2341
2342 =head1 SUPPORT
2343
2344 IRC:
2345
2346     Join #catalyst on irc.perl.org.
2347
2348 Mailing Lists:
2349
2350     http://lists.rawmode.org/mailman/listinfo/catalyst
2351     http://lists.rawmode.org/mailman/listinfo/catalyst-dev
2352
2353 Web:
2354
2355     http://catalyst.perl.org
2356
2357 Wiki:
2358
2359     http://dev.catalyst.perl.org
2360
2361 =head1 SEE ALSO
2362
2363 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2364
2365 =head2 L<Catalyst::Manual> - The Catalyst Manual
2366
2367 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2368
2369 =head2 L<Catalyst::Engine> - Core engine
2370
2371 =head2 L<Catalyst::Log> - Log class.
2372
2373 =head2 L<Catalyst::Request> - Request object
2374
2375 =head2 L<Catalyst::Response> - Response object
2376
2377 =head2 L<Catalyst::Test> - The test suite.
2378
2379 =head1 CREDITS
2380
2381 Andy Grundman
2382
2383 Andy Wardley
2384
2385 Andreas Marienborg
2386
2387 Andrew Bramble
2388
2389 Andrew Ford
2390
2391 Andrew Ruthven
2392
2393 Arthur Bergman
2394
2395 Autrijus Tang
2396
2397 Brian Cassidy
2398
2399 Carl Franks
2400
2401 Christian Hansen
2402
2403 Christopher Hicks
2404
2405 Dan Sully
2406
2407 Danijel Milicevic
2408
2409 David Kamholz
2410
2411 David Naughton
2412
2413 Drew Taylor
2414
2415 Gary Ashton Jones
2416
2417 Geoff Richards
2418
2419 Jesse Sheidlower
2420
2421 Jesse Vincent
2422
2423 Jody Belka
2424
2425 Johan Lindstrom
2426
2427 Juan Camacho
2428
2429 Leon Brocard
2430
2431 Marcus Ramberg
2432
2433 Matt S Trout
2434
2435 Robert Sedlacek
2436
2437 Sam Vilain
2438
2439 Sascha Kiefer
2440
2441 Sebastian Willert
2442
2443 Tatsuhiko Miyagawa
2444
2445 Ulf Edvinsson
2446
2447 Yuval Kogman
2448
2449 =head1 AUTHOR
2450
2451 Sebastian Riedel, C<sri@oook.de>
2452
2453 =head1 LICENSE
2454
2455 This library is free software, you can redistribute it and/or modify it under
2456 the same terms as Perl itself.
2457
2458 =cut
2459
2460 1;