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