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