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