Updated Catalyst::Request and Catalyst::Response to have sensible defaults for attributes
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use Moose;
4 extends 'Catalyst::Component';
5 use bytes;
6 use Catalyst::Exception;
7 use Catalyst::Log;
8 use Catalyst::Request;
9 use Catalyst::Request::Upload;
10 use Catalyst::Response;
11 use Catalyst::Utils;
12 use Catalyst::Controller;
13 use Devel::InnerPackage ();
14 use File::stat;
15 use Module::Pluggable::Object ();
16 use Text::SimpleTable ();
17 use Path::Class::Dir ();
18 use Path::Class::File ();
19 use Time::HiRes qw/gettimeofday tv_interval/;
20 use URI ();
21 use URI::http;
22 use URI::https;
23 use Scalar::Util qw/weaken blessed/;
24 use Tree::Simple qw/use_weak_refs/;
25 use Tree::Simple::Visitor::FindByUID;
26 use attributes;
27 use utf8;
28 use Carp qw/croak carp/;
29
30 BEGIN { require 5.008001; }
31
32 has stack => (is => 'rw', default => sub { [] });
33 has stash => (is => 'rw', default => sub { {} });
34 has state => (is => 'rw', default => 0);
35 has stats => (is => 'rw');
36 has action => (is => 'rw');
37 has counter => (is => 'rw', default => sub { {} });
38 has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
39 has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
40 has namespace => (is => 'rw');
41
42
43 attributes->import( __PACKAGE__, \&namespace, 'lvalue' );
44
45 sub depth { scalar @{ shift->stack || [] }; }
46
47 # Laziness++
48 *comp = \&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 *finalize_output = \&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 around stash => sub {
383     my $orig = shift;
384     my $c = shift;
385
386     my $orig_stash = $c->$orig();
387     if (@_) {
388         my $stash = @_ > 1 ? {@_} : $_[0];
389         croak('stash takes a hash or hashref') unless ref $stash;
390         foreach my $key ( keys %$stash ) {
391             $orig_stash->{$key} = $stash->{$key};
392         }
393     }
394     return $orig_stash;
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 around config => sub {
708     my $orig = shift;
709     my $c = shift;
710
711     $c->log->warn("Setting config after setup has been run is not a good idea.")
712       if ( @_ and $c->setup_finished );
713
714     $c->$orig(@_);
715 };
716
717 =head2 $c->log
718
719 Returns the logging object instance. Unless it is already set, Catalyst
720 sets this up with a L<Catalyst::Log> object. To use your own log class,
721 set the logger with the C<< __PACKAGE__->log >> method prior to calling
722 C<< __PACKAGE__->setup >>.
723
724  __PACKAGE__->log( MyLogger->new );
725  __PACKAGE__->setup;
726
727 And later:
728
729     $c->log->info( 'Now logging with my own logger!' );
730
731 Your log class should implement the methods described in
732 L<Catalyst::Log>.
733
734
735 =head2 $c->debug
736
737 Overload to enable debug messages (same as -Debug option).
738
739 Note that this is a static method, not an accessor and should be overloaded
740 by declaring "sub debug { 1 }" in your MyApp.pm, not by calling $c->debug(1).
741
742 =cut
743
744 sub debug { 0 }
745
746 =head2 $c->dispatcher
747
748 Returns the dispatcher instance. Stringifies to class name. See
749 L<Catalyst::Dispatcher>.
750
751 =head2 $c->engine
752
753 Returns the engine instance. Stringifies to the class name. See
754 L<Catalyst::Engine>.
755
756
757 =head2 UTILITY METHODS
758
759 =head2 $c->path_to(@path)
760
761 Merges C<@path> with C<< $c->config->{home} >> and returns a
762 L<Path::Class::Dir> object.
763
764 For example:
765
766     $c->path_to( 'db', 'sqlite.db' );
767
768 =cut
769
770 sub path_to {
771     my ( $c, @path ) = @_;
772     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
773     if ( -d $path ) { return $path }
774     else { return Path::Class::File->new( $c->config->{home}, @path ) }
775 }
776
777 =head2 $c->plugin( $name, $class, @args )
778
779 Helper method for plugins. It creates a classdata accessor/mutator and
780 loads and instantiates the given class.
781
782     MyApp->plugin( 'prototype', 'HTML::Prototype' );
783
784     $c->prototype->define_javascript_functions;
785
786 =cut
787
788 sub plugin {
789     my ( $class, $name, $plugin, @args ) = @_;
790     $class->_register_plugin( $plugin, 1 );
791
792     eval { $plugin->import };
793     $class->mk_classdata($name);
794     my $obj;
795     eval { $obj = $plugin->new(@args) };
796
797     if ($@) {
798         Catalyst::Exception->throw( message =>
799               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
800     }
801
802     $class->$name($obj);
803     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
804       if $class->debug;
805 }
806
807 =head2 MyApp->setup
808
809 Initializes the dispatcher and engine, loads any plugins, and loads the
810 model, view, and controller components. You may also specify an array
811 of plugins to load here, if you choose to not load them in the C<use
812 Catalyst> line.
813
814     MyApp->setup;
815     MyApp->setup( qw/-Debug/ );
816
817 =cut
818
819 sub setup {
820     my ( $class, @arguments ) = @_;
821
822     $class->log->warn("Running setup twice is not a good idea.")
823       if ( $class->setup_finished );
824
825     unless ( $class->isa('Catalyst') ) {
826
827         Catalyst::Exception->throw(
828             message => qq/'$class' does not inherit from Catalyst/ );
829     }
830
831     if ( $class->arguments ) {
832         @arguments = ( @arguments, @{ $class->arguments } );
833     }
834
835     # Process options
836     my $flags = {};
837
838     foreach (@arguments) {
839
840         if (/^-Debug$/) {
841             $flags->{log} =
842               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
843         }
844         elsif (/^-(\w+)=?(.*)$/) {
845             $flags->{ lc $1 } = $2;
846         }
847         else {
848             push @{ $flags->{plugins} }, $_;
849         }
850     }
851
852     $class->setup_home( delete $flags->{home} );
853
854     $class->setup_log( delete $flags->{log} );
855     $class->setup_plugins( delete $flags->{plugins} );
856     $class->setup_dispatcher( delete $flags->{dispatcher} );
857     $class->setup_engine( delete $flags->{engine} );
858     $class->setup_stats( delete $flags->{stats} );
859
860     for my $flag ( sort keys %{$flags} ) {
861
862         if ( my $code = $class->can( 'setup_' . $flag ) ) {
863             &$code( $class, delete $flags->{$flag} );
864         }
865         else {
866             $class->log->warn(qq/Unknown flag "$flag"/);
867         }
868     }
869
870     eval { require Catalyst::Devel; };
871     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
872         $class->log->warn(<<"EOF");
873 You are running an old script!
874
875   Please update by running (this will overwrite existing files):
876     catalyst.pl -force -scripts $class
877
878   or (this will not overwrite existing files):
879     catalyst.pl -scripts $class
880
881 EOF
882     }
883     
884     if ( $class->debug ) {
885         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
886
887         if (@plugins) {
888             my $t = Text::SimpleTable->new(74);
889             $t->row($_) for @plugins;
890             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
891         }
892
893         my $dispatcher = $class->dispatcher;
894         my $engine     = $class->engine;
895         my $home       = $class->config->{home};
896
897         $class->log->debug(qq/Loaded dispatcher "$dispatcher"/);
898         $class->log->debug(qq/Loaded engine "$engine"/);
899
900         $home
901           ? ( -d $home )
902           ? $class->log->debug(qq/Found home "$home"/)
903           : $class->log->debug(qq/Home "$home" doesn't exist/)
904           : $class->log->debug(q/Couldn't find home/);
905     }
906
907     # Call plugins setup
908     {
909         no warnings qw/redefine/;
910         local *setup = sub { };
911         $class->setup;
912     }
913
914     # Initialize our data structure
915     $class->components( {} );
916
917     $class->setup_components;
918
919     if ( $class->debug ) {
920         my $t = Text::SimpleTable->new( [ 63, 'Class' ], [ 8, 'Type' ] );
921         for my $comp ( sort keys %{ $class->components } ) {
922             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
923             $t->row( $comp, $type );
924         }
925         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
926           if ( keys %{ $class->components } );
927     }
928
929     # Add our self to components, since we are also a component
930     $class->components->{$class} = $class;
931
932     $class->setup_actions;
933
934     if ( $class->debug ) {
935         my $name = $class->config->{name} || 'Application';
936         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
937     }
938     $class->log->_flush() if $class->log->can('_flush');
939
940     $class->setup_finished(1);
941 }
942
943 =head2 $c->uri_for( $path, @args?, \%query_values? )
944
945 Merges path with C<< $c->request->base >> for absolute URIs and with
946 C<< $c->namespace >> for relative URIs, then returns a normalized L<URI>
947 object. If any args are passed, they are added at the end of the path.
948 If the last argument to C<uri_for> is a hash reference, it is assumed to
949 contain GET parameter key/value pairs, which will be appended to the URI
950 in standard fashion.
951
952 Note that uri_for is destructive to the passed hashref.  Subsequent calls
953 with the same hashref may have unintended results.
954
955 Instead of C<$path>, you can also optionally pass a C<$action> object
956 which will be resolved to a path using
957 C<< $c->dispatcher->uri_for_action >>; if the first element of
958 C<@args> is an arrayref it is treated as a list of captures to be passed
959 to C<uri_for_action>.
960
961 =cut
962
963 sub uri_for {
964     my ( $c, $path, @args ) = @_;
965
966     if ( Scalar::Util::blessed($path) ) { # action object
967         my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
968                          ? shift(@args)
969                          : [] );
970         $path = $c->dispatcher->uri_for_action($path, $captures);
971         return undef unless defined($path);
972         $path = '/' if $path eq '';
973     }
974
975     undef($path) if (defined $path && $path eq '');
976
977     my $params =
978       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
979
980     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
981     s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
982
983     unshift(@args, $path);
984
985     unless (defined $path && $path =~ s!^/!!) { # in-place strip
986         my $namespace = $c->namespace;
987         if (defined $path) { # cheesy hack to handle path '../foo'
988            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
989         }
990         unshift(@args, $namespace || '');
991     }
992     
993     # join args with '/', or a blank string
994     my $args = join('/', grep { defined($_) } @args);
995     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
996     $args =~ s!^/!!;
997     my $base = $c->req->base;
998     my $class = ref($base);
999     $base =~ s{(?<!/)$}{/};
1000
1001     my $query = '';
1002
1003     if (my @keys = keys %$params) {
1004       # somewhat lifted from URI::_query's query_form
1005       $query = '?'.join('&', map {
1006           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1007           s/ /+/g;
1008           my $key = $_;
1009           my $val = $params->{$_};
1010           $val = '' unless defined $val;
1011           (map {
1012               $_ = "$_";
1013               utf8::encode( $_ ) if utf8::is_utf8($_);
1014               # using the URI::Escape pattern here so utf8 chars survive
1015               s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1016               s/ /+/g;
1017               "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1018       } @keys);
1019     }
1020
1021     my $res = bless(\"${base}${args}${query}", $class);
1022     $res;
1023 }
1024
1025 =head2 $c->welcome_message
1026
1027 Returns the Catalyst welcome HTML page.
1028
1029 =cut
1030
1031 sub welcome_message {
1032     my $c      = shift;
1033     my $name   = $c->config->{name};
1034     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1035     my $prefix = Catalyst::Utils::appprefix( ref $c );
1036     $c->response->content_type('text/html; charset=utf-8');
1037     return <<"EOF";
1038 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1039     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1040 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1041     <head>
1042     <meta http-equiv="Content-Language" content="en" />
1043     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1044         <title>$name on Catalyst $VERSION</title>
1045         <style type="text/css">
1046             body {
1047                 color: #000;
1048                 background-color: #eee;
1049             }
1050             div#content {
1051                 width: 640px;
1052                 margin-left: auto;
1053                 margin-right: auto;
1054                 margin-top: 10px;
1055                 margin-bottom: 10px;
1056                 text-align: left;
1057                 background-color: #ccc;
1058                 border: 1px solid #aaa;
1059             }
1060             p, h1, h2 {
1061                 margin-left: 20px;
1062                 margin-right: 20px;
1063                 font-family: verdana, tahoma, sans-serif;
1064             }
1065             a {
1066                 font-family: verdana, tahoma, sans-serif;
1067             }
1068             :link, :visited {
1069                     text-decoration: none;
1070                     color: #b00;
1071                     border-bottom: 1px dotted #bbb;
1072             }
1073             :link:hover, :visited:hover {
1074                     color: #555;
1075             }
1076             div#topbar {
1077                 margin: 0px;
1078             }
1079             pre {
1080                 margin: 10px;
1081                 padding: 8px;
1082             }
1083             div#answers {
1084                 padding: 8px;
1085                 margin: 10px;
1086                 background-color: #fff;
1087                 border: 1px solid #aaa;
1088             }
1089             h1 {
1090                 font-size: 0.9em;
1091                 font-weight: normal;
1092                 text-align: center;
1093             }
1094             h2 {
1095                 font-size: 1.0em;
1096             }
1097             p {
1098                 font-size: 0.9em;
1099             }
1100             p img {
1101                 float: right;
1102                 margin-left: 10px;
1103             }
1104             span#appname {
1105                 font-weight: bold;
1106                 font-size: 1.6em;
1107             }
1108         </style>
1109     </head>
1110     <body>
1111         <div id="content">
1112             <div id="topbar">
1113                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1114                     $VERSION</h1>
1115              </div>
1116              <div id="answers">
1117                  <p>
1118                  <img src="$logo" alt="Catalyst Logo" />
1119                  </p>
1120                  <p>Welcome to the  world of Catalyst.
1121                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1122                     framework will make web development something you had
1123                     never expected it to be: Fun, rewarding, and quick.</p>
1124                  <h2>What to do now?</h2>
1125                  <p>That really depends  on what <b>you</b> want to do.
1126                     We do, however, provide you with a few starting points.</p>
1127                  <p>If you want to jump right into web development with Catalyst
1128                     you might want want to start with a tutorial.</p>
1129 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1130 </pre>
1131 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1132 <pre>
1133 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1134 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1135 </code></pre>
1136                  <h2>What to do next?</h2>
1137                  <p>Next it's time to write an actual application. Use the
1138                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1139                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1140                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1141                     they can save you a lot of work.</p>
1142                     <pre><code>script/${prefix}_create.pl -help</code></pre>
1143                     <p>Also, be sure to check out the vast and growing
1144                     collection of <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3APlugin%3A%3A&amp;mode=all">plugins for Catalyst on CPAN</a>;
1145                     you are likely to find what you need there.
1146                     </p>
1147
1148                  <h2>Need help?</h2>
1149                  <p>Catalyst has a very active community. Here are the main places to
1150                     get in touch with us.</p>
1151                  <ul>
1152                      <li>
1153                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1154                      </li>
1155                      <li>
1156                          <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">Mailing-List</a>
1157                      </li>
1158                      <li>
1159                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1160                      </li>
1161                  </ul>
1162                  <h2>In conclusion</h2>
1163                  <p>The Catalyst team hopes you will enjoy using Catalyst as much 
1164                     as we enjoyed making it. Please contact us if you have ideas
1165                     for improvement or other feedback.</p>
1166              </div>
1167          </div>
1168     </body>
1169 </html>
1170 EOF
1171 }
1172
1173 =head1 INTERNAL METHODS
1174
1175 These methods are not meant to be used by end users.
1176
1177 =head2 $c->components
1178
1179 Returns a hash of components.
1180
1181 =head2 $c->context_class
1182
1183 Returns or sets the context class.
1184
1185 =head2 $c->counter
1186
1187 Returns a hashref containing coderefs and execution counts (needed for
1188 deep recursion detection).
1189
1190 =head2 $c->depth
1191
1192 Returns the number of actions on the current internal execution stack.
1193
1194 =head2 $c->dispatch
1195
1196 Dispatches a request to actions.
1197
1198 =cut
1199
1200 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1201
1202 =head2 $c->dispatcher_class
1203
1204 Returns or sets the dispatcher class.
1205
1206 =head2 $c->dump_these
1207
1208 Returns a list of 2-element array references (name, structure) pairs
1209 that will be dumped on the error page in debug mode.
1210
1211 =cut
1212
1213 sub dump_these {
1214     my $c = shift;
1215     [ Request => $c->req ], 
1216     [ Response => $c->res ], 
1217     [ Stash => $c->stash ],
1218     [ Config => $c->config ];
1219 }
1220
1221 =head2 $c->engine_class
1222
1223 Returns or sets the engine class.
1224
1225 =head2 $c->execute( $class, $coderef )
1226
1227 Execute a coderef in given class and catch exceptions. Errors are available
1228 via $c->error.
1229
1230 =cut
1231
1232 sub execute {
1233     my ( $c, $class, $code ) = @_;
1234     $class = $c->component($class) || $class;
1235     $c->state(0);
1236
1237     if ( $c->depth >= $RECURSION ) {
1238         my $action = "$code";
1239         $action = "/$action" unless $action =~ /->/;
1240         my $error = qq/Deep recursion detected calling "$action"/;
1241         $c->log->error($error);
1242         $c->error($error);
1243         $c->state(0);
1244         return $c->state;
1245     }
1246
1247     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1248
1249     push( @{ $c->stack }, $code );
1250     
1251     eval { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ) };
1252
1253     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1254     
1255     my $last = pop( @{ $c->stack } );
1256
1257     if ( my $error = $@ ) {
1258         if ( !ref($error) and $error eq $DETACH ) { die $DETACH if $c->depth > 1 }
1259         else {
1260             unless ( ref $error ) {
1261                 no warnings 'uninitialized';
1262                 chomp $error;
1263                 my $class = $last->class;
1264                 my $name  = $last->name;
1265                 $error = qq/Caught exception in $class->$name "$error"/;
1266             }
1267             $c->error($error);
1268             $c->state(0);
1269         }
1270     }
1271     return $c->state;
1272 }
1273
1274 sub _stats_start_execute {
1275     my ( $c, $code ) = @_;
1276
1277     return if ( ( $code->name =~ /^_.*/ )
1278         && ( !$c->config->{show_internal_actions} ) );
1279
1280     $c->counter->{"$code"}++;
1281
1282     my $action = "$code";
1283     $action = "/$action" unless $action =~ /->/;
1284
1285     # determine if the call was the result of a forward
1286     # this is done by walking up the call stack and looking for a calling
1287     # sub of Catalyst::forward before the eval
1288     my $callsub = q{};
1289     for my $index ( 2 .. 11 ) {
1290         last
1291         if ( ( caller($index) )[0] eq 'Catalyst'
1292             && ( caller($index) )[3] eq '(eval)' );
1293
1294         if ( ( caller($index) )[3] =~ /forward$/ ) {
1295             $callsub = ( caller($index) )[3];
1296             $action  = "-> $action";
1297             last;
1298         }
1299     }
1300
1301     my $uid = "$code" . $c->counter->{"$code"};
1302
1303     # is this a root-level call or a forwarded call?
1304     if ( $callsub =~ /forward$/ ) {
1305
1306         # forward, locate the caller
1307         if ( my $parent = $c->stack->[-1] ) {
1308             $c->stats->profile(
1309                 begin  => $action, 
1310                 parent => "$parent" . $c->counter->{"$parent"},
1311                 uid    => $uid,
1312             );
1313         }
1314         else {
1315
1316             # forward with no caller may come from a plugin
1317             $c->stats->profile(
1318                 begin => $action,
1319                 uid   => $uid,
1320             );
1321         }
1322     }
1323     else {
1324         
1325         # root-level call
1326         $c->stats->profile(
1327             begin => $action,
1328             uid   => $uid,
1329         );
1330     }
1331     return $action;
1332
1333 }
1334
1335 sub _stats_finish_execute {
1336     my ( $c, $info ) = @_;
1337     $c->stats->profile( end => $info );
1338 }
1339
1340 =head2 $c->_localize_fields( sub { }, \%keys );
1341
1342 =cut
1343
1344 #Why does this exist? This is no longer safe and WILL NOT WORK.
1345 # it doesnt seem to be used anywhere. can we remove it?
1346 sub _localize_fields {
1347     my ( $c, $localized, $code ) = ( @_ );
1348
1349     my $request = delete $localized->{request} || {};
1350     my $response = delete $localized->{response} || {};
1351     
1352     local @{ $c }{ keys %$localized } = values %$localized;
1353     local @{ $c->request }{ keys %$request } = values %$request;
1354     local @{ $c->response }{ keys %$response } = values %$response;
1355
1356     $code->();
1357 }
1358
1359 =head2 $c->finalize
1360
1361 Finalizes the request.
1362
1363 =cut
1364
1365 sub finalize {
1366     my $c = shift;
1367
1368     for my $error ( @{ $c->error } ) {
1369         $c->log->error($error);
1370     }
1371
1372     # Allow engine to handle finalize flow (for POE)
1373     my $engine = $c->engine;
1374     if ( my $code = $engine->can('finalize') ) {
1375         $engine->$code($c);
1376     }
1377     else {
1378
1379         $c->finalize_uploads;
1380
1381         # Error
1382         if ( $#{ $c->error } >= 0 ) {
1383             $c->finalize_error;
1384         }
1385
1386         $c->finalize_headers;
1387
1388         # HEAD request
1389         if ( $c->request->method eq 'HEAD' ) {
1390             $c->response->body('');
1391         }
1392
1393         $c->finalize_body;
1394     }
1395     
1396     if ($c->use_stats) {        
1397         my $elapsed = sprintf '%f', $c->stats->elapsed;
1398         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1399         $c->log->info(
1400             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );        
1401     }
1402
1403     return $c->response->status;
1404 }
1405
1406 =head2 $c->finalize_body
1407
1408 Finalizes body.
1409
1410 =cut
1411
1412 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1413
1414 =head2 $c->finalize_cookies
1415
1416 Finalizes cookies.
1417
1418 =cut
1419
1420 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1421
1422 =head2 $c->finalize_error
1423
1424 Finalizes error.
1425
1426 =cut
1427
1428 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1429
1430 =head2 $c->finalize_headers
1431
1432 Finalizes headers.
1433
1434 =cut
1435
1436 sub finalize_headers {
1437     my $c = shift;
1438
1439     my $response = $c->response; #accessor calls can add up?
1440
1441     # Check if we already finalized headers
1442     return if $response->finalized_headers;
1443
1444     # Handle redirects
1445     if ( my $location = $response->redirect ) {
1446         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1447         $response->header( Location => $location );
1448
1449         #Moose TODO: we should probably be using a predicate method here ?
1450         if ( !$response->body ) {
1451             # Add a default body if none is already present
1452             $response->body(
1453                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1454             );
1455         }
1456     }
1457
1458     # Content-Length
1459     if ( $response->body && !$response->content_length ) {
1460
1461         # get the length from a filehandle
1462         if ( blessed( $response->body ) && $response->body->can('read') )
1463         {
1464             my $stat = stat $response->body;
1465             if ( $stat && $stat->size > 0 ) {
1466                 $response->content_length( $stat->size );
1467             }
1468             else {
1469                 $c->log->warn('Serving filehandle without a content-length');
1470             }
1471         }
1472         else {
1473             # everything should be bytes at this point, but just in case
1474             $response->content_length( bytes::length( $response->body ) );
1475         }
1476     }
1477
1478     # Errors
1479     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1480         $response->headers->remove_header("Content-Length");
1481         $response->body('');
1482     }
1483
1484     $c->finalize_cookies;
1485
1486     $c->engine->finalize_headers( $c, @_ );
1487
1488     # Done
1489     $response->finalized_headers(1);
1490 }
1491
1492 =head2 $c->finalize_output
1493
1494 An alias for finalize_body.
1495
1496 =head2 $c->finalize_read
1497
1498 Finalizes the input after reading is complete.
1499
1500 =cut
1501
1502 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1503
1504 =head2 $c->finalize_uploads
1505
1506 Finalizes uploads. Cleans up any temporary files.
1507
1508 =cut
1509
1510 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1511
1512 =head2 $c->get_action( $action, $namespace )
1513
1514 Gets an action in a given namespace.
1515
1516 =cut
1517
1518 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1519
1520 =head2 $c->get_actions( $action, $namespace )
1521
1522 Gets all actions of a given name in a namespace and all parent
1523 namespaces.
1524
1525 =cut
1526
1527 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1528
1529 =head2 $c->handle_request( $class, @arguments )
1530
1531 Called to handle each HTTP request.
1532
1533 =cut
1534
1535 sub handle_request {
1536     my ( $class, @arguments ) = @_;
1537
1538     # Always expect worst case!
1539     my $status = -1;
1540     eval {
1541         if ($class->debug) {
1542             my $secs = time - $START || 1;
1543             my $av = sprintf '%.3f', $COUNT / $secs;
1544             my $time = localtime time;
1545             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1546         }
1547
1548         my $c = $class->prepare(@arguments);
1549         $c->dispatch;
1550         $status = $c->finalize;   
1551     };
1552
1553     if ( my $error = $@ ) {
1554         chomp $error;
1555         $class->log->error(qq/Caught exception in engine "$error"/);
1556     }
1557
1558     $COUNT++;
1559     
1560     if(my $coderef = $class->log->can('_flush')){
1561         $class->log->$coderef();
1562     }
1563     return $status;
1564 }
1565
1566 =head2 $c->prepare( @arguments )
1567
1568 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1569 etc.).
1570
1571 =cut
1572
1573 sub prepare {
1574     my ( $class, @arguments ) = @_;
1575
1576     # XXX
1577     # After the app/ctxt split, this should become an attribute based on something passed
1578     # into the application.
1579     $class->context_class( ref $class || $class ) unless $class->context_class;
1580    
1581     my $c = $class->context_class->new({});
1582
1583     # For on-demand data
1584     $c->request->_context($c);
1585     $c->response->_context($c);
1586
1587     #surely this is not the most efficient way to do things...
1588     $c->stats($class->stats_class->new)->enable($c->use_stats);
1589     if ( $c->debug ) {
1590         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );            
1591     }
1592
1593     #XXX reuse coderef from can
1594     # Allow engine to direct the prepare flow (for POE)
1595     if ( $c->engine->can('prepare') ) {
1596         $c->engine->prepare( $c, @arguments );
1597     }
1598     else {
1599         $c->prepare_request(@arguments);
1600         $c->prepare_connection;
1601         $c->prepare_query_parameters;
1602         $c->prepare_headers;
1603         $c->prepare_cookies;
1604         $c->prepare_path;
1605
1606         # Prepare the body for reading, either by prepare_body
1607         # or the user, if they are using $c->read
1608         $c->prepare_read;
1609         
1610         # Parse the body unless the user wants it on-demand
1611         unless ( $c->config->{parse_on_demand} ) {
1612             $c->prepare_body;
1613         }
1614     }
1615
1616     my $method  = $c->req->method  || '';
1617     my $path    = $c->req->path    || '/';
1618     my $address = $c->req->address || '';
1619
1620     $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1621       if $c->debug;
1622
1623     $c->prepare_action;
1624
1625     return $c;
1626 }
1627
1628 =head2 $c->prepare_action
1629
1630 Prepares action. See L<Catalyst::Dispatcher>.
1631
1632 =cut
1633
1634 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1635
1636 =head2 $c->prepare_body
1637
1638 Prepares message body.
1639
1640 =cut
1641
1642 sub prepare_body {
1643     my $c = shift;
1644
1645     #Moose TODO: what is  _body ??
1646     # Do we run for the first time?
1647     return if defined $c->request->{_body};
1648
1649     # Initialize on-demand data
1650     $c->engine->prepare_body( $c, @_ );
1651     $c->prepare_parameters;
1652     $c->prepare_uploads;
1653
1654     if ( $c->debug && keys %{ $c->req->body_parameters } ) {
1655         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1656         for my $key ( sort keys %{ $c->req->body_parameters } ) {
1657             my $param = $c->req->body_parameters->{$key};
1658             my $value = defined($param) ? $param : '';
1659             $t->row( $key,
1660                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1661         }
1662         $c->log->debug( "Body Parameters are:\n" . $t->draw );
1663     }
1664 }
1665
1666 =head2 $c->prepare_body_chunk( $chunk )
1667
1668 Prepares a chunk of data before sending it to L<HTTP::Body>.
1669
1670 See L<Catalyst::Engine>.
1671
1672 =cut
1673
1674 sub prepare_body_chunk {
1675     my $c = shift;
1676     $c->engine->prepare_body_chunk( $c, @_ );
1677 }
1678
1679 =head2 $c->prepare_body_parameters
1680
1681 Prepares body parameters.
1682
1683 =cut
1684
1685 sub prepare_body_parameters {
1686     my $c = shift;
1687     $c->engine->prepare_body_parameters( $c, @_ );
1688 }
1689
1690 =head2 $c->prepare_connection
1691
1692 Prepares connection.
1693
1694 =cut
1695
1696 sub prepare_connection {
1697     my $c = shift;
1698     $c->engine->prepare_connection( $c, @_ );
1699 }
1700
1701 =head2 $c->prepare_cookies
1702
1703 Prepares cookies.
1704
1705 =cut
1706
1707 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1708
1709 =head2 $c->prepare_headers
1710
1711 Prepares headers.
1712
1713 =cut
1714
1715 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1716
1717 =head2 $c->prepare_parameters
1718
1719 Prepares parameters.
1720
1721 =cut
1722
1723 sub prepare_parameters {
1724     my $c = shift;
1725     $c->prepare_body_parameters;
1726     $c->engine->prepare_parameters( $c, @_ );
1727 }
1728
1729 =head2 $c->prepare_path
1730
1731 Prepares path and base.
1732
1733 =cut
1734
1735 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1736
1737 =head2 $c->prepare_query_parameters
1738
1739 Prepares query parameters.
1740
1741 =cut
1742
1743 sub prepare_query_parameters {
1744     my $c = shift;
1745
1746     $c->engine->prepare_query_parameters( $c, @_ );
1747
1748     if ( $c->debug && keys %{ $c->request->query_parameters } ) {
1749         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
1750         for my $key ( sort keys %{ $c->req->query_parameters } ) {
1751             my $param = $c->req->query_parameters->{$key};
1752             my $value = defined($param) ? $param : '';
1753             $t->row( $key,
1754                 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1755         }
1756         $c->log->debug( "Query Parameters are:\n" . $t->draw );
1757     }
1758 }
1759
1760 =head2 $c->prepare_read
1761
1762 Prepares the input for reading.
1763
1764 =cut
1765
1766 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1767
1768 =head2 $c->prepare_request
1769
1770 Prepares the engine request.
1771
1772 =cut
1773
1774 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1775
1776 =head2 $c->prepare_uploads
1777
1778 Prepares uploads.
1779
1780 =cut
1781
1782 sub prepare_uploads {
1783     my $c = shift;
1784
1785     $c->engine->prepare_uploads( $c, @_ );
1786
1787     if ( $c->debug && keys %{ $c->request->uploads } ) {
1788         my $t = Text::SimpleTable->new(
1789             [ 12, 'Parameter' ],
1790             [ 26, 'Filename' ],
1791             [ 18, 'Type' ],
1792             [ 9,  'Size' ]
1793         );
1794         for my $key ( sort keys %{ $c->request->uploads } ) {
1795             my $upload = $c->request->uploads->{$key};
1796             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
1797                 $t->row( $key, $u->filename, $u->type, $u->size );
1798             }
1799         }
1800         $c->log->debug( "File Uploads are:\n" . $t->draw );
1801     }
1802 }
1803
1804 =head2 $c->prepare_write
1805
1806 Prepares the output for writing.
1807
1808 =cut
1809
1810 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1811
1812 =head2 $c->request_class
1813
1814 Returns or sets the request class.
1815
1816 =head2 $c->response_class
1817
1818 Returns or sets the response class.
1819
1820 =head2 $c->read( [$maxlength] )
1821
1822 Reads a chunk of data from the request body. This method is designed to
1823 be used in a while loop, reading C<$maxlength> bytes on every call.
1824 C<$maxlength> defaults to the size of the request if not specified.
1825
1826 You have to set C<< MyApp->config->{parse_on_demand} >> to use this
1827 directly.
1828
1829 Warning: If you use read(), Catalyst will not process the body,
1830 so you will not be able to access POST parameters or file uploads via
1831 $c->request.  You must handle all body parsing yourself.
1832
1833 =cut
1834
1835 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1836
1837 =head2 $c->run
1838
1839 Starts the engine.
1840
1841 =cut
1842
1843 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1844
1845 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1846
1847 Sets an action in a given namespace.
1848
1849 =cut
1850
1851 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1852
1853 =head2 $c->setup_actions($component)
1854
1855 Sets up actions for a component.
1856
1857 =cut
1858
1859 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1860
1861 =head2 $c->setup_components
1862
1863 Sets up components. Specify a C<setup_components> config option to pass
1864 additional options directly to L<Module::Pluggable>. To add additional
1865 search paths, specify a key named C<search_extra> as an array
1866 reference. Items in the array beginning with C<::> will have the
1867 application class name prepended to them.
1868
1869 =cut
1870
1871 sub setup_components {
1872     my $class = shift;
1873
1874     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
1875     my $config  = $class->config->{ setup_components };
1876     my $extra   = delete $config->{ search_extra } || [];
1877     
1878     push @paths, @$extra;
1879         
1880     my $locator = Module::Pluggable::Object->new(
1881         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1882         %$config
1883     );
1884
1885     my @comps = sort { length $a <=> length $b } $locator->plugins;
1886     my %comps = map { $_ => 1 } @comps;
1887     
1888     for my $component ( @comps ) {
1889
1890         # We pass ignore_loaded here so that overlay files for (e.g.)
1891         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1892         # we know M::P::O found a file on disk so this is safe
1893
1894         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1895         #Class::MOP::load_class($component);
1896
1897         my $module  = $class->setup_component( $component );
1898         my %modules = (
1899             $component => $module,
1900             map {
1901                 $_ => $class->setup_component( $_ )
1902             } grep { 
1903               not exists $comps{$_}
1904             } Devel::InnerPackage::list_packages( $component )
1905         );
1906         
1907         for my $key ( keys %modules ) {
1908             $class->components->{ $key } = $modules{ $key };
1909         }
1910     }
1911 }
1912
1913 =head2 $c->setup_component
1914
1915 =cut
1916
1917 sub setup_component {
1918     my( $class, $component ) = @_;
1919
1920     unless ( $component->can( 'COMPONENT' ) ) {
1921         return $component;
1922     }
1923
1924     my $suffix = Catalyst::Utils::class2classsuffix( $component );
1925     my $config = $class->config->{ $suffix } || {};
1926
1927     my $instance = eval { $component->COMPONENT( $class, $config ); };
1928
1929     if ( my $error = $@ ) {
1930         chomp $error;
1931         Catalyst::Exception->throw(
1932             message => qq/Couldn't instantiate component "$component", "$error"/
1933         );
1934     }
1935
1936     Catalyst::Exception->throw(
1937         message =>
1938         qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
1939     ) unless eval { $instance->can( 'can' ) };
1940
1941     return $instance;
1942 }
1943
1944 =head2 $c->setup_dispatcher
1945
1946 Sets up dispatcher.
1947
1948 =cut
1949
1950 sub setup_dispatcher {
1951     my ( $class, $dispatcher ) = @_;
1952
1953     if ($dispatcher) {
1954         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1955     }
1956
1957     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1958         $dispatcher = 'Catalyst::Dispatcher::' . $env;
1959     }
1960
1961     unless ($dispatcher) {
1962         $dispatcher = $class->dispatcher_class;
1963     }
1964
1965     Class::MOP::load_class($dispatcher);
1966
1967     # dispatcher instance
1968     $class->dispatcher( $dispatcher->new );
1969 }
1970
1971 =head2 $c->setup_engine
1972
1973 Sets up engine.
1974
1975 =cut
1976
1977 sub setup_engine {
1978     my ( $class, $engine ) = @_;
1979
1980     if ($engine) {
1981         $engine = 'Catalyst::Engine::' . $engine;
1982     }
1983
1984     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1985         $engine = 'Catalyst::Engine::' . $env;
1986     }
1987
1988     if ( $ENV{MOD_PERL} ) {
1989
1990         # create the apache method
1991         {
1992             no strict 'refs';
1993             *{"$class\::apache"} = sub { shift->engine->apache };
1994         }
1995
1996         my ( $software, $version ) =
1997           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1998
1999         $version =~ s/_//g;
2000         $version =~ s/(\.[^.]+)\./$1/g;
2001
2002         if ( $software eq 'mod_perl' ) {
2003
2004             if ( !$engine ) {
2005
2006                 if ( $version >= 1.99922 ) {
2007                     $engine = 'Catalyst::Engine::Apache2::MP20';
2008                 }
2009
2010                 elsif ( $version >= 1.9901 ) {
2011                     $engine = 'Catalyst::Engine::Apache2::MP19';
2012                 }
2013
2014                 elsif ( $version >= 1.24 ) {
2015                     $engine = 'Catalyst::Engine::Apache::MP13';
2016                 }
2017
2018                 else {
2019                     Catalyst::Exception->throw( message =>
2020                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2021                 }
2022
2023             }
2024
2025             # install the correct mod_perl handler
2026             if ( $version >= 1.9901 ) {
2027                 *handler = sub  : method {
2028                     shift->handle_request(@_);
2029                 };
2030             }
2031             else {
2032                 *handler = sub ($$) { shift->handle_request(@_) };
2033             }
2034
2035         }
2036
2037         elsif ( $software eq 'Zeus-Perl' ) {
2038             $engine = 'Catalyst::Engine::Zeus';
2039         }
2040
2041         else {
2042             Catalyst::Exception->throw(
2043                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2044         }
2045     }
2046
2047     unless ($engine) {
2048         $engine = $class->engine_class;
2049     }
2050
2051     Class::MOP::load_class($engine);
2052     #unless (Class::Inspector->loaded($engine)) {
2053     #    require Class::Inspector->filename($engine);
2054     #}
2055
2056     # check for old engines that are no longer compatible
2057     my $old_engine;
2058     if ( $engine->isa('Catalyst::Engine::Apache')
2059         && !Catalyst::Engine::Apache->VERSION )
2060     {
2061         $old_engine = 1;
2062     }
2063
2064     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2065         && Catalyst::Engine::Server->VERSION le '0.02' )
2066     {
2067         $old_engine = 1;
2068     }
2069
2070     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2071         && $engine->VERSION eq '0.01' )
2072     {
2073         $old_engine = 1;
2074     }
2075
2076     elsif ($engine->isa('Catalyst::Engine::Zeus')
2077         && $engine->VERSION eq '0.01' )
2078     {
2079         $old_engine = 1;
2080     }
2081
2082     if ($old_engine) {
2083         Catalyst::Exception->throw( message =>
2084               qq/Engine "$engine" is not supported by this version of Catalyst/
2085         );
2086     }
2087
2088     # engine instance
2089     $class->engine( $engine->new );
2090 }
2091
2092 =head2 $c->setup_home
2093
2094 Sets up the home directory.
2095
2096 =cut
2097
2098 sub setup_home {
2099     my ( $class, $home ) = @_;
2100
2101     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2102         $home = $env;
2103     }
2104
2105     $home ||= Catalyst::Utils::home($class);
2106
2107     if ($home) {
2108         #I remember recently being scolded for assigning config values like this
2109         $class->config->{home} ||= $home;
2110         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2111     }
2112 }
2113
2114 =head2 $c->setup_log
2115
2116 Sets up log.
2117
2118 =cut
2119
2120 sub setup_log {
2121     my ( $class, $debug ) = @_;
2122
2123     unless ( $class->log ) {
2124         $class->log( Catalyst::Log->new );
2125     }
2126
2127     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2128     if ( defined($env_debug) ? $env_debug : $debug ) {
2129         no strict 'refs';
2130         #Moose todo: dying to be made a bool attribute
2131         *{"$class\::debug"} = sub { 1 };
2132         $class->log->debug('Debug messages enabled');
2133     }
2134 }
2135
2136 =head2 $c->setup_plugins
2137
2138 Sets up plugins.
2139
2140 =cut
2141
2142 =head2 $c->setup_stats
2143
2144 Sets up timing statistics class.
2145
2146 =cut
2147
2148 sub setup_stats {
2149     my ( $class, $stats ) = @_;
2150
2151     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2152
2153     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2154     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2155         no strict 'refs';
2156         #Moose todo: dying to be made a bool attribute
2157         *{"$class\::use_stats"} = sub { 1 };
2158         $class->log->debug('Statistics enabled');
2159     }
2160 }
2161
2162
2163 =head2 $c->registered_plugins 
2164
2165 Returns a sorted list of the plugins which have either been stated in the
2166 import list or which have been added via C<< MyApp->plugin(@args); >>.
2167
2168 If passed a given plugin name, it will report a boolean value indicating
2169 whether or not that plugin is loaded.  A fully qualified name is required if
2170 the plugin name does not begin with C<Catalyst::Plugin::>.
2171
2172  if ($c->registered_plugins('Some::Plugin')) {
2173      ...
2174  }
2175
2176 =cut
2177
2178 {
2179
2180     sub registered_plugins {
2181         my $proto = shift;
2182         return sort keys %{ $proto->_plugins } unless @_;
2183         my $plugin = shift;
2184         return 1 if exists $proto->_plugins->{$plugin};
2185         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2186     }
2187
2188     sub _register_plugin {
2189         my ( $proto, $plugin, $instant ) = @_;
2190         my $class = ref $proto || $proto;
2191
2192         # no ignore_loaded here, the plugin may already have been
2193         # defined in memory and we don't want to error on "no file" if so
2194
2195         Class::MOP::load_class( $plugin );
2196
2197         $proto->_plugins->{$plugin} = 1;
2198         unless ($instant) {
2199             no strict 'refs';
2200             if( $class->can('meta') ){
2201               my @superclasses = ($plugin, $class->meta->superclasses );
2202               $class->meta->superclasses(@superclasses);
2203             } else {
2204               unshift @{"$class\::ISA"}, $plugin;
2205             }
2206         }
2207         return $class;
2208     }
2209
2210     sub setup_plugins {
2211         my ( $class, $plugins ) = @_;
2212
2213         $class->_plugins( {} ) unless $class->_plugins;
2214         $plugins ||= [];
2215         for my $plugin ( reverse @$plugins ) {
2216
2217             unless ( $plugin =~ s/\A\+// ) {
2218                 $plugin = "Catalyst::Plugin::$plugin";
2219             }
2220
2221             $class->_register_plugin($plugin);
2222         }
2223     }
2224 }
2225
2226 =head2 $c->stack
2227
2228 Returns an arrayref of the internal execution stack (actions that are
2229 currently executing).
2230
2231 =head2 $c->stats_class
2232
2233 Returns or sets the stats (timing statistics) class.
2234
2235 =head2 $c->use_stats
2236
2237 Returns 1 when stats collection is enabled.  Stats collection is enabled
2238 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2239 environment variable is set.
2240
2241 Note that this is a static method, not an accessor and should be overloaded
2242 by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2243
2244 =cut
2245
2246 sub use_stats { 0 }
2247
2248
2249 =head2 $c->write( $data )
2250
2251 Writes $data to the output stream. When using this method directly, you
2252 will need to manually set the C<Content-Length> header to the length of
2253 your output data, if known.
2254
2255 =cut
2256
2257 sub write {
2258     my $c = shift;
2259
2260     # Finalize headers if someone manually writes output
2261     $c->finalize_headers;
2262
2263     return $c->engine->write( $c, @_ );
2264 }
2265
2266 =head2 version
2267
2268 Returns the Catalyst version number. Mostly useful for "powered by"
2269 messages in template systems.
2270
2271 =cut
2272
2273 sub version { return $Catalyst::VERSION }
2274
2275 =head1 INTERNAL ACTIONS
2276
2277 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2278 C<_ACTION>, and C<_END>. These are by default not shown in the private
2279 action table, but you can make them visible with a config parameter.
2280
2281     MyApp->config->{show_internal_actions} = 1;
2282
2283 =head1 CASE SENSITIVITY
2284
2285 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
2286 mapped to C</foo/bar>. You can activate case sensitivity with a config
2287 parameter.
2288
2289     MyApp->config->{case_sensitive} = 1;
2290
2291 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
2292
2293 =head1 ON-DEMAND PARSER
2294
2295 The request body is usually parsed at the beginning of a request,
2296 but if you want to handle input yourself, you can enable on-demand
2297 parsing with a config parameter.
2298
2299     MyApp->config->{parse_on_demand} = 1;
2300     
2301 =head1 PROXY SUPPORT
2302
2303 Many production servers operate using the common double-server approach,
2304 with a lightweight frontend web server passing requests to a larger
2305 backend server. An application running on the backend server must deal
2306 with two problems: the remote user always appears to be C<127.0.0.1> and
2307 the server's hostname will appear to be C<localhost> regardless of the
2308 virtual host that the user connected through.
2309
2310 Catalyst will automatically detect this situation when you are running
2311 the frontend and backend servers on the same machine. The following
2312 changes are made to the request.
2313
2314     $c->req->address is set to the user's real IP address, as read from 
2315     the HTTP X-Forwarded-For header.
2316     
2317     The host value for $c->req->base and $c->req->uri is set to the real
2318     host, as read from the HTTP X-Forwarded-Host header.
2319
2320 Obviously, your web server must support these headers for this to work.
2321
2322 In a more complex server farm environment where you may have your
2323 frontend proxy server(s) on different machines, you will need to set a
2324 configuration option to tell Catalyst to read the proxied data from the
2325 headers.
2326
2327     MyApp->config->{using_frontend_proxy} = 1;
2328     
2329 If you do not wish to use the proxy support at all, you may set:
2330
2331     MyApp->config->{ignore_frontend_proxy} = 1;
2332
2333 =head1 THREAD SAFETY
2334
2335 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2336 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2337 believe the Catalyst core to be thread-safe.
2338
2339 If you plan to operate in a threaded environment, remember that all other
2340 modules you are using must also be thread-safe. Some modules, most notably
2341 L<DBD::SQLite>, are not thread-safe.
2342
2343 =head1 SUPPORT
2344
2345 IRC:
2346
2347     Join #catalyst on irc.perl.org.
2348
2349 Mailing Lists:
2350
2351     http://lists.rawmode.org/mailman/listinfo/catalyst
2352     http://lists.rawmode.org/mailman/listinfo/catalyst-dev
2353
2354 Web:
2355
2356     http://catalyst.perl.org
2357
2358 Wiki:
2359
2360     http://dev.catalyst.perl.org
2361
2362 =head1 SEE ALSO
2363
2364 =head2 L<Task::Catalyst> - All you need to start with Catalyst
2365
2366 =head2 L<Catalyst::Manual> - The Catalyst Manual
2367
2368 =head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
2369
2370 =head2 L<Catalyst::Engine> - Core engine
2371
2372 =head2 L<Catalyst::Log> - Log class.
2373
2374 =head2 L<Catalyst::Request> - Request object
2375
2376 =head2 L<Catalyst::Response> - Response object
2377
2378 =head2 L<Catalyst::Test> - The test suite.
2379
2380 =head1 CREDITS
2381
2382 Andy Grundman
2383
2384 Andy Wardley
2385
2386 Andreas Marienborg
2387
2388 Andrew Bramble
2389
2390 Andrew Ford
2391
2392 Andrew Ruthven
2393
2394 Arthur Bergman
2395
2396 Autrijus Tang
2397
2398 Brian Cassidy
2399
2400 Carl Franks
2401
2402 Christian Hansen
2403
2404 Christopher Hicks
2405
2406 Dan Sully
2407
2408 Danijel Milicevic
2409
2410 David Kamholz
2411
2412 David Naughton
2413
2414 Drew Taylor
2415
2416 Gary Ashton Jones
2417
2418 Geoff Richards
2419
2420 Jesse Sheidlower
2421
2422 Jesse Vincent
2423
2424 Jody Belka
2425
2426 Johan Lindstrom
2427
2428 Juan Camacho
2429
2430 Leon Brocard
2431
2432 Marcus Ramberg
2433
2434 Matt S Trout
2435
2436 Robert Sedlacek
2437
2438 Sam Vilain
2439
2440 Sascha Kiefer
2441
2442 Sebastian Willert
2443
2444 Tatsuhiko Miyagawa
2445
2446 Ulf Edvinsson
2447
2448 Yuval Kogman
2449
2450 =head1 AUTHOR
2451
2452 Sebastian Riedel, C<sri@oook.de>
2453
2454 =head1 LICENSE
2455
2456 This library is free software, you can redistribute it and/or modify it under
2457 the same terms as Perl itself.
2458
2459 =cut
2460
2461 1;