| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | 
| 2 |  |  |  |  |  |  | use Moose; | 
| 3 | 163 |  |  | 166 |  | 4825362 | use Moose::Meta::Class (); | 
|  | 163 |  |  |  |  | 12683994 |  | 
|  | 163 |  |  |  |  | 1584 |  | 
| 4 | 163 |  |  | 163 |  | 972485 | extends 'Catalyst::Component'; | 
|  | 163 |  |  |  |  | 335 |  | 
|  | 163 |  |  |  |  | 5261 |  | 
| 5 |  |  |  |  |  |  | use Moose::Util qw/find_meta/; | 
| 6 | 163 |  |  | 163 |  | 957 | use namespace::clean -except => 'meta'; | 
|  | 163 |  |  |  |  | 298 |  | 
|  | 163 |  |  |  |  | 1102 |  | 
| 7 | 163 |  |  | 163 |  | 50318 | use Catalyst::Exception; | 
|  | 163 |  |  |  |  | 179348 |  | 
|  | 163 |  |  |  |  | 1198 |  | 
| 8 | 163 |  |  | 163 |  | 65864 | use Catalyst::Exception::Detach; | 
|  | 163 |  |  |  |  | 379 |  | 
|  | 163 |  |  |  |  | 4348 |  | 
| 9 | 163 |  |  | 163 |  | 62151 | use Catalyst::Exception::Go; | 
|  | 163 |  |  |  |  | 434 |  | 
|  | 163 |  |  |  |  | 4721 |  | 
| 10 | 163 |  |  | 163 |  | 61746 | use Catalyst::Log; | 
|  | 163 |  |  |  |  | 478 |  | 
|  | 163 |  |  |  |  | 4564 |  | 
| 11 | 163 |  |  | 163 |  | 64389 | use Catalyst::Request; | 
|  | 163 |  |  |  |  | 554 |  | 
|  | 163 |  |  |  |  | 5252 |  | 
| 12 | 163 |  |  | 163 |  | 83657 | use Catalyst::Request::Upload; | 
|  | 163 |  |  |  |  | 673 |  | 
|  | 163 |  |  |  |  | 6579 |  | 
| 13 | 163 |  |  | 163 |  | 77043 | use Catalyst::Response; | 
|  | 163 |  |  |  |  | 2107 |  | 
|  | 163 |  |  |  |  | 5417 |  | 
| 14 | 163 |  |  | 163 |  | 77997 | use Catalyst::Utils; | 
|  | 163 |  |  |  |  | 587 |  | 
|  | 163 |  |  |  |  | 6018 |  | 
| 15 | 163 |  |  | 163 |  | 1180 | use Catalyst::Controller; | 
|  | 163 |  |  |  |  | 332 |  | 
|  | 163 |  |  |  |  | 3687 |  | 
| 16 | 163 |  |  | 163 |  | 69484 | use Data::OptList; | 
|  | 163 |  |  |  |  | 708 |  | 
|  | 163 |  |  |  |  | 6591 |  | 
| 17 | 163 |  |  | 163 |  | 1297 | use Devel::InnerPackage (); | 
|  | 163 |  |  |  |  | 411 |  | 
|  | 163 |  |  |  |  | 1550 |  | 
| 18 | 163 |  |  | 163 |  | 4393 | use Module::Pluggable::Object (); | 
|  | 163 |  |  |  |  | 365 |  | 
|  | 163 |  |  |  |  | 2225 |  | 
| 19 | 163 |  |  | 163 |  | 82176 | use Text::SimpleTable (); | 
|  | 163 |  |  |  |  | 659814 |  | 
|  | 163 |  |  |  |  | 3408 |  | 
| 20 | 163 |  |  | 163 |  | 64641 | use Path::Class::Dir (); | 
|  | 163 |  |  |  |  | 350442 |  | 
|  | 163 |  |  |  |  | 3480 |  | 
| 21 | 163 |  |  | 163 |  | 1215 | use Path::Class::File (); | 
|  | 163 |  |  |  |  | 412 |  | 
|  | 163 |  |  |  |  | 2701 |  | 
| 22 | 163 |  |  | 163 |  | 931 | use URI (); | 
|  | 163 |  |  |  |  | 373 |  | 
|  | 163 |  |  |  |  | 2446 |  | 
| 23 | 163 |  |  | 163 |  | 881 | use URI::http; | 
|  | 163 |  |  |  |  | 375 |  | 
|  | 163 |  |  |  |  | 2357 |  | 
| 24 | 163 |  |  | 163 |  | 801 | use URI::https; | 
|  | 163 |  |  |  |  | 392 |  | 
|  | 163 |  |  |  |  | 5263 |  | 
| 25 | 163 |  |  | 163 |  | 876 | use HTML::Entities; | 
|  | 163 |  |  |  |  | 391 |  | 
|  | 163 |  |  |  |  | 3482 |  | 
| 26 | 163 |  |  | 163 |  | 68340 | use Tree::Simple qw/use_weak_refs/; | 
|  | 163 |  |  |  |  | 820971 |  | 
|  | 163 |  |  |  |  | 10384 |  | 
| 27 | 163 |  |  | 163 |  | 85206 | use Tree::Simple::Visitor::FindByUID; | 
|  | 163 |  |  |  |  | 472632 |  | 
|  | 163 |  |  |  |  | 854 |  | 
| 28 | 163 |  |  | 163 |  | 68190 | use Class::C3::Adopt::NEXT; | 
|  | 163 |  |  |  |  | 302007 |  | 
|  | 163 |  |  |  |  | 5489 |  | 
| 29 | 163 |  |  | 163 |  | 1231 | use List::Util qw/uniq/; | 
|  | 163 |  |  |  |  | 470 |  | 
|  | 163 |  |  |  |  | 2096 |  | 
| 30 | 163 |  |  | 163 |  | 5362 | use attributes; | 
|  | 163 |  |  |  |  | 393 |  | 
|  | 163 |  |  |  |  | 9982 |  | 
| 31 | 163 |  |  | 163 |  | 1075 | use String::RewritePrefix; | 
|  | 163 |  |  |  |  | 399 |  | 
|  | 163 |  |  |  |  | 1410 |  | 
| 32 | 163 |  |  | 163 |  | 6165 | use Catalyst::EngineLoader; | 
|  | 163 |  |  |  |  | 391 |  | 
|  | 163 |  |  |  |  | 1729 |  | 
| 33 | 163 |  |  | 163 |  | 99574 | use utf8; | 
|  | 163 |  |  |  |  | 520 |  | 
|  | 163 |  |  |  |  | 5187 |  | 
| 34 | 163 |  |  | 163 |  | 1198 | use Carp qw/croak carp shortmess/; | 
|  | 163 |  |  |  |  | 356 |  | 
|  | 163 |  |  |  |  | 1274 |  | 
| 35 | 163 |  |  | 163 |  | 4301 | use Try::Tiny; | 
|  | 163 |  |  |  |  | 390 |  | 
|  | 163 |  |  |  |  | 8519 |  | 
| 36 | 163 |  |  | 163 |  | 1003 | use Safe::Isa; | 
|  | 163 |  |  |  |  | 404 |  | 
|  | 163 |  |  |  |  | 5885 |  | 
| 37 | 163 |  |  | 163 |  | 65408 | use Moose::Util 'find_meta'; | 
|  | 163 |  |  |  |  | 68415 |  | 
|  | 163 |  |  |  |  | 19548 |  | 
| 38 | 163 |  |  | 163 |  | 1171 | use Plack::Middleware::Conditional; | 
|  | 163 |  |  |  |  | 406 |  | 
|  | 163 |  |  |  |  | 1527 |  | 
| 39 | 163 |  |  | 163 |  | 94240 | use Plack::Middleware::ReverseProxy; | 
|  | 163 |  |  |  |  | 350304 |  | 
|  | 163 |  |  |  |  | 4712 |  | 
| 40 | 163 |  |  | 163 |  | 54664 | use Plack::Middleware::IIS6ScriptNameFix; | 
|  | 163 |  |  |  |  | 97205 |  | 
|  | 163 |  |  |  |  | 4847 |  | 
| 41 | 163 |  |  | 163 |  | 54934 | use Plack::Middleware::IIS7KeepAliveFix; | 
|  | 163 |  |  |  |  | 46945 |  | 
|  | 163 |  |  |  |  | 4828 |  | 
| 42 | 163 |  |  | 163 |  | 56079 | use Plack::Middleware::LighttpdScriptNameFix; | 
|  | 163 |  |  |  |  | 40535 |  | 
|  | 163 |  |  |  |  | 4473 |  | 
| 43 | 163 |  |  | 163 |  | 55993 | use Plack::Middleware::ContentLength; | 
|  | 163 |  |  |  |  | 48969 |  | 
|  | 163 |  |  |  |  | 4718 |  | 
| 44 | 163 |  |  | 163 |  | 55331 | use Plack::Middleware::Head; | 
|  | 163 |  |  |  |  | 42755 |  | 
|  | 163 |  |  |  |  | 4473 |  | 
| 45 | 163 |  |  | 163 |  | 54503 | use Plack::Middleware::HTTPExceptions; | 
|  | 163 |  |  |  |  | 36588 |  | 
|  | 163 |  |  |  |  | 4482 |  | 
| 46 | 163 |  |  | 163 |  | 57214 | use Plack::Middleware::FixMissingBodyInRedirect; | 
|  | 163 |  |  |  |  | 794783 |  | 
|  | 163 |  |  |  |  | 5230 |  | 
| 47 | 163 |  |  | 163 |  | 55733 | use Plack::Middleware::MethodOverride; | 
|  | 163 |  |  |  |  | 85323 |  | 
|  | 163 |  |  |  |  | 5213 |  | 
| 48 | 163 |  |  | 163 |  | 52707 | use Plack::Middleware::RemoveRedundantBody; | 
|  | 163 |  |  |  |  | 4298293 |  | 
|  | 163 |  |  |  |  | 5133 |  | 
| 49 | 163 |  |  | 163 |  | 59430 | use Catalyst::Middleware::Stash; | 
|  | 163 |  |  |  |  | 42891 |  | 
|  | 163 |  |  |  |  | 5183 |  | 
| 50 | 163 |  |  | 163 |  | 60949 | use Plack::Util; | 
|  | 163 |  |  |  |  | 478 |  | 
|  | 163 |  |  |  |  | 5941 |  | 
| 51 | 163 |  |  | 163 |  | 1406 | use Class::Load 'load_class'; | 
|  | 163 |  |  |  |  | 385 |  | 
|  | 163 |  |  |  |  | 3237 |  | 
| 52 | 163 |  |  | 163 |  | 784 | use Encode 2.21 'decode_utf8', 'encode_utf8'; | 
|  | 163 |  |  |  |  | 316 |  | 
|  | 163 |  |  |  |  | 7398 |  | 
| 53 | 163 |  |  | 163 |  | 891 | use Scalar::Util; | 
|  | 163 |  |  |  |  | 3191 |  | 
|  | 163 |  |  |  |  | 5922 |  | 
| 54 | 163 |  |  | 163 |  | 938 |  | 
|  | 163 |  |  |  |  | 362 |  | 
|  | 163 |  |  |  |  | 9034 |  | 
| 55 |  |  |  |  |  |  | our $VERSION = '5.90129'; | 
| 56 |  |  |  |  |  |  | $VERSION =~ tr/_//d; | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | BEGIN { require 5.008003; } | 
| 59 | 163 |  |  | 163 |  | 251129 |  | 
| 60 |  |  |  |  |  |  | has stack => (is => 'ro', default => sub { [] }); | 
| 61 |  |  |  |  |  |  | has state => (is => 'rw', default => 0); | 
| 62 |  |  |  |  |  |  | has stats => (is => 'rw'); | 
| 63 |  |  |  |  |  |  | has action => (is => 'rw'); | 
| 64 |  |  |  |  |  |  | has counter => (is => 'rw', default => sub { {} }); | 
| 65 |  |  |  |  |  |  | has request => ( | 
| 66 |  |  |  |  |  |  | is => 'rw', | 
| 67 |  |  |  |  |  |  | default => sub { | 
| 68 |  |  |  |  |  |  | my $self = shift; | 
| 69 |  |  |  |  |  |  | my $class = ref $self; | 
| 70 |  |  |  |  |  |  | my $composed_request_class = $class->composed_request_class; | 
| 71 |  |  |  |  |  |  | return $composed_request_class->new( $self->_build_request_constructor_args); | 
| 72 |  |  |  |  |  |  | }, | 
| 73 |  |  |  |  |  |  | predicate => 'has_request', | 
| 74 |  |  |  |  |  |  | lazy => 1, | 
| 75 |  |  |  |  |  |  | ); | 
| 76 |  |  |  |  |  |  | my $self = shift; | 
| 77 |  |  |  |  |  |  | my %p = ( _log => $self->log ); | 
| 78 | 932 |  |  | 932 |  | 1569 | $p{_uploadtmp} = $self->_uploadtmp if $self->_has_uploadtmp; | 
| 79 | 932 |  |  |  |  | 2248 | $p{data_handlers} = {$self->registered_data_handlers}; | 
| 80 | 932 | 100 |  |  |  | 26039 | $p{_use_hash_multivalue} = $self->config->{use_hash_multivalue_in_request} | 
| 81 | 932 |  |  |  |  | 3392 | if $self->config->{use_hash_multivalue_in_request}; | 
| 82 |  |  |  |  |  |  | \%p; | 
| 83 | 932 | 100 |  |  |  | 3043 | } | 
| 84 | 932 |  |  |  |  | 29398 |  | 
| 85 |  |  |  |  |  |  | my $class = shift; | 
| 86 |  |  |  |  |  |  | return $class->_composed_request_class if $class->_composed_request_class; | 
| 87 |  |  |  |  |  |  |  | 
| 88 | 1095 |  |  | 1095 | 1 | 2114 | my @traits = (@{$class->request_class_traits||[]}, @{$class->config->{request_class_traits}||[]}); | 
| 89 | 1095 | 100 |  |  |  | 3880 |  | 
| 90 |  |  |  |  |  |  | # For each trait listed, figure out what the namespace is.  First we try the $trait | 
| 91 | 161 | 100 |  |  |  | 475 | # as it is in the config.  Then try $MyApp::TraitFor::Request:$trait. Last we try | 
|  | 161 | 50 |  |  |  | 1528 |  | 
|  | 161 |  |  |  |  | 804 |  | 
| 92 |  |  |  |  |  |  | # Catalyst::TraitFor::Request::$trait.  If none load, throw error. | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | my $trait_ns = 'TraitFor::Request'; | 
| 95 |  |  |  |  |  |  | my @normalized_traits = map { | 
| 96 |  |  |  |  |  |  | Class::Load::load_first_existing_class($_, $class.'::'.$trait_ns.'::'. $_, 'Catalyst::'.$trait_ns.'::'.$_) | 
| 97 | 161 |  |  |  |  | 577 | } @traits; | 
| 98 |  |  |  |  |  |  |  | 
| 99 | 161 |  |  |  |  | 592 | if ($class->debug && scalar(@normalized_traits)) { | 
|  | 6 |  |  |  |  | 1476 |  | 
| 100 |  |  |  |  |  |  | my $column_width = Catalyst::Utils::term_width() - 6; | 
| 101 |  |  |  |  |  |  | my $t = Text::SimpleTable->new($column_width); | 
| 102 | 161 | 50 | 100 |  |  | 1488 | $t->row($_) for @normalized_traits; | 
| 103 | 0 |  |  |  |  | 0 | $class->log->debug( "Composed Request Class Traits:\n" . $t->draw . "\n" ); | 
| 104 | 0 |  |  |  |  | 0 | } | 
| 105 | 0 |  |  |  |  | 0 |  | 
| 106 | 0 |  |  |  |  | 0 | return $class->_composed_request_class(Moose::Util::with_traits($class->request_class, @normalized_traits)); | 
| 107 |  |  |  |  |  |  | } | 
| 108 |  |  |  |  |  |  |  | 
| 109 | 161 |  |  |  |  | 1722 | has response => ( | 
| 110 |  |  |  |  |  |  | is => 'rw', | 
| 111 |  |  |  |  |  |  | default => sub { | 
| 112 |  |  |  |  |  |  | my $self = shift; | 
| 113 |  |  |  |  |  |  | my $class = ref $self; | 
| 114 |  |  |  |  |  |  | my $composed_response_class = $class->composed_response_class; | 
| 115 |  |  |  |  |  |  | return $composed_response_class->new( $self->_build_response_constructor_args); | 
| 116 |  |  |  |  |  |  | }, | 
| 117 |  |  |  |  |  |  | predicate=>'has_response', | 
| 118 |  |  |  |  |  |  | lazy => 1, | 
| 119 |  |  |  |  |  |  | ); | 
| 120 |  |  |  |  |  |  | return +{ | 
| 121 |  |  |  |  |  |  | _log => $_[0]->log, | 
| 122 |  |  |  |  |  |  | encoding => $_[0]->encoding, | 
| 123 |  |  |  |  |  |  | }; | 
| 124 |  |  |  |  |  |  | } | 
| 125 | 932 |  |  | 932 |  | 2998 |  | 
| 126 |  |  |  |  |  |  | my $class = shift; | 
| 127 |  |  |  |  |  |  | return $class->_composed_response_class if $class->_composed_response_class; | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | my @traits = (@{$class->response_class_traits||[]}, @{$class->config->{response_class_traits}||[]}); | 
| 130 |  |  |  |  |  |  |  | 
| 131 | 1094 |  |  | 1094 | 1 | 2703 | my $trait_ns = 'TraitFor::Response'; | 
| 132 | 1094 | 100 |  |  |  | 3792 | my @normalized_traits = map { | 
| 133 |  |  |  |  |  |  | Class::Load::load_first_existing_class($_, $class.'::'.$trait_ns.'::'. $_, 'Catalyst::'.$trait_ns.'::'.$_) | 
| 134 | 161 | 100 |  |  |  | 585 | } @traits; | 
|  | 161 | 50 |  |  |  | 1292 |  | 
|  | 161 |  |  |  |  | 787 |  | 
| 135 |  |  |  |  |  |  |  | 
| 136 | 161 |  |  |  |  | 531 | if ($class->debug && scalar(@normalized_traits)) { | 
| 137 |  |  |  |  |  |  | my $column_width = Catalyst::Utils::term_width() - 6; | 
| 138 | 161 |  |  |  |  | 540 | my $t = Text::SimpleTable->new($column_width); | 
|  | 3 |  |  |  |  | 597 |  | 
| 139 |  |  |  |  |  |  | $t->row($_) for @normalized_traits; | 
| 140 |  |  |  |  |  |  | $class->log->debug( "Composed Response Class Traits:\n" . $t->draw . "\n" ); | 
| 141 | 161 | 50 | 100 |  |  | 997 | } | 
| 142 | 0 |  |  |  |  | 0 |  | 
| 143 | 0 |  |  |  |  | 0 | return $class->_composed_response_class(Moose::Util::with_traits($class->response_class, @normalized_traits)); | 
| 144 | 0 |  |  |  |  | 0 | } | 
| 145 | 0 |  |  |  |  | 0 |  | 
| 146 |  |  |  |  |  |  | has namespace => (is => 'rw'); | 
| 147 |  |  |  |  |  |  |  | 
| 148 | 161 |  |  |  |  | 1577 |  | 
| 149 |  |  |  |  |  |  | my $self = shift; return $self->request(@_); | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  | my $self = shift; return $self->response(@_); | 
| 152 |  |  |  |  |  |  | } | 
| 153 | 9205 | 50 |  | 9205 | 1 | 10548 |  | 
|  | 9205 |  |  |  |  | 206860 |  | 
| 154 | 15 |  |  | 15 | 1 | 792 | # For backwards compatibility | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | # For statistics | 
| 157 | 23855 |  |  | 23855 | 1 | 69770 | our $COUNT     = 1; | 
|  | 23855 |  |  |  |  | 469737 |  | 
| 158 |  |  |  |  |  |  | our $START     = time; | 
| 159 |  |  |  |  |  |  | our $RECURSION = 1000; | 
| 160 | 5490 |  |  | 5490 | 1 | 62631 | our $DETACH    = Catalyst::Exception::Detach->new; | 
|  | 5490 |  |  |  |  | 113410 |  | 
| 161 |  |  |  |  |  |  | our $GO        = Catalyst::Exception::Go->new; | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | #I imagine that very few of these really | 
| 164 | 0 |  |  | 0 | 1 | 0 | #need to be class variables. if any. | 
| 165 |  |  |  |  |  |  | #maybe we should just make them attributes with a default? | 
| 166 |  |  |  |  |  |  | __PACKAGE__->mk_classdata($_) | 
| 167 |  |  |  |  |  |  | for qw/components arguments dispatcher engine log dispatcher_class | 
| 168 |  |  |  |  |  |  | engine_loader context_class request_class response_class stats_class | 
| 169 |  |  |  |  |  |  | setup_finished _psgi_app loading_psgi_file run_options _psgi_middleware | 
| 170 |  |  |  |  |  |  | _data_handlers _encoding _encode_check finalized_default_middleware | 
| 171 |  |  |  |  |  |  | request_class_traits response_class_traits stats_class_traits | 
| 172 |  |  |  |  |  |  | _composed_request_class _composed_response_class _composed_stats_class/; | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | __PACKAGE__->dispatcher_class('Catalyst::Dispatcher'); | 
| 175 |  |  |  |  |  |  | __PACKAGE__->request_class('Catalyst::Request'); | 
| 176 |  |  |  |  |  |  | __PACKAGE__->response_class('Catalyst::Response'); | 
| 177 |  |  |  |  |  |  | __PACKAGE__->stats_class('Catalyst::Stats'); | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | my $class = shift; | 
| 180 |  |  |  |  |  |  | return $class->_composed_stats_class if $class->_composed_stats_class; | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | my @traits = (@{$class->stats_class_traits||[]}, @{$class->config->{stats_class_traits}||[]}); | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | my $trait_ns = 'TraitFor::Stats'; | 
| 185 |  |  |  |  |  |  | my @normalized_traits = map { | 
| 186 |  |  |  |  |  |  | Class::Load::load_first_existing_class($_, $class.'::'.$trait_ns.'::'. $_, 'Catalyst::'.$trait_ns.'::'.$_) | 
| 187 |  |  |  |  |  |  | } @traits; | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | if ($class->debug && scalar(@normalized_traits)) { | 
| 190 | 162 |  |  | 162 | 1 | 883 | my $column_width = Catalyst::Utils::term_width() - 6; | 
| 191 | 162 | 100 |  |  |  | 1131 | my $t = Text::SimpleTable->new($column_width); | 
| 192 |  |  |  |  |  |  | $t->row($_) for @normalized_traits; | 
| 193 | 161 | 100 |  |  |  | 688 | $class->log->debug( "Composed Stats Class Traits:\n" . $t->draw . "\n" ); | 
|  | 161 | 50 |  |  |  | 1357 |  | 
|  | 161 |  |  |  |  | 798 |  | 
| 194 |  |  |  |  |  |  | } | 
| 195 | 161 |  |  |  |  | 539 |  | 
| 196 |  |  |  |  |  |  | return $class->_composed_stats_class(Moose::Util::with_traits($class->stats_class, @normalized_traits)); | 
| 197 | 161 |  |  |  |  | 530 | } | 
|  | 1 |  |  |  |  | 6 |  | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | __PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC); | 
| 200 | 161 | 50 | 100 |  |  | 724 |  | 
| 201 | 0 |  |  |  |  | 0 | my ( $class, @arguments ) = @_; | 
| 202 | 0 |  |  |  |  | 0 |  | 
| 203 | 0 |  |  |  |  | 0 | # We have to limit $class to Catalyst to avoid pushing Catalyst upon every | 
| 204 | 0 |  |  |  |  | 0 | # callers @ISA. | 
| 205 |  |  |  |  |  |  | return unless $class eq 'Catalyst'; | 
| 206 |  |  |  |  |  |  |  | 
| 207 | 161 |  |  |  |  | 1343 | my $caller = caller(); | 
| 208 |  |  |  |  |  |  | return if $caller eq 'main'; | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | my $meta = Moose::Meta::Class->initialize($caller); | 
| 211 |  |  |  |  |  |  | unless ( $caller->isa('Catalyst') ) { | 
| 212 |  |  |  |  |  |  | my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller'); | 
| 213 | 313 |  |  | 313 |  | 85416 | $meta->superclasses(@superclasses); | 
| 214 |  |  |  |  |  |  | } | 
| 215 |  |  |  |  |  |  | # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp | 
| 216 |  |  |  |  |  |  | $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses); | 
| 217 | 313 | 100 |  |  |  | 17797 |  | 
| 218 |  |  |  |  |  |  | unless( $meta->has_method('meta') ){ | 
| 219 | 165 |  |  |  |  | 463 | if ($Moose::VERSION >= 1.15) { | 
| 220 | 165 | 100 |  |  |  | 4165 | $meta->_add_meta_method('meta'); | 
| 221 |  |  |  |  |  |  | } | 
| 222 | 157 |  |  |  |  | 819 | else { | 
| 223 | 157 | 100 |  |  |  | 107058 | $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } ); | 
| 224 | 148 |  |  |  |  | 589 | } | 
| 225 | 148 |  |  |  |  | 5990 | } | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | $caller->arguments( [@arguments] ); | 
| 228 | 157 |  |  |  |  | 918774 | $caller->setup_home; | 
|  | 313 |  |  |  |  | 6595 |  | 
| 229 |  |  |  |  |  |  | } | 
| 230 | 157 | 100 |  |  |  | 245043 |  | 
| 231 | 149 | 50 |  |  |  | 5078 |  | 
| 232 | 149 |  |  |  |  | 808 | =encoding UTF-8 | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | =head1 NAME | 
| 235 | 0 |  |  | 0 |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 236 |  |  |  |  |  |  | Catalyst - The Elegant MVC Web Application Framework | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 239 | 157 |  |  |  |  | 37241 |  | 
| 240 | 157 |  |  |  |  | 886 | See the L<Catalyst::Manual> distribution for comprehensive | 
| 241 |  |  |  |  |  |  | documentation and tutorials. | 
| 242 |  |  |  |  |  |  |  | 
| 243 | 885 |  |  | 885 |  | 1933 | # Install Catalyst::Devel for helpers and other development tools | 
| 244 |  |  |  |  |  |  | # use the helper to create a new application | 
| 245 |  |  |  |  |  |  | catalyst.pl MyApp | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  | # add models, views, controllers | 
| 248 |  |  |  |  |  |  | script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db | 
| 249 |  |  |  |  |  |  | script/myapp_create.pl view MyTemplate TT | 
| 250 |  |  |  |  |  |  | script/myapp_create.pl controller Search | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | # built in testserver -- use -r to restart automatically on changes | 
| 253 |  |  |  |  |  |  | # --help to see all available options | 
| 254 |  |  |  |  |  |  | script/myapp_server.pl | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | # command line testing interface | 
| 257 |  |  |  |  |  |  | script/myapp_test.pl /yada | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | ### in lib/MyApp.pm | 
| 260 |  |  |  |  |  |  | use Catalyst qw/-Debug/; # include plugins here as well | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | ### In lib/MyApp/Controller/Root.pm (autocreated) | 
| 263 |  |  |  |  |  |  | sub foo : Chained('/') Args() { # called for /foo, /foo/1, /foo/1/2, etc. | 
| 264 |  |  |  |  |  |  | my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2 | 
| 265 |  |  |  |  |  |  | $c->stash->{template} = 'foo.tt'; # set the template | 
| 266 |  |  |  |  |  |  | # lookup something from db -- stash vars are passed to TT | 
| 267 |  |  |  |  |  |  | $c->stash->{data} = | 
| 268 |  |  |  |  |  |  | $c->model('Database::Foo')->search( { country => $args[0] } ); | 
| 269 |  |  |  |  |  |  | if ( $c->req->params->{bar} ) { # access GET or POST parameters | 
| 270 |  |  |  |  |  |  | $c->forward( 'bar' ); # process another action | 
| 271 |  |  |  |  |  |  | # do something else after forward returns | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  | } | 
| 274 |  |  |  |  |  |  |  | 
| 275 |  |  |  |  |  |  | # The foo.tt TT template can use the stash data from the database | 
| 276 |  |  |  |  |  |  | [% WHILE (item = data.next) %] | 
| 277 |  |  |  |  |  |  | [% item.foo %] | 
| 278 |  |  |  |  |  |  | [% END %] | 
| 279 |  |  |  |  |  |  |  | 
| 280 |  |  |  |  |  |  | # called for /bar/of/soap, /bar/of/soap/10, etc. | 
| 281 |  |  |  |  |  |  | sub bar : Chained('/') PathPart('/bar/of/soap') Args() { ... } | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | # called after all actions are finished | 
| 284 |  |  |  |  |  |  | sub end : Action { | 
| 285 |  |  |  |  |  |  | my ( $self, $c ) = @_; | 
| 286 |  |  |  |  |  |  | if ( scalar @{ $c->error } ) { ... } # handle errors | 
| 287 |  |  |  |  |  |  | return if $c->res->body; # already have a response | 
| 288 |  |  |  |  |  |  | $c->forward( 'MyApp::View::TT' ); # render template | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | See L<Catalyst::Manual::Intro> for additional information. | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 294 |  |  |  |  |  |  |  | 
| 295 |  |  |  |  |  |  | Catalyst is a modern framework for making web applications without the | 
| 296 |  |  |  |  |  |  | pain usually associated with this process. This document is a reference | 
| 297 |  |  |  |  |  |  | to the main Catalyst application. If you are a new user, we suggest you | 
| 298 |  |  |  |  |  |  | start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>. | 
| 299 |  |  |  |  |  |  |  | 
| 300 |  |  |  |  |  |  | See L<Catalyst::Manual> for more documentation. | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | Catalyst plugins can be loaded by naming them as arguments to the "use | 
| 303 |  |  |  |  |  |  | Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the | 
| 304 |  |  |  |  |  |  | plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes | 
| 305 |  |  |  |  |  |  | C<My::Module>. | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | use Catalyst qw/My::Module/; | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | If your plugin starts with a name other than C<Catalyst::Plugin::>, you can | 
| 310 |  |  |  |  |  |  | fully qualify the name by using a unary plus: | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  | use Catalyst qw/ | 
| 313 |  |  |  |  |  |  | My::Module | 
| 314 |  |  |  |  |  |  | +Fully::Qualified::Plugin::Name | 
| 315 |  |  |  |  |  |  | /; | 
| 316 |  |  |  |  |  |  |  | 
| 317 |  |  |  |  |  |  | Special flags like C<-Debug> can also be specified as | 
| 318 |  |  |  |  |  |  | arguments when Catalyst is loaded: | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | use Catalyst qw/-Debug My::Module/; | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | The position of plugins and flags in the chain is important, because | 
| 323 |  |  |  |  |  |  | they are loaded in the order in which they appear. | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | The following flags are supported: | 
| 326 |  |  |  |  |  |  |  | 
| 327 |  |  |  |  |  |  | =head2 -Debug | 
| 328 |  |  |  |  |  |  |  | 
| 329 |  |  |  |  |  |  | Enables debug output. You can also force this setting from the system | 
| 330 |  |  |  |  |  |  | environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment | 
| 331 |  |  |  |  |  |  | settings override the application, with <MYAPP>_DEBUG having the highest | 
| 332 |  |  |  |  |  |  | priority. | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | This sets the log level to 'debug' and enables full debug output on the | 
| 335 |  |  |  |  |  |  | error screen. If you only want the latter, see L<< $c->debug >>. | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  | =head2 -Home | 
| 338 |  |  |  |  |  |  |  | 
| 339 |  |  |  |  |  |  | Forces Catalyst to use a specific home directory, e.g.: | 
| 340 |  |  |  |  |  |  |  | 
| 341 |  |  |  |  |  |  | use Catalyst qw[-Home=/usr/mst]; | 
| 342 |  |  |  |  |  |  |  | 
| 343 |  |  |  |  |  |  | This can also be done in the shell environment by setting either the | 
| 344 |  |  |  |  |  |  | C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP> | 
| 345 |  |  |  |  |  |  | is replaced with the uppercased name of your application, any "::" in | 
| 346 |  |  |  |  |  |  | the name will be replaced with underscores, e.g. MyApp::Web should use | 
| 347 |  |  |  |  |  |  | MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used. | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | If none of these are set, Catalyst will attempt to automatically detect the | 
| 350 |  |  |  |  |  |  | home directory. If you are working in a development environment, Catalyst | 
| 351 |  |  |  |  |  |  | will try and find the directory containing either Makefile.PL, Build.PL, | 
| 352 |  |  |  |  |  |  | dist.ini, or cpanfile. If the application has been installed into the system | 
| 353 |  |  |  |  |  |  | (i.e. you have done C<make install>), then Catalyst will use the path to your | 
| 354 |  |  |  |  |  |  | application module, without the .pm extension (e.g., /foo/MyApp if your | 
| 355 |  |  |  |  |  |  | application was installed at /foo/MyApp.pm) | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | =head2 -Log | 
| 358 |  |  |  |  |  |  |  | 
| 359 |  |  |  |  |  |  | use Catalyst '-Log=warn,fatal,error'; | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | Specifies a comma-delimited list of log levels. | 
| 362 |  |  |  |  |  |  |  | 
| 363 |  |  |  |  |  |  | =head2 -Stats | 
| 364 |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  | Enables statistics collection and reporting. | 
| 366 |  |  |  |  |  |  |  | 
| 367 |  |  |  |  |  |  | use Catalyst qw/-Stats=1/; | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | You can also force this setting from the system environment with CATALYST_STATS | 
| 370 |  |  |  |  |  |  | or <MYAPP>_STATS. The environment settings override the application, with | 
| 371 |  |  |  |  |  |  | <MYAPP>_STATS having the highest priority. | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | Stats are also enabled if L<< debugging |/"-Debug" >> is enabled. | 
| 374 |  |  |  |  |  |  |  | 
| 375 |  |  |  |  |  |  | =head1 METHODS | 
| 376 |  |  |  |  |  |  |  | 
| 377 |  |  |  |  |  |  | =head2 INFORMATION ABOUT THE CURRENT REQUEST | 
| 378 |  |  |  |  |  |  |  | 
| 379 |  |  |  |  |  |  | =head2 $c->action | 
| 380 |  |  |  |  |  |  |  | 
| 381 |  |  |  |  |  |  | Returns a L<Catalyst::Action> object for the current action, which | 
| 382 |  |  |  |  |  |  | stringifies to the action name. See L<Catalyst::Action>. | 
| 383 |  |  |  |  |  |  |  | 
| 384 |  |  |  |  |  |  | =head2 $c->namespace | 
| 385 |  |  |  |  |  |  |  | 
| 386 |  |  |  |  |  |  | Returns the namespace of the current action, i.e., the URI prefix | 
| 387 |  |  |  |  |  |  | corresponding to the controller of the current action. For example: | 
| 388 |  |  |  |  |  |  |  | 
| 389 |  |  |  |  |  |  | # in Controller::Foo::Bar | 
| 390 |  |  |  |  |  |  | $c->namespace; # returns 'foo/bar'; | 
| 391 |  |  |  |  |  |  |  | 
| 392 |  |  |  |  |  |  | =head2 $c->request | 
| 393 |  |  |  |  |  |  |  | 
| 394 |  |  |  |  |  |  | =head2 $c->req | 
| 395 |  |  |  |  |  |  |  | 
| 396 |  |  |  |  |  |  | Returns the current L<Catalyst::Request> object, giving access to | 
| 397 |  |  |  |  |  |  | information about the current client request (including parameters, | 
| 398 |  |  |  |  |  |  | cookies, HTTP headers, etc.). See L<Catalyst::Request>. | 
| 399 |  |  |  |  |  |  |  | 
| 400 |  |  |  |  |  |  | There is a predicate method C<has_request> that returns true if the | 
| 401 |  |  |  |  |  |  | request object has been created.  This is something you might need to | 
| 402 |  |  |  |  |  |  | check if you are writing plugins that run before a request is finalized. | 
| 403 |  |  |  |  |  |  |  | 
| 404 |  |  |  |  |  |  | =head2 REQUEST FLOW HANDLING | 
| 405 |  |  |  |  |  |  |  | 
| 406 |  |  |  |  |  |  | =head2 $c->forward( $action [, \@arguments ] ) | 
| 407 |  |  |  |  |  |  |  | 
| 408 |  |  |  |  |  |  | =head2 $c->forward( $class, $method, [, \@arguments ] ) | 
| 409 |  |  |  |  |  |  |  | 
| 410 |  |  |  |  |  |  | This is one way of calling another action (method) in the same or | 
| 411 |  |  |  |  |  |  | a different controller. You can also use C<< $self->my_method($c, @args) >> | 
| 412 |  |  |  |  |  |  | in the same controller or C<< $c->controller('MyController')->my_method($c, @args) >> | 
| 413 |  |  |  |  |  |  | in a different controller. | 
| 414 |  |  |  |  |  |  | The main difference is that 'forward' uses some of the Catalyst request | 
| 415 |  |  |  |  |  |  | cycle overhead, including debugging, which may be useful to you. On the | 
| 416 |  |  |  |  |  |  | other hand, there are some complications to using 'forward', restrictions | 
| 417 |  |  |  |  |  |  | on values returned from 'forward', and it may not handle errors as you prefer. | 
| 418 |  |  |  |  |  |  | Whether you use 'forward' or not is up to you; it is not considered superior to | 
| 419 |  |  |  |  |  |  | the other ways to call a method. | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | 'forward' calls  another action, by its private name. If you give a | 
| 422 |  |  |  |  |  |  | class name but no method, C<process()> is called. You may also optionally | 
| 423 |  |  |  |  |  |  | pass arguments in an arrayref. The action will receive the arguments in | 
| 424 |  |  |  |  |  |  | C<@_> and C<< $c->req->args >>. Upon returning from the function, | 
| 425 |  |  |  |  |  |  | C<< $c->req->args >> will be restored to the previous values. | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | Any data C<return>ed from the action forwarded to, will be returned by the | 
| 428 |  |  |  |  |  |  | call to forward. | 
| 429 |  |  |  |  |  |  |  | 
| 430 |  |  |  |  |  |  | my $foodata = $c->forward('/foo'); | 
| 431 |  |  |  |  |  |  | $c->forward('index'); | 
| 432 |  |  |  |  |  |  | $c->forward(qw/Model::DBIC::Foo do_stuff/); | 
| 433 |  |  |  |  |  |  | $c->forward('View::TT'); | 
| 434 |  |  |  |  |  |  |  | 
| 435 |  |  |  |  |  |  | Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies | 
| 436 |  |  |  |  |  |  | an C<< eval { } >> around the call (actually | 
| 437 |  |  |  |  |  |  | L<< execute|/"$c->execute( $class, $coderef )" >> does), thus rendering all | 
| 438 |  |  |  |  |  |  | exceptions thrown by the called action non-fatal and pushing them onto | 
| 439 |  |  |  |  |  |  | $c->error instead. If you want C<die> to propagate you need to do something | 
| 440 |  |  |  |  |  |  | like: | 
| 441 |  |  |  |  |  |  |  | 
| 442 |  |  |  |  |  |  | $c->forward('foo'); | 
| 443 |  |  |  |  |  |  | die join "\n", @{ $c->error } if @{ $c->error }; | 
| 444 |  |  |  |  |  |  |  | 
| 445 |  |  |  |  |  |  | Or make sure to always return true values from your actions and write | 
| 446 |  |  |  |  |  |  | your code like this: | 
| 447 |  |  |  |  |  |  |  | 
| 448 |  |  |  |  |  |  | $c->forward('foo') || return; | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | Another note is that C<< $c->forward >> always returns a scalar because it | 
| 451 |  |  |  |  |  |  | actually returns $c->state which operates in a scalar context. | 
| 452 |  |  |  |  |  |  | Thus, something like: | 
| 453 |  |  |  |  |  |  |  | 
| 454 |  |  |  |  |  |  | return @array; | 
| 455 |  |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  | in an action that is forwarded to is going to return a scalar, | 
| 457 |  |  |  |  |  |  | i.e. how many items are in that array, which is probably not what you want. | 
| 458 |  |  |  |  |  |  | If you need to return an array then return a reference to it, | 
| 459 |  |  |  |  |  |  | or stash it like so: | 
| 460 |  |  |  |  |  |  |  | 
| 461 |  |  |  |  |  |  | $c->stash->{array} = \@array; | 
| 462 |  |  |  |  |  |  |  | 
| 463 |  |  |  |  |  |  | and access it from the stash. | 
| 464 |  |  |  |  |  |  |  | 
| 465 |  |  |  |  |  |  | Keep in mind that the C<end> method used is that of the caller action. So a C<< $c->detach >> inside a forwarded action would run the C<end> method from the original action requested. | 
| 466 |  |  |  |  |  |  |  | 
| 467 |  |  |  |  |  |  | =cut | 
| 468 |  |  |  |  |  |  |  | 
| 469 |  |  |  |  |  |  |  | 
| 470 |  |  |  |  |  |  | =head2 $c->detach( $action [, \@arguments ] ) | 
| 471 |  |  |  |  |  |  |  | 
| 472 |  |  |  |  |  |  | =head2 $c->detach( $class, $method, [, \@arguments ] ) | 
| 473 |  |  |  |  |  |  |  | 
| 474 |  |  |  |  |  |  | =head2 $c->detach() | 
| 475 |  |  |  |  |  |  |  | 
| 476 |  |  |  |  |  |  | The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but | 
| 477 |  |  |  |  |  |  | doesn't return to the previous action when processing is finished. | 
| 478 |  |  |  |  |  |  |  | 
| 479 |  |  |  |  |  |  | When called with no arguments it escapes the processing chain entirely. | 
| 480 |  |  |  |  |  |  |  | 
| 481 |  |  |  |  |  |  | =cut | 
| 482 | 163 |  |  | 163 | 1 | 1047 |  | 
|  | 163 |  |  | 6882 |  | 1545 |  | 
|  | 163 |  |  |  |  | 573939 |  | 
|  | 6882 |  |  |  |  | 17327 |  | 
|  | 6882 |  |  |  |  | 16980 |  | 
| 483 |  |  |  |  |  |  |  | 
| 484 |  |  |  |  |  |  | =head2 $c->visit( $action [, \@arguments ] ) | 
| 485 |  |  |  |  |  |  |  | 
| 486 |  |  |  |  |  |  | =head2 $c->visit( $action [, \@captures, \@arguments ] ) | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  | =head2 $c->visit( $class, $method, [, \@arguments ] ) | 
| 489 |  |  |  |  |  |  |  | 
| 490 |  |  |  |  |  |  | =head2 $c->visit( $class, $method, [, \@captures, \@arguments ] ) | 
| 491 |  |  |  |  |  |  |  | 
| 492 |  |  |  |  |  |  | Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, | 
| 493 |  |  |  |  |  |  | but does a full dispatch, instead of just calling the new C<$action> / | 
| 494 |  |  |  |  |  |  | C<< $class->$method >>. This means that C<begin>, C<auto> and the method | 
| 495 |  |  |  |  |  |  | you go to are called, just like a new request. | 
| 496 |  |  |  |  |  |  |  | 
| 497 | 16 |  |  | 16 | 1 | 112 | In addition both C<< $c->action >> and C<< $c->namespace >> are localized. | 
|  | 16 |  |  |  |  | 44 |  | 
| 498 |  |  |  |  |  |  | This means, for example, that C<< $c->action >> methods such as | 
| 499 |  |  |  |  |  |  | L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and | 
| 500 |  |  |  |  |  |  | L<reverse|Catalyst::Action/reverse> return information for the visited action | 
| 501 |  |  |  |  |  |  | when they are invoked within the visited action.  This is different from the | 
| 502 |  |  |  |  |  |  | behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which | 
| 503 |  |  |  |  |  |  | continues to use the $c->action object from the caller action even when | 
| 504 |  |  |  |  |  |  | invoked from the called action. | 
| 505 |  |  |  |  |  |  |  | 
| 506 |  |  |  |  |  |  | C<< $c->stash >> is kept unchanged. | 
| 507 |  |  |  |  |  |  |  | 
| 508 |  |  |  |  |  |  | In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> | 
| 509 |  |  |  |  |  |  | allows you to "wrap" another action, just as it would have been called by | 
| 510 |  |  |  |  |  |  | dispatching from a URL, while the analogous | 
| 511 |  |  |  |  |  |  | L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to | 
| 512 |  |  |  |  |  |  | transfer control to another action as if it had been reached directly from a URL. | 
| 513 |  |  |  |  |  |  |  | 
| 514 |  |  |  |  |  |  | =cut | 
| 515 |  |  |  |  |  |  |  | 
| 516 |  |  |  |  |  |  |  | 
| 517 |  |  |  |  |  |  | =head2 $c->go( $action [, \@arguments ] ) | 
| 518 |  |  |  |  |  |  |  | 
| 519 |  |  |  |  |  |  | =head2 $c->go( $action [, \@captures, \@arguments ] ) | 
| 520 |  |  |  |  |  |  |  | 
| 521 |  |  |  |  |  |  | =head2 $c->go( $class, $method, [, \@arguments ] ) | 
| 522 |  |  |  |  |  |  |  | 
| 523 |  |  |  |  |  |  | =head2 $c->go( $class, $method, [, \@captures, \@arguments ] ) | 
| 524 |  |  |  |  |  |  |  | 
| 525 |  |  |  |  |  |  | The relationship between C<go> and | 
| 526 |  |  |  |  |  |  | L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as | 
| 527 |  |  |  |  |  |  | the relationship between | 
| 528 |  |  |  |  |  |  | L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and | 
| 529 |  |  |  |  |  |  | L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>, | 
| 530 |  |  |  |  |  |  | C<< $c->go >> will perform a full dispatch on the specified action or method, | 
| 531 | 26 |  |  | 26 | 1 | 210 | with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>, | 
|  | 26 |  |  |  |  | 60 |  | 
| 532 |  |  |  |  |  |  | C<go> escapes the processing of the current request chain on completion, and | 
| 533 |  |  |  |  |  |  | does not return to its caller. | 
| 534 |  |  |  |  |  |  |  | 
| 535 |  |  |  |  |  |  | @arguments are arguments to the final destination of $action. @captures are | 
| 536 |  |  |  |  |  |  | arguments to the intermediate steps, if any, on the way to the final sub of | 
| 537 |  |  |  |  |  |  | $action. | 
| 538 |  |  |  |  |  |  |  | 
| 539 |  |  |  |  |  |  | =cut | 
| 540 |  |  |  |  |  |  |  | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | =head2 $c->response | 
| 543 |  |  |  |  |  |  |  | 
| 544 |  |  |  |  |  |  | =head2 $c->res | 
| 545 |  |  |  |  |  |  |  | 
| 546 |  |  |  |  |  |  | Returns the current L<Catalyst::Response> object, see there for details. | 
| 547 |  |  |  |  |  |  |  | 
| 548 |  |  |  |  |  |  | There is a predicate method C<has_response> that returns true if the | 
| 549 |  |  |  |  |  |  | request object has been created.  This is something you might need to | 
| 550 |  |  |  |  |  |  | check if you are writing plugins that run before a request is finalized. | 
| 551 |  |  |  |  |  |  |  | 
| 552 |  |  |  |  |  |  | =head2 $c->stash | 
| 553 |  |  |  |  |  |  |  | 
| 554 |  |  |  |  |  |  | Returns a hashref to the stash, which may be used to store data and pass | 
| 555 |  |  |  |  |  |  | it between components during a request. You can also set hash keys by | 
| 556 |  |  |  |  |  |  | passing arguments. The stash is automatically sent to the view. The | 
| 557 | 24 |  |  | 24 | 1 | 194 | stash is cleared at the end of a request; it cannot be used for | 
|  | 24 |  |  |  |  | 64 |  | 
| 558 |  |  |  |  |  |  | persistent storage (for this you must use a session; see | 
| 559 |  |  |  |  |  |  | L<Catalyst::Plugin::Session> for a complete system integrated with | 
| 560 |  |  |  |  |  |  | Catalyst). | 
| 561 |  |  |  |  |  |  |  | 
| 562 |  |  |  |  |  |  | $c->stash->{foo} = $bar; | 
| 563 |  |  |  |  |  |  | $c->stash( { moose => 'majestic', qux => 0 } ); | 
| 564 |  |  |  |  |  |  | $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref | 
| 565 |  |  |  |  |  |  |  | 
| 566 |  |  |  |  |  |  | # stash is automatically passed to the view for use in a template | 
| 567 |  |  |  |  |  |  | $c->forward( 'MyApp::View::TT' ); | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  | The stash hash is currently stored in the PSGI C<$env> and is managed by | 
| 570 |  |  |  |  |  |  | L<Catalyst::Middleware::Stash>.  Since it's part of the C<$env> items in | 
| 571 |  |  |  |  |  |  | the stash can be accessed in sub applications mounted under your main | 
| 572 |  |  |  |  |  |  | L<Catalyst> application.  For example if you delegate the response of an | 
| 573 |  |  |  |  |  |  | action to another L<Catalyst> application, that sub application will have | 
| 574 |  |  |  |  |  |  | access to all the stash keys of the main one, and if can of course add | 
| 575 |  |  |  |  |  |  | more keys of its own.  However those new keys will not 'bubble' back up | 
| 576 |  |  |  |  |  |  | to the main application. | 
| 577 |  |  |  |  |  |  |  | 
| 578 |  |  |  |  |  |  | For more information the best thing to do is to review the test case: | 
| 579 |  |  |  |  |  |  | t/middleware-stash.t in the distribution /t directory. | 
| 580 |  |  |  |  |  |  |  | 
| 581 |  |  |  |  |  |  | =cut | 
| 582 |  |  |  |  |  |  |  | 
| 583 |  |  |  |  |  |  | my $c = shift; | 
| 584 |  |  |  |  |  |  | $c->log->error("You are requesting the stash but you don't have a context") unless blessed $c; | 
| 585 |  |  |  |  |  |  | return Catalyst::Middleware::Stash::get_stash($c->req->env)->(@_); | 
| 586 |  |  |  |  |  |  | } | 
| 587 |  |  |  |  |  |  |  | 
| 588 |  |  |  |  |  |  | =head2 $c->error | 
| 589 |  |  |  |  |  |  |  | 
| 590 |  |  |  |  |  |  | =head2 $c->error($error, ...) | 
| 591 |  |  |  |  |  |  |  | 
| 592 |  |  |  |  |  |  | =head2 $c->error($arrayref) | 
| 593 |  |  |  |  |  |  |  | 
| 594 |  |  |  |  |  |  | Returns an arrayref containing error messages.  If Catalyst encounters an | 
| 595 |  |  |  |  |  |  | error while processing a request, it stores the error in $c->error.  This | 
| 596 |  |  |  |  |  |  | method should only be used to store fatal error messages. | 
| 597 |  |  |  |  |  |  |  | 
| 598 |  |  |  |  |  |  | my @error = @{ $c->error }; | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | Add a new error. | 
| 601 | 2414 |  |  | 2414 | 1 | 6972 |  | 
| 602 | 2414 | 50 |  |  |  | 7209 | $c->error('Something bad happened'); | 
| 603 | 2414 |  |  |  |  | 5751 |  | 
| 604 |  |  |  |  |  |  | Calling this will always return an arrayref (if there are no errors it | 
| 605 |  |  |  |  |  |  | will be an empty arrayref. | 
| 606 |  |  |  |  |  |  |  | 
| 607 |  |  |  |  |  |  | =cut | 
| 608 |  |  |  |  |  |  |  | 
| 609 |  |  |  |  |  |  | my $c = shift; | 
| 610 |  |  |  |  |  |  | if ( $_[0] ) { | 
| 611 |  |  |  |  |  |  | my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_]; | 
| 612 |  |  |  |  |  |  | croak @$error unless ref $c; | 
| 613 |  |  |  |  |  |  | push @{ $c->{error} }, @$error; | 
| 614 |  |  |  |  |  |  | } | 
| 615 |  |  |  |  |  |  | elsif ( defined $_[0] ) { $c->{error} = undef } | 
| 616 |  |  |  |  |  |  | return $c->{error} || []; | 
| 617 |  |  |  |  |  |  | } | 
| 618 |  |  |  |  |  |  |  | 
| 619 |  |  |  |  |  |  | =head2 $c->state | 
| 620 |  |  |  |  |  |  |  | 
| 621 |  |  |  |  |  |  | Contains the return value of the last executed action. | 
| 622 |  |  |  |  |  |  | Note that << $c->state >> operates in a scalar context which means that all | 
| 623 |  |  |  |  |  |  | values it returns are scalar. | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | Please note that if an action throws an exception, the value of state | 
| 626 |  |  |  |  |  |  | should no longer be considered the return if the last action.  It is generally | 
| 627 |  |  |  |  |  |  | going to be 0, which indicates an error state.  Examine $c->error for error | 
| 628 | 11020 |  |  | 11020 | 1 | 103494 | details. | 
| 629 | 11020 | 100 |  |  |  | 23528 |  | 
|  |  | 100 |  |  |  |  |  | 
| 630 | 39 | 50 |  |  |  | 184 | =head2 $c->clear_errors | 
| 631 | 39 | 50 |  |  |  | 142 |  | 
| 632 | 39 |  |  |  |  | 77 | Clear errors.  You probably don't want to clear the errors unless you are | 
|  | 39 |  |  |  |  | 183 |  | 
| 633 |  |  |  |  |  |  | implementing a custom error screen. | 
| 634 | 10 |  |  |  |  | 15 |  | 
| 635 | 11020 |  | 100 |  |  | 48680 | This is equivalent to running | 
| 636 |  |  |  |  |  |  |  | 
| 637 |  |  |  |  |  |  | $c->error(0); | 
| 638 |  |  |  |  |  |  |  | 
| 639 |  |  |  |  |  |  | =cut | 
| 640 |  |  |  |  |  |  |  | 
| 641 |  |  |  |  |  |  | my $c = shift; | 
| 642 |  |  |  |  |  |  | $c->error(0); | 
| 643 |  |  |  |  |  |  | } | 
| 644 |  |  |  |  |  |  |  | 
| 645 |  |  |  |  |  |  | =head2 $c->has_errors | 
| 646 |  |  |  |  |  |  |  | 
| 647 |  |  |  |  |  |  | Returns true if you have errors | 
| 648 |  |  |  |  |  |  |  | 
| 649 |  |  |  |  |  |  | =cut | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  |  | 
| 652 |  |  |  |  |  |  | =head2 $c->last_error | 
| 653 |  |  |  |  |  |  |  | 
| 654 |  |  |  |  |  |  | Returns the most recent error in the stack (the one most recently added...) | 
| 655 |  |  |  |  |  |  | or nothing if there are no errors.  This does not modify the contents of the | 
| 656 |  |  |  |  |  |  | error stack. | 
| 657 |  |  |  |  |  |  |  | 
| 658 |  |  |  |  |  |  | =cut | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | my (@errs) = @{shift->error}; | 
| 661 | 10 |  |  | 10 | 1 | 15 | return scalar(@errs) ? $errs[-1]: undef; | 
| 662 | 10 |  |  |  |  | 20 | } | 
| 663 |  |  |  |  |  |  |  | 
| 664 |  |  |  |  |  |  | =head2 shift_errors | 
| 665 |  |  |  |  |  |  |  | 
| 666 |  |  |  |  |  |  | shifts the most recently added error off the error stack and returns it.  Returns | 
| 667 |  |  |  |  |  |  | nothing if there are no more errors. | 
| 668 |  |  |  |  |  |  |  | 
| 669 |  |  |  |  |  |  | =cut | 
| 670 |  |  |  |  |  |  |  | 
| 671 | 292 | 100 |  | 292 | 1 | 504 | my ($self) = @_; | 
|  | 292 |  |  |  |  | 870 |  | 
| 672 |  |  |  |  |  |  | my @errors = @{$self->error}; | 
| 673 |  |  |  |  |  |  | my $err = shift(@errors); | 
| 674 |  |  |  |  |  |  | $self->{error} = \@errors; | 
| 675 |  |  |  |  |  |  | return $err; | 
| 676 |  |  |  |  |  |  | } | 
| 677 |  |  |  |  |  |  |  | 
| 678 |  |  |  |  |  |  | =head2 pop_errors | 
| 679 |  |  |  |  |  |  |  | 
| 680 |  |  |  |  |  |  | pops the most recently added error off the error stack and returns it.  Returns | 
| 681 |  |  |  |  |  |  | nothing if there are no more errors. | 
| 682 | 0 |  |  | 0 | 1 | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 683 | 0 | 0 |  |  |  | 0 | =cut | 
| 684 |  |  |  |  |  |  |  | 
| 685 |  |  |  |  |  |  | my ($self) = @_; | 
| 686 |  |  |  |  |  |  | my @errors = @{$self->error}; | 
| 687 |  |  |  |  |  |  | my $err = pop(@errors); | 
| 688 |  |  |  |  |  |  | $self->{error} = \@errors; | 
| 689 |  |  |  |  |  |  | return $err; | 
| 690 |  |  |  |  |  |  | } | 
| 691 |  |  |  |  |  |  |  | 
| 692 |  |  |  |  |  |  | my $c = shift; | 
| 693 |  |  |  |  |  |  | return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_); | 
| 694 | 3 |  |  | 3 | 1 | 22 | } | 
| 695 | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 6 |  | 
| 696 | 3 |  |  |  |  | 6 | # search components given a name and some prefixes | 
| 697 | 3 |  |  |  |  | 7 | my ( $c, $name, @prefixes ) = @_; | 
| 698 | 3 |  |  |  |  | 5 | my $appclass = ref $c || $c; | 
| 699 |  |  |  |  |  |  | my $filter   = "^${appclass}::(" . join( '|', @prefixes ) . ')::'; | 
| 700 |  |  |  |  |  |  | $filter = qr/$filter/; # Compile regex now rather than once per loop | 
| 701 |  |  |  |  |  |  |  | 
| 702 |  |  |  |  |  |  | # map the original component name to the sub part that we will search against | 
| 703 |  |  |  |  |  |  | my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; } | 
| 704 |  |  |  |  |  |  | grep { /$filter/ } keys %{ $c->components }; | 
| 705 |  |  |  |  |  |  |  | 
| 706 |  |  |  |  |  |  | # undef for a name will return all | 
| 707 |  |  |  |  |  |  | return keys %eligible if !defined $name; | 
| 708 |  |  |  |  |  |  |  | 
| 709 | 0 |  |  | 0 | 1 | 0 | my $query  = $name->$_isa('Regexp') ? $name : qr/^$name$/i; | 
| 710 | 0 |  |  |  |  | 0 | my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible; | 
|  | 0 |  |  |  |  | 0 |  | 
| 711 | 0 |  |  |  |  | 0 |  | 
| 712 | 0 |  |  |  |  | 0 | return @result if @result; | 
| 713 | 0 |  |  |  |  | 0 |  | 
| 714 |  |  |  |  |  |  | # if we were given a regexp to search against, we're done. | 
| 715 |  |  |  |  |  |  | return if $name->$_isa('Regexp'); | 
| 716 |  |  |  |  |  |  |  | 
| 717 | 64 |  |  | 64 |  | 93 | # skip regexp fallback if configured | 
| 718 | 64 |  |  |  |  | 164 | return | 
| 719 |  |  |  |  |  |  | if $appclass->config->{disable_component_resolution_regex_fallback}; | 
| 720 |  |  |  |  |  |  |  | 
| 721 |  |  |  |  |  |  | # regexp fallback | 
| 722 |  |  |  |  |  |  | $query  = qr/$name/i; | 
| 723 | 67 |  |  | 67 |  | 155 | @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible; | 
| 724 | 67 |  | 66 |  |  | 168 |  | 
| 725 | 67 |  |  |  |  | 213 | # no results? try against full names | 
| 726 | 67 |  |  |  |  | 1029 | if( !@result ) { | 
| 727 |  |  |  |  |  |  | @result = grep { m{$query} } keys %eligible; | 
| 728 |  |  |  |  |  |  | } | 
| 729 | 574 |  |  |  |  | 717 |  | 
|  | 574 |  |  |  |  | 1806 |  | 
|  | 574 |  |  |  |  | 1347 |  | 
| 730 | 67 |  |  |  |  | 129 | # don't warn if we didn't find any results, it just might not exist | 
|  | 1139 |  |  |  |  | 2852 |  | 
|  | 67 |  |  |  |  | 160 |  | 
| 731 |  |  |  |  |  |  | if( @result ) { | 
| 732 |  |  |  |  |  |  | # Disgusting hack to work out correct method name | 
| 733 | 67 | 100 |  |  |  | 255 | my $warn_for = lc $prefixes[0]; | 
| 734 |  |  |  |  |  |  | my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" . | 
| 735 | 61 | 100 |  |  |  | 186 | (join '", "', @result) . "'. Relying on regexp fallback behavior for " . | 
| 736 | 61 |  |  |  |  | 1049 | "component resolution is unreliable and unsafe."; | 
|  | 558 |  |  |  |  | 1298 |  | 
| 737 |  |  |  |  |  |  | my $short = $result[0]; | 
| 738 | 61 | 100 |  |  |  | 373 | # remove the component namespace prefix | 
| 739 |  |  |  |  |  |  | $short =~ s/.*?(Model|Controller|View):://; | 
| 740 |  |  |  |  |  |  | my $shortmess = Carp::shortmess(''); | 
| 741 | 20 | 100 |  |  |  | 45 | if ($shortmess =~ m#Catalyst/Plugin#) { | 
| 742 |  |  |  |  |  |  | $msg .= " You probably need to set '$short' instead of '${name}' in this " . | 
| 743 |  |  |  |  |  |  | "plugin's config"; | 
| 744 |  |  |  |  |  |  | } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) { | 
| 745 | 19 | 100 |  |  |  | 164 | $msg .= " You probably need to set '$short' instead of '${name}' in this " . | 
| 746 |  |  |  |  |  |  | "component's config"; | 
| 747 |  |  |  |  |  |  | } else { | 
| 748 | 18 |  |  |  |  | 143 | $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " . | 
| 749 | 18 |  |  |  |  | 64 | "but if you really wanted to search, pass in a regexp as the argument " . | 
|  | 139 |  |  |  |  | 314 |  | 
| 750 |  |  |  |  |  |  | "like so: \$c->${warn_for}(qr/${name}/)"; | 
| 751 |  |  |  |  |  |  | } | 
| 752 | 18 | 100 |  |  |  | 51 | $c->log->warn( "${msg}$shortmess" ); | 
| 753 | 14 |  |  |  |  | 34 | } | 
|  | 125 |  |  |  |  | 281 |  | 
| 754 |  |  |  |  |  |  |  | 
| 755 |  |  |  |  |  |  | return @result; | 
| 756 |  |  |  |  |  |  | } | 
| 757 | 18 | 100 |  |  |  | 49 |  | 
| 758 |  |  |  |  |  |  | # Find possible names for a prefix | 
| 759 | 14 |  |  |  |  | 36 | my ( $c, @prefixes ) = @_; | 
| 760 | 14 |  |  |  |  | 54 | my $appclass = ref $c || $c; | 
| 761 |  |  |  |  |  |  |  | 
| 762 |  |  |  |  |  |  | my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::'; | 
| 763 | 14 |  |  |  |  | 23 |  | 
| 764 |  |  |  |  |  |  | my @names = map { s{$filter}{}; $_; } | 
| 765 | 14 |  |  |  |  | 66 | $c->_comp_names_search_prefixes( undef, @prefixes ); | 
| 766 | 14 |  |  |  |  | 1610 |  | 
| 767 | 14 | 50 |  |  |  | 151 | return @names; | 
|  |  | 50 |  |  |  |  |  | 
| 768 | 0 |  |  |  |  | 0 | } | 
| 769 |  |  |  |  |  |  |  | 
| 770 |  |  |  |  |  |  | # Filter a component before returning by calling ACCEPT_CONTEXT if available | 
| 771 | 0 |  |  |  |  | 0 |  | 
| 772 |  |  |  |  |  |  | my ( $c, $comp, @args ) = @_; | 
| 773 |  |  |  |  |  |  |  | 
| 774 | 14 |  |  |  |  | 52 | if(ref $comp eq 'CODE') { | 
| 775 |  |  |  |  |  |  | $comp = $comp->(); | 
| 776 |  |  |  |  |  |  | } | 
| 777 |  |  |  |  |  |  |  | 
| 778 | 14 |  |  |  |  | 52 | if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) { | 
| 779 |  |  |  |  |  |  | return $comp->ACCEPT_CONTEXT( $c, @args ); | 
| 780 |  |  |  |  |  |  | } | 
| 781 | 18 |  |  |  |  | 122 |  | 
| 782 |  |  |  |  |  |  | $c->log->warn("You called component '${\$comp->catalyst_component_name}' with arguments [@args], but this component does not ACCEPT_CONTEXT, so args are ignored.") if scalar(@args) && $c->debug; | 
| 783 |  |  |  |  |  |  |  | 
| 784 |  |  |  |  |  |  | return $comp; | 
| 785 |  |  |  |  |  |  | } | 
| 786 | 3 |  |  | 3 |  | 8 |  | 
| 787 | 3 |  | 33 |  |  | 11 | =head2 COMPONENT ACCESSORS | 
| 788 |  |  |  |  |  |  |  | 
| 789 | 3 |  |  |  |  | 12 | =head2 $c->controller($name) | 
| 790 |  |  |  |  |  |  |  | 
| 791 | 3 |  |  |  |  | 7 | Gets a L<Catalyst::Controller> instance by name. | 
|  | 9 |  |  |  |  | 69 |  | 
|  | 9 |  |  |  |  | 23 |  | 
| 792 |  |  |  |  |  |  |  | 
| 793 |  |  |  |  |  |  | $c->controller('Foo')->do_stuff; | 
| 794 | 3 |  |  |  |  | 26 |  | 
| 795 |  |  |  |  |  |  | If the name is omitted, will return the controller for the dispatched | 
| 796 |  |  |  |  |  |  | action. | 
| 797 |  |  |  |  |  |  |  | 
| 798 |  |  |  |  |  |  | If you want to search for controllers, pass in a regexp as the argument. | 
| 799 |  |  |  |  |  |  |  | 
| 800 | 16551 |  |  | 16551 |  | 25314 | # find all controllers that start with Foo | 
| 801 |  |  |  |  |  |  | my @foo_controllers = $c->controller(qr{^Foo}); | 
| 802 | 16551 | 100 |  |  |  | 33357 |  | 
| 803 | 9 |  |  |  |  | 15 |  | 
| 804 |  |  |  |  |  |  | =cut | 
| 805 |  |  |  |  |  |  |  | 
| 806 | 16551 | 100 |  |  |  | 21747 | my ( $c, $name, @args ) = @_; | 
|  | 16551 |  |  |  |  | 52949 |  | 
| 807 | 9 |  |  |  |  | 32 |  | 
| 808 |  |  |  |  |  |  | my $appclass = ref($c) || $c; | 
| 809 |  |  |  |  |  |  | if( $name ) { | 
| 810 | 16542 | 50 | 33 |  |  | 33045 | unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps | 
|  | 0 |  |  |  |  | 0 |  | 
| 811 |  |  |  |  |  |  | my $comps = $c->components; | 
| 812 | 16542 |  |  |  |  | 39887 | my $check = $appclass."::Controller::".$name; | 
| 813 |  |  |  |  |  |  | return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; | 
| 814 |  |  |  |  |  |  | foreach my $path (@{$appclass->config->{ setup_components }->{ search_extra }}) { | 
| 815 |  |  |  |  |  |  | next unless $path =~ /.*::Controller/; | 
| 816 |  |  |  |  |  |  | $check = $path."::".$name; | 
| 817 |  |  |  |  |  |  | return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; | 
| 818 |  |  |  |  |  |  | } | 
| 819 |  |  |  |  |  |  | } | 
| 820 |  |  |  |  |  |  | my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ ); | 
| 821 |  |  |  |  |  |  | return map { $c->_filter_component( $_, @args ) } @result if ref $name; | 
| 822 |  |  |  |  |  |  | return $c->_filter_component( $result[ 0 ], @args ); | 
| 823 |  |  |  |  |  |  | } | 
| 824 |  |  |  |  |  |  |  | 
| 825 |  |  |  |  |  |  | return $c->component( $c->action->class ); | 
| 826 |  |  |  |  |  |  | } | 
| 827 |  |  |  |  |  |  |  | 
| 828 |  |  |  |  |  |  | =head2 $c->model($name) | 
| 829 |  |  |  |  |  |  |  | 
| 830 |  |  |  |  |  |  | Gets a L<Catalyst::Model> instance by name. | 
| 831 |  |  |  |  |  |  |  | 
| 832 |  |  |  |  |  |  | $c->model('Foo')->do_stuff; | 
| 833 |  |  |  |  |  |  |  | 
| 834 |  |  |  |  |  |  | Any extra arguments are directly passed to ACCEPT_CONTEXT, if the model | 
| 835 | 71 |  |  | 71 | 1 | 11164 | defines ACCEPT_CONTEXT.  If it does not, the args are discarded. | 
| 836 |  |  |  |  |  |  |  | 
| 837 | 71 |  | 66 |  |  | 285 | If the name is omitted, it will look for | 
| 838 | 71 | 100 |  |  |  | 169 | - a model object in $c->stash->{current_model_instance}, then | 
| 839 | 61 | 100 |  |  |  | 179 | - a model name in $c->stash->{current_model}, then | 
| 840 | 58 |  |  |  |  | 615 | - a config setting 'default_model', or | 
| 841 | 58 |  |  |  |  | 155 | - check if there is only one model, and return it if that's the case. | 
| 842 | 58 | 100 |  |  |  | 248 |  | 
| 843 | 13 |  |  |  |  | 18 | If you want to search for models, pass in a regexp as the argument. | 
|  | 13 |  |  |  |  | 35 |  | 
| 844 | 2 | 100 |  |  |  | 11 |  | 
| 845 | 1 |  |  |  |  | 4 | # find all models that start with Foo | 
| 846 | 1 | 50 |  |  |  | 8 | my @foo_models = $c->model(qr{^Foo}); | 
| 847 |  |  |  |  |  |  |  | 
| 848 |  |  |  |  |  |  | =cut | 
| 849 | 15 |  |  |  |  | 78 |  | 
| 850 | 15 | 100 |  |  |  | 57 | my ( $c, $name, @args ) = @_; | 
|  | 3 |  |  |  |  | 7 |  | 
| 851 | 12 |  |  |  |  | 28 | my $appclass = ref($c) || $c; | 
| 852 |  |  |  |  |  |  | if( $name ) { | 
| 853 |  |  |  |  |  |  | unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps | 
| 854 | 10 |  |  |  |  | 220 | my $comps = $c->components; | 
| 855 |  |  |  |  |  |  | my $check = $appclass."::Model::".$name; | 
| 856 |  |  |  |  |  |  | return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; | 
| 857 |  |  |  |  |  |  | foreach my $path (@{$appclass->config->{ setup_components }->{ search_extra }}) { | 
| 858 |  |  |  |  |  |  | next unless $path =~ /.*::Model/; | 
| 859 |  |  |  |  |  |  | $check = $path."::".$name; | 
| 860 |  |  |  |  |  |  | return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; | 
| 861 |  |  |  |  |  |  | } | 
| 862 |  |  |  |  |  |  | } | 
| 863 |  |  |  |  |  |  | my @result = $c->_comp_search_prefixes( $name, qw/Model M/ ); | 
| 864 |  |  |  |  |  |  | return map { $c->_filter_component( $_, @args ) } @result if ref $name; | 
| 865 |  |  |  |  |  |  | return $c->_filter_component( $result[ 0 ], @args ); | 
| 866 |  |  |  |  |  |  | } | 
| 867 |  |  |  |  |  |  |  | 
| 868 |  |  |  |  |  |  | if (ref $c) { | 
| 869 |  |  |  |  |  |  | return $c->stash->{current_model_instance} | 
| 870 |  |  |  |  |  |  | if $c->stash->{current_model_instance}; | 
| 871 |  |  |  |  |  |  | return $c->model( $c->stash->{current_model} ) | 
| 872 |  |  |  |  |  |  | if $c->stash->{current_model}; | 
| 873 |  |  |  |  |  |  | } | 
| 874 |  |  |  |  |  |  | return $c->model( $appclass->config->{default_model} ) | 
| 875 |  |  |  |  |  |  | if $appclass->config->{default_model}; | 
| 876 |  |  |  |  |  |  |  | 
| 877 |  |  |  |  |  |  | my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/); | 
| 878 |  |  |  |  |  |  |  | 
| 879 |  |  |  |  |  |  | if( $rest ) { | 
| 880 | 51 |  |  | 51 | 1 | 7644 | $c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') ); | 
| 881 | 51 |  | 66 |  |  | 192 | $c->log->warn( '* $c->config(default_model => "the name of the default model to use")' ); | 
| 882 | 51 | 100 |  |  |  | 144 | $c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' ); | 
| 883 | 49 | 100 |  |  |  | 147 | $c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' ); | 
| 884 | 46 |  |  |  |  | 505 | $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' ); | 
| 885 | 46 |  |  |  |  | 110 | } | 
| 886 | 46 | 100 |  |  |  | 230 |  | 
| 887 | 16 |  |  |  |  | 26 | return $c->_filter_component( $comp ); | 
|  | 16 |  |  |  |  | 40 |  | 
| 888 | 0 | 0 |  |  |  | 0 | } | 
| 889 | 0 |  |  |  |  | 0 |  | 
| 890 | 0 | 0 |  |  |  | 0 |  | 
| 891 |  |  |  |  |  |  | =head2 $c->view($name) | 
| 892 |  |  |  |  |  |  |  | 
| 893 | 19 |  |  |  |  | 102 | Gets a L<Catalyst::View> instance by name. | 
| 894 | 19 | 100 |  |  |  | 52 |  | 
|  | 6 |  |  |  |  | 13 |  | 
| 895 | 14 |  |  |  |  | 37 | $c->view('Foo')->do_stuff; | 
| 896 |  |  |  |  |  |  |  | 
| 897 |  |  |  |  |  |  | Any extra arguments are directly passed to ACCEPT_CONTEXT. | 
| 898 | 2 | 50 |  |  |  | 6 |  | 
| 899 |  |  |  |  |  |  | If the name is omitted, it will look for | 
| 900 | 0 | 0 |  |  |  | 0 | - a view object in $c->stash->{current_view_instance}, then | 
| 901 |  |  |  |  |  |  | - a view name in $c->stash->{current_view}, then | 
| 902 | 0 | 0 |  |  |  | 0 | - a config setting 'default_view', or | 
| 903 |  |  |  |  |  |  | - check if there is only one view, and return it if that's the case. | 
| 904 |  |  |  |  |  |  |  | 
| 905 | 2 | 100 |  |  |  | 5 | If you want to search for views, pass in a regexp as the argument. | 
| 906 |  |  |  |  |  |  |  | 
| 907 | 1 |  |  |  |  | 3 | # find all views that start with Foo | 
| 908 |  |  |  |  |  |  | my @foo_views = $c->view(qr{^Foo}); | 
| 909 | 1 | 50 |  |  |  | 3 |  | 
| 910 | 1 |  |  |  |  | 4 | =cut | 
| 911 | 1 |  |  |  |  | 6 |  | 
| 912 | 1 |  |  |  |  | 4 | my ( $c, $name, @args ) = @_; | 
| 913 | 1 |  |  |  |  | 3 |  | 
| 914 | 1 |  |  |  |  | 3 | my $appclass = ref($c) || $c; | 
| 915 |  |  |  |  |  |  | if( $name ) { | 
| 916 |  |  |  |  |  |  | unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps | 
| 917 | 1 |  |  |  |  | 5 | my $comps = $c->components; | 
| 918 |  |  |  |  |  |  | my $check = $appclass."::View::".$name; | 
| 919 |  |  |  |  |  |  | if( exists $comps->{$check} ) { | 
| 920 |  |  |  |  |  |  | return $c->_filter_component( $comps->{$check}, @args ); | 
| 921 |  |  |  |  |  |  | } | 
| 922 |  |  |  |  |  |  | else { | 
| 923 |  |  |  |  |  |  | $c->log->warn( "Attempted to use view '$check', but does not exist" ); | 
| 924 |  |  |  |  |  |  | } | 
| 925 |  |  |  |  |  |  | foreach my $path (@{$appclass->config->{ setup_components }->{ search_extra }}) { | 
| 926 |  |  |  |  |  |  | next unless $path =~ /.*::View/; | 
| 927 |  |  |  |  |  |  | $check = $path."::".$name; | 
| 928 |  |  |  |  |  |  | return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; | 
| 929 |  |  |  |  |  |  | } | 
| 930 |  |  |  |  |  |  | } | 
| 931 |  |  |  |  |  |  | my @result = $c->_comp_search_prefixes( $name, qw/View V/ ); | 
| 932 |  |  |  |  |  |  | return map { $c->_filter_component( $_, @args ) } @result if ref $name; | 
| 933 |  |  |  |  |  |  | return $c->_filter_component( $result[ 0 ], @args ); | 
| 934 |  |  |  |  |  |  | } | 
| 935 |  |  |  |  |  |  |  | 
| 936 |  |  |  |  |  |  | if (ref $c) { | 
| 937 |  |  |  |  |  |  | return $c->stash->{current_view_instance} | 
| 938 |  |  |  |  |  |  | if $c->stash->{current_view_instance}; | 
| 939 |  |  |  |  |  |  | return $c->view( $c->stash->{current_view} ) | 
| 940 |  |  |  |  |  |  | if $c->stash->{current_view}; | 
| 941 |  |  |  |  |  |  | } | 
| 942 |  |  |  |  |  |  | return $c->view( $appclass->config->{default_view} ) | 
| 943 | 31 |  |  | 31 | 1 | 2114 | if $appclass->config->{default_view}; | 
| 944 |  |  |  |  |  |  |  | 
| 945 | 31 |  | 66 |  |  | 95 | my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/View V/); | 
| 946 | 31 | 100 |  |  |  | 79 |  | 
| 947 | 27 | 100 |  |  |  | 92 | if( $rest ) { | 
| 948 | 24 |  |  |  |  | 235 | $c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' ); | 
| 949 | 24 |  |  |  |  | 50 | $c->log->warn( '* $c->config(default_view => "the name of the default view to use")' ); | 
| 950 | 24 | 100 |  |  |  | 59 | $c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' ); | 
| 951 | 12 |  |  |  |  | 33 | $c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' ); | 
| 952 |  |  |  |  |  |  | $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' ); | 
| 953 |  |  |  |  |  |  | } | 
| 954 | 12 |  |  |  |  | 32 |  | 
| 955 |  |  |  |  |  |  | return $c->_filter_component( $comp ); | 
| 956 | 12 |  |  |  |  | 32 | } | 
|  | 12 |  |  |  |  | 38 |  | 
| 957 | 0 | 0 |  |  |  | 0 |  | 
| 958 | 0 |  |  |  |  | 0 | =head2 $c->controllers | 
| 959 | 0 | 0 |  |  |  | 0 |  | 
| 960 |  |  |  |  |  |  | Returns the available names which can be passed to $c->controller | 
| 961 |  |  |  |  |  |  |  | 
| 962 | 15 |  |  |  |  | 97 | =cut | 
| 963 | 15 | 100 |  |  |  | 46 |  | 
|  | 4 |  |  |  |  | 10 |  | 
| 964 | 12 |  |  |  |  | 59 | my ( $c ) = @_; | 
| 965 |  |  |  |  |  |  | return $c->_comp_names(qw/Controller C/); | 
| 966 |  |  |  |  |  |  | } | 
| 967 | 4 | 100 |  |  |  | 17 |  | 
| 968 |  |  |  |  |  |  | =head2 $c->models | 
| 969 | 2 | 50 |  |  |  | 9 |  | 
| 970 |  |  |  |  |  |  | Returns the available names which can be passed to $c->model | 
| 971 | 2 | 50 |  |  |  | 7 |  | 
| 972 |  |  |  |  |  |  | =cut | 
| 973 |  |  |  |  |  |  |  | 
| 974 | 4 | 100 |  |  |  | 36 | my ( $c ) = @_; | 
| 975 |  |  |  |  |  |  | return $c->_comp_names(qw/Model M/); | 
| 976 | 2 |  |  |  |  | 8 | } | 
| 977 |  |  |  |  |  |  |  | 
| 978 | 2 | 100 |  |  |  | 9 |  | 
| 979 | 1 |  |  |  |  | 3 | =head2 $c->views | 
| 980 | 1 |  |  |  |  | 4 |  | 
| 981 | 1 |  |  |  |  | 4 | Returns the available names which can be passed to $c->view | 
| 982 | 1 |  |  |  |  | 10 |  | 
| 983 | 1 |  |  |  |  | 3 | =cut | 
| 984 |  |  |  |  |  |  |  | 
| 985 |  |  |  |  |  |  | my ( $c ) = @_; | 
| 986 | 2 |  |  |  |  | 7 | return $c->_comp_names(qw/View V/); | 
| 987 |  |  |  |  |  |  | } | 
| 988 |  |  |  |  |  |  |  | 
| 989 |  |  |  |  |  |  | =head2 $c->comp($name) | 
| 990 |  |  |  |  |  |  |  | 
| 991 |  |  |  |  |  |  | =head2 $c->component($name) | 
| 992 |  |  |  |  |  |  |  | 
| 993 |  |  |  |  |  |  | Gets a component object by name. This method is not recommended, | 
| 994 |  |  |  |  |  |  | unless you want to get a specific component by full | 
| 995 |  |  |  |  |  |  | class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >> | 
| 996 | 1 |  |  | 1 | 1 | 3 | should be used instead. | 
| 997 | 1 |  |  |  |  | 4 |  | 
| 998 |  |  |  |  |  |  | If C<$name> is a regexp, a list of components matched against the full | 
| 999 |  |  |  |  |  |  | component name will be returned. | 
| 1000 |  |  |  |  |  |  |  | 
| 1001 |  |  |  |  |  |  | If Catalyst can't find a component by name, it will fallback to regex | 
| 1002 |  |  |  |  |  |  | matching by default. To disable this behaviour set | 
| 1003 |  |  |  |  |  |  | disable_component_resolution_regex_fallback to a true value. | 
| 1004 |  |  |  |  |  |  |  | 
| 1005 |  |  |  |  |  |  | __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 ); | 
| 1006 |  |  |  |  |  |  |  | 
| 1007 | 1 |  |  | 1 | 1 | 3 | =cut | 
| 1008 | 1 |  |  |  |  | 3 |  | 
| 1009 |  |  |  |  |  |  | my ( $c, $name, @args ) = @_; | 
| 1010 |  |  |  |  |  |  |  | 
| 1011 |  |  |  |  |  |  | if( $name ) { | 
| 1012 |  |  |  |  |  |  | my $comps = $c->components; | 
| 1013 |  |  |  |  |  |  |  | 
| 1014 |  |  |  |  |  |  | if( !ref $name ) { | 
| 1015 |  |  |  |  |  |  | # is it the exact name? | 
| 1016 |  |  |  |  |  |  | return $c->_filter_component( $comps->{ $name }, @args ) | 
| 1017 |  |  |  |  |  |  | if exists $comps->{ $name }; | 
| 1018 |  |  |  |  |  |  |  | 
| 1019 | 1 |  |  | 1 | 1 | 404 | # perhaps we just omitted "MyApp"? | 
| 1020 | 1 |  |  |  |  | 5 | my $composed = ( ref $c || $c ) . "::${name}"; | 
| 1021 |  |  |  |  |  |  | return $c->_filter_component( $comps->{ $composed }, @args ) | 
| 1022 |  |  |  |  |  |  | if exists $comps->{ $composed }; | 
| 1023 |  |  |  |  |  |  |  | 
| 1024 |  |  |  |  |  |  | # search all of the models, views and controllers | 
| 1025 |  |  |  |  |  |  | my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ ); | 
| 1026 |  |  |  |  |  |  | return $c->_filter_component( $comp, @args ) if $comp; | 
| 1027 |  |  |  |  |  |  | } | 
| 1028 |  |  |  |  |  |  |  | 
| 1029 |  |  |  |  |  |  | return | 
| 1030 |  |  |  |  |  |  | if $c->config->{disable_component_resolution_regex_fallback}; | 
| 1031 |  |  |  |  |  |  |  | 
| 1032 |  |  |  |  |  |  | # This is here so $c->comp( '::M::' ) works | 
| 1033 |  |  |  |  |  |  | my $query = ref $name ? $name : qr{$name}i; | 
| 1034 |  |  |  |  |  |  |  | 
| 1035 |  |  |  |  |  |  | my @result = grep { m{$query} } keys %{ $c->components }; | 
| 1036 |  |  |  |  |  |  | return map { $c->_filter_component( $_, @args ) } @result if ref $name; | 
| 1037 |  |  |  |  |  |  |  | 
| 1038 |  |  |  |  |  |  | if( $result[ 0 ] ) { | 
| 1039 |  |  |  |  |  |  | $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) ); | 
| 1040 |  |  |  |  |  |  | $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' ); | 
| 1041 |  |  |  |  |  |  | $c->log->warn( 'is unreliable and unsafe. You have been warned' ); | 
| 1042 |  |  |  |  |  |  | return $c->_filter_component( $result[ 0 ], @args ); | 
| 1043 |  |  |  |  |  |  | } | 
| 1044 | 16412 |  |  | 16412 | 1 | 61372 |  | 
| 1045 |  |  |  |  |  |  | # I would expect to return an empty list here, but that breaks back-compat | 
| 1046 | 16412 | 100 |  |  |  | 27728 | } | 
| 1047 | 16411 |  |  |  |  | 36879 |  | 
| 1048 |  |  |  |  |  |  | # fallback | 
| 1049 | 16411 | 100 |  |  |  | 28826 | return sort keys %{ $c->components }; | 
| 1050 |  |  |  |  |  |  | } | 
| 1051 |  |  |  |  |  |  |  | 
| 1052 | 16408 | 100 |  |  |  | 45155 | =head2 CLASS DATA AND HELPER CLASSES | 
| 1053 |  |  |  |  |  |  |  | 
| 1054 |  |  |  |  |  |  | =head2 $c->config | 
| 1055 | 30 |  | 66 |  |  | 169 |  | 
| 1056 |  |  |  |  |  |  | Returns or takes a hashref containing the application's configuration. | 
| 1057 | 30 | 100 |  |  |  | 117 |  | 
| 1058 |  |  |  |  |  |  | __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } ); | 
| 1059 |  |  |  |  |  |  |  | 
| 1060 | 12 |  |  |  |  | 67 | You can also use a C<YAML>, C<XML> or L<Config::General> config file | 
| 1061 | 12 | 100 |  |  |  | 63 | like C<myapp.conf> in your applications home directory. See | 
| 1062 |  |  |  |  |  |  | L<Catalyst::Plugin::ConfigLoader>. | 
| 1063 |  |  |  |  |  |  |  | 
| 1064 |  |  |  |  |  |  | =head3 Cascading configuration | 
| 1065 | 5 | 50 |  |  |  | 14 |  | 
| 1066 |  |  |  |  |  |  | The config method is present on all Catalyst components, and configuration | 
| 1067 |  |  |  |  |  |  | will be merged when an application is started. Configuration loaded with | 
| 1068 | 5 | 100 |  |  |  | 24 | L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration, | 
| 1069 |  |  |  |  |  |  | followed by configuration in your top level C<MyApp> class. These two | 
| 1070 | 5 |  |  |  |  | 9 | configurations are merged, and then configuration data whose hash key matches a | 
|  | 102 |  |  |  |  | 234 |  | 
|  | 5 |  |  |  |  | 12 |  | 
| 1071 | 5 | 100 |  |  |  | 22 | component name is merged with configuration for that component. | 
|  | 3 |  |  |  |  | 6 |  | 
| 1072 |  |  |  |  |  |  |  | 
| 1073 | 2 | 50 |  |  |  | 8 | The configuration for a component is then passed to the C<new> method when a | 
| 1074 | 0 |  |  |  |  | 0 | component is constructed. | 
| 1075 | 0 |  |  |  |  | 0 |  | 
| 1076 | 0 |  |  |  |  | 0 | For example: | 
| 1077 | 0 |  |  |  |  | 0 |  | 
| 1078 |  |  |  |  |  |  | MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } }); | 
| 1079 |  |  |  |  |  |  | MyApp::Model::Foo->config({ quux => 'frob', overrides => 'this' }); | 
| 1080 |  |  |  |  |  |  |  | 
| 1081 |  |  |  |  |  |  | will mean that C<MyApp::Model::Foo> receives the following data when | 
| 1082 |  |  |  |  |  |  | constructed: | 
| 1083 |  |  |  |  |  |  |  | 
| 1084 | 3 |  |  |  |  | 7 | MyApp::Model::Foo->new({ | 
|  | 3 |  |  |  |  | 8 |  | 
| 1085 |  |  |  |  |  |  | bar => 'baz', | 
| 1086 |  |  |  |  |  |  | quux => 'frob', | 
| 1087 |  |  |  |  |  |  | overrides => 'me', | 
| 1088 |  |  |  |  |  |  | }); | 
| 1089 |  |  |  |  |  |  |  | 
| 1090 |  |  |  |  |  |  | It's common practice to use a Moose attribute | 
| 1091 |  |  |  |  |  |  | on the receiving component to access the config value. | 
| 1092 |  |  |  |  |  |  |  | 
| 1093 |  |  |  |  |  |  | package MyApp::Model::Foo; | 
| 1094 |  |  |  |  |  |  |  | 
| 1095 |  |  |  |  |  |  | use Moose; | 
| 1096 |  |  |  |  |  |  |  | 
| 1097 |  |  |  |  |  |  | # this attr will receive 'baz' at construction time | 
| 1098 |  |  |  |  |  |  | has 'bar' => ( | 
| 1099 |  |  |  |  |  |  | is  => 'rw', | 
| 1100 |  |  |  |  |  |  | isa => 'Str', | 
| 1101 |  |  |  |  |  |  | ); | 
| 1102 |  |  |  |  |  |  |  | 
| 1103 |  |  |  |  |  |  | You can then get the value 'baz' by calling $c->model('Foo')->bar | 
| 1104 |  |  |  |  |  |  | (or $self->bar inside code in the model). | 
| 1105 |  |  |  |  |  |  |  | 
| 1106 |  |  |  |  |  |  | B<NOTE:> you MUST NOT call C<< $self->config >> or C<< __PACKAGE__->config >> | 
| 1107 |  |  |  |  |  |  | as a way of reading config within your code, as this B<will not> give you the | 
| 1108 |  |  |  |  |  |  | correctly merged config back. You B<MUST> take the config values supplied to | 
| 1109 |  |  |  |  |  |  | the constructor and use those instead. | 
| 1110 |  |  |  |  |  |  |  | 
| 1111 |  |  |  |  |  |  | =cut | 
| 1112 |  |  |  |  |  |  |  | 
| 1113 |  |  |  |  |  |  | around config => sub { | 
| 1114 |  |  |  |  |  |  | my $orig = shift; | 
| 1115 |  |  |  |  |  |  | my $c = shift; | 
| 1116 |  |  |  |  |  |  |  | 
| 1117 |  |  |  |  |  |  | croak('Setting config after setup has been run is not allowed.') | 
| 1118 |  |  |  |  |  |  | if ( @_ and $c->setup_finished ); | 
| 1119 |  |  |  |  |  |  |  | 
| 1120 |  |  |  |  |  |  | $c->$orig(@_); | 
| 1121 |  |  |  |  |  |  | }; | 
| 1122 |  |  |  |  |  |  |  | 
| 1123 |  |  |  |  |  |  | =head2 $c->log | 
| 1124 |  |  |  |  |  |  |  | 
| 1125 |  |  |  |  |  |  | Returns the logging object instance. Unless it is already set, Catalyst | 
| 1126 |  |  |  |  |  |  | sets this up with a L<Catalyst::Log> object. To use your own log class, | 
| 1127 |  |  |  |  |  |  | set the logger with the C<< __PACKAGE__->log >> method prior to calling | 
| 1128 |  |  |  |  |  |  | C<< __PACKAGE__->setup >>. | 
| 1129 |  |  |  |  |  |  |  | 
| 1130 |  |  |  |  |  |  | __PACKAGE__->log( MyLogger->new ); | 
| 1131 |  |  |  |  |  |  | __PACKAGE__->setup; | 
| 1132 |  |  |  |  |  |  |  | 
| 1133 |  |  |  |  |  |  | And later: | 
| 1134 |  |  |  |  |  |  |  | 
| 1135 |  |  |  |  |  |  | $c->log->info( 'Now logging with my own logger!' ); | 
| 1136 |  |  |  |  |  |  |  | 
| 1137 |  |  |  |  |  |  | Your log class should implement the methods described in | 
| 1138 |  |  |  |  |  |  | L<Catalyst::Log>. | 
| 1139 |  |  |  |  |  |  |  | 
| 1140 |  |  |  |  |  |  | =head2 has_encoding | 
| 1141 |  |  |  |  |  |  |  | 
| 1142 |  |  |  |  |  |  | Returned True if there's a valid encoding | 
| 1143 |  |  |  |  |  |  |  | 
| 1144 |  |  |  |  |  |  | =head2 clear_encoding | 
| 1145 |  |  |  |  |  |  |  | 
| 1146 |  |  |  |  |  |  | Clears the encoding for the current context | 
| 1147 |  |  |  |  |  |  |  | 
| 1148 |  |  |  |  |  |  | =head2 encoding | 
| 1149 |  |  |  |  |  |  |  | 
| 1150 |  |  |  |  |  |  | Sets or gets the application encoding.  Setting encoding takes either an | 
| 1151 |  |  |  |  |  |  | Encoding object or a string that we try to resolve via L<Encode::find_encoding>. | 
| 1152 |  |  |  |  |  |  |  | 
| 1153 |  |  |  |  |  |  | You would expect to get the encoding object back if you attempt to set it.  If | 
| 1154 |  |  |  |  |  |  | there is a failure you will get undef returned and an error message in the log. | 
| 1155 |  |  |  |  |  |  |  | 
| 1156 |  |  |  |  |  |  | =cut | 
| 1157 |  |  |  |  |  |  |  | 
| 1158 |  |  |  |  |  |  |  | 
| 1159 |  |  |  |  |  |  | my $c = shift; | 
| 1160 |  |  |  |  |  |  | if(blessed $c) { | 
| 1161 |  |  |  |  |  |  | $c->encoding(undef); | 
| 1162 |  |  |  |  |  |  | } else { | 
| 1163 |  |  |  |  |  |  | $c->log->error("You can't clear encoding on the application"); | 
| 1164 |  |  |  |  |  |  | } | 
| 1165 |  |  |  |  |  |  | } | 
| 1166 |  |  |  |  |  |  |  | 
| 1167 |  |  |  |  |  |  | my $c = shift; | 
| 1168 |  |  |  |  |  |  | my $encoding; | 
| 1169 |  |  |  |  |  |  |  | 
| 1170 |  |  |  |  |  |  | if ( scalar @_ ) { | 
| 1171 |  |  |  |  |  |  |  | 
| 1172 |  |  |  |  |  |  | # Don't let one change this once we are too far into the response | 
| 1173 |  |  |  |  |  |  | if(blessed $c && $c->res->finalized_headers) { | 
| 1174 |  |  |  |  |  |  | Carp::croak("You may not change the encoding once the headers are finalized"); | 
| 1175 |  |  |  |  |  |  | return; | 
| 1176 |  |  |  |  |  |  | } | 
| 1177 |  |  |  |  |  |  |  | 
| 1178 |  |  |  |  |  |  | # Let it be set to undef | 
| 1179 |  |  |  |  |  |  | if (my $wanted = shift)  { | 
| 1180 |  |  |  |  |  |  | $encoding = Encode::find_encoding($wanted) | 
| 1181 |  |  |  |  |  |  | or Carp::croak( qq/Unknown encoding '$wanted'/ ); | 
| 1182 |  |  |  |  |  |  | binmode(STDERR, ':encoding(' . $encoding->name . ')'); | 
| 1183 |  |  |  |  |  |  | } | 
| 1184 |  |  |  |  |  |  | else { | 
| 1185 |  |  |  |  |  |  | binmode(STDERR); | 
| 1186 |  |  |  |  |  |  | } | 
| 1187 |  |  |  |  |  |  |  | 
| 1188 |  |  |  |  |  |  | $encoding = ref $c | 
| 1189 |  |  |  |  |  |  | ? $c->{encoding} = $encoding | 
| 1190 |  |  |  |  |  |  | : $c->_encoding($encoding); | 
| 1191 |  |  |  |  |  |  | } else { | 
| 1192 |  |  |  |  |  |  | $encoding = ref $c && exists $c->{encoding} | 
| 1193 | 0 | 0 |  | 0 | 1 | 0 | ? $c->{encoding} | 
| 1194 |  |  |  |  |  |  | : $c->_encoding; | 
| 1195 |  |  |  |  |  |  | } | 
| 1196 | 2 |  |  | 2 | 1 | 20 |  | 
| 1197 | 2 | 50 |  |  |  | 8 | return $encoding; | 
| 1198 | 2 |  |  |  |  | 5 | } | 
| 1199 |  |  |  |  |  |  |  | 
| 1200 | 0 |  |  |  |  | 0 | =head2 $c->debug | 
| 1201 |  |  |  |  |  |  |  | 
| 1202 |  |  |  |  |  |  | Returns 1 if debug mode is enabled, 0 otherwise. | 
| 1203 |  |  |  |  |  |  |  | 
| 1204 |  |  |  |  |  |  | You can enable debug mode in several ways: | 
| 1205 | 4914 |  |  | 4914 | 1 | 41354 |  | 
| 1206 | 4914 |  |  |  |  | 6542 | =over | 
| 1207 |  |  |  |  |  |  |  | 
| 1208 | 4914 | 100 |  |  |  | 8845 | =item By calling myapp_server.pl with the -d flag | 
| 1209 |  |  |  |  |  |  |  | 
| 1210 |  |  |  |  |  |  | =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG | 
| 1211 | 172 | 100 | 100 |  |  | 4552 |  | 
| 1212 | 1 |  |  |  |  | 188 | =item The -Debug option in your MyApp.pm | 
| 1213 | 0 |  |  |  |  | 0 |  | 
| 1214 |  |  |  |  |  |  | =item By declaring C<sub debug { 1 }> in your MyApp.pm. | 
| 1215 |  |  |  |  |  |  |  | 
| 1216 |  |  |  |  |  |  | =back | 
| 1217 | 171 | 100 |  |  |  | 5001 |  | 
| 1218 | 167 | 50 |  |  |  | 1044 | The first three also set the log level to 'debug'. | 
| 1219 |  |  |  |  |  |  |  | 
| 1220 | 167 |  |  | 183 |  | 35488 | Calling C<< $c->debug(1) >> has no effect. | 
|  | 150 |  |  |  |  | 5816 |  | 
|  | 150 |  |  |  |  | 316 |  | 
|  | 150 |  |  |  |  | 1215 |  | 
| 1221 |  |  |  |  |  |  |  | 
| 1222 |  |  |  |  |  |  | =cut | 
| 1223 | 4 |  |  |  |  | 27 |  | 
| 1224 |  |  |  |  |  |  |  | 
| 1225 |  |  |  |  |  |  | =head2 $c->dispatcher | 
| 1226 |  |  |  |  |  |  |  | 
| 1227 | 171 | 100 |  |  |  | 133536 | Returns the dispatcher instance. See L<Catalyst::Dispatcher>. | 
| 1228 |  |  |  |  |  |  |  | 
| 1229 |  |  |  |  |  |  | =head2 $c->engine | 
| 1230 |  |  |  |  |  |  |  | 
| 1231 |  |  |  |  |  |  | Returns the engine instance. See L<Catalyst::Engine>. | 
| 1232 | 4742 | 100 | 66 |  |  | 22924 |  | 
| 1233 |  |  |  |  |  |  |  | 
| 1234 |  |  |  |  |  |  | =head2 UTILITY METHODS | 
| 1235 | 4913 |  |  |  |  | 43035 |  | 
| 1236 |  |  |  |  |  |  | =head2 $c->path_to(@path) | 
| 1237 |  |  |  |  |  |  |  | 
| 1238 |  |  |  |  |  |  | Merges C<@path> with C<< $c->config->{home} >> and returns a | 
| 1239 |  |  |  |  |  |  | L<Path::Class::Dir> object. Note you can usually use this object as | 
| 1240 |  |  |  |  |  |  | a filename, but sometimes you will have to explicitly stringify it | 
| 1241 |  |  |  |  |  |  | yourself by calling the C<< ->stringify >> method. | 
| 1242 |  |  |  |  |  |  |  | 
| 1243 |  |  |  |  |  |  | For example: | 
| 1244 |  |  |  |  |  |  |  | 
| 1245 |  |  |  |  |  |  | $c->path_to( 'db', 'sqlite.db' ); | 
| 1246 |  |  |  |  |  |  |  | 
| 1247 |  |  |  |  |  |  | =cut | 
| 1248 |  |  |  |  |  |  |  | 
| 1249 |  |  |  |  |  |  | my ( $c, @path ) = @_; | 
| 1250 |  |  |  |  |  |  | my $path = Path::Class::Dir->new( $c->config->{home}, @path ); | 
| 1251 |  |  |  |  |  |  | if ( -d $path ) { return $path } | 
| 1252 |  |  |  |  |  |  | else { return Path::Class::File->new( $c->config->{home}, @path ) } | 
| 1253 |  |  |  |  |  |  | } | 
| 1254 |  |  |  |  |  |  |  | 
| 1255 |  |  |  |  |  |  | my ( $class, $name, $plugin, @args ) = @_; | 
| 1256 |  |  |  |  |  |  |  | 
| 1257 |  |  |  |  |  |  | # See block comment in t/unit_core_plugin.t | 
| 1258 |  |  |  |  |  |  | $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in a future release/); | 
| 1259 |  |  |  |  |  |  |  | 
| 1260 |  |  |  |  |  |  | $class->_register_plugin( $plugin, 1 ); | 
| 1261 |  |  |  |  |  |  |  | 
| 1262 | 7203 |  |  | 7203 | 1 | 110165 | eval { $plugin->import }; | 
| 1263 |  |  |  |  |  |  | $class->mk_classdata($name); | 
| 1264 |  |  |  |  |  |  | my $obj; | 
| 1265 |  |  |  |  |  |  | eval { $obj = $plugin->new(@args) }; | 
| 1266 |  |  |  |  |  |  |  | 
| 1267 |  |  |  |  |  |  | if ($@) { | 
| 1268 |  |  |  |  |  |  | Catalyst::Exception->throw( message => | 
| 1269 |  |  |  |  |  |  | qq/Couldn't instantiate instant plugin "$plugin", "$@"/ ); | 
| 1270 |  |  |  |  |  |  | } | 
| 1271 |  |  |  |  |  |  |  | 
| 1272 |  |  |  |  |  |  | $class->$name($obj); | 
| 1273 |  |  |  |  |  |  | $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/) | 
| 1274 |  |  |  |  |  |  | if $class->debug; | 
| 1275 |  |  |  |  |  |  | } | 
| 1276 |  |  |  |  |  |  |  | 
| 1277 |  |  |  |  |  |  | =head2 MyApp->setup | 
| 1278 |  |  |  |  |  |  |  | 
| 1279 |  |  |  |  |  |  | Initializes the dispatcher and engine, loads any plugins, and loads the | 
| 1280 |  |  |  |  |  |  | model, view, and controller components. You may also specify an array | 
| 1281 |  |  |  |  |  |  | of plugins to load here, if you choose to not load them in the C<use | 
| 1282 |  |  |  |  |  |  | Catalyst> line. | 
| 1283 |  |  |  |  |  |  |  | 
| 1284 |  |  |  |  |  |  | MyApp->setup; | 
| 1285 |  |  |  |  |  |  | MyApp->setup( qw/-Debug/ ); | 
| 1286 |  |  |  |  |  |  |  | 
| 1287 |  |  |  |  |  |  | B<Note:> You B<should not> wrap this method with method modifiers | 
| 1288 |  |  |  |  |  |  | or bad things will happen - wrap the C<setup_finalize> method instead. | 
| 1289 | 18 |  |  | 18 | 1 | 14238 |  | 
| 1290 | 18 |  |  |  |  | 92 | B<Note:> You can create a custom setup stage that will execute when the | 
| 1291 | 18 | 100 |  |  |  | 1185 | application is starting.  Use this to customize setup. | 
|  | 7 |  |  |  |  | 311 |  | 
| 1292 | 11 |  |  |  |  | 514 |  | 
| 1293 |  |  |  |  |  |  | MyApp->setup(-Custom=value); | 
| 1294 |  |  |  |  |  |  |  | 
| 1295 |  |  |  |  |  |  | sub setup_custom { | 
| 1296 | 1 |  |  | 1 | 0 | 294 | my ($class, $value) = @_; | 
| 1297 |  |  |  |  |  |  | } | 
| 1298 |  |  |  |  |  |  |  | 
| 1299 | 1 |  |  |  |  | 3 | Can be handy if you want to hook into the setup phase. | 
| 1300 |  |  |  |  |  |  |  | 
| 1301 | 1 |  |  |  |  | 15 | =cut | 
| 1302 |  |  |  |  |  |  |  | 
| 1303 | 1 |  |  |  |  | 8 | my ( $class, @arguments ) = @_; | 
|  | 1 |  |  |  |  | 5 |  | 
| 1304 | 1 |  |  |  |  | 28 | croak('Running setup more than once') | 
| 1305 | 1 |  |  |  |  | 3 | if ( $class->setup_finished ); | 
| 1306 | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 1307 |  |  |  |  |  |  | unless ( $class->isa('Catalyst') ) { | 
| 1308 | 1 | 50 |  |  |  | 7 |  | 
| 1309 | 0 |  |  |  |  | 0 | Catalyst::Exception->throw( | 
| 1310 |  |  |  |  |  |  | message => qq/'$class' does not inherit from Catalyst/ ); | 
| 1311 |  |  |  |  |  |  | } | 
| 1312 |  |  |  |  |  |  |  | 
| 1313 | 1 |  |  |  |  | 3 | if ( $class->arguments ) { | 
| 1314 | 1 | 50 |  |  |  | 4 | @arguments = ( @arguments, @{ $class->arguments } ); | 
| 1315 |  |  |  |  |  |  | } | 
| 1316 |  |  |  |  |  |  |  | 
| 1317 |  |  |  |  |  |  | # Process options | 
| 1318 |  |  |  |  |  |  | my $flags = {}; | 
| 1319 |  |  |  |  |  |  |  | 
| 1320 |  |  |  |  |  |  | foreach (@arguments) { | 
| 1321 |  |  |  |  |  |  |  | 
| 1322 |  |  |  |  |  |  | if (/^-Debug$/) { | 
| 1323 |  |  |  |  |  |  | $flags->{log} = | 
| 1324 |  |  |  |  |  |  | ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug'; | 
| 1325 |  |  |  |  |  |  | } | 
| 1326 |  |  |  |  |  |  | elsif (/^-(\w+)=?(.*)$/) { | 
| 1327 |  |  |  |  |  |  | $flags->{ lc $1 } = $2; | 
| 1328 |  |  |  |  |  |  | } | 
| 1329 |  |  |  |  |  |  | else { | 
| 1330 |  |  |  |  |  |  | push @{ $flags->{plugins} }, $_; | 
| 1331 |  |  |  |  |  |  | } | 
| 1332 |  |  |  |  |  |  | } | 
| 1333 |  |  |  |  |  |  |  | 
| 1334 |  |  |  |  |  |  | $class->setup_home( delete $flags->{home} ); | 
| 1335 |  |  |  |  |  |  |  | 
| 1336 |  |  |  |  |  |  | $class->setup_log( delete $flags->{log} ); | 
| 1337 |  |  |  |  |  |  | $class->setup_plugins( delete $flags->{plugins} ); | 
| 1338 |  |  |  |  |  |  |  | 
| 1339 |  |  |  |  |  |  | $class->setup_data_handlers(); | 
| 1340 |  |  |  |  |  |  | $class->setup_dispatcher( delete $flags->{dispatcher} ); | 
| 1341 |  |  |  |  |  |  | if (my $engine = delete $flags->{engine}) { | 
| 1342 |  |  |  |  |  |  | $class->log->warn("Specifying the engine in ->setup is no longer supported, see Catalyst::Upgrading"); | 
| 1343 |  |  |  |  |  |  | } | 
| 1344 |  |  |  |  |  |  | $class->setup_engine(); | 
| 1345 | 162 |  |  | 162 | 1 | 196200 | $class->setup_stats( delete $flags->{stats} ); | 
| 1346 | 162 | 50 |  |  |  | 827 |  | 
| 1347 |  |  |  |  |  |  | for my $flag ( sort keys %{$flags} ) { | 
| 1348 |  |  |  |  |  |  |  | 
| 1349 | 162 | 50 |  |  |  | 1279 | if ( my $code = $class->can( 'setup_' . $flag ) ) { | 
| 1350 |  |  |  |  |  |  | &$code( $class, delete $flags->{$flag} ); | 
| 1351 | 0 |  |  |  |  | 0 | } | 
| 1352 |  |  |  |  |  |  | else { | 
| 1353 |  |  |  |  |  |  | $class->log->warn(qq/Unknown flag "$flag"/); | 
| 1354 |  |  |  |  |  |  | } | 
| 1355 | 162 | 100 |  |  |  | 781 | } | 
| 1356 | 156 |  |  |  |  | 523 |  | 
|  | 156 |  |  |  |  | 560 |  | 
| 1357 |  |  |  |  |  |  | eval { require Catalyst::Devel; }; | 
| 1358 |  |  |  |  |  |  | if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) { | 
| 1359 |  |  |  |  |  |  | $class->log->warn(<<"EOF"); | 
| 1360 | 162 |  |  |  |  | 521 | You are running an old script! | 
| 1361 |  |  |  |  |  |  |  | 
| 1362 | 162 |  |  |  |  | 544 | Please update by running (this will overwrite existing files): | 
| 1363 |  |  |  |  |  |  | catalyst.pl -force -scripts $class | 
| 1364 | 655 | 100 |  |  |  | 1445 |  | 
|  |  | 100 |  |  |  |  |  | 
| 1365 |  |  |  |  |  |  | or (this will not overwrite existing files): | 
| 1366 | 3 | 50 |  |  |  | 18 | catalyst.pl -scripts $class | 
| 1367 |  |  |  |  |  |  |  | 
| 1368 |  |  |  |  |  |  | EOF | 
| 1369 | 9 |  |  |  |  | 60 | } | 
| 1370 |  |  |  |  |  |  |  | 
| 1371 |  |  |  |  |  |  | # Call plugins setup, this is stupid and evil. | 
| 1372 | 643 |  |  |  |  | 724 | # Also screws C3 badly on 5.10, hack to avoid. | 
|  | 643 |  |  |  |  | 1238 |  | 
| 1373 |  |  |  |  |  |  | { | 
| 1374 |  |  |  |  |  |  | no warnings qw/redefine/; | 
| 1375 |  |  |  |  |  |  | local *setup = sub { }; | 
| 1376 | 162 |  |  |  |  | 1126 | $class->setup unless $Catalyst::__AM_RESTARTING; | 
| 1377 |  |  |  |  |  |  | } | 
| 1378 | 162 |  |  |  |  | 1885 |  | 
| 1379 | 162 |  |  |  |  | 1292 | # If you are expecting configuration info as part of your setup, it needs | 
| 1380 |  |  |  |  |  |  | # to get called here and below, since we need the above line to support | 
| 1381 | 162 |  |  |  |  | 409798 | # ConfigLoader based configs. | 
| 1382 | 162 |  |  |  |  | 1160 |  | 
| 1383 | 162 | 50 |  |  |  | 41798 | $class->setup_encoding(); | 
| 1384 | 0 |  |  |  |  | 0 | $class->setup_middleware(); | 
| 1385 |  |  |  |  |  |  |  | 
| 1386 | 162 |  |  |  |  | 1572 | # Initialize our data structure | 
| 1387 | 162 |  |  |  |  | 1642 | $class->components( {} ); | 
| 1388 |  |  |  |  |  |  |  | 
| 1389 | 162 |  |  |  |  | 432 | $class->setup_components; | 
|  | 162 |  |  |  |  | 785 |  | 
| 1390 |  |  |  |  |  |  |  | 
| 1391 | 0 | 0 |  |  |  | 0 | if ( $class->debug ) { | 
| 1392 | 0 |  |  |  |  | 0 | my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins; | 
| 1393 |  |  |  |  |  |  |  | 
| 1394 |  |  |  |  |  |  | if (@plugins) { | 
| 1395 | 0 |  |  |  |  | 0 | my $column_width = Catalyst::Utils::term_width() - 6; | 
| 1396 |  |  |  |  |  |  | my $t = Text::SimpleTable->new($column_width); | 
| 1397 |  |  |  |  |  |  | $t->row($_) for @plugins; | 
| 1398 |  |  |  |  |  |  | $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" ); | 
| 1399 | 162 |  |  |  |  | 2532 | } | 
|  | 162 |  |  |  |  | 20933 |  | 
| 1400 | 162 | 0 | 33 |  |  | 4928 |  | 
|  |  |  | 0 |  |  |  |  | 
| 1401 | 0 |  |  |  |  | 0 | my @middleware = map { | 
| 1402 |  |  |  |  |  |  | ref $_ eq 'CODE' ? | 
| 1403 |  |  |  |  |  |  | "Inline Coderef" : | 
| 1404 |  |  |  |  |  |  | (ref($_) .'  '. ($_->can('VERSION') ? $_->VERSION || '' : '') | 
| 1405 |  |  |  |  |  |  | || '')  } $class->registered_middlewares; | 
| 1406 |  |  |  |  |  |  |  | 
| 1407 |  |  |  |  |  |  | if (@middleware) { | 
| 1408 |  |  |  |  |  |  | my $column_width = Catalyst::Utils::term_width() - 6; | 
| 1409 |  |  |  |  |  |  | my $t = Text::SimpleTable->new($column_width); | 
| 1410 |  |  |  |  |  |  | $t->row($_) for @middleware; | 
| 1411 |  |  |  |  |  |  | $class->log->debug( "Loaded PSGI Middleware:\n" . $t->draw . "\n" ); | 
| 1412 |  |  |  |  |  |  | } | 
| 1413 |  |  |  |  |  |  |  | 
| 1414 |  |  |  |  |  |  | my %dh = $class->registered_data_handlers; | 
| 1415 |  |  |  |  |  |  | if (my @data_handlers = keys %dh) { | 
| 1416 | 163 |  |  | 163 |  | 1513 | my $column_width = Catalyst::Utils::term_width() - 6; | 
|  | 163 |  |  |  |  | 413 |  | 
|  | 163 |  |  |  |  | 403537 |  | 
|  | 162 |  |  |  |  | 2130 |  | 
| 1417 | 162 |  |  | 162 |  | 1793 | my $t = Text::SimpleTable->new($column_width); | 
| 1418 | 162 | 50 |  |  |  | 3213 | $t->row($_) for @data_handlers; | 
| 1419 |  |  |  |  |  |  | $class->log->debug( "Loaded Request Data Handlers:\n" . $t->draw . "\n" ); | 
| 1420 |  |  |  |  |  |  | } | 
| 1421 |  |  |  |  |  |  |  | 
| 1422 |  |  |  |  |  |  | my $dispatcher = $class->dispatcher; | 
| 1423 |  |  |  |  |  |  | my $engine     = $class->engine; | 
| 1424 |  |  |  |  |  |  | my $home       = $class->config->{home}; | 
| 1425 | 162 |  |  |  |  | 1503 |  | 
| 1426 | 162 |  |  |  |  | 1432 | $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher))); | 
| 1427 |  |  |  |  |  |  | $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine))); | 
| 1428 |  |  |  |  |  |  |  | 
| 1429 | 162 |  |  |  |  | 1696 | $home | 
| 1430 |  |  |  |  |  |  | ? ( -d $home ) | 
| 1431 | 162 |  |  |  |  | 1345 | ? $class->log->debug(qq/Found home "$home"/) | 
| 1432 |  |  |  |  |  |  | : $class->log->debug(qq/Home "$home" doesn't exist/) | 
| 1433 | 162 | 100 |  |  |  | 2648 | : $class->log->debug(q/Couldn't find home/); | 
| 1434 | 7 |  | 0 |  |  | 64 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 1435 |  |  |  |  |  |  | my $column_width = Catalyst::Utils::term_width() - 8 - 9; | 
| 1436 | 7 | 50 |  |  |  | 34 |  | 
| 1437 | 0 |  |  |  |  | 0 | my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] ); | 
| 1438 | 0 |  |  |  |  | 0 | for my $comp ( sort keys %{ $class->components } ) { | 
| 1439 | 0 |  |  |  |  | 0 | my $type = ref $class->components->{$comp} ? 'instance' : 'class'; | 
| 1440 | 0 |  |  |  |  | 0 | $t->row( $comp, $type ); | 
| 1441 |  |  |  |  |  |  | } | 
| 1442 |  |  |  |  |  |  | $class->log->debug( "Loaded components:\n" . $t->draw . "\n" ) | 
| 1443 |  |  |  |  |  |  | if ( keys %{ $class->components } ); | 
| 1444 | 7 | 50 | 50 |  |  | 67 | } | 
|  | 49 |  |  |  |  | 653 |  | 
| 1445 |  |  |  |  |  |  |  | 
| 1446 |  |  |  |  |  |  | # Add our self to components, since we are also a component | 
| 1447 |  |  |  |  |  |  | if( $class->isa('Catalyst::Controller') ){ | 
| 1448 |  |  |  |  |  |  | $class->components->{$class} = $class; | 
| 1449 | 7 | 50 |  |  |  | 125 | } | 
| 1450 | 7 |  |  |  |  | 34 |  | 
| 1451 | 7 |  |  |  |  | 71 | $class->setup_actions; | 
| 1452 | 7 |  |  |  |  | 358 |  | 
| 1453 | 7 |  |  |  |  | 2288 | if ( $class->debug ) { | 
| 1454 |  |  |  |  |  |  | my $name = $class->config->{name} || 'Application'; | 
| 1455 |  |  |  |  |  |  | $class->log->info("$name powered by Catalyst $Catalyst::VERSION"); | 
| 1456 | 7 |  |  |  |  | 236 | } | 
| 1457 | 7 | 50 |  |  |  | 47 |  | 
| 1458 | 7 |  |  |  |  | 31 | if ($class->config->{case_sensitive}) { | 
| 1459 | 7 |  |  |  |  | 44 | $class->log->warn($class . "->config->{case_sensitive} is set."); | 
| 1460 | 7 |  |  |  |  | 239 | $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81."); | 
| 1461 | 7 |  |  |  |  | 651 | } | 
| 1462 |  |  |  |  |  |  |  | 
| 1463 |  |  |  |  |  |  | # call these so we pre setup the composed classes | 
| 1464 | 7 |  |  |  |  | 140 | $class->composed_request_class; | 
| 1465 | 7 |  |  |  |  | 50 | $class->composed_response_class; | 
| 1466 | 7 |  |  |  |  | 40 | $class->composed_stats_class; | 
| 1467 |  |  |  |  |  |  |  | 
| 1468 | 7 |  |  |  |  | 31 | $class->setup_finalize; | 
| 1469 | 7 |  |  |  |  | 41 |  | 
| 1470 |  |  |  |  |  |  | # Flush the log for good measure (in case something turned off 'autoflush' early) | 
| 1471 | 7 | 50 |  |  |  | 85 | $class->log->_flush() if $class->log->can('_flush'); | 
|  |  | 100 |  |  |  |  |  | 
| 1472 |  |  |  |  |  |  |  | 
| 1473 |  |  |  |  |  |  | return $class || 1; # Just in case someone named their Application 0... | 
| 1474 |  |  |  |  |  |  | } | 
| 1475 |  |  |  |  |  |  |  | 
| 1476 |  |  |  |  |  |  | =head2 $app->setup_finalize | 
| 1477 | 7 |  |  |  |  | 41 |  | 
| 1478 |  |  |  |  |  |  | A hook to attach modifiers to. This method does not do anything except set the | 
| 1479 | 7 |  |  |  |  | 55 | C<setup_finished> accessor. | 
| 1480 | 7 |  |  |  |  | 577 |  | 
|  | 7 |  |  |  |  | 33 |  | 
| 1481 | 5 | 50 |  |  |  | 40 | Applying method modifiers to the C<setup> method doesn't work, because of quirky things done for plugin setup. | 
| 1482 | 5 |  |  |  |  | 20 |  | 
| 1483 |  |  |  |  |  |  | Example: | 
| 1484 |  |  |  |  |  |  |  | 
| 1485 | 7 | 100 |  |  |  | 397 | after setup_finalize => sub { | 
|  | 7 |  |  |  |  | 33 |  | 
| 1486 |  |  |  |  |  |  | my $app = shift; | 
| 1487 |  |  |  |  |  |  |  | 
| 1488 |  |  |  |  |  |  | ## do stuff here.. | 
| 1489 | 162 | 100 |  |  |  | 1087 | }; | 
| 1490 | 142 |  |  |  |  | 608 |  | 
| 1491 |  |  |  |  |  |  | =cut | 
| 1492 |  |  |  |  |  |  |  | 
| 1493 | 162 |  |  |  |  | 1901 | my ($class) = @_; | 
| 1494 |  |  |  |  |  |  | $class->setup_finished(1); | 
| 1495 | 161 | 100 |  |  |  | 726 | } | 
| 1496 | 7 |  | 100 |  |  | 45 |  | 
| 1497 | 7 |  |  |  |  | 36 | =head2 $c->uri_for( $path?, @args?, \%query_values?, \$fragment? ) | 
| 1498 |  |  |  |  |  |  |  | 
| 1499 |  |  |  |  |  |  | =head2 $c->uri_for( $action, \@captures?, @args?, \%query_values?, \$fragment? ) | 
| 1500 | 161 | 50 |  |  |  | 781 |  | 
| 1501 | 0 |  |  |  |  | 0 | =head2 $c->uri_for( $action, [@captures, @args], \%query_values?, \$fragment? ) | 
| 1502 | 0 |  |  |  |  | 0 |  | 
| 1503 |  |  |  |  |  |  | Constructs an absolute L<URI> object based on the application root, the | 
| 1504 |  |  |  |  |  |  | provided path, and the additional arguments and query parameters provided. | 
| 1505 |  |  |  |  |  |  | When used as a string, provides a textual URI.  If you need more flexibility | 
| 1506 | 161 |  |  |  |  | 3106 | than this (i.e. the option to provide relative URIs etc.) see | 
| 1507 | 161 |  |  |  |  | 1666 | L<Catalyst::Plugin::SmartURI>. | 
| 1508 | 161 |  |  |  |  | 1653 |  | 
| 1509 |  |  |  |  |  |  | If no arguments are provided, the URI for the current action is returned. | 
| 1510 | 161 |  |  |  |  | 1565 | To return the current action and also provide @args, use | 
| 1511 |  |  |  |  |  |  | C<< $c->uri_for( $c->action, @args ) >>. | 
| 1512 |  |  |  |  |  |  |  | 
| 1513 | 161 | 100 |  |  |  | 1221 | If the first argument is a string, it is taken as a public URI path relative | 
| 1514 |  |  |  |  |  |  | to C<< $c->namespace >> (if it doesn't begin with a forward slash) or | 
| 1515 | 161 |  | 50 |  |  | 1645 | relative to the application root (if it does). It is then merged with | 
| 1516 |  |  |  |  |  |  | C<< $c->request->base >>; any C<@args> are appended as additional path | 
| 1517 |  |  |  |  |  |  | components; and any C<%query_values> are appended as C<?foo=bar> parameters. | 
| 1518 |  |  |  |  |  |  |  | 
| 1519 |  |  |  |  |  |  | B<NOTE> If you are using this 'stringy' first argument, we skip encoding and | 
| 1520 |  |  |  |  |  |  | allow you to declare something like: | 
| 1521 |  |  |  |  |  |  |  | 
| 1522 |  |  |  |  |  |  | $c->uri_for('/foo/bar#baz') | 
| 1523 |  |  |  |  |  |  |  | 
| 1524 |  |  |  |  |  |  | Where 'baz' is a URI fragment.  We consider this first argument string to be | 
| 1525 |  |  |  |  |  |  | 'expert' mode where you are expected to create a valid URL and we for the most | 
| 1526 |  |  |  |  |  |  | part just pass it through without a lot of internal effort to escape and encode. | 
| 1527 |  |  |  |  |  |  |  | 
| 1528 |  |  |  |  |  |  | If the first argument is a L<Catalyst::Action> it represents an action which | 
| 1529 |  |  |  |  |  |  | will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The | 
| 1530 |  |  |  |  |  |  | optional C<\@captures> argument (an arrayref) allows passing the captured | 
| 1531 |  |  |  |  |  |  | variables that are needed to fill in the paths of Chained and Regex actions; | 
| 1532 |  |  |  |  |  |  | once the path is resolved, C<uri_for> continues as though a path was | 
| 1533 |  |  |  |  |  |  | provided, appending any arguments or parameters and creating an absolute | 
| 1534 |  |  |  |  |  |  | URI. | 
| 1535 |  |  |  |  |  |  |  | 
| 1536 | 161 |  |  | 161 | 1 | 2652 | The captures for the current request can be found in | 
| 1537 | 161 |  |  |  |  | 1180 | C<< $c->request->captures >>, and actions can be resolved using | 
| 1538 |  |  |  |  |  |  | C<< Catalyst::Controller->action_for($name) >>. If you have a private action | 
| 1539 |  |  |  |  |  |  | path, use C<< $c->uri_for_action >> instead. | 
| 1540 |  |  |  |  |  |  |  | 
| 1541 |  |  |  |  |  |  | # Equivalent to $c->req->uri | 
| 1542 |  |  |  |  |  |  | $c->uri_for($c->action, $c->req->captures, | 
| 1543 |  |  |  |  |  |  | @{ $c->req->args }, $c->req->params); | 
| 1544 |  |  |  |  |  |  |  | 
| 1545 |  |  |  |  |  |  | # For the Foo action in the Bar controller | 
| 1546 |  |  |  |  |  |  | $c->uri_for($c->controller('Bar')->action_for('Foo')); | 
| 1547 |  |  |  |  |  |  |  | 
| 1548 |  |  |  |  |  |  | # Path to a static resource | 
| 1549 |  |  |  |  |  |  | $c->uri_for('/static/images/logo.png'); | 
| 1550 |  |  |  |  |  |  |  | 
| 1551 |  |  |  |  |  |  | In general the scheme of the generated URI object will follow the incoming request | 
| 1552 |  |  |  |  |  |  | however if your targeted action or action chain has the Scheme attribute it will | 
| 1553 |  |  |  |  |  |  | use that instead. | 
| 1554 |  |  |  |  |  |  |  | 
| 1555 |  |  |  |  |  |  | Also, if the targeted Action or Action chain declares Args/CaptureArgs that have | 
| 1556 |  |  |  |  |  |  | type constraints, we will require that your proposed URL verify on those declared | 
| 1557 |  |  |  |  |  |  | constraints. | 
| 1558 |  |  |  |  |  |  |  | 
| 1559 |  |  |  |  |  |  | =cut | 
| 1560 |  |  |  |  |  |  |  | 
| 1561 |  |  |  |  |  |  | my ( $c, $path, @args ) = @_; | 
| 1562 |  |  |  |  |  |  |  | 
| 1563 |  |  |  |  |  |  | if ( $path->$_isa('Catalyst::Controller') ) { | 
| 1564 |  |  |  |  |  |  | $path = $path->path_prefix; | 
| 1565 |  |  |  |  |  |  | $path =~ s{/+\z}{}; | 
| 1566 |  |  |  |  |  |  | $path .= '/'; | 
| 1567 |  |  |  |  |  |  | } | 
| 1568 |  |  |  |  |  |  |  | 
| 1569 |  |  |  |  |  |  | my $fragment =  ((scalar(@args) && ref($args[-1]) eq 'SCALAR') ? ${pop @args} : undef ); | 
| 1570 |  |  |  |  |  |  |  | 
| 1571 |  |  |  |  |  |  | unless(blessed $path) { | 
| 1572 |  |  |  |  |  |  | if (defined($path) and $path =~ s/#(.+)$//)  { | 
| 1573 |  |  |  |  |  |  | if(defined($1) and defined $fragment) { | 
| 1574 |  |  |  |  |  |  | carp "Abiguious fragment declaration: You cannot define a fragment in '$path' and as an argument '$fragment'"; | 
| 1575 |  |  |  |  |  |  | } | 
| 1576 |  |  |  |  |  |  | if(defined($1)) { | 
| 1577 |  |  |  |  |  |  | $fragment = $1; | 
| 1578 |  |  |  |  |  |  | } | 
| 1579 |  |  |  |  |  |  | } | 
| 1580 |  |  |  |  |  |  | } | 
| 1581 |  |  |  |  |  |  |  | 
| 1582 |  |  |  |  |  |  | my $params = | 
| 1583 |  |  |  |  |  |  | ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} ); | 
| 1584 |  |  |  |  |  |  |  | 
| 1585 |  |  |  |  |  |  | undef($path) if (defined $path && $path eq ''); | 
| 1586 |  |  |  |  |  |  |  | 
| 1587 |  |  |  |  |  |  | carp "uri_for called with undef argument" if grep { ! defined $_ } @args; | 
| 1588 |  |  |  |  |  |  |  | 
| 1589 |  |  |  |  |  |  | my $target_action = $path->$_isa('Catalyst::Action') ? $path : undef; | 
| 1590 |  |  |  |  |  |  | if ( $path->$_isa('Catalyst::Action') ) { # action object | 
| 1591 |  |  |  |  |  |  | s|/|%2F|g for @args; | 
| 1592 |  |  |  |  |  |  | my $captures = [ map { s|/|%2F|g; $_; } | 
| 1593 |  |  |  |  |  |  | ( scalar @args && ref $args[0] eq 'ARRAY' | 
| 1594 |  |  |  |  |  |  | ? @{ shift(@args) } | 
| 1595 |  |  |  |  |  |  | : ()) ]; | 
| 1596 |  |  |  |  |  |  |  | 
| 1597 |  |  |  |  |  |  | my $action = $path; | 
| 1598 |  |  |  |  |  |  | my $expanded_action = $c->dispatcher->expand_action( $action ); | 
| 1599 |  |  |  |  |  |  | my $num_captures = $expanded_action->number_of_captures; | 
| 1600 |  |  |  |  |  |  |  | 
| 1601 |  |  |  |  |  |  | # ->uri_for( $action, \@captures_and_args, \%query_values? ) | 
| 1602 |  |  |  |  |  |  | if( !@args && $action->number_of_args && @$captures > $num_captures ) { | 
| 1603 |  |  |  |  |  |  | unshift @args, splice @$captures, $num_captures; | 
| 1604 |  |  |  |  |  |  | } | 
| 1605 | 122 |  |  | 122 | 1 | 22264 |  | 
| 1606 |  |  |  |  |  |  | if($num_captures) { | 
| 1607 | 122 | 100 |  |  |  | 406 | unless($expanded_action->match_captures_constraints($c, $captures)) { | 
| 1608 | 1 |  |  |  |  | 31 | $c->log->debug("captures [@{$captures}] do not match the type constraints in actionchain ending with '$expanded_action'") | 
| 1609 | 1 |  |  |  |  | 3 | if $c->debug; | 
| 1610 | 1 |  |  |  |  | 2 | return undef; | 
| 1611 |  |  |  |  |  |  | } | 
| 1612 |  |  |  |  |  |  | } | 
| 1613 | 122 | 100 | 100 |  |  | 1936 |  | 
|  | 2 |  |  |  |  | 6 |  | 
| 1614 |  |  |  |  |  |  | $path = $c->dispatcher->uri_for_action($action, $captures); | 
| 1615 | 122 | 100 |  |  |  | 346 | if (not defined $path) { | 
| 1616 | 47 | 100 | 100 |  |  | 220 | $c->log->debug(qq/Can't find uri_for action '$action' @$captures/) | 
| 1617 | 5 | 50 | 33 |  |  | 22 | if $c->debug; | 
| 1618 | 0 |  |  |  |  | 0 | return undef; | 
| 1619 |  |  |  |  |  |  | } | 
| 1620 | 5 | 50 |  |  |  | 9 | $path = '/' if $path eq ''; | 
| 1621 | 5 |  |  |  |  | 9 |  | 
| 1622 |  |  |  |  |  |  | # At this point @encoded_args is the remaining Args (all captures removed). | 
| 1623 |  |  |  |  |  |  | if($expanded_action->has_args_constraints) { | 
| 1624 |  |  |  |  |  |  | unless($expanded_action->match_args($c,\@args)) { | 
| 1625 |  |  |  |  |  |  | $c->log->debug("args [@args] do not match the type constraints in action '$expanded_action'") | 
| 1626 | 122 | 100 | 100 |  |  | 461 | if $c->debug; | 
| 1627 |  |  |  |  |  |  | return undef; | 
| 1628 |  |  |  |  |  |  | } | 
| 1629 | 122 | 100 | 100 |  |  | 521 | } | 
| 1630 |  |  |  |  |  |  | } | 
| 1631 | 122 | 50 |  |  |  | 271 |  | 
|  | 127 |  |  |  |  | 276 |  | 
| 1632 |  |  |  |  |  |  | unshift(@args, $path); | 
| 1633 | 122 | 100 |  |  |  | 243 |  | 
| 1634 | 122 | 100 |  |  |  | 1470 | unless (defined $path && $path =~ s!^/!!) { # in-place strip | 
| 1635 | 73 |  |  |  |  | 821 | my $namespace = $c->namespace; | 
| 1636 | 123 |  |  |  |  | 179 | if (defined $path) { # cheesy hack to handle path '../foo' | 
|  | 123 |  |  |  |  | 231 |  | 
| 1637 |  |  |  |  |  |  | $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{}; | 
| 1638 | 73 | 100 | 100 |  |  | 279 | } | 
|  | 53 |  |  |  |  | 89 |  | 
| 1639 |  |  |  |  |  |  | unshift(@args, $namespace || ''); | 
| 1640 |  |  |  |  |  |  | } | 
| 1641 | 73 |  |  |  |  | 124 |  | 
| 1642 | 73 |  |  |  |  | 211 | # join args with '/', or a blank string | 
| 1643 | 73 |  |  |  |  | 693 | my $args = join('/', grep { defined($_) } @args); | 
| 1644 |  |  |  |  |  |  | $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE | 
| 1645 |  |  |  |  |  |  | $args =~ s!^/+!!; | 
| 1646 | 73 | 100 | 100 |  |  | 1115 |  | 
|  |  |  | 100 |  |  |  |  | 
| 1647 | 22 |  |  |  |  | 62 | my ($base, $class) = ('/', 'URI::_generic'); | 
| 1648 |  |  |  |  |  |  | if(blessed($c)) { | 
| 1649 |  |  |  |  |  |  | $base = $c->req->base; | 
| 1650 | 73 | 100 |  |  |  | 170 | if($target_action) { | 
| 1651 | 47 | 100 |  |  |  | 128 | $target_action = $c->dispatcher->expand_action($target_action); | 
| 1652 | 3 | 50 |  |  |  | 63 | if(my $s = $target_action->scheme) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 1653 |  |  |  |  |  |  | $s = lc($s); | 
| 1654 | 3 |  |  |  |  | 78 | $class = "URI::$s"; | 
| 1655 |  |  |  |  |  |  | $base->scheme($s); | 
| 1656 |  |  |  |  |  |  | } else { | 
| 1657 |  |  |  |  |  |  | $class = ref($base); | 
| 1658 | 70 |  |  |  |  | 235 | } | 
| 1659 | 70 | 100 |  |  |  | 325 | } else { | 
| 1660 | 3 | 50 |  |  |  | 8 | $class = ref($base); | 
| 1661 |  |  |  |  |  |  | } | 
| 1662 | 3 |  |  |  |  | 55 |  | 
| 1663 |  |  |  |  |  |  | $base =~ s{(?<!/)$}{/}; | 
| 1664 | 67 | 50 |  |  |  | 189 | } | 
| 1665 |  |  |  |  |  |  |  | 
| 1666 |  |  |  |  |  |  | my $query = ''; | 
| 1667 | 67 | 100 |  |  |  | 2325 | if (my @keys = keys %$params) { | 
| 1668 | 10 | 100 |  |  |  | 36 | # somewhat lifted from URI::_query's query_form | 
| 1669 | 3 | 50 |  |  |  | 59 | $query = '?'.join('&', map { | 
| 1670 |  |  |  |  |  |  | my $val = $params->{$_}; | 
| 1671 | 3 |  |  |  |  | 45 | my $key = encode_utf8($_); | 
| 1672 |  |  |  |  |  |  | # using the URI::Escape pattern here so utf8 chars survive | 
| 1673 |  |  |  |  |  |  | $key =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go; | 
| 1674 |  |  |  |  |  |  | $key =~ s/ /+/g; | 
| 1675 |  |  |  |  |  |  |  | 
| 1676 | 113 |  |  |  |  | 508 | $val = '' unless defined $val; | 
| 1677 |  |  |  |  |  |  | (map { | 
| 1678 | 113 | 100 | 100 |  |  | 603 | my $param = encode_utf8($_); | 
| 1679 | 18 |  |  |  |  | 473 | # using the URI::Escape pattern here so utf8 chars survive | 
| 1680 | 18 | 100 |  |  |  | 38 | $param =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go; | 
| 1681 | 16 |  |  |  |  | 42 | $param =~ s/ /+/g; | 
| 1682 |  |  |  |  |  |  |  | 
| 1683 | 18 |  | 100 |  |  | 55 | "${key}=$param"; | 
| 1684 |  |  |  |  |  |  | } ( ref $val eq 'ARRAY' ? @$val : $val )); | 
| 1685 |  |  |  |  |  |  | } @keys); | 
| 1686 |  |  |  |  |  |  | } | 
| 1687 | 113 |  |  |  |  | 447 |  | 
|  | 226 |  |  |  |  | 501 |  | 
| 1688 | 113 |  |  |  |  | 281 | $base = encode_utf8 $base; | 
| 1689 | 113 |  |  |  |  | 308 | $base =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; | 
| 1690 |  |  |  |  |  |  | $args = encode_utf8 $args; | 
| 1691 | 113 |  |  |  |  | 235 | $args =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; | 
| 1692 | 113 | 100 |  |  |  | 346 |  | 
| 1693 | 104 |  |  |  |  | 249 | if(defined $fragment) { | 
| 1694 | 104 | 100 |  |  |  | 287 | if(blessed $path) { | 
| 1695 | 61 |  |  |  |  | 201 | $fragment = encode_utf8($fragment); | 
| 1696 | 61 | 100 |  |  |  | 247 | $fragment =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go; | 
| 1697 | 3 |  |  |  |  | 13 | $fragment =~ s/ /+/g; | 
| 1698 | 3 |  |  |  |  | 5 | } | 
| 1699 | 3 |  |  |  |  | 15 | $query .= "#$fragment"; | 
| 1700 |  |  |  |  |  |  | } | 
| 1701 | 58 |  |  |  |  | 129 |  | 
| 1702 |  |  |  |  |  |  | my $res = bless(\"${base}${args}${query}", $class); | 
| 1703 |  |  |  |  |  |  | $res; | 
| 1704 | 43 |  |  |  |  | 74 | } | 
| 1705 |  |  |  |  |  |  |  | 
| 1706 |  |  |  |  |  |  | =head2 $c->uri_for_action( $path, \@captures_and_args?, @args?, \%query_values? ) | 
| 1707 | 104 |  |  |  |  | 883 |  | 
| 1708 |  |  |  |  |  |  | =head2 $c->uri_for_action( $action, \@captures_and_args?, @args?, \%query_values? ) | 
| 1709 |  |  |  |  |  |  |  | 
| 1710 | 113 |  |  |  |  | 916 | =over | 
| 1711 | 113 | 100 |  |  |  | 384 |  | 
| 1712 |  |  |  |  |  |  | =item $path | 
| 1713 |  |  |  |  |  |  |  | 
| 1714 | 34 |  |  |  |  | 73 | A private path to the Catalyst action you want to create a URI for. | 
|  | 37 |  |  |  |  | 66 |  | 
| 1715 | 37 |  |  |  |  | 117 |  | 
| 1716 |  |  |  |  |  |  | This is a shortcut for calling C<< $c->dispatcher->get_action_by_path($path) | 
| 1717 | 37 |  |  |  |  | 114 | >> and passing the resulting C<$action> and the remaining arguments to C<< | 
| 1718 | 37 |  |  |  |  | 67 | $c->uri_for >>. | 
| 1719 |  |  |  |  |  |  |  | 
| 1720 | 37 | 100 |  |  |  | 71 | You can also pass in a Catalyst::Action object, in which case it is passed to | 
| 1721 |  |  |  |  |  |  | C<< $c->uri_for >>. | 
| 1722 | 37 | 100 |  |  |  | 84 |  | 
|  | 38 |  |  |  |  | 77 |  | 
| 1723 |  |  |  |  |  |  | Note that although the path looks like a URI that dispatches to the wanted action, it is not a URI, but an internal path to that action. | 
| 1724 | 38 |  |  |  |  | 174 |  | 
| 1725 | 38 |  |  |  |  | 79 | For example, if the action looks like: | 
| 1726 |  |  |  |  |  |  |  | 
| 1727 | 38 |  |  |  |  | 137 | package MyApp::Controller::Users; | 
| 1728 |  |  |  |  |  |  |  | 
| 1729 |  |  |  |  |  |  | sub lst : Path('the-list') {} | 
| 1730 |  |  |  |  |  |  |  | 
| 1731 |  |  |  |  |  |  | You can use: | 
| 1732 | 113 |  |  |  |  | 372 |  | 
| 1733 | 113 |  |  |  |  | 695 | $c->uri_for_action('/users/lst') | 
| 1734 | 113 |  |  |  |  | 271 |  | 
| 1735 | 113 |  |  |  |  | 452 | and it will create the URI /users/the-list. | 
| 1736 |  |  |  |  |  |  |  | 
| 1737 | 113 | 100 |  |  |  | 288 | =item \@captures_and_args? | 
| 1738 | 7 | 100 |  |  |  | 16 |  | 
| 1739 | 1 |  |  |  |  | 3 | Optional array reference of Captures (i.e. C<CaptureArgs> or C<< $c->req->captures >>) | 
| 1740 | 1 |  |  |  |  | 3 | and arguments to the request. Usually used with L<Catalyst::DispatchType::Chained> | 
| 1741 | 1 |  |  |  |  | 7 | to interpolate all the parameters in the URI. | 
| 1742 |  |  |  |  |  |  |  | 
| 1743 | 7 |  |  |  |  | 13 | =item @args? | 
| 1744 |  |  |  |  |  |  |  | 
| 1745 |  |  |  |  |  |  | Optional list of extra arguments - can be supplied in the | 
| 1746 | 113 |  |  |  |  | 364 | C<< \@captures_and_args? >> array ref, or here - whichever is easier for your | 
| 1747 | 113 |  |  |  |  | 1723 | code. | 
| 1748 |  |  |  |  |  |  |  | 
| 1749 |  |  |  |  |  |  | Your action can have zero, a fixed or a variable number of args (e.g. | 
| 1750 |  |  |  |  |  |  | C<< Args(1) >> for a fixed number or C<< Args() >> for a variable number).. | 
| 1751 |  |  |  |  |  |  |  | 
| 1752 |  |  |  |  |  |  | =item \%query_values? | 
| 1753 |  |  |  |  |  |  |  | 
| 1754 |  |  |  |  |  |  | Optional array reference of query parameters to append. E.g. | 
| 1755 |  |  |  |  |  |  |  | 
| 1756 |  |  |  |  |  |  | { foo => 'bar' } | 
| 1757 |  |  |  |  |  |  |  | 
| 1758 |  |  |  |  |  |  | will generate | 
| 1759 |  |  |  |  |  |  |  | 
| 1760 |  |  |  |  |  |  | /rest/of/your/uri?foo=bar | 
| 1761 |  |  |  |  |  |  |  | 
| 1762 |  |  |  |  |  |  | =back | 
| 1763 |  |  |  |  |  |  |  | 
| 1764 |  |  |  |  |  |  | =cut | 
| 1765 |  |  |  |  |  |  |  | 
| 1766 |  |  |  |  |  |  | my ( $c, $path, @args ) = @_; | 
| 1767 |  |  |  |  |  |  | my $action = blessed($path) | 
| 1768 |  |  |  |  |  |  | ? $path | 
| 1769 |  |  |  |  |  |  | : $c->dispatcher->get_action_by_path($path); | 
| 1770 |  |  |  |  |  |  | unless (defined $action) { | 
| 1771 |  |  |  |  |  |  | croak "Can't find action for path '$path'"; | 
| 1772 |  |  |  |  |  |  | } | 
| 1773 |  |  |  |  |  |  | return $c->uri_for( $action, @args ); | 
| 1774 |  |  |  |  |  |  | } | 
| 1775 |  |  |  |  |  |  |  | 
| 1776 |  |  |  |  |  |  | =head2 $c->welcome_message | 
| 1777 |  |  |  |  |  |  |  | 
| 1778 |  |  |  |  |  |  | Returns the Catalyst welcome HTML page. | 
| 1779 |  |  |  |  |  |  |  | 
| 1780 |  |  |  |  |  |  | =cut | 
| 1781 |  |  |  |  |  |  |  | 
| 1782 |  |  |  |  |  |  | my $c      = shift; | 
| 1783 |  |  |  |  |  |  | my $name   = $c->config->{name}; | 
| 1784 |  |  |  |  |  |  | my $logo   = $c->uri_for('/static/images/catalyst_logo.png'); | 
| 1785 |  |  |  |  |  |  | my $prefix = Catalyst::Utils::appprefix( ref $c ); | 
| 1786 |  |  |  |  |  |  | $c->response->content_type('text/html; charset=utf-8'); | 
| 1787 |  |  |  |  |  |  | return <<"EOF"; | 
| 1788 |  |  |  |  |  |  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | 
| 1789 |  |  |  |  |  |  | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | 
| 1790 |  |  |  |  |  |  | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | 
| 1791 |  |  |  |  |  |  | <head> | 
| 1792 |  |  |  |  |  |  | <meta http-equiv="Content-Language" content="en" /> | 
| 1793 |  |  |  |  |  |  | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | 
| 1794 |  |  |  |  |  |  | <title>$name on Catalyst $VERSION</title> | 
| 1795 |  |  |  |  |  |  | <style type="text/css"> | 
| 1796 |  |  |  |  |  |  | body { | 
| 1797 |  |  |  |  |  |  | color: #000; | 
| 1798 |  |  |  |  |  |  | background-color: #eee; | 
| 1799 |  |  |  |  |  |  | } | 
| 1800 |  |  |  |  |  |  | div#content { | 
| 1801 |  |  |  |  |  |  | width: 640px; | 
| 1802 |  |  |  |  |  |  | margin-left: auto; | 
| 1803 |  |  |  |  |  |  | margin-right: auto; | 
| 1804 |  |  |  |  |  |  | margin-top: 10px; | 
| 1805 |  |  |  |  |  |  | margin-bottom: 10px; | 
| 1806 |  |  |  |  |  |  | text-align: left; | 
| 1807 |  |  |  |  |  |  | background-color: #ccc; | 
| 1808 |  |  |  |  |  |  | border: 1px solid #aaa; | 
| 1809 |  |  |  |  |  |  | } | 
| 1810 |  |  |  |  |  |  | p, h1, h2 { | 
| 1811 | 31 |  |  | 31 | 1 | 3298 | margin-left: 20px; | 
| 1812 | 31 | 100 |  |  |  | 155 | margin-right: 20px; | 
| 1813 |  |  |  |  |  |  | font-family: verdana, tahoma, sans-serif; | 
| 1814 |  |  |  |  |  |  | } | 
| 1815 | 31 | 100 |  |  |  | 83 | a { | 
| 1816 | 1 |  |  |  |  | 158 | font-family: verdana, tahoma, sans-serif; | 
| 1817 |  |  |  |  |  |  | } | 
| 1818 | 30 |  |  |  |  | 87 | :link, :visited { | 
| 1819 |  |  |  |  |  |  | text-decoration: none; | 
| 1820 |  |  |  |  |  |  | color: #b00; | 
| 1821 |  |  |  |  |  |  | border-bottom: 1px dotted #bbb; | 
| 1822 |  |  |  |  |  |  | } | 
| 1823 |  |  |  |  |  |  | :link:hover, :visited:hover { | 
| 1824 |  |  |  |  |  |  | color: #555; | 
| 1825 |  |  |  |  |  |  | } | 
| 1826 |  |  |  |  |  |  | div#topbar { | 
| 1827 |  |  |  |  |  |  | margin: 0px; | 
| 1828 | 0 |  |  | 0 | 1 | 0 | } | 
| 1829 | 0 |  |  |  |  | 0 | pre { | 
| 1830 | 0 |  |  |  |  | 0 | margin: 10px; | 
| 1831 | 0 |  |  |  |  | 0 | padding: 8px; | 
| 1832 | 0 |  |  |  |  | 0 | } | 
| 1833 | 0 |  |  |  |  | 0 | div#answers { | 
| 1834 |  |  |  |  |  |  | padding: 8px; | 
| 1835 |  |  |  |  |  |  | margin: 10px; | 
| 1836 |  |  |  |  |  |  | background-color: #fff; | 
| 1837 |  |  |  |  |  |  | border: 1px solid #aaa; | 
| 1838 |  |  |  |  |  |  | } | 
| 1839 |  |  |  |  |  |  | h1 { | 
| 1840 |  |  |  |  |  |  | font-size: 0.9em; | 
| 1841 |  |  |  |  |  |  | font-weight: normal; | 
| 1842 |  |  |  |  |  |  | text-align: center; | 
| 1843 |  |  |  |  |  |  | } | 
| 1844 |  |  |  |  |  |  | h2 { | 
| 1845 |  |  |  |  |  |  | font-size: 1.0em; | 
| 1846 |  |  |  |  |  |  | } | 
| 1847 |  |  |  |  |  |  | p { | 
| 1848 |  |  |  |  |  |  | font-size: 0.9em; | 
| 1849 |  |  |  |  |  |  | } | 
| 1850 |  |  |  |  |  |  | p img { | 
| 1851 |  |  |  |  |  |  | float: right; | 
| 1852 |  |  |  |  |  |  | margin-left: 10px; | 
| 1853 |  |  |  |  |  |  | } | 
| 1854 |  |  |  |  |  |  | span#appname { | 
| 1855 |  |  |  |  |  |  | font-weight: bold; | 
| 1856 |  |  |  |  |  |  | font-size: 1.6em; | 
| 1857 |  |  |  |  |  |  | } | 
| 1858 |  |  |  |  |  |  | </style> | 
| 1859 |  |  |  |  |  |  | </head> | 
| 1860 |  |  |  |  |  |  | <body> | 
| 1861 |  |  |  |  |  |  | <div id="content"> | 
| 1862 |  |  |  |  |  |  | <div id="topbar"> | 
| 1863 |  |  |  |  |  |  | <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a> | 
| 1864 |  |  |  |  |  |  | $VERSION</h1> | 
| 1865 |  |  |  |  |  |  | </div> | 
| 1866 |  |  |  |  |  |  | <div id="answers"> | 
| 1867 |  |  |  |  |  |  | <p> | 
| 1868 |  |  |  |  |  |  | <img src="$logo" alt="Catalyst Logo" /> | 
| 1869 |  |  |  |  |  |  | </p> | 
| 1870 |  |  |  |  |  |  | <p>Welcome to the  world of Catalyst. | 
| 1871 |  |  |  |  |  |  | This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a> | 
| 1872 |  |  |  |  |  |  | framework will make web development something you had | 
| 1873 |  |  |  |  |  |  | never expected it to be: Fun, rewarding, and quick.</p> | 
| 1874 |  |  |  |  |  |  | <h2>What to do now?</h2> | 
| 1875 |  |  |  |  |  |  | <p>That really depends  on what <b>you</b> want to do. | 
| 1876 |  |  |  |  |  |  | We do, however, provide you with a few starting points.</p> | 
| 1877 |  |  |  |  |  |  | <p>If you want to jump right into web development with Catalyst | 
| 1878 |  |  |  |  |  |  | you might want to start with a tutorial.</p> | 
| 1879 |  |  |  |  |  |  | <pre>perldoc <a href="https://metacpan.org/module/Catalyst::Manual::Tutorial">Catalyst::Manual::Tutorial</a></code> | 
| 1880 |  |  |  |  |  |  | </pre> | 
| 1881 |  |  |  |  |  |  | <p>Afterwards you can go on to check out a more complete look at our features.</p> | 
| 1882 |  |  |  |  |  |  | <pre> | 
| 1883 |  |  |  |  |  |  | <code>perldoc <a href="https://metacpan.org/module/Catalyst::Manual::Intro">Catalyst::Manual::Intro</a> | 
| 1884 |  |  |  |  |  |  | <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful --> | 
| 1885 |  |  |  |  |  |  | </code></pre> | 
| 1886 |  |  |  |  |  |  | <h2>What to do next?</h2> | 
| 1887 |  |  |  |  |  |  | <p>Next it's time to write an actual application. Use the | 
| 1888 |  |  |  |  |  |  | helper scripts to generate <a href="https://metacpan.org/search?q=Catalyst%3A%3AController">controllers</a>, | 
| 1889 |  |  |  |  |  |  | <a href="https://metacpan.org/search?q=Catalyst%3A%3AModel">models</a>, and | 
| 1890 |  |  |  |  |  |  | <a href="https://metacpan.org/search?q=Catalyst%3A%3AView">views</a>; | 
| 1891 |  |  |  |  |  |  | they can save you a lot of work.</p> | 
| 1892 |  |  |  |  |  |  | <pre><code>script/${prefix}_create.pl --help</code></pre> | 
| 1893 |  |  |  |  |  |  | <p>Also, be sure to check out the vast and growing | 
| 1894 |  |  |  |  |  |  | collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>; | 
| 1895 |  |  |  |  |  |  | you are likely to find what you need there. | 
| 1896 |  |  |  |  |  |  | </p> | 
| 1897 |  |  |  |  |  |  |  | 
| 1898 |  |  |  |  |  |  | <h2>Need help?</h2> | 
| 1899 |  |  |  |  |  |  | <p>Catalyst has a very active community. Here are the main places to | 
| 1900 |  |  |  |  |  |  | get in touch with us.</p> | 
| 1901 |  |  |  |  |  |  | <ul> | 
| 1902 |  |  |  |  |  |  | <li> | 
| 1903 |  |  |  |  |  |  | <a href="http://dev.catalyst.perl.org">Wiki</a> | 
| 1904 |  |  |  |  |  |  | </li> | 
| 1905 |  |  |  |  |  |  | <li> | 
| 1906 |  |  |  |  |  |  | <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a> | 
| 1907 |  |  |  |  |  |  | </li> | 
| 1908 |  |  |  |  |  |  | <li> | 
| 1909 |  |  |  |  |  |  | <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a> | 
| 1910 |  |  |  |  |  |  | </li> | 
| 1911 |  |  |  |  |  |  | </ul> | 
| 1912 |  |  |  |  |  |  | <h2>In conclusion</h2> | 
| 1913 |  |  |  |  |  |  | <p>The Catalyst team hopes you will enjoy using Catalyst as much | 
| 1914 |  |  |  |  |  |  | as we enjoyed making it. Please contact us if you have ideas | 
| 1915 |  |  |  |  |  |  | for improvement or other feedback.</p> | 
| 1916 |  |  |  |  |  |  | </div> | 
| 1917 |  |  |  |  |  |  | </div> | 
| 1918 |  |  |  |  |  |  | </body> | 
| 1919 |  |  |  |  |  |  | </html> | 
| 1920 |  |  |  |  |  |  | EOF | 
| 1921 |  |  |  |  |  |  | } | 
| 1922 |  |  |  |  |  |  |  | 
| 1923 |  |  |  |  |  |  | =head2 run_options | 
| 1924 |  |  |  |  |  |  |  | 
| 1925 |  |  |  |  |  |  | Contains a hash of options passed from the application script, including | 
| 1926 |  |  |  |  |  |  | the original ARGV the script received, the processed values from that | 
| 1927 |  |  |  |  |  |  | ARGV and any extra arguments to the script which were not processed. | 
| 1928 |  |  |  |  |  |  |  | 
| 1929 |  |  |  |  |  |  | This can be used to add custom options to your application's scripts | 
| 1930 |  |  |  |  |  |  | and setup your application differently depending on the values of these | 
| 1931 |  |  |  |  |  |  | options. | 
| 1932 |  |  |  |  |  |  |  | 
| 1933 |  |  |  |  |  |  | =head1 INTERNAL METHODS | 
| 1934 |  |  |  |  |  |  |  | 
| 1935 |  |  |  |  |  |  | These methods are not meant to be used by end users. | 
| 1936 |  |  |  |  |  |  |  | 
| 1937 |  |  |  |  |  |  | =head2 $c->components | 
| 1938 |  |  |  |  |  |  |  | 
| 1939 |  |  |  |  |  |  | Returns a hash of components. | 
| 1940 |  |  |  |  |  |  |  | 
| 1941 |  |  |  |  |  |  | =head2 $c->context_class | 
| 1942 |  |  |  |  |  |  |  | 
| 1943 |  |  |  |  |  |  | Returns or sets the context class. | 
| 1944 |  |  |  |  |  |  |  | 
| 1945 |  |  |  |  |  |  | =head2 $c->counter | 
| 1946 |  |  |  |  |  |  |  | 
| 1947 |  |  |  |  |  |  | Returns a hashref containing coderefs and execution counts (needed for | 
| 1948 |  |  |  |  |  |  | deep recursion detection). | 
| 1949 |  |  |  |  |  |  |  | 
| 1950 |  |  |  |  |  |  | =head2 $c->depth | 
| 1951 |  |  |  |  |  |  |  | 
| 1952 |  |  |  |  |  |  | Returns the number of actions on the current internal execution stack. | 
| 1953 |  |  |  |  |  |  |  | 
| 1954 |  |  |  |  |  |  | =head2 $c->dispatch | 
| 1955 |  |  |  |  |  |  |  | 
| 1956 |  |  |  |  |  |  | Dispatches a request to actions. | 
| 1957 |  |  |  |  |  |  |  | 
| 1958 |  |  |  |  |  |  | =cut | 
| 1959 |  |  |  |  |  |  |  | 
| 1960 |  |  |  |  |  |  |  | 
| 1961 |  |  |  |  |  |  | =head2 $c->dispatcher_class | 
| 1962 |  |  |  |  |  |  |  | 
| 1963 |  |  |  |  |  |  | Returns or sets the dispatcher class. | 
| 1964 |  |  |  |  |  |  |  | 
| 1965 |  |  |  |  |  |  | =head2 $c->dump_these | 
| 1966 |  |  |  |  |  |  |  | 
| 1967 |  |  |  |  |  |  | Returns a list of 2-element array references (name, structure) pairs | 
| 1968 |  |  |  |  |  |  | that will be dumped on the error page in debug mode. | 
| 1969 |  |  |  |  |  |  |  | 
| 1970 |  |  |  |  |  |  | =cut | 
| 1971 |  |  |  |  |  |  |  | 
| 1972 |  |  |  |  |  |  | my $c = shift; | 
| 1973 |  |  |  |  |  |  | [ Request => $c->req ], | 
| 1974 |  |  |  |  |  |  | [ Response => $c->res ], | 
| 1975 |  |  |  |  |  |  | [ Stash => $c->stash ], | 
| 1976 |  |  |  |  |  |  | [ Config => $c->config ]; | 
| 1977 |  |  |  |  |  |  | } | 
| 1978 |  |  |  |  |  |  |  | 
| 1979 |  |  |  |  |  |  | =head2 $c->engine_class | 
| 1980 |  |  |  |  |  |  |  | 
| 1981 |  |  |  |  |  |  | Returns or sets the engine class. | 
| 1982 |  |  |  |  |  |  |  | 
| 1983 |  |  |  |  |  |  | =head2 $c->execute( $class, $coderef ) | 
| 1984 |  |  |  |  |  |  |  | 
| 1985 |  |  |  |  |  |  | Execute a coderef in given class and catch exceptions. Errors are available | 
| 1986 |  |  |  |  |  |  | via $c->error. | 
| 1987 |  |  |  |  |  |  |  | 
| 1988 |  |  |  |  |  |  | =cut | 
| 1989 |  |  |  |  |  |  |  | 
| 1990 |  |  |  |  |  |  | my ( $c, $class, $code ) = @_; | 
| 1991 |  |  |  |  |  |  | $class = $c->component($class) || $class; | 
| 1992 |  |  |  |  |  |  | #$c->state(0); | 
| 1993 |  |  |  |  |  |  |  | 
| 1994 |  |  |  |  |  |  | if ( $c->depth >= $RECURSION ) { | 
| 1995 |  |  |  |  |  |  | my $action = $code->reverse(); | 
| 1996 |  |  |  |  |  |  | $action = "/$action" unless $action =~ /->/; | 
| 1997 |  |  |  |  |  |  | my $error = qq/Deep recursion detected calling "${action}"/; | 
| 1998 |  |  |  |  |  |  | $c->log->error($error); | 
| 1999 |  |  |  |  |  |  | $c->error($error); | 
| 2000 |  |  |  |  |  |  | $c->state(0); | 
| 2001 |  |  |  |  |  |  | return $c->state; | 
| 2002 |  |  |  |  |  |  | } | 
| 2003 |  |  |  |  |  |  |  | 
| 2004 |  |  |  |  |  |  | my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats; | 
| 2005 |  |  |  |  |  |  |  | 
| 2006 | 918 |  |  | 918 | 1 | 2901 | push( @{ $c->stack }, $code ); | 
|  | 918 |  |  |  |  | 2879 |  | 
| 2007 |  |  |  |  |  |  |  | 
| 2008 |  |  |  |  |  |  | no warnings 'recursion'; | 
| 2009 |  |  |  |  |  |  | # N.B. This used to be combined, but I have seen $c get clobbered if so, and | 
| 2010 |  |  |  |  |  |  | #      I have no idea how, ergo $ret (which appears to fix the issue) | 
| 2011 |  |  |  |  |  |  | eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) }; | 
| 2012 |  |  |  |  |  |  |  | 
| 2013 |  |  |  |  |  |  | $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info; | 
| 2014 |  |  |  |  |  |  |  | 
| 2015 |  |  |  |  |  |  | my $last = pop( @{ $c->stack } ); | 
| 2016 |  |  |  |  |  |  |  | 
| 2017 |  |  |  |  |  |  | if ( my $error = $@ ) { | 
| 2018 |  |  |  |  |  |  | #rethow if this can be handled by middleware | 
| 2019 |  |  |  |  |  |  | if ( $c->_handle_http_exception($error) ) { | 
| 2020 | 36 |  |  | 36 | 1 | 49 | foreach my $err (@{$c->error}) { | 
| 2021 | 36 |  |  |  |  | 78 | $c->log->error($err); | 
| 2022 |  |  |  |  |  |  | } | 
| 2023 |  |  |  |  |  |  | $c->clear_errors; | 
| 2024 |  |  |  |  |  |  | $c->log->_flush if $c->log->can('_flush'); | 
| 2025 |  |  |  |  |  |  |  | 
| 2026 |  |  |  |  |  |  | $error->can('rethrow') ? $error->rethrow : croak $error; | 
| 2027 |  |  |  |  |  |  | } | 
| 2028 |  |  |  |  |  |  | if ( blessed($error) and $error->isa('Catalyst::Exception::Detach') ) { | 
| 2029 |  |  |  |  |  |  | $error->rethrow if $c->depth > 1; | 
| 2030 |  |  |  |  |  |  | } | 
| 2031 |  |  |  |  |  |  | elsif ( blessed($error) and $error->isa('Catalyst::Exception::Go') ) { | 
| 2032 |  |  |  |  |  |  | $error->rethrow if $c->depth > 0; | 
| 2033 |  |  |  |  |  |  | } | 
| 2034 |  |  |  |  |  |  | else { | 
| 2035 |  |  |  |  |  |  | unless ( ref $error ) { | 
| 2036 |  |  |  |  |  |  | no warnings 'uninitialized'; | 
| 2037 |  |  |  |  |  |  | chomp $error; | 
| 2038 |  |  |  |  |  |  | my $class = $last->class; | 
| 2039 | 9112 |  |  | 9112 | 1 | 215041 | my $name  = $last->name; | 
| 2040 | 9112 |  | 33 |  |  | 18696 | $error = qq/Caught exception in $class->$name "$error"/; | 
| 2041 |  |  |  |  |  |  | } | 
| 2042 |  |  |  |  |  |  | $c->error($error); | 
| 2043 | 9112 | 100 |  |  |  | 18338 | } | 
| 2044 | 1 |  |  |  |  | 30 | #$c->state(0); | 
| 2045 | 1 | 50 |  |  |  | 7 | } | 
| 2046 | 1 |  |  |  |  | 25 | return $c->state; | 
| 2047 | 1 |  |  |  |  | 8 | } | 
| 2048 | 1 |  |  |  |  | 8 |  | 
| 2049 | 1 |  |  |  |  | 28 | my ( $c, $code ) = @_; | 
| 2050 | 1 |  |  |  |  | 61 | my $appclass = ref($c) || $c; | 
| 2051 |  |  |  |  |  |  | return if ( ( $code->name =~ /^_.*/ ) | 
| 2052 |  |  |  |  |  |  | && ( !$appclass->config->{show_internal_actions} ) ); | 
| 2053 | 9111 | 100 |  |  |  | 20226 |  | 
| 2054 |  |  |  |  |  |  | my $action_name = $code->reverse(); | 
| 2055 | 9111 |  |  |  |  | 11033 | $c->counter->{$action_name}++; | 
|  | 9111 |  |  |  |  | 166443 |  | 
| 2056 |  |  |  |  |  |  |  | 
| 2057 | 163 |  |  | 163 |  | 1353 | my $action = $action_name; | 
|  | 163 |  |  |  |  | 437 |  | 
|  | 163 |  |  |  |  | 36729 |  | 
| 2058 |  |  |  |  |  |  | $action = "/$action" unless $action =~ /->/; | 
| 2059 |  |  |  |  |  |  |  | 
| 2060 | 9111 |  | 100 |  |  | 12276 | # determine if the call was the result of a forward | 
|  | 9111 |  |  |  |  | 11203 |  | 
|  | 8985 |  |  |  |  | 233805 |  | 
| 2061 |  |  |  |  |  |  | # this is done by walking up the call stack and looking for a calling | 
| 2062 | 9108 | 100 | 100 |  |  | 16798 | # sub of Catalyst::forward before the eval | 
| 2063 |  |  |  |  |  |  | my $callsub = q{}; | 
| 2064 | 9108 |  |  |  |  | 10893 | for my $index ( 2 .. 11 ) { | 
|  | 9108 |  |  |  |  | 165467 |  | 
| 2065 |  |  |  |  |  |  | last | 
| 2066 | 9108 | 100 |  |  |  | 19075 | if ( ( caller($index) )[0] eq 'Catalyst' | 
| 2067 |  |  |  |  |  |  | && ( caller($index) )[3] eq '(eval)' ); | 
| 2068 | 123 | 100 |  |  |  | 393 |  | 
| 2069 | 9 |  |  |  |  | 14 | if ( ( caller($index) )[3] =~ /forward$/ ) { | 
|  | 9 |  |  |  |  | 18 |  | 
| 2070 | 0 |  |  |  |  | 0 | $callsub = ( caller($index) )[3]; | 
| 2071 |  |  |  |  |  |  | $action  = "-> $action"; | 
| 2072 | 9 |  |  |  |  | 22 | last; | 
| 2073 | 9 | 50 |  |  |  | 23 | } | 
| 2074 |  |  |  |  |  |  | } | 
| 2075 | 9 | 50 |  |  |  | 256 |  | 
| 2076 |  |  |  |  |  |  | my $uid = $action_name . $c->counter->{$action_name}; | 
| 2077 | 114 | 100 | 100 |  |  | 1021 |  | 
|  |  | 100 | 100 |  |  |  |  | 
| 2078 | 27 | 100 |  |  |  | 63 | # is this a root-level call or a forwarded call? | 
| 2079 |  |  |  |  |  |  | if ( $callsub =~ /forward$/ ) { | 
| 2080 |  |  |  |  |  |  | my $parent = $c->stack->[-1]; | 
| 2081 | 66 | 100 |  |  |  | 142 |  | 
| 2082 |  |  |  |  |  |  | # forward, locate the caller | 
| 2083 |  |  |  |  |  |  | if ( defined $parent && exists $c->counter->{"$parent"} ) { | 
| 2084 | 21 | 100 |  |  |  | 76 | $c->stats->profile( | 
| 2085 | 163 |  |  | 163 |  | 1269 | begin  => $action, | 
|  | 163 |  |  |  |  | 562 |  | 
|  | 163 |  |  |  |  | 1357888 |  | 
| 2086 | 13 |  |  |  |  | 35 | parent => "$parent" . $c->counter->{"$parent"}, | 
| 2087 | 13 |  |  |  |  | 370 | uid    => $uid, | 
| 2088 | 13 |  |  |  |  | 320 | ); | 
| 2089 | 13 |  |  |  |  | 84 | } | 
| 2090 |  |  |  |  |  |  | else { | 
| 2091 | 21 |  |  |  |  | 78 |  | 
| 2092 |  |  |  |  |  |  | # forward with no caller may come from a plugin | 
| 2093 |  |  |  |  |  |  | $c->stats->profile( | 
| 2094 |  |  |  |  |  |  | begin => $action, | 
| 2095 | 9031 |  |  |  |  | 164079 | uid   => $uid, | 
| 2096 |  |  |  |  |  |  | ); | 
| 2097 |  |  |  |  |  |  | } | 
| 2098 |  |  |  |  |  |  | } | 
| 2099 | 111 |  |  | 111 |  | 167 | else { | 
| 2100 | 111 |  | 33 |  |  | 228 |  | 
| 2101 |  |  |  |  |  |  | # root-level call | 
| 2102 | 111 | 100 | 100 |  |  | 2320 | $c->stats->profile( | 
| 2103 |  |  |  |  |  |  | begin => $action, | 
| 2104 | 29 |  |  |  |  | 656 | uid   => $uid, | 
| 2105 | 29 |  |  |  |  | 617 | ); | 
| 2106 |  |  |  |  |  |  | } | 
| 2107 | 29 |  |  |  |  | 46 | return $action; | 
| 2108 | 29 | 50 |  |  |  | 98 |  | 
| 2109 |  |  |  |  |  |  | } | 
| 2110 |  |  |  |  |  |  |  | 
| 2111 |  |  |  |  |  |  | my ( $c, $info ) = @_; | 
| 2112 |  |  |  |  |  |  | $c->stats->profile( end => $info ); | 
| 2113 | 29 |  |  |  |  | 48 | } | 
| 2114 | 29 |  |  |  |  | 65 |  | 
| 2115 |  |  |  |  |  |  | =head2 $c->finalize | 
| 2116 | 111 | 100 | 100 |  |  | 580 |  | 
| 2117 |  |  |  |  |  |  | Finalizes the request. | 
| 2118 |  |  |  |  |  |  |  | 
| 2119 | 87 | 100 |  |  |  | 356 | =cut | 
| 2120 | 5 |  |  |  |  | 15 |  | 
| 2121 | 5 |  |  |  |  | 11 | my $c = shift; | 
| 2122 | 5 |  |  |  |  | 7 |  | 
| 2123 |  |  |  |  |  |  | for my $error ( @{ $c->error } ) { | 
| 2124 |  |  |  |  |  |  | $c->log->error($error); | 
| 2125 |  |  |  |  |  |  | } | 
| 2126 | 29 |  |  |  |  | 649 |  | 
| 2127 |  |  |  |  |  |  | # Support skipping finalize for psgix.io style 'jailbreak'.  Used to support | 
| 2128 |  |  |  |  |  |  | # stuff like cometd and websockets | 
| 2129 | 29 | 100 |  |  |  | 75 |  | 
| 2130 | 5 |  |  |  |  | 93 | if($c->request->_has_io_fh) { | 
| 2131 |  |  |  |  |  |  | $c->log_response; | 
| 2132 |  |  |  |  |  |  | return; | 
| 2133 | 5 | 100 | 66 |  |  | 82 | } | 
| 2134 |  |  |  |  |  |  |  | 
| 2135 |  |  |  |  |  |  | # Allow engine to handle finalize flow (for POE) | 
| 2136 | 4 |  |  |  |  | 77 | my $engine = $c->engine; | 
| 2137 |  |  |  |  |  |  | if ( my $code = $engine->can('finalize') ) { | 
| 2138 |  |  |  |  |  |  | $engine->$code($c); | 
| 2139 |  |  |  |  |  |  | } | 
| 2140 |  |  |  |  |  |  | else { | 
| 2141 |  |  |  |  |  |  |  | 
| 2142 |  |  |  |  |  |  | $c->finalize_uploads; | 
| 2143 | 1 |  |  |  |  | 20 |  | 
| 2144 |  |  |  |  |  |  | # Error | 
| 2145 |  |  |  |  |  |  | if ( $#{ $c->error } >= 0 ) { | 
| 2146 |  |  |  |  |  |  | $c->finalize_error; | 
| 2147 |  |  |  |  |  |  | } | 
| 2148 |  |  |  |  |  |  |  | 
| 2149 |  |  |  |  |  |  | $c->finalize_encoding; | 
| 2150 |  |  |  |  |  |  | $c->finalize_headers unless $c->response->finalized_headers; | 
| 2151 |  |  |  |  |  |  | $c->finalize_body; | 
| 2152 | 24 |  |  |  |  | 496 | } | 
| 2153 |  |  |  |  |  |  |  | 
| 2154 |  |  |  |  |  |  | $c->log_response; | 
| 2155 |  |  |  |  |  |  |  | 
| 2156 |  |  |  |  |  |  | $c->log_stats if $c->use_stats; | 
| 2157 | 29 |  |  |  |  | 156 |  | 
| 2158 |  |  |  |  |  |  | return $c->response->status; | 
| 2159 |  |  |  |  |  |  | } | 
| 2160 |  |  |  |  |  |  |  | 
| 2161 |  |  |  |  |  |  | =head2 $c->log_stats | 
| 2162 | 29 |  |  | 29 |  | 63 |  | 
| 2163 | 29 |  |  |  |  | 572 | Logs statistics. | 
| 2164 |  |  |  |  |  |  |  | 
| 2165 |  |  |  |  |  |  | =cut | 
| 2166 |  |  |  |  |  |  |  | 
| 2167 |  |  |  |  |  |  | my $c = shift; | 
| 2168 |  |  |  |  |  |  |  | 
| 2169 |  |  |  |  |  |  | my $elapsed = $c->stats->elapsed; | 
| 2170 |  |  |  |  |  |  | my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed; | 
| 2171 |  |  |  |  |  |  | $c->log->info( | 
| 2172 |  |  |  |  |  |  | "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" ); | 
| 2173 | 918 |  |  | 918 | 1 | 1718 | } | 
| 2174 |  |  |  |  |  |  |  | 
| 2175 | 918 |  |  |  |  | 1295 |  | 
|  | 918 |  |  |  |  | 2021 |  | 
| 2176 | 37 |  |  |  |  | 153 | =head2 $c->finalize_body | 
| 2177 |  |  |  |  |  |  |  | 
| 2178 |  |  |  |  |  |  | Finalizes body. | 
| 2179 |  |  |  |  |  |  |  | 
| 2180 |  |  |  |  |  |  | =cut | 
| 2181 |  |  |  |  |  |  |  | 
| 2182 | 918 | 50 |  |  |  | 19727 |  | 
| 2183 | 0 |  |  |  |  | 0 | =head2 $c->finalize_cookies | 
| 2184 | 0 |  |  |  |  | 0 |  | 
| 2185 |  |  |  |  |  |  | Finalizes cookies. | 
| 2186 |  |  |  |  |  |  |  | 
| 2187 |  |  |  |  |  |  | =cut | 
| 2188 | 918 |  |  |  |  | 3128 |  | 
| 2189 | 918 | 50 |  |  |  | 4918 |  | 
| 2190 | 0 |  |  |  |  | 0 | =head2 $c->finalize_error | 
| 2191 |  |  |  |  |  |  |  | 
| 2192 |  |  |  |  |  |  | Finalizes error.  If there is only one error in L</error> and it is an object that | 
| 2193 |  |  |  |  |  |  | does C<as_psgi> or C<code> we rethrow the error and presume it caught by middleware | 
| 2194 | 918 |  |  |  |  | 3518 | up the ladder.  Otherwise we return the debugging error page (in debug mode) or we | 
| 2195 |  |  |  |  |  |  | return the default error page (production mode). | 
| 2196 |  |  |  |  |  |  |  | 
| 2197 | 918 | 100 |  |  |  | 1457 | =cut | 
|  | 918 |  |  |  |  | 2315 |  | 
| 2198 | 34 |  |  |  |  | 199 |  | 
| 2199 |  |  |  |  |  |  | my $c = shift; | 
| 2200 |  |  |  |  |  |  | if($#{$c->error} > 0) { | 
| 2201 | 918 |  |  |  |  | 3570 | $c->engine->finalize_error( $c, @_ ); | 
| 2202 | 918 | 100 |  |  |  | 27057 | } else { | 
| 2203 | 918 |  |  |  |  | 3413 | my ($error) = @{$c->error}; | 
| 2204 |  |  |  |  |  |  | if ( $c->_handle_http_exception($error) ) { | 
| 2205 |  |  |  |  |  |  | # In the case where the error 'knows what it wants', becauses its PSGI | 
| 2206 | 918 |  |  |  |  | 4033 | # aware, just rethow and let middleware catch it | 
| 2207 |  |  |  |  |  |  | $error->can('rethrow') ? $error->rethrow : croak $error; | 
| 2208 | 918 | 100 |  |  |  | 2254 | } else { | 
| 2209 |  |  |  |  |  |  | $c->engine->finalize_error( $c, @_ ) | 
| 2210 | 918 |  |  |  |  | 19975 | } | 
| 2211 |  |  |  |  |  |  | } | 
| 2212 |  |  |  |  |  |  | } | 
| 2213 |  |  |  |  |  |  |  | 
| 2214 |  |  |  |  |  |  | =head2 $c->finalize_headers | 
| 2215 |  |  |  |  |  |  |  | 
| 2216 |  |  |  |  |  |  | Finalizes headers. | 
| 2217 |  |  |  |  |  |  |  | 
| 2218 |  |  |  |  |  |  | =cut | 
| 2219 |  |  |  |  |  |  |  | 
| 2220 | 15 |  |  | 15 | 1 | 28 | my $c = shift; | 
| 2221 |  |  |  |  |  |  |  | 
| 2222 | 15 |  |  |  |  | 295 | my $response = $c->response; #accessor calls can add up? | 
| 2223 | 15 | 50 |  |  |  | 378 |  | 
| 2224 | 15 |  |  |  |  | 75 | # Check if we already finalized headers | 
| 2225 |  |  |  |  |  |  | return if $response->finalized_headers; | 
| 2226 |  |  |  |  |  |  |  | 
| 2227 |  |  |  |  |  |  | # Handle redirects | 
| 2228 |  |  |  |  |  |  | if ( my $location = $response->redirect ) { | 
| 2229 |  |  |  |  |  |  | $c->log->debug(qq/Redirecting to "$location"/) if $c->debug; | 
| 2230 |  |  |  |  |  |  | $response->header( Location => $location ); | 
| 2231 |  |  |  |  |  |  | } | 
| 2232 |  |  |  |  |  |  |  | 
| 2233 |  |  |  |  |  |  | # Remove incorrectly added body and content related meta data when returning | 
| 2234 |  |  |  |  |  |  | # an information response, or a response the is required to not include a body | 
| 2235 | 918 |  |  | 918 | 1 | 1545 |  | 
|  | 918 |  |  |  |  | 2286 |  | 
| 2236 |  |  |  |  |  |  | $c->finalize_cookies; | 
| 2237 |  |  |  |  |  |  |  | 
| 2238 |  |  |  |  |  |  | # This currently is a NOOP but I don't want to remove it since I guess people | 
| 2239 |  |  |  |  |  |  | # might have Response subclasses that use it for something... (JNAP) | 
| 2240 |  |  |  |  |  |  | $c->response->finalize_headers(); | 
| 2241 |  |  |  |  |  |  |  | 
| 2242 |  |  |  |  |  |  | # Done | 
| 2243 | 918 |  |  | 918 | 1 | 1455 | $response->finalized_headers(1); | 
|  | 918 |  |  |  |  | 2660 |  | 
| 2244 |  |  |  |  |  |  | } | 
| 2245 |  |  |  |  |  |  |  | 
| 2246 |  |  |  |  |  |  | =head2 $c->finalize_encoding | 
| 2247 |  |  |  |  |  |  |  | 
| 2248 |  |  |  |  |  |  | Make sure your body is encoded properly IF you set an encoding.  By | 
| 2249 |  |  |  |  |  |  | default the encoding is UTF-8 but you can disable it by explicitly setting the | 
| 2250 |  |  |  |  |  |  | encoding configuration value to undef. | 
| 2251 |  |  |  |  |  |  |  | 
| 2252 |  |  |  |  |  |  | We can only encode when the body is a scalar.  Methods for encoding via the | 
| 2253 |  |  |  |  |  |  | streaming interfaces (such as C<write> and C<write_fh> on L<Catalyst::Response> | 
| 2254 |  |  |  |  |  |  | are available). | 
| 2255 | 34 |  |  | 34 | 1 | 313 |  | 
| 2256 | 34 | 100 |  |  |  | 54 | See L</ENCODING>. | 
|  | 34 |  |  |  |  | 86 |  | 
| 2257 | 3 |  |  |  |  | 19 |  | 
| 2258 |  |  |  |  |  |  | =cut | 
| 2259 | 31 |  |  |  |  | 60 |  | 
|  | 31 |  |  |  |  | 95 |  | 
| 2260 | 31 | 50 |  |  |  | 163 | my $c = shift; | 
| 2261 |  |  |  |  |  |  | my $res = $c->res || return; | 
| 2262 |  |  |  |  |  |  |  | 
| 2263 | 0 | 0 |  |  |  | 0 | # Warn if the set charset is different from the one you put into encoding.  We need | 
| 2264 |  |  |  |  |  |  | # to do this early since encodable_response is false for this condition and we need | 
| 2265 | 31 |  |  |  |  | 124 | # to match the debug output for backcompat (there's a test for this...) -JNAP | 
| 2266 |  |  |  |  |  |  | if( | 
| 2267 |  |  |  |  |  |  | $res->content_type_charset and $c->encoding and | 
| 2268 |  |  |  |  |  |  | (uc($c->encoding->mime_name) ne uc($res->content_type_charset)) | 
| 2269 |  |  |  |  |  |  | ) { | 
| 2270 |  |  |  |  |  |  | my $ct = lc($res->content_type_charset); | 
| 2271 |  |  |  |  |  |  | $c->log->debug("Catalyst encoding config is set to encode in '" . | 
| 2272 |  |  |  |  |  |  | $c->encoding->mime_name . | 
| 2273 |  |  |  |  |  |  | "', content type is '$ct', not encoding "); | 
| 2274 |  |  |  |  |  |  | } | 
| 2275 |  |  |  |  |  |  |  | 
| 2276 |  |  |  |  |  |  | if( | 
| 2277 | 918 |  |  | 918 | 1 | 7715 | ($res->encodable_response) and | 
| 2278 |  |  |  |  |  |  | (defined($res->body)) and | 
| 2279 | 918 |  |  |  |  | 19877 | (ref(\$res->body) eq 'SCALAR') | 
| 2280 |  |  |  |  |  |  | ) { | 
| 2281 |  |  |  |  |  |  | # if you are finding yourself here and your body is already encoded correctly | 
| 2282 | 918 | 50 |  |  |  | 21434 | # and you want to turn this off, use $c->clear_encoding to prevent encoding | 
| 2283 |  |  |  |  |  |  | # at this step, or set encoding to undef in the config to do so for the whole | 
| 2284 |  |  |  |  |  |  | # application.  See the ENCODING documentaiton for better notes. | 
| 2285 | 918 | 100 |  |  |  | 3670 | $c->res->body( $c->encoding->encode( $c->res->body, $c->_encode_check ) ); | 
| 2286 | 14 | 50 |  |  |  | 48 |  | 
| 2287 | 14 |  |  |  |  | 39 | # Set the charset if necessary.  This might be a bit bonkers since encodable response | 
| 2288 |  |  |  |  |  |  | # is false when the set charset is not the same as the encoding mimetype (maybe | 
| 2289 |  |  |  |  |  |  | # confusing action at a distance here.. | 
| 2290 |  |  |  |  |  |  | # Don't try to set the charset if one already exists or if headers are already finalized | 
| 2291 |  |  |  |  |  |  | $c->res->content_type($c->res->content_type . "; charset=" . $c->encoding->mime_name) | 
| 2292 |  |  |  |  |  |  | unless($c->res->content_type_charset || | 
| 2293 | 918 |  |  |  |  | 4042 | ($c->res->_context && $c->res->finalized_headers && !$c->res->_has_response_cb)); | 
| 2294 |  |  |  |  |  |  | } | 
| 2295 |  |  |  |  |  |  | } | 
| 2296 |  |  |  |  |  |  |  | 
| 2297 | 918 |  |  |  |  | 18223 | =head2 $c->finalize_output | 
| 2298 |  |  |  |  |  |  |  | 
| 2299 |  |  |  |  |  |  | An alias for finalize_body. | 
| 2300 | 918 |  |  |  |  | 21284 |  | 
| 2301 |  |  |  |  |  |  | =head2 $c->finalize_read | 
| 2302 |  |  |  |  |  |  |  | 
| 2303 |  |  |  |  |  |  | Finalizes the input after reading is complete. | 
| 2304 |  |  |  |  |  |  |  | 
| 2305 |  |  |  |  |  |  | =cut | 
| 2306 |  |  |  |  |  |  |  | 
| 2307 |  |  |  |  |  |  |  | 
| 2308 |  |  |  |  |  |  | =head2 $c->finalize_uploads | 
| 2309 |  |  |  |  |  |  |  | 
| 2310 |  |  |  |  |  |  | Finalizes uploads. Cleans up any temporary files. | 
| 2311 |  |  |  |  |  |  |  | 
| 2312 |  |  |  |  |  |  | =cut | 
| 2313 |  |  |  |  |  |  |  | 
| 2314 |  |  |  |  |  |  |  | 
| 2315 |  |  |  |  |  |  | =head2 $c->get_action( $action, $namespace ) | 
| 2316 |  |  |  |  |  |  |  | 
| 2317 |  |  |  |  |  |  | Gets an action in a given namespace. | 
| 2318 | 918 |  |  | 918 | 1 | 1470 |  | 
| 2319 | 918 |  | 50 |  |  | 2179 | =cut | 
| 2320 |  |  |  |  |  |  |  | 
| 2321 |  |  |  |  |  |  |  | 
| 2322 |  |  |  |  |  |  | =head2 $c->get_actions( $action, $namespace ) | 
| 2323 |  |  |  |  |  |  |  | 
| 2324 | 918 | 100 | 100 |  |  | 4853 | Gets all actions of a given name in a namespace and all parent | 
|  |  |  | 100 |  |  |  |  | 
| 2325 |  |  |  |  |  |  | namespaces. | 
| 2326 |  |  |  |  |  |  |  | 
| 2327 |  |  |  |  |  |  | =cut | 
| 2328 | 2 |  |  |  |  | 187 |  | 
| 2329 | 2 |  |  |  |  | 175 |  | 
| 2330 |  |  |  |  |  |  | =head2 $app->handle_request( @arguments ) | 
| 2331 |  |  |  |  |  |  |  | 
| 2332 |  |  |  |  |  |  | Called to handle each HTTP request. | 
| 2333 |  |  |  |  |  |  |  | 
| 2334 | 918 | 100 | 100 |  |  | 176280 | =cut | 
|  |  |  | 100 |  |  |  |  | 
| 2335 |  |  |  |  |  |  |  | 
| 2336 |  |  |  |  |  |  | my ( $class, @arguments ) = @_; | 
| 2337 |  |  |  |  |  |  |  | 
| 2338 |  |  |  |  |  |  | # Always expect worst case! | 
| 2339 |  |  |  |  |  |  | my $status = -1; | 
| 2340 |  |  |  |  |  |  | try { | 
| 2341 |  |  |  |  |  |  | if ($class->debug) { | 
| 2342 |  |  |  |  |  |  | my $secs = time - $START || 1; | 
| 2343 | 203 |  |  |  |  | 659 | my $av = sprintf '%.3f', $COUNT / $secs; | 
| 2344 |  |  |  |  |  |  | my $time = localtime time; | 
| 2345 |  |  |  |  |  |  | $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***"); | 
| 2346 |  |  |  |  |  |  | } | 
| 2347 |  |  |  |  |  |  |  | 
| 2348 |  |  |  |  |  |  | my $c = $class->prepare(@arguments); | 
| 2349 | 203 | 100 | 66 |  |  | 867 | $c->dispatch; | 
|  |  |  | 66 |  |  |  |  | 
|  |  |  | 100 |  |  |  |  | 
| 2350 |  |  |  |  |  |  | $status = $c->finalize; | 
| 2351 |  |  |  |  |  |  | } catch { | 
| 2352 |  |  |  |  |  |  | #rethow if this can be handled by middleware | 
| 2353 |  |  |  |  |  |  | if ( $class->_handle_http_exception($_) ) { | 
| 2354 |  |  |  |  |  |  | $_->can('rethrow') ? $_->rethrow : croak $_; | 
| 2355 |  |  |  |  |  |  | } | 
| 2356 |  |  |  |  |  |  | chomp(my $error = $_); | 
| 2357 |  |  |  |  |  |  | $class->log->error(qq/Caught exception in engine "$error"/); | 
| 2358 |  |  |  |  |  |  | }; | 
| 2359 |  |  |  |  |  |  |  | 
| 2360 |  |  |  |  |  |  | $COUNT++; | 
| 2361 |  |  |  |  |  |  |  | 
| 2362 |  |  |  |  |  |  | if(my $coderef = $class->log->can('_flush')){ | 
| 2363 |  |  |  |  |  |  | $class->log->$coderef(); | 
| 2364 |  |  |  |  |  |  | } | 
| 2365 | 0 |  |  | 0 | 1 | 0 | return $status; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2366 |  |  |  |  |  |  | } | 
| 2367 |  |  |  |  |  |  |  | 
| 2368 |  |  |  |  |  |  | =head2 $class->prepare( @arguments ) | 
| 2369 |  |  |  |  |  |  |  | 
| 2370 |  |  |  |  |  |  | Creates a Catalyst context from an engine-specific request (Apache, CGI, | 
| 2371 |  |  |  |  |  |  | etc.). | 
| 2372 |  |  |  |  |  |  |  | 
| 2373 | 918 |  |  | 918 | 1 | 1479 | =cut | 
|  | 918 |  |  |  |  | 1937 |  | 
| 2374 |  |  |  |  |  |  |  | 
| 2375 |  |  |  |  |  |  | has _uploadtmp => ( | 
| 2376 |  |  |  |  |  |  | is => 'ro', | 
| 2377 |  |  |  |  |  |  | predicate => '_has_uploadtmp', | 
| 2378 |  |  |  |  |  |  | ); | 
| 2379 |  |  |  |  |  |  |  | 
| 2380 |  |  |  |  |  |  | my ( $class, @arguments ) = @_; | 
| 2381 | 7753 |  |  | 7753 | 1 | 10826 |  | 
|  | 7753 |  |  |  |  | 17331 |  | 
| 2382 |  |  |  |  |  |  | # XXX | 
| 2383 |  |  |  |  |  |  | # After the app/ctxt split, this should become an attribute based on something passed | 
| 2384 |  |  |  |  |  |  | # into the application. | 
| 2385 |  |  |  |  |  |  | $class->context_class( ref $class || $class ) unless $class->context_class; | 
| 2386 |  |  |  |  |  |  |  | 
| 2387 |  |  |  |  |  |  | my $uploadtmp = $class->config->{uploadtmp}; | 
| 2388 |  |  |  |  |  |  | my $c = $class->context_class->new({ $uploadtmp ? (_uploadtmp => $uploadtmp) : ()}); | 
| 2389 |  |  |  |  |  |  |  | 
| 2390 | 2901 |  |  | 2901 | 1 | 4283 | $c->response->_context($c); | 
|  | 2901 |  |  |  |  | 6832 |  | 
| 2391 |  |  |  |  |  |  | $c->stats($class->stats_class->new)->enable($c->use_stats); | 
| 2392 |  |  |  |  |  |  |  | 
| 2393 |  |  |  |  |  |  | if ( $c->debug || $c->config->{enable_catalyst_header} ) { | 
| 2394 |  |  |  |  |  |  | $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION ); | 
| 2395 |  |  |  |  |  |  | } | 
| 2396 |  |  |  |  |  |  |  | 
| 2397 |  |  |  |  |  |  | try { | 
| 2398 |  |  |  |  |  |  | # Allow engine to direct the prepare flow (for POE) | 
| 2399 | 923 |  |  | 923 | 1 | 2979 | if ( my $prepare = $c->engine->can('prepare') ) { | 
| 2400 |  |  |  |  |  |  | $c->engine->$prepare( $c, @arguments ); | 
| 2401 |  |  |  |  |  |  | } | 
| 2402 | 923 |  |  |  |  | 1672 | else { | 
| 2403 |  |  |  |  |  |  | $c->prepare_request(@arguments); | 
| 2404 | 923 | 100 |  | 923 |  | 29168 | $c->prepare_connection; | 
| 2405 | 16 |  | 100 |  |  | 100 | $c->prepare_query_parameters; | 
| 2406 | 16 |  |  |  |  | 119 | $c->prepare_headers; # Just hooks, no longer needed - they just | 
| 2407 | 16 |  |  |  |  | 569 | $c->prepare_cookies; # cause the lazy attribute on req to build | 
| 2408 | 16 |  |  |  |  | 84 | $c->prepare_path; | 
| 2409 |  |  |  |  |  |  |  | 
| 2410 |  |  |  |  |  |  | # Prepare the body for reading, either by prepare_body | 
| 2411 | 923 |  |  |  |  | 3407 | # or the user, if they are using $c->read | 
| 2412 | 918 |  |  |  |  | 36957 | $c->prepare_read; | 
| 2413 | 914 |  |  |  |  | 4969 |  | 
| 2414 |  |  |  |  |  |  | # Parse the body unless the user wants it on-demand | 
| 2415 |  |  |  |  |  |  | unless ( ref($c)->config->{parse_on_demand} ) { | 
| 2416 | 8 | 100 |  | 8 |  | 132 | $c->prepare_body; | 
| 2417 | 4 | 50 |  |  |  | 100 | } | 
| 2418 |  |  |  |  |  |  | } | 
| 2419 | 4 |  |  |  |  | 12 | $c->prepare_action; | 
| 2420 | 4 |  |  |  |  | 14 | } | 
| 2421 | 923 |  |  |  |  | 5804 | # VERY ugly and probably shouldn't rely on ->finalize actually working | 
| 2422 |  |  |  |  |  |  | catch { | 
| 2423 | 918 |  |  |  |  | 14541 | # failed prepare is always due to an invalid request, right? | 
| 2424 |  |  |  |  |  |  | # Note we call finalize and then die here, which escapes | 
| 2425 | 918 | 100 |  |  |  | 3743 | # finalize being called in the enclosing block.. | 
| 2426 | 867 |  |  |  |  | 2248 | # It in fact couldn't be called, as we don't return $c.. | 
| 2427 |  |  |  |  |  |  | # This is a mess - but I'm unsure you can fix this without | 
| 2428 | 918 |  |  |  |  | 3292 | # breaking compat for people doing crazy things (we should set | 
| 2429 |  |  |  |  |  |  | # the 400 and just return the ctx here IMO, letting finalize get called | 
| 2430 |  |  |  |  |  |  | # above... | 
| 2431 |  |  |  |  |  |  | if ( $c->_handle_http_exception($_) ) { | 
| 2432 |  |  |  |  |  |  | foreach my $err (@{$c->error}) { | 
| 2433 |  |  |  |  |  |  | $c->log->error($err); | 
| 2434 |  |  |  |  |  |  | } | 
| 2435 |  |  |  |  |  |  | $c->clear_errors; | 
| 2436 |  |  |  |  |  |  | $c->log->_flush if $c->log->can('_flush'); | 
| 2437 |  |  |  |  |  |  | $_->can('rethrow') ? $_->rethrow : croak $_; | 
| 2438 |  |  |  |  |  |  | } else { | 
| 2439 |  |  |  |  |  |  | $c->response->status(400); | 
| 2440 |  |  |  |  |  |  | $c->response->content_type('text/plain'); | 
| 2441 |  |  |  |  |  |  | $c->response->body('Bad Request'); | 
| 2442 |  |  |  |  |  |  | $c->finalize; | 
| 2443 |  |  |  |  |  |  | die $_; | 
| 2444 | 923 |  |  | 923 | 1 | 16957 | } | 
| 2445 |  |  |  |  |  |  | }; | 
| 2446 |  |  |  |  |  |  |  | 
| 2447 |  |  |  |  |  |  | $c->log_request; | 
| 2448 |  |  |  |  |  |  | $c->{stash} = $c->stash; | 
| 2449 | 923 | 100 | 33 |  |  | 3784 | Scalar::Util::weaken($c->{stash}); | 
| 2450 |  |  |  |  |  |  |  | 
| 2451 | 923 |  |  |  |  | 3279 | return $c; | 
| 2452 | 923 | 100 |  |  |  | 2740 | } | 
| 2453 |  |  |  |  |  |  |  | 
| 2454 | 923 |  |  |  |  | 94947 | =head2 $c->prepare_action | 
| 2455 | 923 |  |  |  |  | 3909 |  | 
| 2456 |  |  |  |  |  |  | Prepares action. See L<Catalyst::Dispatcher>. | 
| 2457 | 923 | 100 | 66 |  |  | 2937 |  | 
| 2458 | 16 |  |  |  |  | 104 | =cut | 
| 2459 |  |  |  |  |  |  |  | 
| 2460 |  |  |  |  |  |  | my $c = shift; | 
| 2461 |  |  |  |  |  |  | my $ret = $c->dispatcher->prepare_action( $c, @_); | 
| 2462 |  |  |  |  |  |  |  | 
| 2463 | 923 | 50 |  | 923 |  | 35890 | if($c->encoding) { | 
| 2464 | 0 |  |  |  |  | 0 | foreach (@{$c->req->arguments}, @{$c->req->captures}) { | 
| 2465 |  |  |  |  |  |  | $_ = $c->_handle_param_unicode_decoding($_); | 
| 2466 |  |  |  |  |  |  | } | 
| 2467 | 923 |  |  |  |  | 4276 | } | 
| 2468 | 923 |  |  |  |  | 3515 |  | 
| 2469 | 923 |  |  |  |  | 3258 | return $ret; | 
| 2470 | 922 |  |  |  |  | 13963 | } | 
| 2471 | 922 |  |  |  |  | 3257 |  | 
| 2472 | 922 |  |  |  |  | 3453 |  | 
| 2473 |  |  |  |  |  |  | =head2 $c->prepare_body | 
| 2474 |  |  |  |  |  |  |  | 
| 2475 |  |  |  |  |  |  | Prepares message body. | 
| 2476 | 922 |  |  |  |  | 3337 |  | 
| 2477 |  |  |  |  |  |  | =cut | 
| 2478 |  |  |  |  |  |  |  | 
| 2479 | 922 | 100 |  |  |  | 3647 | my $c = shift; | 
| 2480 | 919 |  |  |  |  | 3344 |  | 
| 2481 |  |  |  |  |  |  | return if $c->request->_has_body; | 
| 2482 |  |  |  |  |  |  |  | 
| 2483 | 920 |  |  |  |  | 3788 | # Initialize on-demand data | 
| 2484 |  |  |  |  |  |  | $c->engine->prepare_body( $c, @_ ); | 
| 2485 |  |  |  |  |  |  | $c->prepare_parameters; | 
| 2486 |  |  |  |  |  |  | $c->prepare_uploads; | 
| 2487 |  |  |  |  |  |  | } | 
| 2488 |  |  |  |  |  |  |  | 
| 2489 |  |  |  |  |  |  | =head2 $c->prepare_body_chunk( $chunk ) | 
| 2490 |  |  |  |  |  |  |  | 
| 2491 |  |  |  |  |  |  | Prepares a chunk of data before sending it to L<HTTP::Body>. | 
| 2492 |  |  |  |  |  |  |  | 
| 2493 |  |  |  |  |  |  | See L<Catalyst::Engine>. | 
| 2494 |  |  |  |  |  |  |  | 
| 2495 | 5 | 100 |  | 5 |  | 141 | =cut | 
| 2496 | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 18 |  | 
| 2497 | 0 |  |  |  |  | 0 | my $c = shift; | 
| 2498 |  |  |  |  |  |  | $c->engine->prepare_body_chunk( $c, @_ ); | 
| 2499 | 1 |  |  |  |  | 8 | } | 
| 2500 | 1 | 50 |  |  |  | 4 |  | 
| 2501 | 1 | 50 |  |  |  | 48 | =head2 $c->prepare_body_parameters | 
| 2502 |  |  |  |  |  |  |  | 
| 2503 | 4 |  |  |  |  | 119 | Prepares body parameters. | 
| 2504 | 4 |  |  |  |  | 78 |  | 
| 2505 | 4 |  |  |  |  | 141 | =cut | 
| 2506 | 4 |  |  |  |  | 21 |  | 
| 2507 | 4 |  |  |  |  | 30 | my $c = shift; | 
| 2508 |  |  |  |  |  |  | $c->request->prepare_body_parameters( $c, @_ ); | 
| 2509 | 923 |  |  |  |  | 9294 | } | 
| 2510 |  |  |  |  |  |  |  | 
| 2511 | 918 |  |  |  |  | 55271 | =head2 $c->prepare_connection | 
| 2512 | 918 |  |  |  |  | 2543 |  | 
| 2513 | 918 |  |  |  |  | 3108 | Prepares connection. | 
| 2514 |  |  |  |  |  |  |  | 
| 2515 | 918 |  |  |  |  | 2612 | =cut | 
| 2516 |  |  |  |  |  |  |  | 
| 2517 |  |  |  |  |  |  | my $c = shift; | 
| 2518 |  |  |  |  |  |  | $c->request->prepare_connection($c); | 
| 2519 |  |  |  |  |  |  | } | 
| 2520 |  |  |  |  |  |  |  | 
| 2521 |  |  |  |  |  |  | =head2 $c->prepare_cookies | 
| 2522 |  |  |  |  |  |  |  | 
| 2523 |  |  |  |  |  |  | Prepares cookies by ensuring that the attribute on the request | 
| 2524 |  |  |  |  |  |  | object has been built. | 
| 2525 | 920 |  |  | 920 | 1 | 5679 |  | 
| 2526 | 920 |  |  |  |  | 3155 | =cut | 
| 2527 |  |  |  |  |  |  |  | 
| 2528 | 920 | 100 |  |  |  | 2420 |  | 
| 2529 | 919 |  |  |  |  | 1545 | =head2 $c->prepare_headers | 
|  | 919 |  |  |  |  | 2387 |  | 
|  | 919 |  |  |  |  | 2268 |  | 
| 2530 | 780 |  |  |  |  | 6318 |  | 
| 2531 |  |  |  |  |  |  | Prepares request headers by ensuring that the attribute on the request | 
| 2532 |  |  |  |  |  |  | object has been built. | 
| 2533 |  |  |  |  |  |  |  | 
| 2534 | 918 |  |  |  |  | 10769 | =cut | 
| 2535 |  |  |  |  |  |  |  | 
| 2536 |  |  |  |  |  |  |  | 
| 2537 |  |  |  |  |  |  | =head2 $c->prepare_parameters | 
| 2538 |  |  |  |  |  |  |  | 
| 2539 |  |  |  |  |  |  | Prepares parameters. | 
| 2540 |  |  |  |  |  |  |  | 
| 2541 |  |  |  |  |  |  | =cut | 
| 2542 |  |  |  |  |  |  |  | 
| 2543 |  |  |  |  |  |  | my $c = shift; | 
| 2544 |  |  |  |  |  |  | $c->prepare_body_parameters; | 
| 2545 | 1021 |  |  | 1021 | 1 | 2952 | $c->engine->prepare_parameters( $c, @_ ); | 
| 2546 |  |  |  |  |  |  | } | 
| 2547 | 1021 | 100 |  |  |  | 23562 |  | 
| 2548 |  |  |  |  |  |  | =head2 $c->prepare_path | 
| 2549 |  |  |  |  |  |  |  | 
| 2550 | 920 |  |  |  |  | 2863 | Prepares path and base. | 
| 2551 | 919 |  |  |  |  | 3679 |  | 
| 2552 | 918 |  |  |  |  | 3270 | =cut | 
| 2553 |  |  |  |  |  |  |  | 
| 2554 |  |  |  |  |  |  |  | 
| 2555 |  |  |  |  |  |  | =head2 $c->prepare_query_parameters | 
| 2556 |  |  |  |  |  |  |  | 
| 2557 |  |  |  |  |  |  | Prepares query parameters. | 
| 2558 |  |  |  |  |  |  |  | 
| 2559 |  |  |  |  |  |  | =cut | 
| 2560 |  |  |  |  |  |  |  | 
| 2561 |  |  |  |  |  |  | my $c = shift; | 
| 2562 |  |  |  |  |  |  |  | 
| 2563 |  |  |  |  |  |  | $c->engine->prepare_query_parameters( $c, @_ ); | 
| 2564 | 0 |  |  | 0 | 1 | 0 | } | 
| 2565 | 0 |  |  |  |  | 0 |  | 
| 2566 |  |  |  |  |  |  | =head2 $c->log_request | 
| 2567 |  |  |  |  |  |  |  | 
| 2568 |  |  |  |  |  |  | Writes information about the request to the debug logs.  This includes: | 
| 2569 |  |  |  |  |  |  |  | 
| 2570 |  |  |  |  |  |  | =over 4 | 
| 2571 |  |  |  |  |  |  |  | 
| 2572 |  |  |  |  |  |  | =item * Request method, path, and remote IP address | 
| 2573 |  |  |  |  |  |  |  | 
| 2574 |  |  |  |  |  |  | =item * Query keywords (see L<Catalyst::Request/query_keywords>) | 
| 2575 | 920 |  |  | 920 | 1 | 1372 |  | 
| 2576 | 920 |  |  |  |  | 17915 | =item * Request parameters | 
| 2577 |  |  |  |  |  |  |  | 
| 2578 |  |  |  |  |  |  | =item * File uploads | 
| 2579 |  |  |  |  |  |  |  | 
| 2580 |  |  |  |  |  |  | =back | 
| 2581 |  |  |  |  |  |  |  | 
| 2582 |  |  |  |  |  |  | =cut | 
| 2583 |  |  |  |  |  |  |  | 
| 2584 |  |  |  |  |  |  | my $c = shift; | 
| 2585 |  |  |  |  |  |  |  | 
| 2586 | 923 |  |  | 923 | 1 | 1470 | return unless $c->debug; | 
| 2587 | 923 |  |  |  |  | 18271 |  | 
| 2588 |  |  |  |  |  |  | my($dump) = grep {$_->[0] eq 'Request' } $c->dump_these; | 
| 2589 |  |  |  |  |  |  | my $request = $dump->[1]; | 
| 2590 |  |  |  |  |  |  |  | 
| 2591 |  |  |  |  |  |  | my ( $method, $path, $address ) = ( $request->method, $request->path, $request->address ); | 
| 2592 |  |  |  |  |  |  | $method ||= ''; | 
| 2593 |  |  |  |  |  |  | $path = '/' unless length $path; | 
| 2594 |  |  |  |  |  |  | $address ||= ''; | 
| 2595 |  |  |  |  |  |  |  | 
| 2596 |  |  |  |  |  |  | $path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; | 
| 2597 | 922 |  |  | 922 | 1 | 1501 | $path = decode_utf8($path); | 
|  | 922 |  |  |  |  | 19438 |  | 
| 2598 |  |  |  |  |  |  |  | 
| 2599 |  |  |  |  |  |  | $c->log->debug(qq/"$method" request for "$path" from "$address"/); | 
| 2600 |  |  |  |  |  |  |  | 
| 2601 |  |  |  |  |  |  | $c->log_request_headers($request->headers); | 
| 2602 |  |  |  |  |  |  |  | 
| 2603 |  |  |  |  |  |  | if ( my $keywords = $request->query_keywords ) { | 
| 2604 |  |  |  |  |  |  | $c->log->debug("Query keywords are: $keywords"); | 
| 2605 |  |  |  |  |  |  | } | 
| 2606 | 922 |  |  | 922 | 1 | 1546 |  | 
|  | 922 |  |  |  |  | 19120 |  | 
| 2607 |  |  |  |  |  |  | $c->log_request_parameters( query => $request->query_parameters, $request->_has_body ? (body => $request->body_parameters) : () ); | 
| 2608 |  |  |  |  |  |  |  | 
| 2609 |  |  |  |  |  |  | $c->log_request_uploads($request); | 
| 2610 |  |  |  |  |  |  | } | 
| 2611 |  |  |  |  |  |  |  | 
| 2612 |  |  |  |  |  |  | =head2 $c->log_response | 
| 2613 |  |  |  |  |  |  |  | 
| 2614 |  |  |  |  |  |  | Writes information about the response to the debug logs by calling | 
| 2615 | 920 |  |  | 920 | 1 | 1543 | C<< $c->log_response_status_line >> and C<< $c->log_response_headers >>. | 
| 2616 | 920 |  |  |  |  | 2799 |  | 
| 2617 | 919 |  |  |  |  | 2830 | =cut | 
| 2618 |  |  |  |  |  |  |  | 
| 2619 |  |  |  |  |  |  | my $c = shift; | 
| 2620 |  |  |  |  |  |  |  | 
| 2621 |  |  |  |  |  |  | return unless $c->debug; | 
| 2622 |  |  |  |  |  |  |  | 
| 2623 |  |  |  |  |  |  | my($dump) = grep {$_->[0] eq 'Response' } $c->dump_these; | 
| 2624 |  |  |  |  |  |  | my $response = $dump->[1]; | 
| 2625 |  |  |  |  |  |  |  | 
| 2626 | 922 |  |  | 922 | 1 | 1503 | $c->log_response_status_line($response); | 
|  | 922 |  |  |  |  | 3027 |  | 
| 2627 |  |  |  |  |  |  | $c->log_response_headers($response->headers); | 
| 2628 |  |  |  |  |  |  | } | 
| 2629 |  |  |  |  |  |  |  | 
| 2630 |  |  |  |  |  |  | =head2 $c->log_response_status_line($response) | 
| 2631 |  |  |  |  |  |  |  | 
| 2632 |  |  |  |  |  |  | Writes one line of information about the response to the debug logs.  This includes: | 
| 2633 |  |  |  |  |  |  |  | 
| 2634 |  |  |  |  |  |  | =over 4 | 
| 2635 | 923 |  |  | 923 | 1 | 1511 |  | 
| 2636 |  |  |  |  |  |  | =item * Response status code | 
| 2637 | 923 |  |  |  |  | 2712 |  | 
| 2638 |  |  |  |  |  |  | =item * Content-Type header (if present) | 
| 2639 |  |  |  |  |  |  |  | 
| 2640 |  |  |  |  |  |  | =item * Content-Length header (if present) | 
| 2641 |  |  |  |  |  |  |  | 
| 2642 |  |  |  |  |  |  | =back | 
| 2643 |  |  |  |  |  |  |  | 
| 2644 |  |  |  |  |  |  | =cut | 
| 2645 |  |  |  |  |  |  |  | 
| 2646 |  |  |  |  |  |  | my ($c, $response) = @_; | 
| 2647 |  |  |  |  |  |  |  | 
| 2648 |  |  |  |  |  |  | $c->log->debug( | 
| 2649 |  |  |  |  |  |  | sprintf( | 
| 2650 |  |  |  |  |  |  | 'Response Code: %s; Content-Type: %s; Content-Length: %s', | 
| 2651 |  |  |  |  |  |  | $response->status                            || 'unknown', | 
| 2652 |  |  |  |  |  |  | $response->headers->header('Content-Type')   || 'unknown', | 
| 2653 |  |  |  |  |  |  | $response->headers->header('Content-Length') || 'unknown' | 
| 2654 |  |  |  |  |  |  | ) | 
| 2655 |  |  |  |  |  |  | ); | 
| 2656 |  |  |  |  |  |  | } | 
| 2657 |  |  |  |  |  |  |  | 
| 2658 |  |  |  |  |  |  | =head2 $c->log_response_headers($headers); | 
| 2659 | 918 |  |  | 918 | 1 | 1578 |  | 
| 2660 |  |  |  |  |  |  | Hook method which can be wrapped by plugins to log the response headers. | 
| 2661 | 918 | 100 |  |  |  | 2245 | No-op in the default implementation. | 
| 2662 |  |  |  |  |  |  |  | 
| 2663 | 16 |  |  |  |  | 115 | =cut | 
|  | 64 |  |  |  |  | 133 |  | 
| 2664 | 16 |  |  |  |  | 40 |  | 
| 2665 |  |  |  |  |  |  |  | 
| 2666 | 16 |  |  |  |  | 415 | =head2 $c->log_request_parameters( query => {}, body => {} ) | 
| 2667 | 16 |  | 50 |  |  | 41 |  | 
| 2668 | 16 | 100 |  |  |  | 39 | Logs request parameters to debug logs | 
| 2669 | 16 |  | 50 |  |  | 44 |  | 
| 2670 |  |  |  |  |  |  | =cut | 
| 2671 | 16 |  |  |  |  | 40 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 2672 | 16 |  |  |  |  | 117 | my $c          = shift; | 
| 2673 |  |  |  |  |  |  | my %all_params = @_; | 
| 2674 | 16 |  |  |  |  | 119 |  | 
| 2675 |  |  |  |  |  |  | return unless $c->debug; | 
| 2676 | 16 |  |  |  |  | 371 |  | 
| 2677 |  |  |  |  |  |  | my $column_width = Catalyst::Utils::term_width() - 44; | 
| 2678 | 16 | 50 |  |  |  | 380 | foreach my $type (qw(query body)) { | 
| 2679 | 0 |  |  |  |  | 0 | my $params = $all_params{$type}; | 
| 2680 |  |  |  |  |  |  | next if ! keys %$params; | 
| 2681 |  |  |  |  |  |  | my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] ); | 
| 2682 | 16 | 50 |  |  |  | 366 | for my $key ( sort keys %$params ) { | 
| 2683 |  |  |  |  |  |  | my @values = (); | 
| 2684 | 16 |  |  |  |  | 64 | if(ref $params eq 'Hash::MultiValue') { | 
| 2685 |  |  |  |  |  |  | @values = $params->get_all($key); | 
| 2686 |  |  |  |  |  |  | } else { | 
| 2687 |  |  |  |  |  |  | my $param = $params->{$key}; | 
| 2688 |  |  |  |  |  |  | if( defined($param) ) { | 
| 2689 |  |  |  |  |  |  | @values = ref $param eq 'ARRAY' ? @$param : $param; | 
| 2690 |  |  |  |  |  |  | } | 
| 2691 |  |  |  |  |  |  | } | 
| 2692 |  |  |  |  |  |  | $t->row( $key.( scalar @values > 1 ? ' [multiple]' : ''), join(', ', @values) ); | 
| 2693 |  |  |  |  |  |  | } | 
| 2694 |  |  |  |  |  |  | $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw ); | 
| 2695 | 918 |  |  | 918 | 1 | 1475 | } | 
| 2696 |  |  |  |  |  |  | } | 
| 2697 | 918 | 100 |  |  |  | 2297 |  | 
| 2698 |  |  |  |  |  |  | =head2 $c->log_request_uploads | 
| 2699 | 13 |  |  |  |  | 63 |  | 
|  | 52 |  |  |  |  | 116 |  | 
| 2700 | 13 |  |  |  |  | 39 | Logs file uploads included in the request to the debug logs. | 
| 2701 |  |  |  |  |  |  | The parameter name, filename, file type, and file size are all included in | 
| 2702 | 13 |  |  |  |  | 52 | the debug logs. | 
| 2703 | 13 |  |  |  |  | 51 |  | 
| 2704 |  |  |  |  |  |  | =cut | 
| 2705 |  |  |  |  |  |  |  | 
| 2706 |  |  |  |  |  |  | my $c = shift; | 
| 2707 |  |  |  |  |  |  | my $request = shift; | 
| 2708 |  |  |  |  |  |  | return unless $c->debug; | 
| 2709 |  |  |  |  |  |  | my $uploads = $request->uploads; | 
| 2710 |  |  |  |  |  |  | if ( keys %$uploads ) { | 
| 2711 |  |  |  |  |  |  | my $t = Text::SimpleTable->new( | 
| 2712 |  |  |  |  |  |  | [ 12, 'Parameter' ], | 
| 2713 |  |  |  |  |  |  | [ 26, 'Filename' ], | 
| 2714 |  |  |  |  |  |  | [ 18, 'Type' ], | 
| 2715 |  |  |  |  |  |  | [ 9,  'Size' ] | 
| 2716 |  |  |  |  |  |  | ); | 
| 2717 |  |  |  |  |  |  | for my $key ( sort keys %$uploads ) { | 
| 2718 |  |  |  |  |  |  | my $upload = $uploads->{$key}; | 
| 2719 |  |  |  |  |  |  | for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) { | 
| 2720 |  |  |  |  |  |  | $t->row( $key, $u->filename, $u->type, $u->size ); | 
| 2721 |  |  |  |  |  |  | } | 
| 2722 |  |  |  |  |  |  | } | 
| 2723 | 13 |  |  | 13 | 1 | 27 | $c->log->debug( "File Uploads are:\n" . $t->draw ); | 
| 2724 |  |  |  |  |  |  | } | 
| 2725 | 13 |  | 50 |  |  | 36 | } | 
|  |  |  | 100 |  |  |  |  | 
|  |  |  | 50 |  |  |  |  | 
| 2726 |  |  |  |  |  |  |  | 
| 2727 |  |  |  |  |  |  | =head2 $c->log_request_headers($headers); | 
| 2728 |  |  |  |  |  |  |  | 
| 2729 |  |  |  |  |  |  | Hook method which can be wrapped by plugins to log the request headers. | 
| 2730 |  |  |  |  |  |  | No-op in the default implementation. | 
| 2731 |  |  |  |  |  |  |  | 
| 2732 |  |  |  |  |  |  | =cut | 
| 2733 |  |  |  |  |  |  |  | 
| 2734 |  |  |  |  |  |  |  | 
| 2735 |  |  |  |  |  |  | =head2 $c->log_headers($type => $headers) | 
| 2736 |  |  |  |  |  |  |  | 
| 2737 |  |  |  |  |  |  | Logs L<HTTP::Headers> (either request or response) to the debug logs. | 
| 2738 |  |  |  |  |  |  |  | 
| 2739 |  |  |  |  |  |  | =cut | 
| 2740 |  |  |  |  |  |  |  | 
| 2741 |  |  |  |  |  |  | my $c       = shift; | 
| 2742 |  |  |  | 13 | 1 |  | my $type    = shift; | 
| 2743 |  |  |  |  |  |  | my $headers = shift;    # an HTTP::Headers instance | 
| 2744 |  |  |  |  |  |  |  | 
| 2745 |  |  |  |  |  |  | return unless $c->debug; | 
| 2746 |  |  |  |  |  |  |  | 
| 2747 |  |  |  |  |  |  | my $column_width = Catalyst::Utils::term_width() - 28; | 
| 2748 |  |  |  |  |  |  | my $t = Text::SimpleTable->new( [ 15, 'Header Name' ], [ $column_width, 'Value' ] ); | 
| 2749 |  |  |  |  |  |  | $headers->scan( | 
| 2750 |  |  |  |  |  |  | sub { | 
| 2751 | 16 |  |  | 16 | 1 | 50 | my ( $name, $value ) = @_; | 
| 2752 | 16 |  |  |  |  | 52 | $t->row( $name, $value ); | 
| 2753 |  |  |  |  |  |  | } | 
| 2754 | 16 | 50 |  |  |  | 52 | ); | 
| 2755 |  |  |  |  |  |  | $c->log->debug( ucfirst($type) . " Headers:\n" . $t->draw ); | 
| 2756 | 16 |  |  |  |  | 81 | } | 
| 2757 | 16 |  |  |  |  | 36 |  | 
| 2758 | 32 |  |  |  |  | 56 |  | 
| 2759 | 32 | 50 |  |  |  | 99 | =head2 $c->prepare_read | 
| 2760 | 0 |  |  |  |  | 0 |  | 
| 2761 | 0 |  |  |  |  | 0 | Prepares the input for reading. | 
| 2762 | 0 |  |  |  |  | 0 |  | 
| 2763 | 0 | 0 |  |  |  | 0 | =cut | 
| 2764 | 0 |  |  |  |  | 0 |  | 
| 2765 |  |  |  |  |  |  |  | 
| 2766 | 0 |  |  |  |  | 0 | =head2 $c->prepare_request | 
| 2767 | 0 | 0 |  |  |  | 0 |  | 
| 2768 | 0 | 0 |  |  |  | 0 | Prepares the engine request. | 
| 2769 |  |  |  |  |  |  |  | 
| 2770 |  |  |  |  |  |  | =cut | 
| 2771 | 0 | 0 |  |  |  | 0 |  | 
| 2772 |  |  |  |  |  |  |  | 
| 2773 | 0 |  |  |  |  | 0 | =head2 $c->prepare_uploads | 
| 2774 |  |  |  |  |  |  |  | 
| 2775 |  |  |  |  |  |  | Prepares uploads. | 
| 2776 |  |  |  |  |  |  |  | 
| 2777 |  |  |  |  |  |  | =cut | 
| 2778 |  |  |  |  |  |  |  | 
| 2779 |  |  |  |  |  |  | my $c = shift; | 
| 2780 |  |  |  |  |  |  | $c->engine->prepare_uploads( $c, @_ ); | 
| 2781 |  |  |  |  |  |  | } | 
| 2782 |  |  |  |  |  |  |  | 
| 2783 |  |  |  |  |  |  | =head2 $c->prepare_write | 
| 2784 |  |  |  |  |  |  |  | 
| 2785 |  |  |  |  |  |  | Prepares the output for writing. | 
| 2786 | 16 |  |  | 16 | 1 | 32 |  | 
| 2787 | 16 |  |  |  |  | 24 | =cut | 
| 2788 | 16 | 50 |  |  |  | 30 |  | 
| 2789 | 16 |  |  |  |  | 407 |  | 
| 2790 | 16 | 50 |  |  |  | 74 | =head2 $c->request_class | 
| 2791 | 0 |  |  |  |  | 0 |  | 
| 2792 |  |  |  |  |  |  | Returns or sets the request class. Defaults to L<Catalyst::Request>. | 
| 2793 |  |  |  |  |  |  |  | 
| 2794 |  |  |  |  |  |  | =head2 $app->request_class_traits | 
| 2795 |  |  |  |  |  |  |  | 
| 2796 |  |  |  |  |  |  | An arrayref of L<Moose::Role>s which are applied to the request class.  You can | 
| 2797 | 0 |  |  |  |  | 0 | name the full namespace of the role, or a namespace suffix, which will then | 
| 2798 | 0 |  |  |  |  | 0 | be tried against the following standard namespace prefixes. | 
| 2799 | 0 | 0 |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 2800 | 0 |  |  |  |  | 0 | $MyApp::TraitFor::Request::$trait_suffix | 
| 2801 |  |  |  |  |  |  | Catalyst::TraitFor::Request::$trait_suffix | 
| 2802 |  |  |  |  |  |  |  | 
| 2803 | 0 |  |  |  |  | 0 | So for example if you set: | 
| 2804 |  |  |  |  |  |  |  | 
| 2805 |  |  |  |  |  |  | MyApp->request_class_traits(['Foo']); | 
| 2806 |  |  |  |  |  |  |  | 
| 2807 |  |  |  |  |  |  | We try each possible role in turn (and throw an error if none load) | 
| 2808 |  |  |  |  |  |  |  | 
| 2809 |  |  |  |  |  |  | Foo | 
| 2810 |  |  |  |  |  |  | MyApp::TraitFor::Request::Foo | 
| 2811 |  |  |  |  |  |  | Catalyst::TraitFor::Request::Foo | 
| 2812 |  |  |  |  |  |  |  | 
| 2813 |  |  |  |  |  |  | The namespace part 'TraitFor::Request' was chosen to assist in backwards | 
| 2814 |  |  |  | 16 | 1 |  | compatibility with L<CatalystX::RoleApplicator> which previously provided | 
| 2815 |  |  |  |  |  |  | these features in a stand alone package. | 
| 2816 |  |  |  |  |  |  |  | 
| 2817 |  |  |  |  |  |  | =head2 $app->composed_request_class | 
| 2818 |  |  |  |  |  |  |  | 
| 2819 |  |  |  |  |  |  | This is the request class which has been composed with any request_class_traits. | 
| 2820 |  |  |  |  |  |  |  | 
| 2821 |  |  |  |  |  |  | =head2 $c->response_class | 
| 2822 |  |  |  |  |  |  |  | 
| 2823 | 0 |  |  | 0 | 1 | 0 | Returns or sets the response class. Defaults to L<Catalyst::Response>. | 
| 2824 | 0 |  |  |  |  | 0 |  | 
| 2825 | 0 |  |  |  |  | 0 | =head2 $app->response_class_traits | 
| 2826 |  |  |  |  |  |  |  | 
| 2827 | 0 | 0 |  |  |  | 0 | An arrayref of L<Moose::Role>s which are applied to the response class.  You can | 
| 2828 |  |  |  |  |  |  | name the full namespace of the role, or a namespace suffix, which will then | 
| 2829 | 0 |  |  |  |  | 0 | be tried against the following standard namespace prefixes. | 
| 2830 | 0 |  |  |  |  | 0 |  | 
| 2831 |  |  |  |  |  |  | $MyApp::TraitFor::Response::$trait_suffix | 
| 2832 |  |  |  |  |  |  | Catalyst::TraitFor::Response::$trait_suffix | 
| 2833 | 0 |  |  | 0 |  | 0 |  | 
| 2834 | 0 |  |  |  |  | 0 | So for example if you set: | 
| 2835 |  |  |  |  |  |  |  | 
| 2836 | 0 |  |  |  |  | 0 | MyApp->response_class_traits(['Foo']); | 
| 2837 | 0 |  |  |  |  | 0 |  | 
| 2838 |  |  |  |  |  |  | We try each possible role in turn (and throw an error if none load) | 
| 2839 |  |  |  |  |  |  |  | 
| 2840 |  |  |  |  |  |  | Foo | 
| 2841 |  |  |  |  |  |  | MyApp::TraitFor::Response::Foo | 
| 2842 |  |  |  |  |  |  | Catalyst::TraitFor::Responset::Foo | 
| 2843 |  |  |  |  |  |  |  | 
| 2844 |  |  |  |  |  |  | The namespace part 'TraitFor::Response' was chosen to assist in backwards | 
| 2845 |  |  |  |  |  |  | compatibility with L<CatalystX::RoleApplicator> which previously provided | 
| 2846 |  |  |  |  |  |  | these features in a stand alone package. | 
| 2847 | 922 |  |  | 922 | 1 | 1502 |  | 
|  | 922 |  |  |  |  | 2591 |  | 
| 2848 |  |  |  |  |  |  |  | 
| 2849 |  |  |  |  |  |  | =head2 $app->composed_response_class | 
| 2850 |  |  |  |  |  |  |  | 
| 2851 |  |  |  |  |  |  | This is the request class which has been composed with any response_class_traits. | 
| 2852 |  |  |  |  |  |  |  | 
| 2853 |  |  |  |  |  |  | =head2 $c->read( [$maxlength] ) | 
| 2854 |  |  |  |  |  |  |  | 
| 2855 | 923 |  |  | 923 | 1 | 1583 | Reads a chunk of data from the request body. This method is designed to | 
|  | 923 |  |  |  |  | 2077 |  | 
| 2856 |  |  |  |  |  |  | be used in a while loop, reading C<$maxlength> bytes on every call. | 
| 2857 |  |  |  |  |  |  | C<$maxlength> defaults to the size of the request if not specified. | 
| 2858 |  |  |  |  |  |  |  | 
| 2859 |  |  |  |  |  |  | You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this | 
| 2860 |  |  |  |  |  |  | directly. | 
| 2861 |  |  |  |  |  |  |  | 
| 2862 |  |  |  |  |  |  | Warning: If you use read(), Catalyst will not process the body, | 
| 2863 |  |  |  |  |  |  | so you will not be able to access POST parameters or file uploads via | 
| 2864 | 918 |  |  | 918 | 1 | 1564 | $c->request.  You must handle all body parsing yourself. | 
| 2865 | 918 |  |  |  |  | 2539 |  | 
| 2866 |  |  |  |  |  |  | =cut | 
| 2867 |  |  |  |  |  |  |  | 
| 2868 |  |  |  |  |  |  |  | 
| 2869 |  |  |  |  |  |  | =head2 $c->run | 
| 2870 |  |  |  |  |  |  |  | 
| 2871 |  |  |  |  |  |  | Starts the engine. | 
| 2872 |  |  |  |  |  |  |  | 
| 2873 |  |  |  |  |  |  | =cut | 
| 2874 | 0 |  |  | 0 | 1 | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 2875 |  |  |  |  |  |  | my $app = shift; | 
| 2876 |  |  |  |  |  |  | $app->_make_immutable_if_needed; | 
| 2877 |  |  |  |  |  |  | $app->engine_loader->needs_psgi_engine_compat_hack ? | 
| 2878 |  |  |  |  |  |  | $app->engine->run($app, @_) : | 
| 2879 |  |  |  |  |  |  | $app->engine->run( $app, $app->_finalized_psgi_app, @_ ); | 
| 2880 |  |  |  |  |  |  | } | 
| 2881 |  |  |  |  |  |  |  | 
| 2882 |  |  |  |  |  |  | my $class = shift; | 
| 2883 |  |  |  |  |  |  | my $meta = find_meta($class); | 
| 2884 |  |  |  |  |  |  | my $isa_ca = $class->isa('Class::Accessor::Fast') || $class->isa('Class::Accessor'); | 
| 2885 |  |  |  |  |  |  | if ( | 
| 2886 |  |  |  |  |  |  | $meta->is_immutable | 
| 2887 |  |  |  |  |  |  | && ! { $meta->immutable_options }->{replace_constructor} | 
| 2888 |  |  |  |  |  |  | && $isa_ca | 
| 2889 |  |  |  |  |  |  | ) { | 
| 2890 |  |  |  |  |  |  | warn("You made your application class ($class) immutable, " | 
| 2891 |  |  |  |  |  |  | . "but did not inline the\nconstructor. " | 
| 2892 |  |  |  |  |  |  | . "This will break catalyst, as your app \@ISA " | 
| 2893 |  |  |  |  |  |  | . "Class::Accessor(::Fast)?\nPlease pass " | 
| 2894 |  |  |  |  |  |  | . "(replace_constructor => 1)\nwhen making your class immutable.\n"); | 
| 2895 |  |  |  |  |  |  | } | 
| 2896 |  |  |  |  |  |  | unless ($meta->is_immutable) { | 
| 2897 |  |  |  |  |  |  | # XXX - FIXME warning here as you should make your app immutable yourself. | 
| 2898 |  |  |  |  |  |  | $meta->make_immutable( | 
| 2899 |  |  |  |  |  |  | replace_constructor => 1, | 
| 2900 |  |  |  |  |  |  | ); | 
| 2901 |  |  |  |  |  |  | } | 
| 2902 |  |  |  |  |  |  | } | 
| 2903 |  |  |  |  |  |  |  | 
| 2904 |  |  |  |  |  |  | =head2 $c->set_action( $action, $code, $namespace, $attrs ) | 
| 2905 |  |  |  |  |  |  |  | 
| 2906 |  |  |  |  |  |  | Sets an action in a given namespace. | 
| 2907 |  |  |  |  |  |  |  | 
| 2908 |  |  |  |  |  |  | =cut | 
| 2909 |  |  |  |  |  |  |  | 
| 2910 |  |  |  |  |  |  |  | 
| 2911 |  |  |  |  |  |  | =head2 $c->setup_actions($component) | 
| 2912 |  |  |  |  |  |  |  | 
| 2913 |  |  |  |  |  |  | Sets up actions for a component. | 
| 2914 |  |  |  |  |  |  |  | 
| 2915 |  |  |  |  |  |  | =cut | 
| 2916 |  |  |  |  |  |  |  | 
| 2917 |  |  |  |  |  |  |  | 
| 2918 |  |  |  |  |  |  | =head2 $c->setup_components | 
| 2919 |  |  |  |  |  |  |  | 
| 2920 |  |  |  |  |  |  | This method is called internally to set up the application's components. | 
| 2921 |  |  |  |  |  |  |  | 
| 2922 |  |  |  |  |  |  | It finds modules by calling the L<locate_components> method, expands them to | 
| 2923 |  |  |  |  |  |  | package names with the L<expand_component_module> method, and then installs | 
| 2924 |  |  |  |  |  |  | each component into the application. | 
| 2925 |  |  |  |  |  |  |  | 
| 2926 |  |  |  |  |  |  | The C<setup_components> config option is passed to both of the above methods. | 
| 2927 |  |  |  |  |  |  |  | 
| 2928 |  |  |  |  |  |  | Installation of each component is performed by the L<setup_component> method, | 
| 2929 |  |  |  |  |  |  | below. | 
| 2930 |  |  |  |  |  |  |  | 
| 2931 |  |  |  |  |  |  | =cut | 
| 2932 |  |  |  |  |  |  |  | 
| 2933 |  |  |  |  |  |  | my $class = shift; | 
| 2934 |  |  |  |  |  |  |  | 
| 2935 |  |  |  |  |  |  | my $config  = $class->config->{ setup_components }; | 
| 2936 |  |  |  |  |  |  |  | 
| 2937 |  |  |  |  |  |  | my @comps = $class->locate_components($config); | 
| 2938 |  |  |  |  |  |  | my %comps = map { $_ => 1 } @comps; | 
| 2939 |  |  |  |  |  |  |  | 
| 2940 |  |  |  |  |  |  | my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps; | 
| 2941 |  |  |  |  |  |  | $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}. | 
| 2942 |  |  |  |  |  |  | qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n} | 
| 2943 |  |  |  |  |  |  | ) if $deprecatedcatalyst_component_names; | 
| 2944 |  |  |  |  |  |  |  | 
| 2945 |  |  |  |  |  |  | for my $component ( @comps ) { | 
| 2946 |  |  |  |  |  |  |  | 
| 2947 |  |  |  |  |  |  | # We pass ignore_loaded here so that overlay files for (e.g.) | 
| 2948 |  |  |  |  |  |  | # Model::DBI::Schema sub-classes are loaded - if it's in @comps | 
| 2949 |  |  |  |  |  |  | # we know M::P::O found a file on disk so this is safe | 
| 2950 |  |  |  |  |  |  |  | 
| 2951 |  |  |  |  |  |  | Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } ); | 
| 2952 |  |  |  |  |  |  | } | 
| 2953 |  |  |  |  |  |  |  | 
| 2954 | 12 |  |  | 12 | 1 | 79 | for my $component (@comps) { | 
|  | 12 |  |  |  |  | 223 |  | 
| 2955 |  |  |  |  |  |  | my $instance = $class->components->{ $component } = $class->delayed_setup_component($component); | 
| 2956 |  |  |  |  |  |  | } | 
| 2957 |  |  |  |  |  |  |  | 
| 2958 |  |  |  |  |  |  | # Inject a component or wrap a stand alone class in an adaptor. This makes a list | 
| 2959 |  |  |  |  |  |  | # of named components in the configuration that are not actually existing (not a | 
| 2960 |  |  |  |  |  |  | # real file). | 
| 2961 |  |  |  |  |  |  |  | 
| 2962 |  |  |  |  |  |  | my @injected = $class->setup_injected_components; | 
| 2963 | 1 |  |  | 1 | 1 | 42 |  | 
| 2964 | 1 |  |  |  |  | 7 | # All components are registered, now we need to 'init' them. | 
| 2965 | 1 | 50 |  |  |  | 310 | foreach my $component_name (@comps, @injected) { | 
| 2966 |  |  |  |  |  |  | $class->components->{$component_name} = $class->components->{$component_name}->() if | 
| 2967 |  |  |  |  |  |  | (ref($class->components->{$component_name}) || '') eq 'CODE'; | 
| 2968 |  |  |  |  |  |  | } | 
| 2969 |  |  |  |  |  |  | } | 
| 2970 |  |  |  |  |  |  |  | 
| 2971 | 3 |  |  | 3 |  | 118 | =head2 $app->setup_injected_components | 
| 2972 | 3 |  |  |  |  | 12 |  | 
| 2973 | 3 |  | 66 |  |  | 63 | Called by setup_compoents to setup components that are injected. | 
| 2974 | 3 | 50 | 66 |  |  | 23 |  | 
|  |  |  | 66 |  |  |  |  | 
| 2975 |  |  |  |  |  |  | =cut | 
| 2976 |  |  |  |  |  |  |  | 
| 2977 |  |  |  |  |  |  | my ($class) = @_; | 
| 2978 |  |  |  |  |  |  | my @injected_components = keys %{$class->config->{inject_components} ||+{}}; | 
| 2979 | 1 |  |  |  |  | 49 |  | 
| 2980 |  |  |  |  |  |  | foreach my $injected_comp_name(@injected_components) { | 
| 2981 |  |  |  |  |  |  | $class->setup_injected_component( | 
| 2982 |  |  |  |  |  |  | $injected_comp_name, | 
| 2983 |  |  |  |  |  |  | $class->config->{inject_components}->{$injected_comp_name}); | 
| 2984 |  |  |  |  |  |  | } | 
| 2985 | 3 | 100 |  |  |  | 30 |  | 
| 2986 |  |  |  |  |  |  | return map { $class ."::" . $_ } | 
| 2987 | 2 |  |  |  |  | 15 | @injected_components; | 
| 2988 |  |  |  |  |  |  | } | 
| 2989 |  |  |  |  |  |  |  | 
| 2990 |  |  |  |  |  |  | =head2 $app->setup_injected_component( $injected_component_name, $config ) | 
| 2991 |  |  |  |  |  |  |  | 
| 2992 |  |  |  |  |  |  | Setup a given injected component. | 
| 2993 |  |  |  |  |  |  |  | 
| 2994 |  |  |  |  |  |  | =cut | 
| 2995 |  |  |  |  |  |  |  | 
| 2996 |  |  |  |  |  |  | my ($class, $injected_comp_name, $config) = @_; | 
| 2997 |  |  |  |  |  |  | if(my $component_class = $config->{from_component}) { | 
| 2998 |  |  |  |  |  |  | my @roles = @{$config->{roles} ||[]}; | 
| 2999 | 0 |  |  | 0 | 1 | 0 | Catalyst::Utils::inject_component( | 
|  | 0 |  |  |  |  | 0 |  | 
| 3000 |  |  |  |  |  |  | into => $class, | 
| 3001 |  |  |  |  |  |  | component => $component_class, | 
| 3002 |  |  |  |  |  |  | (scalar(@roles) ? (traits => \@roles) : ()), | 
| 3003 |  |  |  |  |  |  | as => $injected_comp_name); | 
| 3004 |  |  |  |  |  |  | } | 
| 3005 |  |  |  |  |  |  | } | 
| 3006 |  |  |  |  |  |  |  | 
| 3007 | 167 |  |  | 167 | 1 | 6113 | =head2 $app->inject_component($MyApp_Component_name => \%args); | 
|  | 167 |  |  |  |  | 1134 |  | 
| 3008 |  |  |  |  |  |  |  | 
| 3009 |  |  |  |  |  |  | Add a component that is injected at setup: | 
| 3010 |  |  |  |  |  |  |  | 
| 3011 |  |  |  |  |  |  | MyApp->inject_component( 'Model::Foo' => { from_component => 'Common::Foo' } ); | 
| 3012 |  |  |  |  |  |  |  | 
| 3013 |  |  |  |  |  |  | Must be called before ->setup.  Expects a component name for your | 
| 3014 |  |  |  |  |  |  | current application and \%args where | 
| 3015 |  |  |  |  |  |  |  | 
| 3016 |  |  |  |  |  |  | =over 4 | 
| 3017 |  |  |  |  |  |  |  | 
| 3018 |  |  |  |  |  |  | =item from_component | 
| 3019 |  |  |  |  |  |  |  | 
| 3020 |  |  |  |  |  |  | The target component being injected into your application | 
| 3021 |  |  |  |  |  |  |  | 
| 3022 |  |  |  |  |  |  | =item roles | 
| 3023 |  |  |  |  |  |  |  | 
| 3024 |  |  |  |  |  |  | An arrayref of L<Moose::Role>s that are applied to your component. | 
| 3025 | 162 |  |  | 162 | 1 | 400 |  | 
| 3026 |  |  |  |  |  |  | =back | 
| 3027 | 162 |  |  |  |  | 588 |  | 
| 3028 |  |  |  |  |  |  | Example | 
| 3029 | 162 |  |  |  |  | 1536 |  | 
| 3030 | 162 |  |  |  |  | 585 | MyApp->inject_component( | 
|  | 6694 |  |  |  |  | 8995 |  | 
| 3031 |  |  |  |  |  |  | 'Model::Foo' => { | 
| 3032 | 162 |  |  |  |  | 1025 | from_component => 'Common::Model::Foo', | 
|  | 6694 |  |  |  |  | 12325 |  | 
| 3033 | 162 | 100 |  |  |  | 744 | roles => ['Role1', 'Role2'], | 
| 3034 |  |  |  |  |  |  | }); | 
| 3035 |  |  |  |  |  |  |  | 
| 3036 |  |  |  |  |  |  | =head2 $app->inject_components | 
| 3037 | 162 |  |  |  |  | 515 |  | 
| 3038 |  |  |  |  |  |  | Inject a list of components: | 
| 3039 |  |  |  |  |  |  |  | 
| 3040 |  |  |  |  |  |  | MyApp->inject_components( | 
| 3041 |  |  |  |  |  |  | 'Model::FooOne' => { | 
| 3042 |  |  |  |  |  |  | from_component => 'Common::Model::Foo', | 
| 3043 | 6694 |  |  |  |  | 22905 | roles => ['Role1', 'Role2'], | 
| 3044 |  |  |  |  |  |  | }, | 
| 3045 |  |  |  |  |  |  | 'Model::FooTwo' => { | 
| 3046 | 162 |  |  |  |  | 2671 | from_component => 'Common::Model::Foo', | 
| 3047 | 6694 |  |  |  |  | 12794 | roles => ['Role1', 'Role2'], | 
| 3048 |  |  |  |  |  |  | }); | 
| 3049 |  |  |  |  |  |  |  | 
| 3050 |  |  |  |  |  |  | =cut | 
| 3051 |  |  |  |  |  |  |  | 
| 3052 |  |  |  |  |  |  | my ($app, $name, $args) = @_; | 
| 3053 |  |  |  |  |  |  | die "Component $name exists" if | 
| 3054 | 162 |  |  |  |  | 1848 | $app->config->{inject_components}->{$name}; | 
| 3055 |  |  |  |  |  |  | $app->config->{inject_components}->{$name} = $args; | 
| 3056 |  |  |  |  |  |  | } | 
| 3057 | 162 |  |  |  |  | 506 |  | 
| 3058 |  |  |  |  |  |  | my $app = shift; | 
| 3059 | 6699 | 50 | 50 |  |  | 14187 | while(@_) { | 
| 3060 |  |  |  |  |  |  | $app->inject_component(shift, shift); | 
| 3061 |  |  |  |  |  |  | } | 
| 3062 |  |  |  |  |  |  | } | 
| 3063 |  |  |  |  |  |  |  | 
| 3064 |  |  |  |  |  |  | =head2 $c->locate_components( $setup_component_config ) | 
| 3065 |  |  |  |  |  |  |  | 
| 3066 |  |  |  |  |  |  | This method is meant to provide a list of component modules that should be | 
| 3067 |  |  |  |  |  |  | setup for the application.  By default, it will use L<Module::Pluggable>. | 
| 3068 |  |  |  |  |  |  |  | 
| 3069 |  |  |  |  |  |  | Specify a C<setup_components> config option to pass additional options directly | 
| 3070 | 162 |  |  | 162 | 1 | 568 | to L<Module::Pluggable>. To add additional search paths, specify a key named | 
| 3071 | 162 | 100 |  |  |  | 403 | C<search_extra> as an array reference. Items in the array beginning with C<::> | 
|  | 162 |  |  |  |  | 809 |  | 
| 3072 |  |  |  |  |  |  | will have the application class name prepended to them. | 
| 3073 | 162 |  |  |  |  | 707 |  | 
| 3074 |  |  |  |  |  |  | =cut | 
| 3075 |  |  |  |  |  |  |  | 
| 3076 | 5 |  |  |  |  | 13 | my $class  = shift; | 
| 3077 |  |  |  |  |  |  | my $config = shift; | 
| 3078 |  |  |  |  |  |  |  | 
| 3079 | 162 |  |  |  |  | 600 | my @paths   = qw( ::M ::Model ::V ::View ::C ::Controller ); | 
|  | 5 |  |  |  |  | 12 |  | 
| 3080 |  |  |  |  |  |  | my $extra   = $config->{ search_extra } || []; | 
| 3081 |  |  |  |  |  |  |  | 
| 3082 |  |  |  |  |  |  | unshift @paths, @$extra; | 
| 3083 |  |  |  |  |  |  |  | 
| 3084 |  |  |  |  |  |  | my @comps = map { sort { length($a) <=> length($b) } Module::Pluggable::Object->new( | 
| 3085 |  |  |  |  |  |  | search_path => [ map { s/^(?=::)/$class/; $_; } ($_) ], | 
| 3086 |  |  |  |  |  |  | %$config | 
| 3087 |  |  |  |  |  |  | )->plugins } @paths; | 
| 3088 |  |  |  |  |  |  |  | 
| 3089 |  |  |  |  |  |  | return @comps; | 
| 3090 | 5 |  |  | 5 | 1 | 11 | } | 
| 3091 | 5 | 50 |  |  |  | 16 |  | 
| 3092 | 5 | 100 |  |  |  | 7 | =head2 $c->expand_component_module( $component, $setup_component_config ) | 
|  | 5 |  |  |  |  | 16 |  | 
| 3093 | 5 | 100 |  |  |  | 20 |  | 
| 3094 |  |  |  |  |  |  | Components found by C<locate_components> will be passed to this method, which | 
| 3095 |  |  |  |  |  |  | is expected to return a list of component (package) names to be set up. | 
| 3096 |  |  |  |  |  |  |  | 
| 3097 |  |  |  |  |  |  | =cut | 
| 3098 |  |  |  |  |  |  |  | 
| 3099 |  |  |  |  |  |  | my ($class, $module) = @_; | 
| 3100 |  |  |  |  |  |  | return Devel::InnerPackage::list_packages( $module ); | 
| 3101 |  |  |  |  |  |  | } | 
| 3102 |  |  |  |  |  |  |  | 
| 3103 |  |  |  |  |  |  | =head2 $app->delayed_setup_component | 
| 3104 |  |  |  |  |  |  |  | 
| 3105 |  |  |  |  |  |  | Returns a coderef that points to a setup_component instance.  Used | 
| 3106 |  |  |  |  |  |  | internally for when you want to delay setup until the first time | 
| 3107 |  |  |  |  |  |  | the component is called. | 
| 3108 |  |  |  |  |  |  |  | 
| 3109 |  |  |  |  |  |  | =cut | 
| 3110 |  |  |  |  |  |  |  | 
| 3111 |  |  |  |  |  |  | my($class, $component, @more) = @_; | 
| 3112 |  |  |  |  |  |  | return sub { | 
| 3113 |  |  |  |  |  |  | return my $instance = $class->setup_component($component, @more); | 
| 3114 |  |  |  |  |  |  | }; | 
| 3115 |  |  |  |  |  |  | } | 
| 3116 |  |  |  |  |  |  |  | 
| 3117 |  |  |  |  |  |  | =head2 $c->setup_component | 
| 3118 |  |  |  |  |  |  |  | 
| 3119 |  |  |  |  |  |  | =cut | 
| 3120 |  |  |  |  |  |  |  | 
| 3121 |  |  |  |  |  |  | my( $class, $component ) = @_; | 
| 3122 |  |  |  |  |  |  |  | 
| 3123 |  |  |  |  |  |  | unless ( $component->can( 'COMPONENT' ) ) { | 
| 3124 |  |  |  |  |  |  | return $component; | 
| 3125 |  |  |  |  |  |  | } | 
| 3126 |  |  |  |  |  |  |  | 
| 3127 |  |  |  |  |  |  | my $config = $class->config_for($component); | 
| 3128 |  |  |  |  |  |  | # Stash catalyst_component_name in the config here, so that custom COMPONENT | 
| 3129 |  |  |  |  |  |  | # methods also pass it. local to avoid pointlessly shitting in config | 
| 3130 |  |  |  |  |  |  | # for the debug screen, as $component is already the key name. | 
| 3131 |  |  |  |  |  |  | local $config->{catalyst_component_name} = $component; | 
| 3132 |  |  |  |  |  |  |  | 
| 3133 |  |  |  |  |  |  | my $instance = eval { | 
| 3134 |  |  |  |  |  |  | $component->COMPONENT( $class, $config ); | 
| 3135 |  |  |  |  |  |  | } || do { | 
| 3136 |  |  |  |  |  |  | my $error = $@; | 
| 3137 |  |  |  |  |  |  | chomp $error; | 
| 3138 |  |  |  |  |  |  | Catalyst::Exception->throw( | 
| 3139 |  |  |  |  |  |  | message => qq/Couldn't instantiate component "$component", "$error"/ | 
| 3140 |  |  |  |  |  |  | ); | 
| 3141 |  |  |  |  |  |  | }; | 
| 3142 |  |  |  |  |  |  |  | 
| 3143 |  |  |  |  |  |  | unless (blessed $instance) { | 
| 3144 |  |  |  |  |  |  | my $metaclass = Moose::Util::find_meta($component); | 
| 3145 |  |  |  |  |  |  | my $method_meta = $metaclass->find_method_by_name('COMPONENT'); | 
| 3146 |  |  |  |  |  |  | my $component_method_from = $method_meta->associated_metaclass->name; | 
| 3147 | 2 |  |  | 2 | 1 | 5 | my $value = defined($instance) ? $instance : 'undef'; | 
| 3148 |  |  |  |  |  |  | Catalyst::Exception->throw( | 
| 3149 | 2 | 50 |  |  |  | 8 | message => | 
| 3150 | 2 |  |  |  |  | 6 | qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./ | 
| 3151 |  |  |  |  |  |  | ); | 
| 3152 |  |  |  |  |  |  | } | 
| 3153 |  |  |  |  |  |  |  | 
| 3154 | 1 |  |  | 1 | 1 | 13 | my @expanded_components = $instance->can('expand_modules') | 
| 3155 | 1 |  |  |  |  | 4 | ? $instance->expand_modules( $component, $config ) | 
| 3156 | 2 |  |  |  |  | 7 | : $class->expand_component_module( $component, $config ); | 
| 3157 |  |  |  |  |  |  | for my $component (@expanded_components) { | 
| 3158 |  |  |  |  |  |  | next if $class->components->{ $component }; | 
| 3159 |  |  |  |  |  |  | $class->components->{ $component } = $class->setup_component($component); | 
| 3160 |  |  |  |  |  |  | } | 
| 3161 |  |  |  |  |  |  |  | 
| 3162 |  |  |  |  |  |  | return $instance; | 
| 3163 |  |  |  |  |  |  | } | 
| 3164 |  |  |  |  |  |  |  | 
| 3165 |  |  |  |  |  |  | =head2 $app->config_for( $component_name ) | 
| 3166 |  |  |  |  |  |  |  | 
| 3167 |  |  |  |  |  |  | Return the application level configuration (which is not yet merged with any | 
| 3168 |  |  |  |  |  |  | local component configuration, via $component_class->config) for the named | 
| 3169 |  |  |  |  |  |  | component or component object. Example: | 
| 3170 |  |  |  |  |  |  |  | 
| 3171 |  |  |  |  |  |  | MyApp->config( | 
| 3172 |  |  |  |  |  |  | 'Model::Foo' => { a => 1, b => 2}, | 
| 3173 | 162 |  |  | 162 | 1 | 429 | ); | 
| 3174 | 162 |  |  |  |  | 339 |  | 
| 3175 |  |  |  |  |  |  | my $config = MyApp->config_for('MyApp::Model::Foo'); | 
| 3176 | 162 |  |  |  |  | 700 |  | 
| 3177 | 162 |  | 100 |  |  | 1045 | In this case $config is the hashref C<< {a=>1, b=>2} >>. | 
| 3178 |  |  |  |  |  |  |  | 
| 3179 | 162 |  |  |  |  | 477 | This is also handy for looking up configuration for a plugin, to make sure you follow | 
| 3180 |  |  |  |  |  |  | existing L<Catalyst> standards for where a plugin should put its configuration. | 
| 3181 | 162 |  |  |  |  | 506 |  | 
|  | 27794 |  |  |  |  | 1397576 |  | 
| 3182 | 974 |  |  |  |  | 241217 | =cut | 
|  | 974 |  |  |  |  | 3778 |  | 
|  | 974 |  |  |  |  | 5715 |  | 
| 3183 |  |  |  |  |  |  |  | 
| 3184 |  |  |  |  |  |  | my ($class, $component_name) = @_; | 
| 3185 |  |  |  |  |  |  | my $component_suffix = Catalyst::Utils::class2classsuffix($component_name); | 
| 3186 | 162 |  |  |  |  | 51130 | my $config = $class->config->{ $component_suffix } || {}; | 
| 3187 |  |  |  |  |  |  |  | 
| 3188 |  |  |  |  |  |  | return $config; | 
| 3189 |  |  |  |  |  |  | } | 
| 3190 |  |  |  |  |  |  |  | 
| 3191 |  |  |  |  |  |  | =head2 $c->setup_dispatcher | 
| 3192 |  |  |  |  |  |  |  | 
| 3193 |  |  |  |  |  |  | Sets up dispatcher. | 
| 3194 |  |  |  |  |  |  |  | 
| 3195 |  |  |  |  |  |  | =cut | 
| 3196 |  |  |  |  |  |  |  | 
| 3197 | 0 |  |  | 0 | 1 | 0 | my ( $class, $dispatcher ) = @_; | 
| 3198 | 0 |  |  |  |  | 0 |  | 
| 3199 |  |  |  |  |  |  | if ($dispatcher) { | 
| 3200 |  |  |  |  |  |  | $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher; | 
| 3201 |  |  |  |  |  |  | } | 
| 3202 |  |  |  |  |  |  |  | 
| 3203 |  |  |  |  |  |  | if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) { | 
| 3204 |  |  |  |  |  |  | $dispatcher = 'Catalyst::Dispatcher::' . $env; | 
| 3205 |  |  |  |  |  |  | } | 
| 3206 |  |  |  |  |  |  |  | 
| 3207 |  |  |  |  |  |  | unless ($dispatcher) { | 
| 3208 |  |  |  |  |  |  | $dispatcher = $class->dispatcher_class; | 
| 3209 |  |  |  |  |  |  | } | 
| 3210 | 6705 |  |  | 6705 | 1 | 11957 |  | 
| 3211 |  |  |  |  |  |  | load_class($dispatcher); | 
| 3212 | 6714 |  |  | 6714 |  | 14576 |  | 
| 3213 | 6705 |  |  |  |  | 25419 | # dispatcher instance | 
| 3214 |  |  |  |  |  |  | $class->dispatcher( $dispatcher->new ); | 
| 3215 |  |  |  |  |  |  | } | 
| 3216 |  |  |  |  |  |  |  | 
| 3217 |  |  |  |  |  |  | =head2 $c->setup_engine | 
| 3218 |  |  |  |  |  |  |  | 
| 3219 |  |  |  |  |  |  | Sets up engine. | 
| 3220 |  |  |  |  |  |  |  | 
| 3221 | 7189 |  |  | 7189 | 1 | 11677 | =cut | 
| 3222 |  |  |  |  |  |  |  | 
| 3223 | 7189 | 100 |  |  |  | 104709 | my ($class, $requested_engine) = @_; | 
| 3224 | 238 |  |  |  |  | 981 |  | 
| 3225 |  |  |  |  |  |  | if (!$class->engine_loader || $requested_engine) { | 
| 3226 |  |  |  |  |  |  | $class->engine_loader( | 
| 3227 | 6951 |  |  |  |  | 18508 | Catalyst::EngineLoader->new({ | 
| 3228 |  |  |  |  |  |  | application_name => $class, | 
| 3229 |  |  |  |  |  |  | (defined $requested_engine | 
| 3230 |  |  |  |  |  |  | ? (catalyst_engine_class => $requested_engine) : ()), | 
| 3231 | 6951 |  |  |  |  | 17953 | }), | 
| 3232 |  |  |  |  |  |  | ); | 
| 3233 |  |  |  |  |  |  | } | 
| 3234 |  |  |  |  |  |  |  | 
| 3235 | 6951 |  | 33 |  |  | 10001 | $class->engine_loader->catalyst_engine_class; | 
| 3236 |  |  |  |  |  |  | } | 
| 3237 |  |  |  |  |  |  |  | 
| 3238 |  |  |  |  |  |  | my ($class, $requested_engine) = @_; | 
| 3239 |  |  |  |  |  |  |  | 
| 3240 |  |  |  |  |  |  | my $engine = do { | 
| 3241 |  |  |  |  |  |  | my $loader = $class->engine_loader; | 
| 3242 |  |  |  |  |  |  |  | 
| 3243 | 6951 | 50 |  |  |  | 597056 | if (!$loader || $requested_engine) { | 
| 3244 | 0 |  |  |  |  | 0 | $loader = Catalyst::EngineLoader->new({ | 
| 3245 | 0 |  |  |  |  | 0 | application_name => $class, | 
| 3246 | 0 |  |  |  |  | 0 | (defined $requested_engine | 
| 3247 | 0 | 0 |  |  |  | 0 | ? (requested_engine => $requested_engine) : ()), | 
| 3248 | 0 |  |  |  |  | 0 | }), | 
| 3249 |  |  |  |  |  |  |  | 
| 3250 |  |  |  |  |  |  | $class->engine_loader($loader); | 
| 3251 |  |  |  |  |  |  | } | 
| 3252 |  |  |  |  |  |  |  | 
| 3253 |  |  |  |  |  |  | $loader->catalyst_engine_class; | 
| 3254 | 6951 | 50 |  |  |  | 49191 | }; | 
| 3255 |  |  |  |  |  |  |  | 
| 3256 |  |  |  |  |  |  | # Don't really setup_engine -- see _setup_psgi_app for explanation. | 
| 3257 | 6951 |  |  |  |  | 469383 | return if $class->loading_psgi_file; | 
| 3258 | 6955 | 100 |  |  |  | 12979 |  | 
| 3259 | 475 |  |  |  |  | 2057 | load_class($engine); | 
| 3260 |  |  |  |  |  |  |  | 
| 3261 |  |  |  |  |  |  | if ($ENV{MOD_PERL}) { | 
| 3262 | 6951 |  |  |  |  | 31954 | my $apache = $class->engine_loader->auto; | 
| 3263 |  |  |  |  |  |  |  | 
| 3264 |  |  |  |  |  |  | my $meta = find_meta($class); | 
| 3265 |  |  |  |  |  |  | my $was_immutable = $meta->is_immutable; | 
| 3266 |  |  |  |  |  |  | my %immutable_options = $meta->immutable_options; | 
| 3267 |  |  |  |  |  |  | $meta->make_mutable if $was_immutable; | 
| 3268 |  |  |  |  |  |  |  | 
| 3269 |  |  |  |  |  |  | $meta->add_method(handler => sub { | 
| 3270 |  |  |  |  |  |  | my $r = shift; | 
| 3271 |  |  |  |  |  |  | my $psgi_app = $class->_finalized_psgi_app; | 
| 3272 |  |  |  |  |  |  | $apache->call_app($r, $psgi_app); | 
| 3273 |  |  |  |  |  |  | }); | 
| 3274 |  |  |  |  |  |  |  | 
| 3275 |  |  |  |  |  |  | $meta->make_immutable(%immutable_options) if $was_immutable; | 
| 3276 |  |  |  |  |  |  | } | 
| 3277 |  |  |  |  |  |  |  | 
| 3278 |  |  |  |  |  |  | $class->engine( $engine->new ); | 
| 3279 |  |  |  |  |  |  |  | 
| 3280 |  |  |  |  |  |  | return; | 
| 3281 |  |  |  |  |  |  | } | 
| 3282 |  |  |  |  |  |  |  | 
| 3283 |  |  |  |  |  |  | ## This exists just to supply a prebuild psgi app for mod_perl and for the | 
| 3284 |  |  |  |  |  |  | ## build in server support (back compat support for pre psgi port behavior). | 
| 3285 | 6951 |  |  | 6951 | 1 | 10831 | ## This is so that we don't build a new psgi app for each request when using | 
| 3286 | 6951 |  |  |  |  | 16387 | ## the mod_perl handler or the built in servers (http and fcgi, etc). | 
| 3287 | 6951 |  | 100 |  |  | 19660 |  | 
| 3288 |  |  |  |  |  |  | my ($app) = @_; | 
| 3289 | 6951 |  |  |  |  | 12150 |  | 
| 3290 |  |  |  |  |  |  | unless ($app->_psgi_app) { | 
| 3291 |  |  |  |  |  |  | my $psgi_app = $app->_setup_psgi_app; | 
| 3292 |  |  |  |  |  |  | $app->_psgi_app($psgi_app); | 
| 3293 |  |  |  |  |  |  | } | 
| 3294 |  |  |  |  |  |  |  | 
| 3295 |  |  |  |  |  |  | return $app->_psgi_app; | 
| 3296 |  |  |  |  |  |  | } | 
| 3297 |  |  |  |  |  |  |  | 
| 3298 |  |  |  |  |  |  | ## Look for a psgi file like 'myapp_web.psgi' (if the app is MyApp::Web) in the | 
| 3299 | 162 |  |  | 162 | 1 | 6900 | ## home directory and load that and return it (just assume it is doing the | 
| 3300 |  |  |  |  |  |  | ## right thing :) ).  If that does not exist, call $app->psgi_app, wrap that | 
| 3301 | 162 | 50 |  |  |  | 685 | ## in default_middleware and return it ( this is for backward compatibility | 
| 3302 | 0 |  |  |  |  | 0 | ## with pre psgi port behavior ). | 
| 3303 |  |  |  |  |  |  |  | 
| 3304 |  |  |  |  |  |  | my ($app) = @_; | 
| 3305 | 162 | 50 |  |  |  | 771 |  | 
| 3306 | 0 |  |  |  |  | 0 | for my $home (Path::Class::Dir->new($app->config->{home})) { | 
| 3307 |  |  |  |  |  |  | my $psgi_file = $home->file( | 
| 3308 |  |  |  |  |  |  | Catalyst::Utils::appprefix($app) . '.psgi', | 
| 3309 | 162 | 50 |  |  |  | 847 | ); | 
| 3310 | 162 |  |  |  |  | 1420 |  | 
| 3311 |  |  |  |  |  |  | next unless -e $psgi_file; | 
| 3312 |  |  |  |  |  |  |  | 
| 3313 | 162 |  |  |  |  | 1076 | # If $psgi_file calls ->setup_engine, it's doing so to load | 
| 3314 |  |  |  |  |  |  | # Catalyst::Engine::PSGI. But if it does that, we're only going to | 
| 3315 |  |  |  |  |  |  | # throw away the loaded PSGI-app and load the 5.9 Catalyst::Engine | 
| 3316 | 162 |  |  |  |  | 9982 | # anyway. So set a flag (ick) that tells setup_engine not to populate | 
| 3317 |  |  |  |  |  |  | # $c->engine or do any other things we might regret. | 
| 3318 |  |  |  |  |  |  |  | 
| 3319 |  |  |  |  |  |  | $app->loading_psgi_file(1); | 
| 3320 |  |  |  |  |  |  | my $psgi_app = Plack::Util::load_psgi($psgi_file); | 
| 3321 |  |  |  |  |  |  | $app->loading_psgi_file(0); | 
| 3322 |  |  |  |  |  |  |  | 
| 3323 |  |  |  |  |  |  | return $psgi_app | 
| 3324 |  |  |  |  |  |  | unless $app->engine_loader->needs_psgi_engine_compat_hack; | 
| 3325 |  |  |  |  |  |  |  | 
| 3326 | 0 |  |  | 0 | 1 | 0 | warn <<"EOW"; | 
| 3327 |  |  |  |  |  |  | Found a legacy Catalyst::Engine::PSGI .psgi file at ${psgi_file}. | 
| 3328 | 0 | 0 | 0 |  |  | 0 |  | 
| 3329 | 0 | 0 |  |  |  | 0 | Its content has been ignored. Please consult the Catalyst::Upgrading | 
| 3330 |  |  |  |  |  |  | documentation on how to upgrade from Catalyst::Engine::PSGI. | 
| 3331 |  |  |  |  |  |  | EOW | 
| 3332 |  |  |  |  |  |  | } | 
| 3333 |  |  |  |  |  |  |  | 
| 3334 |  |  |  |  |  |  | return $app->apply_default_middlewares($app->psgi_app); | 
| 3335 |  |  |  |  |  |  | } | 
| 3336 |  |  |  |  |  |  |  | 
| 3337 |  |  |  |  |  |  | =head2 $c->apply_default_middlewares | 
| 3338 | 0 |  |  |  |  | 0 |  | 
| 3339 |  |  |  |  |  |  | Adds the following L<Plack> middlewares to your application, since they are | 
| 3340 |  |  |  |  |  |  | useful and commonly needed: | 
| 3341 |  |  |  |  |  |  |  | 
| 3342 | 162 |  |  | 162 | 1 | 537 | L<Plack::Middleware::LighttpdScriptNameFix> (if you are using Lighttpd), | 
| 3343 |  |  |  |  |  |  | L<Plack::Middleware::IIS6ScriptNameFix> (always applied since this middleware | 
| 3344 | 162 |  |  |  |  | 369 | is smart enough to conditionally apply itself). | 
| 3345 | 162 |  |  |  |  | 1297 |  | 
| 3346 |  |  |  |  |  |  | We will also automatically add L<Plack::Middleware::ReverseProxy> if we notice | 
| 3347 | 162 | 50 | 33 |  |  | 1149 | that your HTTP $env variable C<REMOTE_ADDR> is '127.0.0.1'.  This is usually | 
| 3348 | 162 | 50 |  |  |  | 6716 | an indication that your server is running behind a proxy frontend.  However in | 
| 3349 |  |  |  |  |  |  | 2014 this is often not the case.  We preserve this code for backwards compatibility | 
| 3350 |  |  |  |  |  |  | however I B<highly> recommend that if you are running the server behind a front | 
| 3351 |  |  |  |  |  |  | end proxy that you clearly indicate so with the C<using_frontend_proxy> configuration | 
| 3352 |  |  |  |  |  |  | setting to true for your environment configurations that run behind a proxy.  This | 
| 3353 |  |  |  |  |  |  | way if you change your front end proxy address someday your code would inexplicably | 
| 3354 |  |  |  |  |  |  | stop working as expected. | 
| 3355 |  |  |  |  |  |  |  | 
| 3356 |  |  |  |  |  |  | Additionally if we detect we are using Nginx, we add a bit of custom middleware | 
| 3357 | 162 |  |  |  |  | 6345 | to solve some problems with the way that server handles $ENV{PATH_INFO} and | 
| 3358 |  |  |  |  |  |  | $ENV{SCRIPT_NAME}. | 
| 3359 |  |  |  |  |  |  |  | 
| 3360 |  |  |  |  |  |  | Please B<NOTE> that if you do use C<using_frontend_proxy> the middleware is now | 
| 3361 | 162 | 50 |  |  |  | 1894 | adding via C<registered_middleware> rather than this method. | 
| 3362 |  |  |  |  |  |  |  | 
| 3363 | 162 |  |  |  |  | 1199 | If you are using Lighttpd or IIS6 you may wish to apply these middlewares.  In | 
| 3364 |  |  |  |  |  |  | general this is no longer a common case but we have this here for backward | 
| 3365 | 162 | 50 |  |  |  | 4592 | compatibility. | 
| 3366 | 0 |  |  |  |  | 0 |  | 
| 3367 |  |  |  |  |  |  | =cut | 
| 3368 | 0 |  |  |  |  | 0 |  | 
| 3369 | 0 |  |  |  |  | 0 |  | 
| 3370 | 0 |  |  |  |  | 0 | my ($app, $psgi_app) = @_; | 
| 3371 | 0 | 0 |  |  |  | 0 |  | 
| 3372 |  |  |  |  |  |  | # Don't add this conditional IF we are explicitly saying we want the | 
| 3373 |  |  |  |  |  |  | # frontend proxy support.  We don't need it here since if that is the | 
| 3374 | 0 |  |  | 0 |  | 0 | # case it will be always loaded in the default_middleware. | 
| 3375 | 0 |  |  |  |  | 0 |  | 
| 3376 | 0 |  |  |  |  | 0 | unless($app->config->{using_frontend_proxy}) { | 
| 3377 | 0 |  |  |  |  | 0 | $psgi_app = Plack::Middleware::Conditional->wrap( | 
| 3378 |  |  |  |  |  |  | $psgi_app, | 
| 3379 | 0 | 0 |  |  |  | 0 | builder   => sub { Plack::Middleware::ReverseProxy->wrap($_[0]) }, | 
| 3380 |  |  |  |  |  |  | condition => sub { | 
| 3381 |  |  |  |  |  |  | my ($env) = @_; | 
| 3382 | 162 |  |  |  |  | 8685 | return if $app->config->{ignore_frontend_proxy}; | 
| 3383 |  |  |  |  |  |  | return $env->{REMOTE_ADDR} && $env->{REMOTE_ADDR} eq '127.0.0.1'; | 
| 3384 | 162 |  |  |  |  | 436 | }, | 
| 3385 |  |  |  |  |  |  | ); | 
| 3386 |  |  |  |  |  |  | } | 
| 3387 |  |  |  |  |  |  |  | 
| 3388 |  |  |  |  |  |  | # If we're running under Lighttpd, swap PATH_INFO and SCRIPT_NAME | 
| 3389 |  |  |  |  |  |  | # http://lists.scsys.co.uk/pipermail/catalyst/2006-June/008361.html | 
| 3390 |  |  |  |  |  |  | $psgi_app = Plack::Middleware::Conditional->wrap( | 
| 3391 |  |  |  |  |  |  | $psgi_app, | 
| 3392 |  |  |  |  |  |  | builder   => sub { Plack::Middleware::LighttpdScriptNameFix->wrap($_[0]) }, | 
| 3393 | 908 |  |  | 908 |  | 2178 | condition => sub { | 
| 3394 |  |  |  |  |  |  | my ($env) = @_; | 
| 3395 | 908 | 100 |  |  |  | 3536 | return unless $env->{SERVER_SOFTWARE} && $env->{SERVER_SOFTWARE} =~ m!lighttpd[-/]1\.(\d+\.\d+)!; | 
| 3396 | 121 |  |  |  |  | 1024 | return unless $1 < 4.23; | 
| 3397 | 121 |  |  |  |  | 630 | 1; | 
| 3398 |  |  |  |  |  |  | }, | 
| 3399 |  |  |  |  |  |  | ); | 
| 3400 | 908 |  |  |  |  | 2558 |  | 
| 3401 |  |  |  |  |  |  | # we're applying this unconditionally as the middleware itself already makes | 
| 3402 |  |  |  |  |  |  | # sure it doesn't fuck things up if it's not running under one of the right | 
| 3403 |  |  |  |  |  |  | # IIS versions | 
| 3404 |  |  |  |  |  |  | $psgi_app = Plack::Middleware::IIS6ScriptNameFix->wrap($psgi_app); | 
| 3405 |  |  |  |  |  |  |  | 
| 3406 |  |  |  |  |  |  | # And another IIS issue, this time with IIS7. | 
| 3407 |  |  |  |  |  |  | $psgi_app = Plack::Middleware::Conditional->wrap( | 
| 3408 |  |  |  |  |  |  | $psgi_app, | 
| 3409 |  |  |  |  |  |  | builder => sub { Plack::Middleware::IIS7KeepAliveFix->wrap($_[0]) }, | 
| 3410 | 121 |  |  | 121 |  | 400 | condition => sub { | 
| 3411 |  |  |  |  |  |  | my ($env) = @_; | 
| 3412 | 121 |  |  |  |  | 900 | return $env->{SERVER_SOFTWARE} && $env->{SERVER_SOFTWARE} =~ m!IIS/7\.[0-9]!; | 
| 3413 | 90 |  |  |  |  | 11354 | }, | 
| 3414 |  |  |  |  |  |  | ); | 
| 3415 |  |  |  |  |  |  |  | 
| 3416 |  |  |  |  |  |  | return $psgi_app; | 
| 3417 | 90 | 100 |  |  |  | 11838 | } | 
| 3418 |  |  |  |  |  |  |  | 
| 3419 |  |  |  |  |  |  | =head2 App->psgi_app | 
| 3420 |  |  |  |  |  |  |  | 
| 3421 |  |  |  |  |  |  | =head2 App->to_app | 
| 3422 |  |  |  |  |  |  |  | 
| 3423 |  |  |  |  |  |  | Returns a PSGI application code reference for the catalyst application | 
| 3424 |  |  |  |  |  |  | C<$c>. This is the bare application created without the C<apply_default_middlewares> | 
| 3425 | 2 |  |  |  |  | 176 | method called.  We do however apply C<registered_middleware> since those are | 
| 3426 | 2 |  |  |  |  | 24 | integral to how L<Catalyst> functions.  Also, unlike starting your application | 
| 3427 | 2 |  |  |  |  | 73 | with a generated server script (via L<Catalyst::Devel> and C<catalyst.pl>) we do | 
| 3428 |  |  |  |  |  |  | not attempt to return a valid L<PSGI> application using any existing C<${myapp}.psgi> | 
| 3429 | 2 | 50 |  |  |  | 31 | scripts in your $HOME directory. | 
| 3430 |  |  |  |  |  |  |  | 
| 3431 |  |  |  |  |  |  | B<NOTE> C<apply_default_middlewares> was originally created when the first PSGI | 
| 3432 | 0 |  |  |  |  | 0 | port was done for v5.90000.  These are middlewares that are added to achieve | 
| 3433 |  |  |  |  |  |  | backward compatibility with older applications.  If you start your application | 
| 3434 |  |  |  |  |  |  | using one of the supplied server scripts (generated with L<Catalyst::Devel> and | 
| 3435 |  |  |  |  |  |  | the project skeleton script C<catalyst.pl>) we apply C<apply_default_middlewares> | 
| 3436 |  |  |  |  |  |  | automatically.  This was done so that pre and post PSGI port applications would | 
| 3437 |  |  |  |  |  |  | work the same way. | 
| 3438 |  |  |  |  |  |  |  | 
| 3439 |  |  |  |  |  |  | This is what you want to be using to retrieve the PSGI application code | 
| 3440 | 119 |  |  |  |  | 8703 | reference of your Catalyst application for use in a custom F<.psgi> or in your | 
| 3441 |  |  |  |  |  |  | own created server modules. | 
| 3442 |  |  |  |  |  |  |  | 
| 3443 |  |  |  |  |  |  | =cut | 
| 3444 |  |  |  |  |  |  |  | 
| 3445 |  |  |  |  |  |  | *to_app = \&psgi_app; | 
| 3446 |  |  |  |  |  |  |  | 
| 3447 |  |  |  |  |  |  | my ($app) = @_; | 
| 3448 |  |  |  |  |  |  | my $psgi = $app->engine->build_psgi_app($app); | 
| 3449 |  |  |  |  |  |  | return $app->Catalyst::Utils::apply_registered_middleware($psgi); | 
| 3450 |  |  |  |  |  |  | } | 
| 3451 |  |  |  |  |  |  |  | 
| 3452 |  |  |  |  |  |  | =head2 $c->setup_home | 
| 3453 |  |  |  |  |  |  |  | 
| 3454 |  |  |  |  |  |  | Sets up the home directory. | 
| 3455 |  |  |  |  |  |  |  | 
| 3456 |  |  |  |  |  |  | =cut | 
| 3457 |  |  |  |  |  |  |  | 
| 3458 |  |  |  |  |  |  | my ( $class, $home ) = @_; | 
| 3459 |  |  |  |  |  |  |  | 
| 3460 |  |  |  |  |  |  | if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) { | 
| 3461 |  |  |  |  |  |  | $home = $env; | 
| 3462 |  |  |  |  |  |  | } | 
| 3463 |  |  |  |  |  |  |  | 
| 3464 |  |  |  |  |  |  | $home ||= Catalyst::Utils::home($class); | 
| 3465 |  |  |  |  |  |  |  | 
| 3466 |  |  |  |  |  |  | if ($home) { | 
| 3467 |  |  |  |  |  |  | #I remember recently being scolded for assigning config values like this | 
| 3468 |  |  |  |  |  |  | $class->config->{home} ||= $home; | 
| 3469 |  |  |  |  |  |  | $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root'); | 
| 3470 |  |  |  |  |  |  | } | 
| 3471 |  |  |  |  |  |  | } | 
| 3472 |  |  |  |  |  |  |  | 
| 3473 |  |  |  |  |  |  | =head2 $c->setup_encoding | 
| 3474 |  |  |  |  |  |  |  | 
| 3475 |  |  |  |  |  |  | Sets up the input/output encoding. See L<ENCODING> | 
| 3476 |  |  |  |  |  |  |  | 
| 3477 | 121 |  |  | 121 | 1 | 774 | =cut | 
| 3478 |  |  |  |  |  |  |  | 
| 3479 |  |  |  |  |  |  | my $c = shift; | 
| 3480 |  |  |  |  |  |  | if( exists($c->config->{encoding}) && !defined($c->config->{encoding}) ) { | 
| 3481 |  |  |  |  |  |  | # Ok, so the user has explicitly said "I don't want encoding..." | 
| 3482 |  |  |  |  |  |  | return; | 
| 3483 | 121 | 50 |  |  |  | 518 | } else { | 
| 3484 |  |  |  |  |  |  | my $enc = defined($c->config->{encoding}) ? | 
| 3485 |  |  |  |  |  |  | delete $c->config->{encoding} : 'UTF-8'; # not sure why we delete it... (JNAP) | 
| 3486 | 121 |  |  | 121 |  | 10676 | $c->encoding($enc); | 
| 3487 |  |  |  |  |  |  | } | 
| 3488 | 908 |  |  | 908 |  | 10336 | } | 
| 3489 | 908 | 100 |  |  |  | 4476 |  | 
| 3490 | 907 |  | 66 |  |  | 4813 | =head2 handle_unicode_encoding_exception | 
| 3491 |  |  |  |  |  |  |  | 
| 3492 | 121 |  |  |  |  | 1850 | Hook to let you customize how encoding errors are handled. By default | 
| 3493 |  |  |  |  |  |  | we just throw an exception and the default error page will pick it up. | 
| 3494 |  |  |  |  |  |  | Receives a hashref of debug information. Example of call (from the | 
| 3495 |  |  |  |  |  |  | Catalyst internals): | 
| 3496 |  |  |  |  |  |  |  | 
| 3497 |  |  |  |  |  |  | my $decoded_after_fail = $c->handle_unicode_encoding_exception({ | 
| 3498 |  |  |  |  |  |  | param_value => $value, | 
| 3499 | 121 |  |  | 121 |  | 4200 | error_msg => $_, | 
| 3500 |  |  |  |  |  |  | encoding_step => 'params', | 
| 3501 | 908 |  |  | 908 |  | 24895 | }); | 
| 3502 | 908 | 100 | 100 |  |  | 3287 |  | 
| 3503 | 1 | 50 |  |  |  | 7 | The calling code expects to receive a decoded string or an exception. | 
| 3504 | 1 |  |  |  |  | 3 |  | 
| 3505 |  |  |  |  |  |  | You can override this for custom handling of unicode errors. By | 
| 3506 | 121 |  |  |  |  | 5569 | default we just die. If you want a custom response here, one approach | 
| 3507 |  |  |  |  |  |  | is to throw an HTTP style exception, instead of returning a decoded | 
| 3508 |  |  |  |  |  |  | string or throwing a generic exception. | 
| 3509 |  |  |  |  |  |  |  | 
| 3510 |  |  |  |  |  |  | sub handle_unicode_encoding_exception { | 
| 3511 | 121 |  |  |  |  | 10572 | my ($c, $params) = @_; | 
| 3512 |  |  |  |  |  |  | HTTP::Exception::BAD_REQUEST->throw(status_message=>$params->{error_msg}); | 
| 3513 |  |  |  |  |  |  | } | 
| 3514 |  |  |  |  |  |  |  | 
| 3515 |  |  |  |  |  |  | Alternatively you can 'catch' the error, stash it and write handling code later | 
| 3516 | 121 |  |  | 121 |  | 4081 | in your application: | 
| 3517 |  |  |  |  |  |  |  | 
| 3518 | 908 |  |  | 908 |  | 12458 | sub handle_unicode_encoding_exception { | 
| 3519 | 908 |  | 66 |  |  | 3287 | my ($c, $params) = @_; | 
| 3520 |  |  |  |  |  |  | $c->stash(BAD_UNICODE_DATA=>$params); | 
| 3521 | 121 |  |  |  |  | 4306 | # return a dummy string. | 
| 3522 |  |  |  |  |  |  | return 1; | 
| 3523 | 121 |  |  |  |  | 4157 | } | 
| 3524 |  |  |  |  |  |  |  | 
| 3525 |  |  |  |  |  |  | <B>NOTE:</b> Please keep in mind that once an error like this occurs, | 
| 3526 |  |  |  |  |  |  | the request setup is still ongoing, which means the state of C<$c> and | 
| 3527 |  |  |  |  |  |  | related context parts like the request and response may not be setup | 
| 3528 |  |  |  |  |  |  | up correctly (since we haven't finished the setup yet). If you throw | 
| 3529 |  |  |  |  |  |  | an exception the setup is aborted. | 
| 3530 |  |  |  |  |  |  |  | 
| 3531 |  |  |  |  |  |  | =cut | 
| 3532 |  |  |  |  |  |  |  | 
| 3533 |  |  |  |  |  |  | my ( $self, $exception_ctx ) = @_; | 
| 3534 |  |  |  |  |  |  | die $exception_ctx->{error_msg}; | 
| 3535 |  |  |  |  |  |  | } | 
| 3536 |  |  |  |  |  |  |  | 
| 3537 |  |  |  |  |  |  | # Some unicode helpers cargo culted from the old plugin.  These could likely | 
| 3538 |  |  |  |  |  |  | # be neater. | 
| 3539 |  |  |  |  |  |  |  | 
| 3540 |  |  |  |  |  |  | my ( $self, $value ) = @_; | 
| 3541 |  |  |  |  |  |  |  | 
| 3542 |  |  |  |  |  |  | return unless defined $value; | 
| 3543 |  |  |  |  |  |  |  | 
| 3544 |  |  |  |  |  |  | ## I think this mess is to support the old nested | 
| 3545 |  |  |  |  |  |  | if ( ref $value eq 'ARRAY' ) { | 
| 3546 |  |  |  |  |  |  | foreach ( @$value ) { | 
| 3547 |  |  |  |  |  |  | $_ = $self->_handle_unicode_decoding($_); | 
| 3548 |  |  |  |  |  |  | } | 
| 3549 |  |  |  |  |  |  | return $value; | 
| 3550 |  |  |  |  |  |  | } | 
| 3551 |  |  |  |  |  |  | elsif ( ref $value eq 'HASH' ) { | 
| 3552 |  |  |  |  |  |  | foreach (keys %$value) { | 
| 3553 |  |  |  |  |  |  | my $encoded_key = $self->_handle_param_unicode_decoding($_); | 
| 3554 |  |  |  |  |  |  | $value->{$encoded_key} = $self->_handle_unicode_decoding($value->{$_}); | 
| 3555 | 133 |  |  | 133 | 1 | 3592 |  | 
| 3556 | 133 |  |  |  |  | 898 | # If the key was encoded we now have two (the original and current so | 
| 3557 | 133 |  |  |  |  | 1108 | # delete the original. | 
| 3558 |  |  |  |  |  |  | delete $value->{$_} if $_ ne $encoded_key; | 
| 3559 |  |  |  |  |  |  | } | 
| 3560 |  |  |  |  |  |  | return $value; | 
| 3561 |  |  |  |  |  |  | } | 
| 3562 |  |  |  |  |  |  | else { | 
| 3563 |  |  |  |  |  |  | return $self->_handle_param_unicode_decoding($value); | 
| 3564 |  |  |  |  |  |  | } | 
| 3565 |  |  |  |  |  |  | } | 
| 3566 |  |  |  |  |  |  |  | 
| 3567 | 319 |  |  | 319 | 1 | 904 | my ( $self, $value, $check ) = @_; | 
| 3568 |  |  |  |  |  |  | return unless defined $value; # not in love with just ignoring undefs - jnap | 
| 3569 | 319 | 100 |  |  |  | 1485 | return $value if blessed($value); #don't decode when the value is an object. | 
| 3570 | 2 |  |  |  |  | 3 |  | 
| 3571 |  |  |  |  |  |  | my $enc = $self->encoding; | 
| 3572 |  |  |  |  |  |  |  | 
| 3573 | 319 |  | 100 |  |  | 1667 | return $value unless $enc; # don't decode if no encoding is specified | 
| 3574 |  |  |  |  |  |  |  | 
| 3575 | 319 | 100 |  |  |  | 33359 | $check ||= $self->_encode_check; | 
| 3576 |  |  |  |  |  |  | return try { | 
| 3577 | 219 |  | 66 |  |  | 1093 | $enc->decode( $value, $check); | 
| 3578 | 219 |  | 66 |  |  | 685 | } | 
| 3579 |  |  |  |  |  |  | catch { | 
| 3580 |  |  |  |  |  |  | return $self->handle_unicode_encoding_exception({ | 
| 3581 |  |  |  |  |  |  | param_value => $value, | 
| 3582 |  |  |  |  |  |  | error_msg => $_, | 
| 3583 |  |  |  |  |  |  | encoding_step => 'params', | 
| 3584 |  |  |  |  |  |  | }); | 
| 3585 |  |  |  |  |  |  | }; | 
| 3586 |  |  |  |  |  |  | } | 
| 3587 |  |  |  |  |  |  |  | 
| 3588 |  |  |  |  |  |  | =head2 $c->setup_log | 
| 3589 | 162 |  |  | 162 | 1 | 428 |  | 
| 3590 | 162 | 100 | 100 |  |  | 3192 | Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and | 
| 3591 |  |  |  |  |  |  | passing it to C<log()>. Pass in a comma-delimited list of levels to set the | 
| 3592 | 1 |  |  |  |  | 2 | log to. | 
| 3593 |  |  |  |  |  |  |  | 
| 3594 |  |  |  |  |  |  | This method also installs a C<debug> method that returns a true value into the | 
| 3595 | 161 | 100 |  |  |  | 4237 | catalyst subclass if the "debug" level is passed in the comma-delimited list, | 
| 3596 | 161 |  |  |  |  | 1458 | or if the C<$CATALYST_DEBUG> environment variable is set to a true value. | 
| 3597 |  |  |  |  |  |  |  | 
| 3598 |  |  |  |  |  |  | Note that if the log has already been setup, by either a previous call to | 
| 3599 |  |  |  |  |  |  | C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>, | 
| 3600 |  |  |  |  |  |  | that this method won't actually set up the log object. | 
| 3601 |  |  |  |  |  |  |  | 
| 3602 |  |  |  |  |  |  | =cut | 
| 3603 |  |  |  |  |  |  |  | 
| 3604 |  |  |  |  |  |  | my ( $class, $levels ) = @_; | 
| 3605 |  |  |  |  |  |  |  | 
| 3606 |  |  |  |  |  |  | $levels ||= ''; | 
| 3607 |  |  |  |  |  |  | $levels =~ s/^\s+//; | 
| 3608 |  |  |  |  |  |  | $levels =~ s/\s+$//; | 
| 3609 |  |  |  |  |  |  | my %levels = map { $_ => 1 } split /\s*,\s*/, $levels; | 
| 3610 |  |  |  |  |  |  |  | 
| 3611 |  |  |  |  |  |  | my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' ); | 
| 3612 |  |  |  |  |  |  | if ( defined $env_debug ) { | 
| 3613 |  |  |  |  |  |  | $levels{debug} = 1 if $env_debug; # Ugly! | 
| 3614 |  |  |  |  |  |  | delete($levels{debug}) unless $env_debug; | 
| 3615 |  |  |  |  |  |  | } | 
| 3616 |  |  |  |  |  |  |  | 
| 3617 |  |  |  |  |  |  | unless ( $class->log ) { | 
| 3618 |  |  |  |  |  |  | $class->log( Catalyst::Log->new(keys %levels) ); | 
| 3619 |  |  |  |  |  |  | } | 
| 3620 |  |  |  |  |  |  |  | 
| 3621 |  |  |  |  |  |  | if ( $levels{debug} ) { | 
| 3622 |  |  |  |  |  |  | Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 }); | 
| 3623 |  |  |  |  |  |  | $class->log->debug('Debug messages enabled'); | 
| 3624 |  |  |  |  |  |  | } | 
| 3625 |  |  |  |  |  |  | } | 
| 3626 |  |  |  |  |  |  |  | 
| 3627 |  |  |  |  |  |  | =head2 $c->setup_plugins | 
| 3628 |  |  |  |  |  |  |  | 
| 3629 |  |  |  |  |  |  | Sets up plugins. | 
| 3630 |  |  |  |  |  |  |  | 
| 3631 |  |  |  |  |  |  | =cut | 
| 3632 |  |  |  |  |  |  |  | 
| 3633 |  |  |  |  |  |  | =head2 $c->setup_stats | 
| 3634 |  |  |  |  |  |  |  | 
| 3635 |  |  |  |  |  |  | Sets up timing statistics class. | 
| 3636 |  |  |  |  |  |  |  | 
| 3637 |  |  |  |  |  |  | =cut | 
| 3638 |  |  |  |  |  |  |  | 
| 3639 |  |  |  |  |  |  | my ( $class, $stats ) = @_; | 
| 3640 |  |  |  |  |  |  |  | 
| 3641 |  |  |  |  |  |  | Catalyst::Utils::ensure_class_loaded($class->stats_class); | 
| 3642 |  |  |  |  |  |  |  | 
| 3643 |  |  |  |  |  |  | my $env = Catalyst::Utils::env_value( $class, 'STATS' ); | 
| 3644 | 3 |  |  | 3 | 1 | 7 | if ( defined($env) ? $env : ($stats || $class->debug ) ) { | 
| 3645 | 3 |  |  |  |  | 20 | Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 }); | 
| 3646 |  |  |  |  |  |  | $class->log->debug('Statistics enabled'); | 
| 3647 |  |  |  |  |  |  | } | 
| 3648 |  |  |  |  |  |  | } | 
| 3649 |  |  |  |  |  |  |  | 
| 3650 |  |  |  |  |  |  |  | 
| 3651 |  |  |  |  |  |  | =head2 $c->registered_plugins | 
| 3652 | 120 |  |  | 120 |  | 246 |  | 
| 3653 |  |  |  |  |  |  | Returns a sorted list of the plugins which have either been stated in the | 
| 3654 | 120 | 50 |  |  |  | 263 | import list. | 
| 3655 |  |  |  |  |  |  |  | 
| 3656 |  |  |  |  |  |  | If passed a given plugin name, it will report a boolean value indicating | 
| 3657 | 120 | 100 |  |  |  | 347 | whether or not that plugin is loaded.  A fully qualified name is required if | 
|  |  | 100 |  |  |  |  |  | 
| 3658 | 3 |  |  |  |  | 6 | the plugin name does not begin with C<Catalyst::Plugin::>. | 
| 3659 | 12 |  |  |  |  | 150 |  | 
| 3660 |  |  |  |  |  |  | if ($c->registered_plugins('Some::Plugin')) { | 
| 3661 | 3 |  |  |  |  | 53 | ... | 
| 3662 |  |  |  |  |  |  | } | 
| 3663 |  |  |  |  |  |  |  | 
| 3664 | 36 |  |  |  |  | 128 | =cut | 
| 3665 | 34 |  |  |  |  | 105 |  | 
| 3666 | 34 |  |  |  |  | 679 | { | 
| 3667 |  |  |  |  |  |  |  | 
| 3668 |  |  |  |  |  |  | my $proto = shift; | 
| 3669 |  |  |  |  |  |  | return sort keys %{ $proto->_plugins } unless @_; | 
| 3670 | 33 | 100 |  |  |  | 521 | my $plugin = shift; | 
| 3671 |  |  |  |  |  |  | return 1 if exists $proto->_plugins->{$plugin}; | 
| 3672 | 35 |  |  |  |  | 128 | return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"}; | 
| 3673 |  |  |  |  |  |  | } | 
| 3674 |  |  |  |  |  |  |  | 
| 3675 | 81 |  |  |  |  | 196 | my ( $proto, $plugin, $instant ) = @_; | 
| 3676 |  |  |  |  |  |  | my $class = ref $proto || $proto; | 
| 3677 |  |  |  |  |  |  |  | 
| 3678 |  |  |  |  |  |  | load_class( $plugin ); | 
| 3679 |  |  |  |  |  |  | $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is deprecated and will not work in 5.81" ) | 
| 3680 | 1217 |  |  | 1217 |  | 2511 | if $plugin->isa( 'Catalyst::Component' ); | 
| 3681 | 1217 | 50 |  |  |  | 2306 | my $plugin_meta = Moose::Meta::Class->create($plugin); | 
| 3682 | 1217 | 50 |  |  |  | 2881 | if (!$plugin_meta->has_method('new') | 
| 3683 |  |  |  |  |  |  | && ( $plugin->isa('Class::Accessor::Fast') || $plugin->isa('Class::Accessor') ) ) { | 
| 3684 | 1217 |  |  |  |  | 2229 | $plugin_meta->add_method('new', Moose::Object->meta->get_method('new')) | 
| 3685 |  |  |  |  |  |  | } | 
| 3686 | 1217 | 100 |  |  |  | 2792 | if (!$instant && !$proto->_plugins->{$plugin}) { | 
| 3687 |  |  |  |  |  |  | my $meta = Class::MOP::get_metaclass_by_name($class); | 
| 3688 | 1213 |  | 66 |  |  | 3812 | $meta->superclasses($plugin, $meta->superclasses); | 
| 3689 |  |  |  |  |  |  | } | 
| 3690 | 1213 |  |  | 1213 |  | 46285 | $proto->_plugins->{$plugin} = 1; | 
| 3691 |  |  |  |  |  |  | return $class; | 
| 3692 |  |  |  |  |  |  | } | 
| 3693 | 19 |  |  | 19 |  | 509 |  | 
| 3694 |  |  |  |  |  |  |  | 
| 3695 |  |  |  |  |  |  | my ( $class, $plugins ) = @_; | 
| 3696 |  |  |  |  |  |  |  | 
| 3697 |  |  |  |  |  |  | $class->_plugins( {} ) unless $class->_plugins; | 
| 3698 | 1213 |  |  |  |  | 7452 | $plugins = [ grep { | 
| 3699 |  |  |  |  |  |  | m/Unicode::Encoding/ ? do { | 
| 3700 |  |  |  |  |  |  | $class->log->warn( | 
| 3701 |  |  |  |  |  |  | 'Unicode::Encoding plugin is auto-applied,' | 
| 3702 |  |  |  |  |  |  | . ' please remove this from your appclass' | 
| 3703 |  |  |  |  |  |  | . ' and make sure to define "encoding" config' | 
| 3704 |  |  |  |  |  |  | ); | 
| 3705 |  |  |  |  |  |  | unless (exists $class->config->{'encoding'}) { | 
| 3706 |  |  |  |  |  |  | $class->config->{'encoding'} = 'UTF-8'; | 
| 3707 |  |  |  |  |  |  | } | 
| 3708 |  |  |  |  |  |  | () } | 
| 3709 |  |  |  |  |  |  | : $_ | 
| 3710 |  |  |  |  |  |  | } @$plugins ]; | 
| 3711 |  |  |  |  |  |  | push @$plugins, $class->_default_plugins; | 
| 3712 |  |  |  |  |  |  | $plugins = Data::OptList::mkopt($plugins || []); | 
| 3713 |  |  |  |  |  |  |  | 
| 3714 |  |  |  |  |  |  | my @plugins = map { | 
| 3715 |  |  |  |  |  |  | [ Catalyst::Utils::resolve_namespace( | 
| 3716 |  |  |  |  |  |  | $class . '::Plugin', | 
| 3717 |  |  |  |  |  |  | 'Catalyst::Plugin', $_->[0] | 
| 3718 | 174 |  |  | 174 | 1 | 28959 | ), | 
| 3719 |  |  |  |  |  |  | $_->[1], | 
| 3720 | 174 |  | 100 |  |  | 1112 | ] | 
| 3721 | 174 |  |  |  |  | 476 | } @{ $plugins }; | 
| 3722 | 174 |  |  |  |  | 404 |  | 
| 3723 | 174 |  |  |  |  | 691 | for my $plugin ( reverse @plugins ) { | 
|  | 23 |  |  |  |  | 83 |  | 
| 3724 |  |  |  |  |  |  | load_class($plugin->[0], $plugin->[1]); | 
| 3725 | 174 |  |  |  |  | 668 | my $meta = find_meta($plugin->[0]); | 
| 3726 | 174 | 100 |  |  |  | 706 | next if $meta && $meta->isa('Moose::Meta::Role'); | 
| 3727 | 4 | 100 |  |  |  | 24 |  | 
| 3728 | 4 | 100 |  |  |  | 20 | $class->_register_plugin($plugin->[0]); | 
| 3729 |  |  |  |  |  |  | } | 
| 3730 |  |  |  |  |  |  |  | 
| 3731 | 174 | 100 |  |  |  | 1028 | my @roles = | 
| 3732 | 150 |  |  |  |  | 1587 | map  { $_->[0]->name, $_->[1] } | 
| 3733 |  |  |  |  |  |  | grep { blessed($_->[0]) && $_->[0]->isa('Moose::Meta::Role') } | 
| 3734 |  |  |  |  |  |  | map  { [find_meta($_->[0]), $_->[1]] } | 
| 3735 | 174 | 100 |  |  |  | 1170 | @plugins; | 
| 3736 | 5 |  |  | 33 |  | 20 |  | 
|  | 33 |  |  | 18 |  | 1435 |  | 
| 3737 | 5 |  |  |  |  | 258 | Moose::Util::apply_all_roles( | 
| 3738 |  |  |  |  |  |  | $class => @roles | 
| 3739 |  |  |  |  |  |  | ) if @roles; | 
| 3740 |  |  |  |  |  |  | } | 
| 3741 |  |  |  |  |  |  | } | 
| 3742 |  |  |  |  |  |  |  | 
| 3743 |  |  |  |  |  |  | =head2 default_middleware | 
| 3744 |  |  |  |  |  |  |  | 
| 3745 |  |  |  |  |  |  | Returns a list of instantiated PSGI middleware objects which is the default | 
| 3746 |  |  |  |  |  |  | middleware that is active for this application (taking any configuration | 
| 3747 |  |  |  |  |  |  | options into account, excluding your custom added middleware via the C<psgi_middleware> | 
| 3748 |  |  |  |  |  |  | configuration option).  You can override this method if you wish to change | 
| 3749 |  |  |  |  |  |  | the default middleware (although do so at risk since some middleware is vital | 
| 3750 |  |  |  |  |  |  | to application function.) | 
| 3751 |  |  |  |  |  |  |  | 
| 3752 |  |  |  |  |  |  | The current default middleware list is: | 
| 3753 |  |  |  |  |  |  |  | 
| 3754 | 167 |  |  | 167 | 1 | 27916 | Catalyst::Middleware::Stash | 
| 3755 |  |  |  |  |  |  | Plack::Middleware::HTTPExceptions | 
| 3756 | 167 |  |  |  |  | 2779 | Plack::Middleware::RemoveRedundantBody | 
| 3757 |  |  |  |  |  |  | Plack::Middleware::FixMissingBodyInRedirect | 
| 3758 | 167 |  |  |  |  | 2681 | Plack::Middleware::ContentLength | 
| 3759 | 167 | 100 | 100 |  |  | 14188 | Plack::Middleware::MethodOverride | 
|  |  | 100 |  |  |  |  |  | 
| 3760 | 11 |  |  | 258 |  | 61 | Plack::Middleware::Head | 
|  | 258 |  |  |  |  | 1229 |  | 
| 3761 | 11 |  |  |  |  | 713 |  | 
| 3762 |  |  |  |  |  |  | If the configuration setting C<using_frontend_proxy> is true we add: | 
| 3763 |  |  |  |  |  |  |  | 
| 3764 |  |  |  |  |  |  | Plack::Middleware::ReverseProxy | 
| 3765 |  |  |  |  |  |  |  | 
| 3766 |  |  |  |  |  |  | If the configuration setting C<using_frontend_proxy_path> is true we add: | 
| 3767 |  |  |  |  |  |  |  | 
| 3768 |  |  |  |  |  |  | Plack::Middleware::ReverseProxyPath | 
| 3769 |  |  |  |  |  |  |  | 
| 3770 |  |  |  |  |  |  | But B<NOTE> that L<Plack::Middleware::ReverseProxyPath> is not a dependency of the | 
| 3771 |  |  |  |  |  |  | L<Catalyst> distribution so if you want to use this option you should add it to | 
| 3772 |  |  |  |  |  |  | your project distribution file. | 
| 3773 |  |  |  |  |  |  |  | 
| 3774 |  |  |  |  |  |  | These middlewares will be added at L</setup_middleware> during the | 
| 3775 |  |  |  |  |  |  | L</setup> phase of application startup. | 
| 3776 |  |  |  |  |  |  |  | 
| 3777 |  |  |  |  |  |  | =cut | 
| 3778 |  |  |  |  |  |  |  | 
| 3779 |  |  |  |  |  |  | my $class = shift; | 
| 3780 |  |  |  |  |  |  | my @mw = ( | 
| 3781 |  |  |  |  |  |  | Catalyst::Middleware::Stash->new, | 
| 3782 |  |  |  |  |  |  | Plack::Middleware::HTTPExceptions->new, | 
| 3783 |  |  |  |  |  |  | Plack::Middleware::RemoveRedundantBody->new, | 
| 3784 | 634 |  |  | 892 | 1 | 40054 | Plack::Middleware::FixMissingBodyInRedirect->new, | 
| 3785 | 634 | 100 |  |  |  | 1701 | Plack::Middleware::ContentLength->new, | 
|  | 627 |  |  |  |  | 2354 |  | 
| 3786 | 7 |  |  |  |  | 10 | Plack::Middleware::MethodOverride->new, | 
| 3787 | 7 | 100 |  |  |  | 19 | Plack::Middleware::Head->new); | 
| 3788 | 4 |  |  |  |  | 8 |  | 
| 3789 |  |  |  |  |  |  | if($class->config->{using_frontend_proxy}) { | 
| 3790 |  |  |  |  |  |  | push @mw, Plack::Middleware::ReverseProxy->new; | 
| 3791 |  |  |  |  |  |  | } | 
| 3792 | 564 |  |  | 567 |  | 1295 |  | 
| 3793 | 564 |  | 33 |  |  | 2050 | if($class->config->{using_frontend_proxy_path}) { | 
| 3794 |  |  |  |  |  |  | if(Class::Load::try_load_class('Plack::Middleware::ReverseProxyPath')) { | 
| 3795 | 564 |  |  |  |  | 1465 | push @mw, Plack::Middleware::ReverseProxyPath->new; | 
| 3796 | 564 | 50 |  |  |  | 19207 | } else { | 
| 3797 |  |  |  |  |  |  | $class->log->error("Cannot use configuration 'using_frontend_proxy_path' because 'Plack::Middleware::ReverseProxyPath' is not installed"); | 
| 3798 | 564 |  |  |  |  | 2697 | } | 
| 3799 | 564 | 100 | 66 |  |  | 471878 | } | 
|  |  |  | 66 |  |  |  |  | 
| 3800 |  |  |  |  |  |  |  | 
| 3801 | 1 |  |  |  |  | 41 | return @mw; | 
| 3802 |  |  |  |  |  |  | } | 
| 3803 | 564 | 50 | 66 |  |  | 18976 |  | 
| 3804 | 563 |  |  |  |  | 1331 | =head2 registered_middlewares | 
| 3805 | 563 |  |  |  |  | 2439 |  | 
| 3806 |  |  |  |  |  |  | Read only accessor that returns an array of all the middleware in the order | 
| 3807 | 564 |  |  |  |  | 2277805 | that they were added (which is the REVERSE of the order they will be applied). | 
| 3808 | 564 |  |  |  |  | 1463 |  | 
| 3809 |  |  |  |  |  |  | The values returned will be either instances of L<Plack::Middleware> or of a | 
| 3810 |  |  |  |  |  |  | compatible interface, or a coderef, which is assumed to be inlined middleware | 
| 3811 | 162 |  |  | 162 |  | 455 |  | 
| 3812 |  |  |  |  |  |  | =head2 setup_middleware (?@middleware) | 
| 3813 |  |  |  |  |  |  |  | 
| 3814 | 162 |  |  | 162 | 1 | 582 | Read configuration information stored in configuration key C<psgi_middleware> or | 
| 3815 |  |  |  |  |  |  | from passed @args. | 
| 3816 | 162 | 50 |  |  |  | 1174 |  | 
| 3817 |  |  |  |  |  |  | See under L</CONFIGURATION> information regarding C<psgi_middleware> and how | 
| 3818 | 162 | 50 |  |  |  | 722 | to use it to enable L<Plack::Middleware> | 
|  | 643 |  |  |  |  | 1705 |  | 
| 3819 | 0 |  |  |  |  | 0 |  | 
| 3820 |  |  |  |  |  |  | This method is automatically called during 'setup' of your application, so | 
| 3821 |  |  |  |  |  |  | you really don't need to invoke it.  However you may do so if you find the idea | 
| 3822 |  |  |  |  |  |  | of loading middleware via configuration weird :).  For example: | 
| 3823 |  |  |  |  |  |  |  | 
| 3824 | 0 | 0 |  |  |  | 0 | package MyApp; | 
| 3825 | 0 |  |  |  |  | 0 |  | 
| 3826 |  |  |  |  |  |  | use Catalyst; | 
| 3827 | 0 |  |  |  |  | 0 |  | 
| 3828 |  |  |  |  |  |  | __PACKAGE__->setup_middleware('Head'); | 
| 3829 |  |  |  |  |  |  | __PACKAGE__->setup; | 
| 3830 | 162 |  |  |  |  | 1282 |  | 
| 3831 | 162 |  | 50 |  |  | 1114 | When we read middleware definitions from configuration, we reverse the list | 
| 3832 |  |  |  |  |  |  | which sounds odd but is likely how you expect it to work if you have prior | 
| 3833 |  |  |  |  |  |  | experience with L<Plack::Builder> or if you previously used the plugin | 
| 3834 | 642 |  |  |  |  | 26916 | L<Catalyst::Plugin::EnableMiddleware> (which is now considered deprecated) | 
| 3835 |  |  |  |  |  |  |  | 
| 3836 |  |  |  |  |  |  | So basically your middleware handles an incoming request from the first | 
| 3837 |  |  |  |  |  |  | registered middleware, down and handles the response from the last middleware | 
| 3838 |  |  |  |  |  |  | up. | 
| 3839 |  |  |  |  |  |  |  | 
| 3840 | 162 |  |  |  |  | 8554 | =cut | 
|  | 162 |  |  |  |  | 517 |  | 
| 3841 |  |  |  |  |  |  |  | 
| 3842 | 162 |  |  |  |  | 4268 | my $class = shift; | 
| 3843 | 642 |  |  |  |  | 2470 | if(my $middleware = $class->_psgi_middleware) { | 
| 3844 | 642 |  |  |  |  | 791357 | my @mw = ($class->default_middleware, @$middleware); | 
| 3845 | 642 | 100 | 100 |  |  | 7407 |  | 
| 3846 |  |  |  |  |  |  | if($class->config->{using_frontend_proxy}) { | 
| 3847 | 563 |  |  |  |  | 5339 | push @mw, Plack::Middleware::ReverseProxy->new; | 
| 3848 |  |  |  |  |  |  | } | 
| 3849 |  |  |  |  |  |  |  | 
| 3850 |  |  |  |  |  |  | return @mw; | 
| 3851 | 79 |  |  |  |  | 607 | } else { | 
| 3852 | 642 | 50 |  |  |  | 4026 | die "You cannot call ->registered_middlewares until middleware has been setup"; | 
| 3853 | 162 |  |  |  |  | 760 | } | 
|  | 642 |  |  |  |  | 3870 |  | 
| 3854 |  |  |  |  |  |  | } | 
| 3855 |  |  |  |  |  |  |  | 
| 3856 | 162 | 100 |  |  |  | 897 | my $class = shift; | 
| 3857 |  |  |  |  |  |  | my @middleware_definitions; | 
| 3858 |  |  |  |  |  |  |  | 
| 3859 |  |  |  |  |  |  | # If someone calls this method you can add middleware with args.  However if its | 
| 3860 |  |  |  |  |  |  | # called without an arg we need to setup the configuration middleware. | 
| 3861 |  |  |  |  |  |  | if(@_) { | 
| 3862 |  |  |  |  |  |  | @middleware_definitions = reverse(@_); | 
| 3863 |  |  |  |  |  |  | } else { | 
| 3864 |  |  |  |  |  |  | @middleware_definitions = reverse(@{$class->config->{'psgi_middleware'}||[]}) | 
| 3865 |  |  |  |  |  |  | unless $class->finalized_default_middleware; | 
| 3866 |  |  |  |  |  |  | $class->finalized_default_middleware(1); # Only do this once, just in case some people call setup over and over... | 
| 3867 |  |  |  |  |  |  | } | 
| 3868 |  |  |  |  |  |  |  | 
| 3869 |  |  |  |  |  |  | my @middleware = (); | 
| 3870 |  |  |  |  |  |  | while(my $next = shift(@middleware_definitions)) { | 
| 3871 |  |  |  |  |  |  | if(ref $next) { | 
| 3872 |  |  |  |  |  |  | if(Scalar::Util::blessed $next && $next->can('wrap')) { | 
| 3873 |  |  |  |  |  |  | push @middleware, $next; | 
| 3874 |  |  |  |  |  |  | } elsif(ref $next eq 'CODE') { | 
| 3875 |  |  |  |  |  |  | push @middleware, $next; | 
| 3876 |  |  |  |  |  |  | } elsif(ref $next eq 'HASH') { | 
| 3877 |  |  |  |  |  |  | my $namespace = shift @middleware_definitions; | 
| 3878 |  |  |  |  |  |  | my $mw = $class->Catalyst::Utils::build_middleware($namespace, %$next); | 
| 3879 |  |  |  |  |  |  | push @middleware, $mw; | 
| 3880 |  |  |  |  |  |  | } else { | 
| 3881 |  |  |  |  |  |  | die "I can't handle middleware definition ${\ref $next}"; | 
| 3882 |  |  |  |  |  |  | } | 
| 3883 |  |  |  |  |  |  | } else { | 
| 3884 |  |  |  |  |  |  | my $mw = $class->Catalyst::Utils::build_middleware($next); | 
| 3885 |  |  |  |  |  |  | push @middleware, $mw; | 
| 3886 |  |  |  |  |  |  | } | 
| 3887 |  |  |  |  |  |  | } | 
| 3888 |  |  |  |  |  |  |  | 
| 3889 |  |  |  |  |  |  | my @existing = @{$class->_psgi_middleware || []}; | 
| 3890 |  |  |  |  |  |  | $class->_psgi_middleware([@middleware,@existing,]); | 
| 3891 |  |  |  |  |  |  | } | 
| 3892 |  |  |  |  |  |  |  | 
| 3893 |  |  |  |  |  |  | =head2 registered_data_handlers | 
| 3894 |  |  |  |  |  |  |  | 
| 3895 |  |  |  |  |  |  | A read only copy of registered Data Handlers returned as a Hash, where each key | 
| 3896 |  |  |  |  |  |  | is a content type and each value is a subref that attempts to decode that content | 
| 3897 |  |  |  |  |  |  | type. | 
| 3898 |  |  |  |  |  |  |  | 
| 3899 | 142 |  |  | 142 | 1 | 383 | =head2 setup_data_handlers (?@data_handler) | 
| 3900 | 142 |  |  |  |  | 2261 |  | 
| 3901 |  |  |  |  |  |  | Read configuration information stored in configuration key C<data_handlers> or | 
| 3902 |  |  |  |  |  |  | from passed @args. | 
| 3903 |  |  |  |  |  |  |  | 
| 3904 |  |  |  |  |  |  | See under L</CONFIGURATION> information regarding C<data_handlers>. | 
| 3905 |  |  |  |  |  |  |  | 
| 3906 |  |  |  |  |  |  | This method is automatically called during 'setup' of your application, so | 
| 3907 |  |  |  |  |  |  | you really don't need to invoke it. | 
| 3908 |  |  |  |  |  |  |  | 
| 3909 | 142 | 50 |  |  |  | 21873 | =head2 default_data_handlers | 
| 3910 | 0 |  |  |  |  | 0 |  | 
| 3911 |  |  |  |  |  |  | Default Data Handlers that come bundled with L<Catalyst>.  Currently there are | 
| 3912 |  |  |  |  |  |  | only two default data handlers, for 'application/json' and an alternative to | 
| 3913 | 142 | 50 |  |  |  | 650 | 'application/x-www-form-urlencoded' which supposed nested form parameters via | 
| 3914 | 0 | 0 |  |  |  | 0 | L<CGI::Struct> or via L<CGI::Struct::XS> IF you've installed it. | 
| 3915 | 0 |  |  |  |  | 0 |  | 
| 3916 |  |  |  |  |  |  | The 'application/json' data handler is used to parse incoming JSON into a Perl | 
| 3917 | 0 |  |  |  |  | 0 | data structure.  It uses L<JSON::MaybeXS>.  This allows you to fail back to | 
| 3918 |  |  |  |  |  |  | L<JSON::PP>, which is a Pure Perl JSON decoder, and has the smallest dependency | 
| 3919 |  |  |  |  |  |  | impact. | 
| 3920 |  |  |  |  |  |  |  | 
| 3921 | 142 |  |  |  |  | 693 | Because we don't wish to add more dependencies to L<Catalyst>, if you wish to | 
| 3922 |  |  |  |  |  |  | use this new feature we recommend installing L<Cpanel::JSON::XS> in order to get | 
| 3923 |  |  |  |  |  |  | the best performance.  You should add either to your dependency list | 
| 3924 |  |  |  |  |  |  | (Makefile.PL, dist.ini, cpanfile, etc.) | 
| 3925 |  |  |  |  |  |  |  | 
| 3926 |  |  |  |  |  |  | =cut | 
| 3927 |  |  |  |  |  |  |  | 
| 3928 |  |  |  |  |  |  | my $class = shift; | 
| 3929 |  |  |  |  |  |  | if(my $data_handlers = $class->_data_handlers) { | 
| 3930 |  |  |  |  |  |  | return %$data_handlers; | 
| 3931 |  |  |  |  |  |  | } else { | 
| 3932 |  |  |  |  |  |  | $class->setup_data_handlers; | 
| 3933 |  |  |  |  |  |  | return $class->registered_data_handlers; | 
| 3934 |  |  |  |  |  |  | } | 
| 3935 |  |  |  |  |  |  | } | 
| 3936 |  |  |  |  |  |  |  | 
| 3937 |  |  |  |  |  |  | my ($class, %data_handler_callbacks) = @_; | 
| 3938 |  |  |  |  |  |  | %data_handler_callbacks = ( | 
| 3939 |  |  |  |  |  |  | %{$class->default_data_handlers}, | 
| 3940 |  |  |  |  |  |  | %{$class->config->{'data_handlers'}||+{}}, | 
| 3941 |  |  |  |  |  |  | %data_handler_callbacks); | 
| 3942 |  |  |  |  |  |  |  | 
| 3943 |  |  |  |  |  |  | $class->_data_handlers(\%data_handler_callbacks); | 
| 3944 |  |  |  |  |  |  | } | 
| 3945 |  |  |  |  |  |  |  | 
| 3946 |  |  |  |  |  |  | my ($class) = @_; | 
| 3947 |  |  |  |  |  |  | return +{ | 
| 3948 |  |  |  |  |  |  | 'application/x-www-form-urlencoded' => sub { | 
| 3949 |  |  |  |  |  |  | my ($fh, $req) = @_; | 
| 3950 |  |  |  |  |  |  | my $params = $req->_use_hash_multivalue ? $req->body_parameters->mixed : $req->body_parameters; | 
| 3951 |  |  |  |  |  |  | Class::Load::load_first_existing_class('CGI::Struct::XS', 'CGI::Struct') | 
| 3952 |  |  |  |  |  |  | ->can('build_cgi_struct')->($params); | 
| 3953 |  |  |  |  |  |  | }, | 
| 3954 |  |  |  |  |  |  | 'application/json' => sub { | 
| 3955 |  |  |  |  |  |  | my ($fh, $req) = @_; | 
| 3956 |  |  |  |  |  |  | require JSON::MaybeXS; | 
| 3957 |  |  |  |  |  |  | my $slurped; | 
| 3958 |  |  |  |  |  |  | return eval { | 
| 3959 |  |  |  |  |  |  | local $/; | 
| 3960 |  |  |  |  |  |  | $slurped = $fh->getline; | 
| 3961 |  |  |  |  |  |  | JSON::MaybeXS::decode_json($slurped); # decode_json does utf8 decoding for us | 
| 3962 |  |  |  |  |  |  | } || Catalyst::Exception->throw(sprintf "Error Parsing POST '%s', Error: %s", (defined($slurped) ? $slurped : 'undef') ,$@); | 
| 3963 | 142 |  |  | 142 | 1 | 1177 | }, | 
| 3964 | 142 | 50 |  |  |  | 804 | }; | 
| 3965 | 142 |  |  |  |  | 1188 | } | 
| 3966 |  |  |  |  |  |  |  | 
| 3967 | 142 | 50 |  |  |  | 592 | my ( $self, $error ) = @_; | 
| 3968 | 0 |  |  |  |  | 0 | if ( | 
| 3969 |  |  |  |  |  |  | !$self->config->{always_catch_http_exceptions} | 
| 3970 |  |  |  |  |  |  | && blessed $error | 
| 3971 | 142 |  |  |  |  | 802 | && ( | 
| 3972 |  |  |  |  |  |  | $error->can('as_psgi') | 
| 3973 | 0 |  |  |  |  | 0 | || (   $error->can('code') | 
| 3974 |  |  |  |  |  |  | && $error->code =~ m/^[1-5][0-9][0-9]$/ ) | 
| 3975 |  |  |  |  |  |  | ) | 
| 3976 |  |  |  |  |  |  | ) | 
| 3977 |  |  |  |  |  |  | { | 
| 3978 | 166 |  |  | 166 | 1 | 625 | return 1; | 
| 3979 | 166 |  |  |  |  | 344 | } | 
| 3980 |  |  |  |  |  |  | } | 
| 3981 |  |  |  |  |  |  |  | 
| 3982 |  |  |  |  |  |  | =head2 $c->stack | 
| 3983 | 166 | 100 |  |  |  | 578 |  | 
| 3984 | 2 |  |  |  |  | 7 | Returns an arrayref of the internal execution stack (actions that are | 
| 3985 |  |  |  |  |  |  | currently executing). | 
| 3986 | 164 | 100 |  |  |  | 1042 |  | 
|  | 162 | 100 |  |  |  | 858 |  | 
| 3987 |  |  |  |  |  |  | =head2 $c->stats | 
| 3988 | 164 |  |  |  |  | 664 |  | 
| 3989 |  |  |  |  |  |  | Returns the current timing statistics object. By default Catalyst uses | 
| 3990 |  |  |  |  |  |  | L<Catalyst::Stats|Catalyst::Stats>, but can be set otherwise with | 
| 3991 | 166 |  |  |  |  | 4604 | L<< stats_class|/"$c->stats_class" >>. | 
| 3992 | 166 |  |  |  |  | 742 |  | 
| 3993 | 14 | 100 |  |  |  | 32 | Even if L<< -Stats|/"-Stats" >> is not enabled, the stats object is still | 
| 3994 | 8 | 100 | 66 |  |  | 54 | available. By enabling it with C<< $c->stats->enabled(1) >>, it can be used to | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 3995 | 2 |  |  |  |  | 8 | profile explicitly, although MyApp.pm still won't profile nor output anything | 
| 3996 |  |  |  |  |  |  | by itself. | 
| 3997 | 2 |  |  |  |  | 7 |  | 
| 3998 |  |  |  |  |  |  | =head2 $c->stats_class | 
| 3999 | 4 |  |  |  |  | 7 |  | 
| 4000 | 4 |  |  |  |  | 31 | Returns or sets the stats (timing statistics) class. L<Catalyst::Stats|Catalyst::Stats> is used by default. | 
| 4001 | 4 |  |  |  |  | 1311 |  | 
| 4002 |  |  |  |  |  |  | =head2 $app->stats_class_traits | 
| 4003 | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 4004 |  |  |  |  |  |  | A arrayref of L<Moose::Role>s that are applied to the stats_class before creating it. | 
| 4005 |  |  |  |  |  |  |  | 
| 4006 | 6 |  |  |  |  | 36 | =head2 $app->composed_stats_class | 
| 4007 | 5 |  |  |  |  | 126 |  | 
| 4008 |  |  |  |  |  |  | this is the stats_class composed with any 'stats_class_traits'.  You can | 
| 4009 |  |  |  |  |  |  | name the full namespace of the role, or a namespace suffix, which will then | 
| 4010 |  |  |  |  |  |  | be tried against the following standard namespace prefixes. | 
| 4011 | 165 | 100 |  |  |  | 389 |  | 
|  | 165 |  |  |  |  | 1217 |  | 
| 4012 | 165 |  |  |  |  | 708 | $MyApp::TraitFor::Stats::$trait_suffix | 
| 4013 |  |  |  |  |  |  | Catalyst::TraitFor::Stats::$trait_suffix | 
| 4014 |  |  |  |  |  |  |  | 
| 4015 |  |  |  |  |  |  | So for example if you set: | 
| 4016 |  |  |  |  |  |  |  | 
| 4017 |  |  |  |  |  |  | MyApp->stats_class_traits(['Foo']); | 
| 4018 |  |  |  |  |  |  |  | 
| 4019 |  |  |  |  |  |  | We try each possible role in turn (and throw an error if none load) | 
| 4020 |  |  |  |  |  |  |  | 
| 4021 |  |  |  |  |  |  | Foo | 
| 4022 |  |  |  |  |  |  | MyApp::TraitFor::Stats::Foo | 
| 4023 |  |  |  |  |  |  | Catalyst::TraitFor::Stats::Foo | 
| 4024 |  |  |  |  |  |  |  | 
| 4025 |  |  |  |  |  |  | The namespace part 'TraitFor::Stats' was chosen to assist in backwards | 
| 4026 |  |  |  |  |  |  | compatibility with L<CatalystX::RoleApplicator> which previously provided | 
| 4027 |  |  |  |  |  |  | these features in a stand alone package. | 
| 4028 |  |  |  |  |  |  |  | 
| 4029 |  |  |  |  |  |  | =head2 $c->use_stats | 
| 4030 |  |  |  |  |  |  |  | 
| 4031 |  |  |  |  |  |  | Returns 1 when L<< stats collection|/"-Stats" >> is enabled. | 
| 4032 |  |  |  |  |  |  |  | 
| 4033 |  |  |  |  |  |  | Note that this is a static method, not an accessor and should be overridden | 
| 4034 |  |  |  |  |  |  | by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>. | 
| 4035 |  |  |  |  |  |  |  | 
| 4036 |  |  |  |  |  |  | =cut | 
| 4037 |  |  |  |  |  |  |  | 
| 4038 |  |  |  |  |  |  |  | 
| 4039 |  |  |  |  |  |  |  | 
| 4040 |  |  |  |  |  |  | =head2 $c->write( $data ) | 
| 4041 |  |  |  |  |  |  |  | 
| 4042 |  |  |  |  |  |  | Writes $data to the output stream. When using this method directly, you | 
| 4043 |  |  |  |  |  |  | will need to manually set the C<Content-Length> header to the length of | 
| 4044 |  |  |  |  |  |  | your output data, if known. | 
| 4045 |  |  |  |  |  |  |  | 
| 4046 |  |  |  |  |  |  | =cut | 
| 4047 |  |  |  |  |  |  |  | 
| 4048 |  |  |  |  |  |  | my $c = shift; | 
| 4049 |  |  |  |  |  |  |  | 
| 4050 |  |  |  |  |  |  | # Finalize headers if someone manually writes output (for compat) | 
| 4051 | 939 |  |  | 939 | 1 | 1689 | $c->finalize_headers; | 
| 4052 | 939 | 50 |  |  |  | 2845 |  | 
| 4053 | 939 |  |  |  |  | 5005 | return $c->response->write( @_ ); | 
| 4054 |  |  |  |  |  |  | } | 
| 4055 | 0 |  |  |  |  | 0 |  | 
| 4056 | 0 |  |  |  |  | 0 | =head2 version | 
| 4057 |  |  |  |  |  |  |  | 
| 4058 |  |  |  |  |  |  | Returns the Catalyst version number. Mostly useful for "powered by" | 
| 4059 |  |  |  |  |  |  | messages in template systems. | 
| 4060 |  |  |  |  |  |  |  | 
| 4061 | 162 |  |  | 162 | 1 | 581 | =cut | 
| 4062 |  |  |  |  |  |  |  | 
| 4063 | 162 |  |  |  |  | 1000 |  | 
| 4064 | 162 | 50 |  |  |  | 348 | =head1 CONFIGURATION | 
|  | 162 |  |  |  |  | 1002 |  | 
| 4065 |  |  |  |  |  |  |  | 
| 4066 |  |  |  |  |  |  | There are a number of 'base' config variables which can be set: | 
| 4067 | 162 |  |  |  |  | 1604 |  | 
| 4068 |  |  |  |  |  |  | =over | 
| 4069 |  |  |  |  |  |  |  | 
| 4070 |  |  |  |  |  |  | =item * | 
| 4071 | 162 |  |  | 162 | 1 | 456 |  | 
| 4072 |  |  |  |  |  |  | C<always_catch_http_exceptions> - As of version 5.90060 Catalyst | 
| 4073 |  |  |  |  |  |  | rethrows errors conforming to the interface described by | 
| 4074 | 1 |  |  | 1 |  | 4 | L<Plack::Middleware::HTTPExceptions> and lets the middleware deal with it. | 
| 4075 | 1 | 50 |  |  |  | 24 | Set true to get the deprecated behaviour and have Catalyst catch HTTP exceptions. | 
| 4076 | 1 |  |  |  |  | 6 |  | 
| 4077 |  |  |  |  |  |  | =item * | 
| 4078 |  |  |  |  |  |  |  | 
| 4079 |  |  |  |  |  |  | C<default_model> - The default model picked if you say C<< $c->model >>. See L<< /$c->model($name) >>. | 
| 4080 | 5 |  |  | 5 |  | 19 |  | 
| 4081 | 5 |  |  |  |  | 26 | =item * | 
| 4082 | 5 |  |  |  |  | 9 |  | 
| 4083 | 5 |  | 66 |  |  | 7 | C<default_view> - The default view to be rendered or returned when C<< $c->view >> is called. See L<< /$c->view($name) >>. | 
| 4084 |  |  |  |  |  |  |  | 
| 4085 |  |  |  |  |  |  | =item * | 
| 4086 |  |  |  |  |  |  |  | 
| 4087 |  |  |  |  |  |  | C<disable_component_resolution_regex_fallback> - Turns | 
| 4088 |  |  |  |  |  |  | off the deprecated component resolution functionality so | 
| 4089 | 162 |  |  |  |  | 1833 | that if any of the component methods (e.g. C<< $c->controller('Foo') >>) | 
| 4090 |  |  |  |  |  |  | are called then regex search will not be attempted on string values and | 
| 4091 |  |  |  |  |  |  | instead C<undef> will be returned. | 
| 4092 |  |  |  |  |  |  |  | 
| 4093 | 167 |  |  | 167 |  | 357 | =item * | 
| 4094 | 167 | 100 | 100 |  |  | 469 |  | 
|  |  |  | 100 |  |  |  |  | 
|  |  |  | 100 |  |  |  |  | 
| 4095 |  |  |  |  |  |  | C<home> - The application home directory. In an uninstalled application, | 
| 4096 |  |  |  |  |  |  | this is the top level application directory. In an installed application, | 
| 4097 |  |  |  |  |  |  | this will be the directory containing C<< MyApp.pm >>. | 
| 4098 |  |  |  |  |  |  |  | 
| 4099 |  |  |  |  |  |  | =item * | 
| 4100 |  |  |  |  |  |  |  | 
| 4101 |  |  |  |  |  |  | C<ignore_frontend_proxy> - See L</PROXY SUPPORT> | 
| 4102 |  |  |  |  |  |  |  | 
| 4103 |  |  |  |  |  |  | =item * | 
| 4104 | 14 |  |  |  |  | 66 |  | 
| 4105 |  |  |  |  |  |  | C<name> - The name of the application in debug messages and the debug and | 
| 4106 |  |  |  |  |  |  | welcome screens | 
| 4107 |  |  |  |  |  |  |  | 
| 4108 |  |  |  |  |  |  | =item * | 
| 4109 |  |  |  |  |  |  |  | 
| 4110 |  |  |  |  |  |  | C<parse_on_demand> - The request body (for example file uploads) will not be parsed | 
| 4111 |  |  |  |  |  |  | until it is accessed. This allows you to (for example) check authentication (and reject | 
| 4112 |  |  |  |  |  |  | the upload) before actually receiving all the data. See L</ON-DEMAND PARSER> | 
| 4113 |  |  |  |  |  |  |  | 
| 4114 |  |  |  |  |  |  | =item * | 
| 4115 |  |  |  |  |  |  |  | 
| 4116 |  |  |  |  |  |  | C<root> - The root directory for templates. Usually this is just a | 
| 4117 |  |  |  |  |  |  | subdirectory of the home directory, but you can set it to change the | 
| 4118 |  |  |  |  |  |  | templates to a different directory. | 
| 4119 |  |  |  |  |  |  |  | 
| 4120 |  |  |  |  |  |  | =item * | 
| 4121 |  |  |  |  |  |  |  | 
| 4122 |  |  |  |  |  |  | C<search_extra> - Array reference passed to Module::Pluggable to for additional | 
| 4123 |  |  |  |  |  |  | namespaces from which components will be loaded (and constructed and stored in | 
| 4124 |  |  |  |  |  |  | C<< $c->components >>). | 
| 4125 |  |  |  |  |  |  |  | 
| 4126 |  |  |  |  |  |  | =item * | 
| 4127 |  |  |  |  |  |  |  | 
| 4128 |  |  |  |  |  |  | C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >> | 
| 4129 |  |  |  |  |  |  | to be shown in hit debug tables in the test server. | 
| 4130 |  |  |  |  |  |  |  | 
| 4131 |  |  |  |  |  |  | =item * | 
| 4132 |  |  |  |  |  |  |  | 
| 4133 |  |  |  |  |  |  | C<use_request_uri_for_path> - Controls if the C<REQUEST_URI> or C<PATH_INFO> environment | 
| 4134 |  |  |  |  |  |  | variable should be used for determining the request path. | 
| 4135 |  |  |  |  |  |  |  | 
| 4136 |  |  |  |  |  |  | Most web server environments pass the requested path to the application using environment variables, | 
| 4137 |  |  |  |  |  |  | from which Catalyst has to reconstruct the request base (i.e. the top level path to / in the application, | 
| 4138 |  |  |  |  |  |  | exposed as C<< $c->request->base >>) and the request path below that base. | 
| 4139 |  |  |  |  |  |  |  | 
| 4140 |  |  |  |  |  |  | There are two methods of doing this, both of which have advantages and disadvantages. Which method is used | 
| 4141 |  |  |  |  |  |  | is determined by the C<< $c->config(use_request_uri_for_path) >> setting (which can either be true or false). | 
| 4142 |  |  |  |  |  |  |  | 
| 4143 |  |  |  |  |  |  | =over | 
| 4144 |  |  |  |  |  |  |  | 
| 4145 |  |  |  |  |  |  | =item use_request_uri_for_path => 0 | 
| 4146 |  |  |  |  |  |  |  | 
| 4147 |  |  |  |  |  |  | This is the default (and the) traditional method that Catalyst has used for determining the path information. | 
| 4148 |  |  |  |  |  |  | The path is generated from a combination of the C<PATH_INFO> and C<SCRIPT_NAME> environment variables. | 
| 4149 |  |  |  |  |  |  | The allows the application to behave correctly when C<mod_rewrite> is being used to redirect requests | 
| 4150 |  |  |  |  |  |  | into the application, as these variables are adjusted by mod_rewrite to take account for the redirect. | 
| 4151 |  |  |  |  |  |  |  | 
| 4152 |  |  |  |  |  |  | However this method has the major disadvantage that it is impossible to correctly decode some elements | 
| 4153 |  |  |  |  |  |  | of the path, as RFC 3875 says: "C<< Unlike a URI path, the PATH_INFO is not URL-encoded, and cannot | 
| 4154 |  |  |  |  |  |  | contain path-segment parameters. >>" This means PATH_INFO is B<always> decoded, and therefore Catalyst | 
| 4155 |  |  |  |  |  |  | can't distinguish / vs %2F in paths (in addition to other encoded values). | 
| 4156 |  |  |  |  |  |  |  | 
| 4157 |  |  |  |  |  |  | =item use_request_uri_for_path => 1 | 
| 4158 |  |  |  |  |  |  |  | 
| 4159 |  |  |  |  |  |  | This method uses the C<REQUEST_URI> and C<SCRIPT_NAME> environment variables. As C<REQUEST_URI> is never | 
| 4160 |  |  |  |  |  |  | decoded, this means that applications using this mode can correctly handle URIs including the %2F character | 
| 4161 |  |  |  |  |  |  | (i.e. with C<AllowEncodedSlashes> set to C<On> in Apache). | 
| 4162 |  |  |  |  |  |  |  | 
| 4163 |  |  |  |  |  |  | Given that this method of path resolution is provably more correct, it is recommended that you use | 
| 4164 | 19807 |  |  | 19807 | 1 | 55918 | this unless you have a specific need to deploy your application in a non-standard environment, and you are | 
| 4165 |  |  |  |  |  |  | aware of the implications of not being able to handle encoded URI paths correctly. | 
| 4166 |  |  |  |  |  |  |  | 
| 4167 |  |  |  |  |  |  | However it also means that in a number of cases when the app isn't installed directly at a path, but instead | 
| 4168 |  |  |  |  |  |  | is having paths rewritten into it (e.g. as a .cgi/fcgi in a public_html directory, with mod_rewrite in a | 
| 4169 |  |  |  |  |  |  | .htaccess file, or when SSI is used to rewrite pages into the app, or when sub-paths of the app are exposed | 
| 4170 |  |  |  |  |  |  | at other URIs than that which the app is 'normally' based at with C<mod_rewrite>), the resolution of | 
| 4171 |  |  |  |  |  |  | C<< $c->request->base >> will be incorrect. | 
| 4172 |  |  |  |  |  |  |  | 
| 4173 |  |  |  |  |  |  | =back | 
| 4174 |  |  |  |  |  |  |  | 
| 4175 |  |  |  |  |  |  | =item * | 
| 4176 | 0 |  |  | 0 | 1 | 0 |  | 
| 4177 |  |  |  |  |  |  | C<using_frontend_proxy> - See L</PROXY SUPPORT>. | 
| 4178 |  |  |  |  |  |  |  | 
| 4179 | 0 |  |  |  |  | 0 | =item * | 
| 4180 |  |  |  |  |  |  |  | 
| 4181 | 0 |  |  |  |  | 0 | C<using_frontend_proxy_path> - Enabled L<Plack::Middleware::ReverseProxyPath> on your application (if | 
| 4182 |  |  |  |  |  |  | installed, otherwise log an error).  This is useful if your application is not running on the | 
| 4183 |  |  |  |  |  |  | 'root' (or /) of your host server.  B<NOTE> if you use this feature you should add the required | 
| 4184 |  |  |  |  |  |  | middleware to your project dependency list since its not automatically a dependency of L<Catalyst>. | 
| 4185 |  |  |  |  |  |  | This has been done since not all people need this feature and we wish to restrict the growth of | 
| 4186 |  |  |  |  |  |  | L<Catalyst> dependencies. | 
| 4187 |  |  |  |  |  |  |  | 
| 4188 |  |  |  |  |  |  | =item * | 
| 4189 |  |  |  |  |  |  |  | 
| 4190 |  |  |  |  |  |  | C<encoding> - See L</ENCODING> | 
| 4191 | 0 |  |  | 0 | 1 | 0 |  | 
| 4192 |  |  |  |  |  |  | This now defaults to 'UTF-8'.  You my turn it off by setting this configuration | 
| 4193 |  |  |  |  |  |  | value to undef. | 
| 4194 |  |  |  |  |  |  |  | 
| 4195 |  |  |  |  |  |  | =item * | 
| 4196 |  |  |  |  |  |  |  | 
| 4197 |  |  |  |  |  |  | C<abort_chain_on_error_fix> | 
| 4198 |  |  |  |  |  |  |  | 
| 4199 |  |  |  |  |  |  | Defaults to true. | 
| 4200 |  |  |  |  |  |  |  | 
| 4201 |  |  |  |  |  |  | When there is an error in an action chain, the default behavior is to | 
| 4202 |  |  |  |  |  |  | abort the processing of the remaining actions to avoid running them | 
| 4203 |  |  |  |  |  |  | when the application is in an unexpected state. | 
| 4204 |  |  |  |  |  |  |  | 
| 4205 |  |  |  |  |  |  | Before version 5.90070, the default used to be false. To keep the old | 
| 4206 |  |  |  |  |  |  | behaviour, you can explicitly set the value to false. E.g. | 
| 4207 |  |  |  |  |  |  |  | 
| 4208 |  |  |  |  |  |  | __PACKAGE__->config(abort_chain_on_error_fix => 0); | 
| 4209 |  |  |  |  |  |  |  | 
| 4210 |  |  |  |  |  |  | If this setting is set to false, then the remaining actions are | 
| 4211 |  |  |  |  |  |  | performed and the error is caught at the end of the chain. | 
| 4212 |  |  |  |  |  |  |  | 
| 4213 |  |  |  |  |  |  |  | 
| 4214 |  |  |  |  |  |  | =item * | 
| 4215 |  |  |  |  |  |  |  | 
| 4216 |  |  |  |  |  |  | C<use_hash_multivalue_in_request> | 
| 4217 |  |  |  |  |  |  |  | 
| 4218 |  |  |  |  |  |  | In L<Catalyst::Request> the methods C<query_parameters>, C<body_parametes> | 
| 4219 |  |  |  |  |  |  | and C<parameters> return a hashref where values might be scalar or an arrayref | 
| 4220 |  |  |  |  |  |  | depending on the incoming data.  In many cases this can be undesirable as it | 
| 4221 |  |  |  |  |  |  | leads one to writing defensive code like the following: | 
| 4222 |  |  |  |  |  |  |  | 
| 4223 |  |  |  |  |  |  | my ($val) = ref($c->req->parameters->{a}) ? | 
| 4224 |  |  |  |  |  |  | @{$c->req->parameters->{a}} : | 
| 4225 |  |  |  |  |  |  | $c->req->parameters->{a}; | 
| 4226 |  |  |  |  |  |  |  | 
| 4227 |  |  |  |  |  |  | Setting this configuration item to true will make L<Catalyst> populate the | 
| 4228 |  |  |  |  |  |  | attributes underlying these methods with an instance of L<Hash::MultiValue> | 
| 4229 |  |  |  |  |  |  | which is used by L<Plack::Request> and others to solve this very issue.  You | 
| 4230 |  |  |  |  |  |  | may prefer this behavior to the default, if so enable this option (be warned | 
| 4231 |  |  |  |  |  |  | if you enable it in a legacy application we are not sure if it is completely | 
| 4232 |  |  |  |  |  |  | backwardly compatible). | 
| 4233 |  |  |  |  |  |  |  | 
| 4234 |  |  |  |  |  |  | =item * | 
| 4235 |  |  |  |  |  |  |  | 
| 4236 |  |  |  |  |  |  | C<skip_complex_post_part_handling> | 
| 4237 |  |  |  |  |  |  |  | 
| 4238 |  |  |  |  |  |  | When creating body parameters from a POST, if we run into a multipart POST | 
| 4239 |  |  |  |  |  |  | that does not contain uploads, but instead contains inlined complex data | 
| 4240 |  |  |  |  |  |  | (very uncommon) we cannot reliably convert that into field => value pairs.  So | 
| 4241 |  |  |  |  |  |  | instead we create an instance of L<Catalyst::Request::PartData>.  If this causes | 
| 4242 |  |  |  |  |  |  | issue for you, you can disable this by setting C<skip_complex_post_part_handling> | 
| 4243 |  |  |  |  |  |  | to true (default is false). | 
| 4244 |  |  |  |  |  |  |  | 
| 4245 |  |  |  |  |  |  | =item * | 
| 4246 |  |  |  |  |  |  |  | 
| 4247 |  |  |  |  |  |  | C<skip_body_param_unicode_decoding> | 
| 4248 |  |  |  |  |  |  |  | 
| 4249 |  |  |  |  |  |  | Generally we decode incoming POST params based on your declared encoding (the | 
| 4250 |  |  |  |  |  |  | default for this is to decode UTF-8).  If this is causing you trouble and you | 
| 4251 |  |  |  |  |  |  | do not wish to turn all encoding support off (with the C<encoding> configuration | 
| 4252 |  |  |  |  |  |  | parameter) you may disable this step atomically by setting this configuration | 
| 4253 |  |  |  |  |  |  | parameter to true. | 
| 4254 |  |  |  |  |  |  |  | 
| 4255 |  |  |  |  |  |  | =item * | 
| 4256 |  |  |  |  |  |  |  | 
| 4257 |  |  |  |  |  |  | C<do_not_decode_query> | 
| 4258 |  |  |  |  |  |  |  | 
| 4259 |  |  |  |  |  |  | If true, then do not try to character decode any wide characters in your | 
| 4260 |  |  |  |  |  |  | request URL query or keywords.  Most readings of the relevant specifications | 
| 4261 |  |  |  |  |  |  | suggest these should be UTF-* encoded, which is the default that L<Catalyst> | 
| 4262 |  |  |  |  |  |  | will use, however if you are creating a lot of URLs manually or have external | 
| 4263 |  |  |  |  |  |  | evil clients, this might cause you trouble.  If you find the changes introduced | 
| 4264 |  |  |  |  |  |  | in Catalyst version 5.90080+ break some of your query code, you may disable | 
| 4265 |  |  |  |  |  |  | the UTF-8 decoding globally using this configuration. | 
| 4266 |  |  |  |  |  |  |  | 
| 4267 |  |  |  |  |  |  | This setting takes precedence over C<default_query_encoding> | 
| 4268 |  |  |  |  |  |  |  | 
| 4269 |  |  |  |  |  |  | =item * | 
| 4270 |  |  |  |  |  |  |  | 
| 4271 |  |  |  |  |  |  | C<do_not_check_query_encoding> | 
| 4272 |  |  |  |  |  |  |  | 
| 4273 |  |  |  |  |  |  | Catalyst versions 5.90080 - 5.90106 would decode query parts of an incoming | 
| 4274 |  |  |  |  |  |  | request but would not raise an exception when the decoding failed due to | 
| 4275 |  |  |  |  |  |  | incorrect unicode.  It now does, but if this change is giving you trouble | 
| 4276 |  |  |  |  |  |  | you may disable it by setting this configuration to true. | 
| 4277 |  |  |  |  |  |  |  | 
| 4278 |  |  |  |  |  |  | =item * | 
| 4279 |  |  |  |  |  |  |  | 
| 4280 |  |  |  |  |  |  | C<default_query_encoding> | 
| 4281 |  |  |  |  |  |  |  | 
| 4282 |  |  |  |  |  |  | By default we decode query and keywords in your request URL using UTF-8, which | 
| 4283 |  |  |  |  |  |  | is our reading of the relevant specifications.  This setting allows one to | 
| 4284 |  |  |  |  |  |  | specify a fixed value for how to decode your query.  You might need this if | 
| 4285 |  |  |  |  |  |  | you are doing a lot of custom encoding of your URLs and not using UTF-8. | 
| 4286 |  |  |  |  |  |  |  | 
| 4287 |  |  |  |  |  |  | =item * | 
| 4288 |  |  |  |  |  |  |  | 
| 4289 |  |  |  |  |  |  | C<use_chained_args_0_special_case> | 
| 4290 |  |  |  |  |  |  |  | 
| 4291 |  |  |  |  |  |  | In older versions of Catalyst, when more than one action matched the same path | 
| 4292 |  |  |  |  |  |  | AND all those matching actions declared Args(0), we'd break the tie by choosing | 
| 4293 |  |  |  |  |  |  | the first action defined.  We now normalized how Args(0) works so that it | 
| 4294 |  |  |  |  |  |  | follows the same rule as Args(N), which is to say when we need to break a tie | 
| 4295 |  |  |  |  |  |  | we choose the LAST action defined.  If this breaks your code and you don't | 
| 4296 |  |  |  |  |  |  | have time to update to follow the new normalized approach, you may set this | 
| 4297 |  |  |  |  |  |  | value to true and it will globally revert to the original chaining behavior. | 
| 4298 |  |  |  |  |  |  |  | 
| 4299 |  |  |  |  |  |  | =item * | 
| 4300 |  |  |  |  |  |  |  | 
| 4301 |  |  |  |  |  |  | C<psgi_middleware> - See L<PSGI MIDDLEWARE>. | 
| 4302 |  |  |  |  |  |  |  | 
| 4303 |  |  |  |  |  |  | =item * | 
| 4304 |  |  |  |  |  |  |  | 
| 4305 |  |  |  |  |  |  | C<data_handlers> - See L<DATA HANDLERS>. | 
| 4306 |  |  |  |  |  |  |  | 
| 4307 |  |  |  |  |  |  | =item * | 
| 4308 |  |  |  |  |  |  |  | 
| 4309 |  |  |  |  |  |  | C<stats_class_traits> | 
| 4310 |  |  |  |  |  |  |  | 
| 4311 |  |  |  |  |  |  | An arrayref of L<Moose::Role>s that get composed into your stats class. | 
| 4312 |  |  |  |  |  |  |  | 
| 4313 |  |  |  |  |  |  | =item * | 
| 4314 |  |  |  |  |  |  |  | 
| 4315 |  |  |  |  |  |  | C<request_class_traits> | 
| 4316 |  |  |  |  |  |  |  | 
| 4317 |  |  |  |  |  |  | An arrayref of L<Moose::Role>s that get composed into your request class. | 
| 4318 |  |  |  |  |  |  |  | 
| 4319 |  |  |  |  |  |  | =item * | 
| 4320 |  |  |  |  |  |  |  | 
| 4321 |  |  |  |  |  |  | C<response_class_traits> | 
| 4322 |  |  |  |  |  |  |  | 
| 4323 |  |  |  |  |  |  | An arrayref of L<Moose::Role>s that get composed into your response class. | 
| 4324 |  |  |  |  |  |  |  | 
| 4325 |  |  |  |  |  |  | =item * | 
| 4326 |  |  |  |  |  |  |  | 
| 4327 |  |  |  |  |  |  | C<inject_components> | 
| 4328 |  |  |  |  |  |  |  | 
| 4329 |  |  |  |  |  |  | A Hashref of L<Catalyst::Component> subclasses that are 'injected' into configuration. | 
| 4330 |  |  |  |  |  |  | For example: | 
| 4331 |  |  |  |  |  |  |  | 
| 4332 |  |  |  |  |  |  | MyApp->config({ | 
| 4333 |  |  |  |  |  |  | inject_components => { | 
| 4334 |  |  |  |  |  |  | 'Controller::Err' => { from_component => 'Local::Controller::Errors' }, | 
| 4335 |  |  |  |  |  |  | 'Model::Zoo' => { from_component => 'Local::Model::Foo' }, | 
| 4336 |  |  |  |  |  |  | 'Model::Foo' => { from_component => 'Local::Model::Foo', roles => ['TestRole'] }, | 
| 4337 |  |  |  |  |  |  | }, | 
| 4338 |  |  |  |  |  |  | 'Controller::Err' => { a => 100, b=>200, namespace=>'error' }, | 
| 4339 |  |  |  |  |  |  | 'Model::Zoo' => { a => 2 }, | 
| 4340 |  |  |  |  |  |  | 'Model::Foo' => { a => 100 }, | 
| 4341 |  |  |  |  |  |  | }); | 
| 4342 |  |  |  |  |  |  |  | 
| 4343 |  |  |  |  |  |  | Generally L<Catalyst> looks for components in your Model/View or Controller directories. | 
| 4344 |  |  |  |  |  |  | However for cases when you which to use an existing component and you don't need any | 
| 4345 |  |  |  |  |  |  | customization (where for when you can apply a role to customize it) you may inject those | 
| 4346 |  |  |  |  |  |  | components into your application.  Please note any configuration should be done 'in the | 
| 4347 |  |  |  |  |  |  | normal way', with a key under configuration named after the component affix, as in the | 
| 4348 |  |  |  |  |  |  | above example. | 
| 4349 |  |  |  |  |  |  |  | 
| 4350 |  |  |  |  |  |  | Using this type of injection allows you to construct significant amounts of your application | 
| 4351 |  |  |  |  |  |  | with only configuration!.  This may or may not lead to increased code understanding. | 
| 4352 |  |  |  |  |  |  |  | 
| 4353 |  |  |  |  |  |  | Please not you may also call the ->inject_components application method as well, although | 
| 4354 |  |  |  |  |  |  | you must do so BEFORE setup. | 
| 4355 |  |  |  |  |  |  |  | 
| 4356 |  |  |  |  |  |  | =back | 
| 4357 |  |  |  |  |  |  |  | 
| 4358 |  |  |  |  |  |  | =head1 EXCEPTIONS | 
| 4359 |  |  |  |  |  |  |  | 
| 4360 |  |  |  |  |  |  | Generally when you throw an exception inside an Action (or somewhere in | 
| 4361 |  |  |  |  |  |  | your stack, such as in a model that an Action is calling) that exception | 
| 4362 |  |  |  |  |  |  | is caught by Catalyst and unless you either catch it yourself (via eval | 
| 4363 |  |  |  |  |  |  | or something like L<Try::Tiny> or by reviewing the L</error> stack, it | 
| 4364 |  |  |  |  |  |  | will eventually reach L</finalize_errors> and return either the debugging | 
| 4365 |  |  |  |  |  |  | error stack page, or the default error page.  However, if your exception | 
| 4366 |  |  |  |  |  |  | can be caught by L<Plack::Middleware::HTTPExceptions>, L<Catalyst> will | 
| 4367 |  |  |  |  |  |  | instead rethrow it so that it can be handled by that middleware (which | 
| 4368 |  |  |  |  |  |  | is part of the default middleware).  For example this would allow | 
| 4369 |  |  |  |  |  |  |  | 
| 4370 |  |  |  |  |  |  | use HTTP::Throwable::Factory 'http_throw'; | 
| 4371 |  |  |  |  |  |  |  | 
| 4372 |  |  |  |  |  |  | sub throws_exception :Local { | 
| 4373 |  |  |  |  |  |  | my ($self, $c) = @_; | 
| 4374 |  |  |  |  |  |  |  | 
| 4375 |  |  |  |  |  |  | http_throw(SeeOther => { location => | 
| 4376 |  |  |  |  |  |  | $c->uri_for($self->action_for('redirect')) }); | 
| 4377 |  |  |  |  |  |  |  | 
| 4378 |  |  |  |  |  |  | } | 
| 4379 |  |  |  |  |  |  |  | 
| 4380 |  |  |  |  |  |  | =head1 INTERNAL ACTIONS | 
| 4381 |  |  |  |  |  |  |  | 
| 4382 |  |  |  |  |  |  | Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>, | 
| 4383 |  |  |  |  |  |  | C<_ACTION>, and C<_END>. These are by default not shown in the private | 
| 4384 |  |  |  |  |  |  | action table, but you can make them visible with a config parameter. | 
| 4385 |  |  |  |  |  |  |  | 
| 4386 |  |  |  |  |  |  | MyApp->config(show_internal_actions => 1); | 
| 4387 |  |  |  |  |  |  |  | 
| 4388 |  |  |  |  |  |  | =head1 ON-DEMAND PARSER | 
| 4389 |  |  |  |  |  |  |  | 
| 4390 |  |  |  |  |  |  | The request body is usually parsed at the beginning of a request, | 
| 4391 |  |  |  |  |  |  | but if you want to handle input yourself, you can enable on-demand | 
| 4392 |  |  |  |  |  |  | parsing with a config parameter. | 
| 4393 |  |  |  |  |  |  |  | 
| 4394 |  |  |  |  |  |  | MyApp->config(parse_on_demand => 1); | 
| 4395 |  |  |  |  |  |  |  | 
| 4396 |  |  |  |  |  |  | =head1 PROXY SUPPORT | 
| 4397 |  |  |  |  |  |  |  | 
| 4398 |  |  |  |  |  |  | Many production servers operate using the common double-server approach, | 
| 4399 |  |  |  |  |  |  | with a lightweight frontend web server passing requests to a larger | 
| 4400 |  |  |  |  |  |  | backend server. An application running on the backend server must deal | 
| 4401 |  |  |  |  |  |  | with two problems: the remote user always appears to be C<127.0.0.1> and | 
| 4402 |  |  |  |  |  |  | the server's hostname will appear to be C<localhost> regardless of the | 
| 4403 |  |  |  |  |  |  | virtual host that the user connected through. | 
| 4404 |  |  |  |  |  |  |  | 
| 4405 |  |  |  |  |  |  | Catalyst will automatically detect this situation when you are running | 
| 4406 |  |  |  |  |  |  | the frontend and backend servers on the same machine. The following | 
| 4407 |  |  |  |  |  |  | changes are made to the request. | 
| 4408 |  |  |  |  |  |  |  | 
| 4409 |  |  |  |  |  |  | $c->req->address is set to the user's real IP address, as read from | 
| 4410 |  |  |  |  |  |  | the HTTP X-Forwarded-For header. | 
| 4411 |  |  |  |  |  |  |  | 
| 4412 |  |  |  |  |  |  | The host value for $c->req->base and $c->req->uri is set to the real | 
| 4413 |  |  |  |  |  |  | host, as read from the HTTP X-Forwarded-Host header. | 
| 4414 |  |  |  |  |  |  |  | 
| 4415 |  |  |  |  |  |  | Additionally, you may be running your backend application on an insecure | 
| 4416 |  |  |  |  |  |  | connection (port 80) while your frontend proxy is running under SSL.  If there | 
| 4417 |  |  |  |  |  |  | is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to | 
| 4418 |  |  |  |  |  |  | tell Catalyst what port the frontend listens on.  This will allow all URIs to | 
| 4419 |  |  |  |  |  |  | be created properly. | 
| 4420 |  |  |  |  |  |  |  | 
| 4421 |  |  |  |  |  |  | In the case of passing in: | 
| 4422 |  |  |  |  |  |  |  | 
| 4423 |  |  |  |  |  |  | X-Forwarded-Port: 443 | 
| 4424 |  |  |  |  |  |  |  | 
| 4425 |  |  |  |  |  |  | All calls to C<uri_for> will result in an https link, as is expected. | 
| 4426 |  |  |  |  |  |  |  | 
| 4427 |  |  |  |  |  |  | Obviously, your web server must support these headers for this to work. | 
| 4428 |  |  |  |  |  |  |  | 
| 4429 |  |  |  |  |  |  | In a more complex server farm environment where you may have your | 
| 4430 |  |  |  |  |  |  | frontend proxy server(s) on different machines, you will need to set a | 
| 4431 |  |  |  |  |  |  | configuration option to tell Catalyst to read the proxied data from the | 
| 4432 |  |  |  |  |  |  | headers. | 
| 4433 |  |  |  |  |  |  |  | 
| 4434 |  |  |  |  |  |  | MyApp->config(using_frontend_proxy => 1); | 
| 4435 |  |  |  |  |  |  |  | 
| 4436 |  |  |  |  |  |  | If you do not wish to use the proxy support at all, you may set: | 
| 4437 |  |  |  |  |  |  |  | 
| 4438 |  |  |  |  |  |  | MyApp->config(ignore_frontend_proxy => 0); | 
| 4439 |  |  |  |  |  |  |  | 
| 4440 |  |  |  |  |  |  | =head2 Note about psgi files | 
| 4441 |  |  |  |  |  |  |  | 
| 4442 |  |  |  |  |  |  | Note that if you supply your own .psgi file, calling | 
| 4443 |  |  |  |  |  |  | C<< MyApp->psgi_app(@_); >>, then B<this will not happen automatically>. | 
| 4444 |  |  |  |  |  |  |  | 
| 4445 |  |  |  |  |  |  | You either need to apply L<Plack::Middleware::ReverseProxy> yourself | 
| 4446 |  |  |  |  |  |  | in your psgi, for example: | 
| 4447 |  |  |  |  |  |  |  | 
| 4448 |  |  |  |  |  |  | builder { | 
| 4449 |  |  |  |  |  |  | enable "Plack::Middleware::ReverseProxy"; | 
| 4450 |  |  |  |  |  |  | MyApp->psgi_app | 
| 4451 |  |  |  |  |  |  | }; | 
| 4452 |  |  |  |  |  |  |  | 
| 4453 |  |  |  |  |  |  | This will unconditionally add the ReverseProxy support, or you need to call | 
| 4454 |  |  |  |  |  |  | C<< $app = MyApp->apply_default_middlewares($app) >> (to conditionally | 
| 4455 |  |  |  |  |  |  | apply the support depending upon your config). | 
| 4456 |  |  |  |  |  |  |  | 
| 4457 |  |  |  |  |  |  | See L<Catalyst::PSGI> for more information. | 
| 4458 |  |  |  |  |  |  |  | 
| 4459 |  |  |  |  |  |  | =head1 THREAD SAFETY | 
| 4460 |  |  |  |  |  |  |  | 
| 4461 |  |  |  |  |  |  | Catalyst has been tested under Apache 2's threading C<mpm_worker>, | 
| 4462 |  |  |  |  |  |  | C<mpm_winnt>, and the standalone forking HTTP server on Windows. We | 
| 4463 |  |  |  |  |  |  | believe the Catalyst core to be thread-safe. | 
| 4464 |  |  |  |  |  |  |  | 
| 4465 |  |  |  |  |  |  | If you plan to operate in a threaded environment, remember that all other | 
| 4466 |  |  |  |  |  |  | modules you are using must also be thread-safe. Some modules, most notably | 
| 4467 |  |  |  |  |  |  | L<DBD::SQLite>, are not thread-safe. | 
| 4468 |  |  |  |  |  |  |  | 
| 4469 |  |  |  |  |  |  | =head1 DATA HANDLERS | 
| 4470 |  |  |  |  |  |  |  | 
| 4471 |  |  |  |  |  |  | The L<Catalyst::Request> object uses L<HTTP::Body> to populate 'classic' HTML | 
| 4472 |  |  |  |  |  |  | form parameters and URL search query fields.  However it has become common | 
| 4473 |  |  |  |  |  |  | for various alternative content types to be PUT or POSTed to your controllers | 
| 4474 |  |  |  |  |  |  | and actions.  People working on RESTful APIs, or using AJAX often use JSON, | 
| 4475 |  |  |  |  |  |  | XML and other content types when communicating with an application server.  In | 
| 4476 |  |  |  |  |  |  | order to better support this use case, L<Catalyst> defines a global configuration | 
| 4477 |  |  |  |  |  |  | option, C<data_handlers>, which lets you associate a content type with a coderef | 
| 4478 |  |  |  |  |  |  | that parses that content type into something Perl can readily access. | 
| 4479 |  |  |  |  |  |  |  | 
| 4480 |  |  |  |  |  |  | package MyApp::Web; | 
| 4481 |  |  |  |  |  |  |  | 
| 4482 |  |  |  |  |  |  | use Catalyst; | 
| 4483 |  |  |  |  |  |  | use JSON::MaybeXS; | 
| 4484 |  |  |  |  |  |  |  | 
| 4485 |  |  |  |  |  |  | __PACKAGE__->config( | 
| 4486 |  |  |  |  |  |  | data_handlers => { | 
| 4487 |  |  |  |  |  |  | 'application/json' => sub { local $/; decode_json $_->getline }, | 
| 4488 |  |  |  |  |  |  | }, | 
| 4489 |  |  |  |  |  |  | ## Any other configuration. | 
| 4490 |  |  |  |  |  |  | ); | 
| 4491 |  |  |  |  |  |  |  | 
| 4492 |  |  |  |  |  |  | __PACKAGE__->setup; | 
| 4493 |  |  |  |  |  |  |  | 
| 4494 |  |  |  |  |  |  | By default L<Catalyst> comes with a generic JSON data handler similar to the | 
| 4495 |  |  |  |  |  |  | example given above, which uses L<JSON::MaybeXS> to provide either L<JSON::PP> | 
| 4496 |  |  |  |  |  |  | (a pure Perl, dependency free JSON parser) or L<Cpanel::JSON::XS> if you have | 
| 4497 |  |  |  |  |  |  | it installed (if you want the faster XS parser, add it to you project Makefile.PL | 
| 4498 |  |  |  |  |  |  | or dist.ini, cpanfile, etc.) | 
| 4499 |  |  |  |  |  |  |  | 
| 4500 |  |  |  |  |  |  | The C<data_handlers> configuration is a hashref whose keys are HTTP Content-Types | 
| 4501 |  |  |  |  |  |  | (matched against the incoming request type using a regexp such as to be case | 
| 4502 |  |  |  |  |  |  | insensitive) and whose values are coderefs that receive a localized version of | 
| 4503 |  |  |  |  |  |  | C<$_> which is a filehandle object pointing to received body. | 
| 4504 |  |  |  |  |  |  |  | 
| 4505 |  |  |  |  |  |  | This feature is considered an early access release and we reserve the right | 
| 4506 |  |  |  |  |  |  | to alter the interface in order to provide a performant and secure solution to | 
| 4507 |  |  |  |  |  |  | alternative request body content.  Your reports welcomed! | 
| 4508 |  |  |  |  |  |  |  | 
| 4509 |  |  |  |  |  |  | =head1 PSGI MIDDLEWARE | 
| 4510 |  |  |  |  |  |  |  | 
| 4511 |  |  |  |  |  |  | You can define middleware, defined as L<Plack::Middleware> or a compatible | 
| 4512 |  |  |  |  |  |  | interface in configuration.  Your middleware definitions are in the form of an | 
| 4513 |  |  |  |  |  |  | arrayref under the configuration key C<psgi_middleware>.  Here's an example | 
| 4514 |  |  |  |  |  |  | with details to follow: | 
| 4515 |  |  |  |  |  |  |  | 
| 4516 |  |  |  |  |  |  | package MyApp::Web; | 
| 4517 |  |  |  |  |  |  |  | 
| 4518 |  |  |  |  |  |  | use Catalyst; | 
| 4519 |  |  |  |  |  |  | use Plack::Middleware::StackTrace; | 
| 4520 |  |  |  |  |  |  |  | 
| 4521 |  |  |  |  |  |  | my $stacktrace_middleware = Plack::Middleware::StackTrace->new; | 
| 4522 |  |  |  |  |  |  |  | 
| 4523 |  |  |  |  |  |  | __PACKAGE__->config( | 
| 4524 |  |  |  |  |  |  | 'psgi_middleware', [ | 
| 4525 |  |  |  |  |  |  | 'Debug', | 
| 4526 |  |  |  |  |  |  | '+MyApp::Custom', | 
| 4527 |  |  |  |  |  |  | $stacktrace_middleware, | 
| 4528 |  |  |  |  |  |  | 'Session' => {store => 'File'}, | 
| 4529 |  |  |  |  |  |  | sub { | 
| 4530 |  |  |  |  |  |  | my $app = shift; | 
| 4531 |  |  |  |  |  |  | return sub { | 
| 4532 |  |  |  |  |  |  | my $env = shift; | 
| 4533 |  |  |  |  |  |  | $env->{myapp.customkey} = 'helloworld'; | 
| 4534 |  |  |  |  |  |  | $app->($env); | 
| 4535 |  |  |  |  |  |  | }, | 
| 4536 |  |  |  |  |  |  | }, | 
| 4537 |  |  |  |  |  |  | ], | 
| 4538 |  |  |  |  |  |  | ); | 
| 4539 |  |  |  |  |  |  |  | 
| 4540 |  |  |  |  |  |  | __PACKAGE__->setup; | 
| 4541 |  |  |  |  |  |  |  | 
| 4542 |  |  |  |  |  |  | So the general form is: | 
| 4543 |  |  |  |  |  |  |  | 
| 4544 |  |  |  |  |  |  | __PACKAGE__->config(psgi_middleware => \@middleware_definitions); | 
| 4545 |  |  |  |  |  |  |  | 
| 4546 |  |  |  |  |  |  | Where C<@middleware> is one or more of the following, applied in the REVERSE of | 
| 4547 |  |  |  |  |  |  | the order listed (to make it function similarly to L<Plack::Builder>: | 
| 4548 |  |  |  |  |  |  |  | 
| 4549 |  |  |  |  |  |  | Alternatively, you may also define middleware by calling the L</setup_middleware> | 
| 4550 |  |  |  |  |  |  | package method: | 
| 4551 |  |  |  |  |  |  |  | 
| 4552 |  |  |  |  |  |  | package MyApp::Web; | 
| 4553 |  |  |  |  |  |  |  | 
| 4554 |  |  |  |  |  |  | use Catalyst; | 
| 4555 |  |  |  |  |  |  |  | 
| 4556 |  |  |  |  |  |  | __PACKAGE__->setup_middleware( \@middleware_definitions); | 
| 4557 |  |  |  |  |  |  | __PACKAGE__->setup; | 
| 4558 |  |  |  |  |  |  |  | 
| 4559 |  |  |  |  |  |  | In the case where you do both (use 'setup_middleware' and configuration) the | 
| 4560 |  |  |  |  |  |  | package call to setup_middleware will be applied earlier (in other words its | 
| 4561 |  |  |  |  |  |  | middleware will wrap closer to the application).  Keep this in mind since in | 
| 4562 |  |  |  |  |  |  | some cases the order of middleware is important. | 
| 4563 |  |  |  |  |  |  |  | 
| 4564 |  |  |  |  |  |  | The two approaches are not exclusive. | 
| 4565 |  |  |  |  |  |  |  | 
| 4566 |  |  |  |  |  |  | =over 4 | 
| 4567 |  |  |  |  |  |  |  | 
| 4568 |  |  |  |  |  |  | =item Middleware Object | 
| 4569 |  |  |  |  |  |  |  | 
| 4570 |  |  |  |  |  |  | An already initialized object that conforms to the L<Plack::Middleware> | 
| 4571 |  |  |  |  |  |  | specification: | 
| 4572 |  |  |  |  |  |  |  | 
| 4573 |  |  |  |  |  |  | my $stacktrace_middleware = Plack::Middleware::StackTrace->new; | 
| 4574 |  |  |  |  |  |  |  | 
| 4575 |  |  |  |  |  |  | __PACKAGE__->config( | 
| 4576 |  |  |  |  |  |  | 'psgi_middleware', [ | 
| 4577 |  |  |  |  |  |  | $stacktrace_middleware, | 
| 4578 |  |  |  |  |  |  | ]); | 
| 4579 |  |  |  |  |  |  |  | 
| 4580 |  |  |  |  |  |  |  | 
| 4581 |  |  |  |  |  |  | =item coderef | 
| 4582 |  |  |  |  |  |  |  | 
| 4583 |  |  |  |  |  |  | A coderef that is an inlined middleware: | 
| 4584 |  |  |  |  |  |  |  | 
| 4585 |  |  |  |  |  |  | __PACKAGE__->config( | 
| 4586 |  |  |  |  |  |  | 'psgi_middleware', [ | 
| 4587 |  |  |  |  |  |  | sub { | 
| 4588 |  |  |  |  |  |  | my $app = shift; | 
| 4589 |  |  |  |  |  |  | return sub { | 
| 4590 |  |  |  |  |  |  | my $env = shift; | 
| 4591 |  |  |  |  |  |  | if($env->{PATH_INFO} =~m/forced/) { | 
| 4592 |  |  |  |  |  |  | Plack::App::File | 
| 4593 |  |  |  |  |  |  | ->new(file=>TestApp->path_to(qw/share static forced.txt/)) | 
| 4594 |  |  |  |  |  |  | ->call($env); | 
| 4595 |  |  |  |  |  |  | } else { | 
| 4596 |  |  |  |  |  |  | return $app->($env); | 
| 4597 |  |  |  |  |  |  | } | 
| 4598 |  |  |  |  |  |  | }, | 
| 4599 |  |  |  |  |  |  | }, | 
| 4600 |  |  |  |  |  |  | ]); | 
| 4601 |  |  |  |  |  |  |  | 
| 4602 |  |  |  |  |  |  |  | 
| 4603 |  |  |  |  |  |  |  | 
| 4604 |  |  |  |  |  |  | =item a scalar | 
| 4605 |  |  |  |  |  |  |  | 
| 4606 |  |  |  |  |  |  | We assume the scalar refers to a namespace after normalizing it using the | 
| 4607 |  |  |  |  |  |  | following rules: | 
| 4608 |  |  |  |  |  |  |  | 
| 4609 |  |  |  |  |  |  | (1) If the scalar is prefixed with a "+" (as in C<+MyApp::Foo>) then the full string | 
| 4610 |  |  |  |  |  |  | is assumed to be 'as is', and we just install and use the middleware. | 
| 4611 |  |  |  |  |  |  |  | 
| 4612 |  |  |  |  |  |  | (2) If the scalar begins with "Plack::Middleware" or your application namespace | 
| 4613 |  |  |  |  |  |  | (the package name of your Catalyst application subclass), we also assume then | 
| 4614 |  |  |  |  |  |  | that it is a full namespace, and use it. | 
| 4615 |  |  |  |  |  |  |  | 
| 4616 |  |  |  |  |  |  | (3) Lastly, we then assume that the scalar is a partial namespace, and attempt to | 
| 4617 |  |  |  |  |  |  | resolve it first by looking for it under your application namespace (for example | 
| 4618 |  |  |  |  |  |  | if you application is "MyApp::Web" and the scalar is "MyMiddleware", we'd look | 
| 4619 |  |  |  |  |  |  | under "MyApp::Web::Middleware::MyMiddleware") and if we don't find it there, we | 
| 4620 |  |  |  |  |  |  | will then look under the regular L<Plack::Middleware> namespace (i.e. for the | 
| 4621 |  |  |  |  |  |  | previous we'd try "Plack::Middleware::MyMiddleware").  We look under your application | 
| 4622 |  |  |  |  |  |  | namespace first to let you 'override' common L<Plack::Middleware> locally, should | 
| 4623 |  |  |  |  |  |  | you find that a good idea. | 
| 4624 |  |  |  |  |  |  |  | 
| 4625 |  |  |  |  |  |  | Examples: | 
| 4626 |  |  |  |  |  |  |  | 
| 4627 |  |  |  |  |  |  | package MyApp::Web; | 
| 4628 |  |  |  |  |  |  |  | 
| 4629 |  |  |  |  |  |  | __PACKAGE__->config( | 
| 4630 |  |  |  |  |  |  | 'psgi_middleware', [ | 
| 4631 |  |  |  |  |  |  | 'Debug',  ## MyAppWeb::Middleware::Debug->wrap or Plack::Middleware::Debug->wrap | 
| 4632 |  |  |  |  |  |  | 'Plack::Middleware::Stacktrace', ## Plack::Middleware::Stacktrace->wrap | 
| 4633 |  |  |  |  |  |  | '+MyApp::Custom',  ## MyApp::Custom->wrap | 
| 4634 |  |  |  |  |  |  | ], | 
| 4635 |  |  |  |  |  |  | ); | 
| 4636 |  |  |  |  |  |  |  | 
| 4637 |  |  |  |  |  |  | =item a scalar followed by a hashref | 
| 4638 |  |  |  |  |  |  |  | 
| 4639 |  |  |  |  |  |  | Just like the previous, except the following C<HashRef> is used as arguments | 
| 4640 |  |  |  |  |  |  | to initialize the middleware object. | 
| 4641 |  |  |  |  |  |  |  | 
| 4642 |  |  |  |  |  |  | __PACKAGE__->config( | 
| 4643 |  |  |  |  |  |  | 'psgi_middleware', [ | 
| 4644 |  |  |  |  |  |  | 'Session' => {store => 'File'}, | 
| 4645 |  |  |  |  |  |  | ]); | 
| 4646 |  |  |  |  |  |  |  | 
| 4647 |  |  |  |  |  |  | =back | 
| 4648 |  |  |  |  |  |  |  | 
| 4649 |  |  |  |  |  |  | Please see L<PSGI> for more on middleware. | 
| 4650 |  |  |  |  |  |  |  | 
| 4651 |  |  |  |  |  |  | =head1 ENCODING | 
| 4652 |  |  |  |  |  |  |  | 
| 4653 |  |  |  |  |  |  | Starting in L<Catalyst> version 5.90080 encoding is automatically enabled | 
| 4654 |  |  |  |  |  |  | and set to encode all body responses to UTF8 when possible and applicable. | 
| 4655 |  |  |  |  |  |  | Following is documentation on this process.  If you are using an older | 
| 4656 |  |  |  |  |  |  | version of L<Catalyst> you should review documentation for that version since | 
| 4657 |  |  |  |  |  |  | a lot has changed. | 
| 4658 |  |  |  |  |  |  |  | 
| 4659 |  |  |  |  |  |  | By default encoding is now 'UTF-8'.  You may turn it off by setting | 
| 4660 |  |  |  |  |  |  | the encoding configuration to undef. | 
| 4661 |  |  |  |  |  |  |  | 
| 4662 |  |  |  |  |  |  | MyApp->config(encoding => undef); | 
| 4663 |  |  |  |  |  |  |  | 
| 4664 |  |  |  |  |  |  | This is recommended for temporary backwards compatibility only. | 
| 4665 |  |  |  |  |  |  |  | 
| 4666 |  |  |  |  |  |  | To turn it off for a single request use the L<clear_encoding> | 
| 4667 |  |  |  |  |  |  | method to turn off encoding for this request.  This can be useful | 
| 4668 |  |  |  |  |  |  | when you are setting the body to be an arbitrary block of bytes, | 
| 4669 |  |  |  |  |  |  | especially if that block happens to be a block of UTF8 text. | 
| 4670 |  |  |  |  |  |  |  | 
| 4671 |  |  |  |  |  |  | Encoding is automatically applied when the content-type is set to | 
| 4672 |  |  |  |  |  |  | a type that can be encoded.  Currently we encode when the content type | 
| 4673 |  |  |  |  |  |  | matches the following regular expression: | 
| 4674 |  |  |  |  |  |  |  | 
| 4675 |  |  |  |  |  |  | $content_type =~ /^text|xml$|javascript$/ | 
| 4676 |  |  |  |  |  |  |  | 
| 4677 |  |  |  |  |  |  | Encoding is set on the application, but it is copied to the context object | 
| 4678 |  |  |  |  |  |  | so that you can override it on a request basis. | 
| 4679 |  |  |  |  |  |  |  | 
| 4680 |  |  |  |  |  |  | Be default we don't automatically encode 'application/json' since the most | 
| 4681 |  |  |  |  |  |  | common approaches to generating this type of response (Either via L<Catalyst::View::JSON> | 
| 4682 |  |  |  |  |  |  | or L<Catalyst::Action::REST>) will do so already and we want to avoid double | 
| 4683 |  |  |  |  |  |  | encoding issues. | 
| 4684 |  |  |  |  |  |  |  | 
| 4685 |  |  |  |  |  |  | If you are producing JSON response in an unconventional manner (such | 
| 4686 |  |  |  |  |  |  | as via a template or manual strings) you should perform the UTF8 encoding | 
| 4687 |  |  |  |  |  |  | manually as well such as to conform to the JSON specification. | 
| 4688 |  |  |  |  |  |  |  | 
| 4689 |  |  |  |  |  |  | NOTE: We also examine the value of $c->response->content_encoding.  If | 
| 4690 |  |  |  |  |  |  | you set this (like for example 'gzip', and manually gzipping the body) | 
| 4691 |  |  |  |  |  |  | we assume that you have done all the necessary encoding yourself, since | 
| 4692 |  |  |  |  |  |  | we cannot encode the gzipped contents.  If you use a plugin like | 
| 4693 |  |  |  |  |  |  | L<Catalyst::Plugin::Compress> you need to update to a modern version in order | 
| 4694 |  |  |  |  |  |  | to have this function correctly  with the new UTF8 encoding code, or you | 
| 4695 |  |  |  |  |  |  | can use L<Plack::Middleware::Deflater> or (probably best) do your compression on | 
| 4696 |  |  |  |  |  |  | a front end proxy. | 
| 4697 |  |  |  |  |  |  |  | 
| 4698 |  |  |  |  |  |  | =head2 Methods | 
| 4699 |  |  |  |  |  |  |  | 
| 4700 |  |  |  |  |  |  | =over 4 | 
| 4701 |  |  |  |  |  |  |  | 
| 4702 |  |  |  |  |  |  | =item encoding | 
| 4703 |  |  |  |  |  |  |  | 
| 4704 |  |  |  |  |  |  | Returns an instance of an C<Encode> encoding | 
| 4705 |  |  |  |  |  |  |  | 
| 4706 |  |  |  |  |  |  | print $c->encoding->name | 
| 4707 |  |  |  |  |  |  |  | 
| 4708 |  |  |  |  |  |  | =item handle_unicode_encoding_exception ($exception_context) | 
| 4709 |  |  |  |  |  |  |  | 
| 4710 |  |  |  |  |  |  | Method called when decoding process for a request fails. | 
| 4711 |  |  |  |  |  |  |  | 
| 4712 |  |  |  |  |  |  | An C<$exception_context> hashref is provided to allow you to override the | 
| 4713 |  |  |  |  |  |  | behaviour of your application when given data with incorrect encodings. | 
| 4714 |  |  |  |  |  |  |  | 
| 4715 |  |  |  |  |  |  | The default method throws exceptions in the case of invalid request parameters | 
| 4716 |  |  |  |  |  |  | (resulting in a 500 error), but ignores errors in upload filenames. | 
| 4717 |  |  |  |  |  |  |  | 
| 4718 |  |  |  |  |  |  | The keys passed in the C<$exception_context> hash are: | 
| 4719 |  |  |  |  |  |  |  | 
| 4720 |  |  |  |  |  |  | =over | 
| 4721 |  |  |  |  |  |  |  | 
| 4722 |  |  |  |  |  |  | =item param_value | 
| 4723 |  |  |  |  |  |  |  | 
| 4724 |  |  |  |  |  |  | The value which was not able to be decoded. | 
| 4725 |  |  |  |  |  |  |  | 
| 4726 |  |  |  |  |  |  | =item error_msg | 
| 4727 |  |  |  |  |  |  |  | 
| 4728 |  |  |  |  |  |  | The exception received from L<Encode>. | 
| 4729 |  |  |  |  |  |  |  | 
| 4730 |  |  |  |  |  |  | =item encoding_step | 
| 4731 |  |  |  |  |  |  |  | 
| 4732 |  |  |  |  |  |  | What type of data was being decoded. Valid values are (currently) | 
| 4733 |  |  |  |  |  |  | C<params> - for request parameters / arguments / captures | 
| 4734 |  |  |  |  |  |  | and C<uploads> - for request upload filenames. | 
| 4735 |  |  |  |  |  |  |  | 
| 4736 |  |  |  |  |  |  | =back | 
| 4737 |  |  |  |  |  |  |  | 
| 4738 |  |  |  |  |  |  | =back | 
| 4739 |  |  |  |  |  |  |  | 
| 4740 |  |  |  |  |  |  | =head1 SUPPORT | 
| 4741 |  |  |  |  |  |  |  | 
| 4742 |  |  |  |  |  |  | IRC: | 
| 4743 |  |  |  |  |  |  |  | 
| 4744 |  |  |  |  |  |  | Join #catalyst on irc.perl.org. | 
| 4745 |  |  |  |  |  |  |  | 
| 4746 |  |  |  |  |  |  | Mailing Lists: | 
| 4747 |  |  |  |  |  |  |  | 
| 4748 |  |  |  |  |  |  | http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst | 
| 4749 |  |  |  |  |  |  | http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev | 
| 4750 |  |  |  |  |  |  |  | 
| 4751 |  |  |  |  |  |  | Web: | 
| 4752 |  |  |  |  |  |  |  | 
| 4753 |  |  |  |  |  |  | http://catalyst.perl.org | 
| 4754 |  |  |  |  |  |  |  | 
| 4755 |  |  |  |  |  |  | Wiki: | 
| 4756 |  |  |  |  |  |  |  | 
| 4757 |  |  |  |  |  |  | http://dev.catalyst.perl.org | 
| 4758 |  |  |  |  |  |  |  | 
| 4759 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 4760 |  |  |  |  |  |  |  | 
| 4761 |  |  |  |  |  |  | =head2 L<Task::Catalyst> - All you need to start with Catalyst | 
| 4762 |  |  |  |  |  |  |  | 
| 4763 |  |  |  |  |  |  | =head2 L<Catalyst::Manual> - The Catalyst Manual | 
| 4764 |  |  |  |  |  |  |  | 
| 4765 |  |  |  |  |  |  | =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components | 
| 4766 |  |  |  |  |  |  |  | 
| 4767 |  |  |  |  |  |  | =head2 L<Catalyst::Engine> - Core engine | 
| 4768 |  |  |  |  |  |  |  | 
| 4769 |  |  |  |  |  |  | =head2 L<Catalyst::Log> - Log class. | 
| 4770 |  |  |  |  |  |  |  | 
| 4771 |  |  |  |  |  |  | =head2 L<Catalyst::Request> - Request object | 
| 4772 |  |  |  |  |  |  |  | 
| 4773 |  |  |  |  |  |  | =head2 L<Catalyst::Response> - Response object | 
| 4774 |  |  |  |  |  |  |  | 
| 4775 |  |  |  |  |  |  | =head2 L<Catalyst::Test> - The test suite. | 
| 4776 |  |  |  |  |  |  |  | 
| 4777 |  |  |  |  |  |  | =head1 PROJECT FOUNDER | 
| 4778 |  |  |  |  |  |  |  | 
| 4779 |  |  |  |  |  |  | sri: Sebastian Riedel <sri@cpan.org> | 
| 4780 |  |  |  |  |  |  |  | 
| 4781 |  |  |  |  |  |  | =head1 CONTRIBUTORS | 
| 4782 |  |  |  |  |  |  |  | 
| 4783 |  |  |  |  |  |  | abw: Andy Wardley | 
| 4784 |  |  |  |  |  |  |  | 
| 4785 |  |  |  |  |  |  | acme: Leon Brocard <leon@astray.com> | 
| 4786 |  |  |  |  |  |  |  | 
| 4787 |  |  |  |  |  |  | abraxxa: Alexander Hartmaier <abraxxa@cpan.org> | 
| 4788 |  |  |  |  |  |  |  | 
| 4789 |  |  |  |  |  |  | andrewalker: André Walker <andre@cpan.org> | 
| 4790 |  |  |  |  |  |  |  | 
| 4791 |  |  |  |  |  |  | Andrew Bramble | 
| 4792 |  |  |  |  |  |  |  | 
| 4793 |  |  |  |  |  |  | Andrew Ford <A.Ford@ford-mason.co.uk> | 
| 4794 |  |  |  |  |  |  |  | 
| 4795 |  |  |  |  |  |  | Andrew Ruthven | 
| 4796 |  |  |  |  |  |  |  | 
| 4797 |  |  |  |  |  |  | andyg: Andy Grundman <andy@hybridized.org> | 
| 4798 |  |  |  |  |  |  |  | 
| 4799 |  |  |  |  |  |  | audreyt: Audrey Tang | 
| 4800 |  |  |  |  |  |  |  | 
| 4801 |  |  |  |  |  |  | bricas: Brian Cassidy <bricas@cpan.org> | 
| 4802 |  |  |  |  |  |  |  | 
| 4803 |  |  |  |  |  |  | Caelum: Rafael Kitover <rkitover@io.com> | 
| 4804 |  |  |  |  |  |  |  | 
| 4805 |  |  |  |  |  |  | chansen: Christian Hansen | 
| 4806 |  |  |  |  |  |  |  | 
| 4807 |  |  |  |  |  |  | Chase Venters <chase.venters@gmail.com> | 
| 4808 |  |  |  |  |  |  |  | 
| 4809 |  |  |  |  |  |  | chicks: Christopher Hicks | 
| 4810 |  |  |  |  |  |  |  | 
| 4811 |  |  |  |  |  |  | Chisel Wright <pause@herlpacker.co.uk> | 
| 4812 |  |  |  |  |  |  |  | 
| 4813 |  |  |  |  |  |  | Danijel Milicevic <me@danijel.de> | 
| 4814 |  |  |  |  |  |  |  | 
| 4815 |  |  |  |  |  |  | davewood: David Schmidt <davewood@cpan.org> | 
| 4816 |  |  |  |  |  |  |  | 
| 4817 |  |  |  |  |  |  | David Kamholz <dkamholz@cpan.org> | 
| 4818 |  |  |  |  |  |  |  | 
| 4819 |  |  |  |  |  |  | David Naughton <naughton@umn.edu> | 
| 4820 |  |  |  |  |  |  |  | 
| 4821 |  |  |  |  |  |  | David E. Wheeler | 
| 4822 |  |  |  |  |  |  |  | 
| 4823 |  |  |  |  |  |  | dhoss: Devin Austin <dhoss@cpan.org> | 
| 4824 |  |  |  |  |  |  |  | 
| 4825 |  |  |  |  |  |  | dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com> | 
| 4826 |  |  |  |  |  |  |  | 
| 4827 |  |  |  |  |  |  | Drew Taylor | 
| 4828 |  |  |  |  |  |  |  | 
| 4829 |  |  |  |  |  |  | dwc: Daniel Westermann-Clark <danieltwc@cpan.org> | 
| 4830 |  |  |  |  |  |  |  | 
| 4831 |  |  |  |  |  |  | esskar: Sascha Kiefer | 
| 4832 |  |  |  |  |  |  |  | 
| 4833 |  |  |  |  |  |  | fireartist: Carl Franks <cfranks@cpan.org> | 
| 4834 |  |  |  |  |  |  |  | 
| 4835 |  |  |  |  |  |  | frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com> | 
| 4836 |  |  |  |  |  |  |  | 
| 4837 |  |  |  |  |  |  | gabb: Danijel Milicevic | 
| 4838 |  |  |  |  |  |  |  | 
| 4839 |  |  |  |  |  |  | Gary Ashton Jones | 
| 4840 |  |  |  |  |  |  |  | 
| 4841 |  |  |  |  |  |  | Gavin Henry <ghenry@perl.me.uk> | 
| 4842 |  |  |  |  |  |  |  | 
| 4843 |  |  |  |  |  |  | Geoff Richards | 
| 4844 |  |  |  |  |  |  |  | 
| 4845 |  |  |  |  |  |  | groditi: Guillermo Roditi <groditi@gmail.com> | 
| 4846 |  |  |  |  |  |  |  | 
| 4847 |  |  |  |  |  |  | hobbs: Andrew Rodland <andrew@cleverdomain.org> | 
| 4848 |  |  |  |  |  |  |  | 
| 4849 |  |  |  |  |  |  | ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> | 
| 4850 |  |  |  |  |  |  |  | 
| 4851 |  |  |  |  |  |  | jcamacho: Juan Camacho | 
| 4852 |  |  |  |  |  |  |  | 
| 4853 |  |  |  |  |  |  | jester: Jesse Sheidlower <jester@panix.com> | 
| 4854 |  |  |  |  |  |  |  | 
| 4855 |  |  |  |  |  |  | jhannah: Jay Hannah <jay@jays.net> | 
| 4856 |  |  |  |  |  |  |  | 
| 4857 |  |  |  |  |  |  | Jody Belka | 
| 4858 |  |  |  |  |  |  |  | 
| 4859 |  |  |  |  |  |  | Johan Lindstrom | 
| 4860 |  |  |  |  |  |  |  | 
| 4861 |  |  |  |  |  |  | jon: Jon Schutz <jjschutz@cpan.org> | 
| 4862 |  |  |  |  |  |  |  | 
| 4863 |  |  |  |  |  |  | Jonathan Rockway <jrockway@cpan.org> | 
| 4864 |  |  |  |  |  |  |  | 
| 4865 |  |  |  |  |  |  | Kieren Diment <kd@totaldatasolution.com> | 
| 4866 |  |  |  |  |  |  |  | 
| 4867 |  |  |  |  |  |  | konobi: Scott McWhirter <konobi@cpan.org> | 
| 4868 |  |  |  |  |  |  |  | 
| 4869 |  |  |  |  |  |  | marcus: Marcus Ramberg <mramberg@cpan.org> | 
| 4870 |  |  |  |  |  |  |  | 
| 4871 |  |  |  |  |  |  | miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net> | 
| 4872 |  |  |  |  |  |  |  | 
| 4873 |  |  |  |  |  |  | mgrimes: Mark Grimes <mgrimes@cpan.org> | 
| 4874 |  |  |  |  |  |  |  | 
| 4875 |  |  |  |  |  |  | mst: Matt S. Trout <mst@shadowcatsystems.co.uk> | 
| 4876 |  |  |  |  |  |  |  | 
| 4877 |  |  |  |  |  |  | mugwump: Sam Vilain | 
| 4878 |  |  |  |  |  |  |  | 
| 4879 |  |  |  |  |  |  | naughton: David Naughton | 
| 4880 |  |  |  |  |  |  |  | 
| 4881 |  |  |  |  |  |  | ningu: David Kamholz <dkamholz@cpan.org> | 
| 4882 |  |  |  |  |  |  |  | 
| 4883 |  |  |  |  |  |  | nothingmuch: Yuval Kogman <nothingmuch@woobling.org> | 
| 4884 |  |  |  |  |  |  |  | 
| 4885 |  |  |  |  |  |  | numa: Dan Sully <daniel@cpan.org> | 
| 4886 |  |  |  |  |  |  |  | 
| 4887 |  |  |  |  |  |  | obra: Jesse Vincent | 
| 4888 |  |  |  |  |  |  |  | 
| 4889 |  |  |  |  |  |  | Octavian Rasnita | 
| 4890 |  |  |  |  |  |  |  | 
| 4891 |  |  |  |  |  |  | omega: Andreas Marienborg | 
| 4892 |  |  |  |  |  |  |  | 
| 4893 |  |  |  |  |  |  | Oleg Kostyuk <cub.uanic@gmail.com> | 
| 4894 |  |  |  |  |  |  |  | 
| 4895 |  |  |  |  |  |  | phaylon: Robert Sedlacek <phaylon@dunkelheit.at> | 
| 4896 |  |  |  |  |  |  |  | 
| 4897 |  |  |  |  |  |  | rafl: Florian Ragwitz <rafl@debian.org> | 
| 4898 |  |  |  |  |  |  |  | 
| 4899 |  |  |  |  |  |  | random: Roland Lammel <lammel@cpan.org> | 
| 4900 |  |  |  |  |  |  |  | 
| 4901 |  |  |  |  |  |  | revmischa: Mischa Spiegelmock <revmischa@cpan.org> | 
| 4902 |  |  |  |  |  |  |  | 
| 4903 |  |  |  |  |  |  | Robert Sedlacek <rs@474.at> | 
| 4904 |  |  |  |  |  |  |  | 
| 4905 |  |  |  |  |  |  | rrwo: Robert Rothenberg <rrwo@cpan.org> | 
| 4906 |  |  |  |  |  |  |  | 
| 4907 |  |  |  |  |  |  | SpiceMan: Marcel Montes | 
| 4908 |  |  |  |  |  |  |  | 
| 4909 |  |  |  |  |  |  | sky: Arthur Bergman | 
| 4910 |  |  |  |  |  |  |  | 
| 4911 |  |  |  |  |  |  | szbalint: Balint Szilakszi <szbalint@cpan.org> | 
| 4912 |  |  |  |  |  |  |  | 
| 4913 |  |  |  |  |  |  | t0m: Tomas Doran <bobtfish@bobtfish.net> | 
| 4914 |  |  |  |  |  |  |  | 
| 4915 |  |  |  |  |  |  | Ulf Edvinsson | 
| 4916 |  |  |  |  |  |  |  | 
| 4917 |  |  |  |  |  |  | vanstyn: Henry Van Styn <vanstyn@cpan.org> | 
| 4918 |  |  |  |  |  |  |  | 
| 4919 |  |  |  |  |  |  | Viljo Marrandi <vilts@yahoo.com> | 
| 4920 |  |  |  |  |  |  |  | 
| 4921 |  |  |  |  |  |  | Will Hawes <info@whawes.co.uk> | 
| 4922 |  |  |  |  |  |  |  | 
| 4923 |  |  |  |  |  |  | willert: Sebastian Willert <willert@cpan.org> | 
| 4924 |  |  |  |  |  |  |  | 
| 4925 |  |  |  |  |  |  | wreis: Wallace Reis <wreis@cpan.org> | 
| 4926 |  |  |  |  |  |  |  | 
| 4927 |  |  |  |  |  |  | Yuval Kogman <nothingmuch@woobling.org> | 
| 4928 |  |  |  |  |  |  |  | 
| 4929 |  |  |  |  |  |  | rainboxx: Matthias Dietrich <perl@rainboxx.de> | 
| 4930 |  |  |  |  |  |  |  | 
| 4931 |  |  |  |  |  |  | dd070: Dhaval Dhanani <dhaval070@gmail.com> | 
| 4932 |  |  |  |  |  |  |  | 
| 4933 |  |  |  |  |  |  | Upasana <me@upasana.me> | 
| 4934 |  |  |  |  |  |  |  | 
| 4935 |  |  |  |  |  |  | John Napiorkowski (jnap) <jjnapiork@cpan.org> | 
| 4936 |  |  |  |  |  |  |  | 
| 4937 |  |  |  |  |  |  | =head1 COPYRIGHT | 
| 4938 |  |  |  |  |  |  |  | 
| 4939 |  |  |  |  |  |  | Copyright (c) 2005-2015, the above named PROJECT FOUNDER and CONTRIBUTORS. | 
| 4940 |  |  |  |  |  |  |  | 
| 4941 |  |  |  |  |  |  | =head1 LICENSE | 
| 4942 |  |  |  |  |  |  |  | 
| 4943 |  |  |  |  |  |  | This library is free software. You can redistribute it and/or modify it under | 
| 4944 |  |  |  |  |  |  | the same terms as Perl itself. | 
| 4945 |  |  |  |  |  |  |  | 
| 4946 |  |  |  |  |  |  | =cut | 
| 4947 |  |  |  |  |  |  |  | 
| 4948 |  |  |  |  |  |  | no Moose; | 
| 4949 |  |  |  |  |  |  |  | 
| 4950 |  |  |  |  |  |  | __PACKAGE__->meta->make_immutable; | 
| 4951 |  |  |  |  |  |  |  | 
| 4952 |  |  |  |  |  |  | 1; |