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