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