X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FEngine.pm;h=0c0b8cc411b8700ecae47766dc8e265fdfbfca9c;hb=3245f607a5d5494a4e7b4e8b06a63891b87893e5;hp=486bbf77485924dcc36fa6450246b9ce3841aa5a;hpb=61bacdcc9ec458cabeba0cf4ce0d40cb5eb9b8d4;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Engine.pm b/lib/Catalyst/Engine.pm index 486bbf7..0c0b8cc 100644 --- a/lib/Catalyst/Engine.pm +++ b/lib/Catalyst/Engine.pm @@ -26,6 +26,9 @@ __PACKAGE__->mk_accessors(qw/request response state/); *req = \&request; *res = \&response; +# For backwards compatibility +*finalize_output = \&finalize_body; + # For statistics our $COUNT = 1; our $START = time; @@ -77,18 +80,24 @@ Regex search for a component. =cut sub component { - my ( $c, $name ) = @_; + my $c = shift; - if ( my $component = $c->components->{$name} ) { - return $component; - } + if ( @_ ) { - else { - for my $component ( keys %{ $c->components } ) { - return $c->components->{$component} if $component =~ /$name/i; + my $name = shift; + + if ( my $component = $c->components->{$name} ) { + return $component; + } + + else { + for my $component ( keys %{ $c->components } ) { + return $c->components->{$component} if $component =~ /$name/i; + } } } + return sort keys %{ $c->components }; } =item $c->error @@ -123,7 +132,7 @@ Errors are available via $c->error. sub execute { my ( $c, $class, $code ) = @_; - $class = $c->comp($class) || $class; + $class = $c->components->{$class} || $class; $c->state(0); my $callsub = ( caller(1) )[3]; @@ -176,20 +185,28 @@ sub finalize { $c->finalize_error; } - if ( !$c->response->output && $c->response->status !~ /^(1|3)\d\d$/ ) { + if ( !$c->response->body && $c->response->status !~ /^(1|3)\d\d$/ ) { $c->finalize_error; } - if ( $c->response->output && !$c->response->content_length ) { + if ( $c->response->body && !$c->response->content_length ) { use bytes; # play safe with a utf8 aware perl - $c->response->content_length( length $c->response->output ); + $c->response->content_length( length $c->response->body ); } my $status = $c->finalize_headers; - $c->finalize_output; + $c->finalize_body; return $status; } +=item $c->finalize_body + +Finalize body. + +=cut + +sub finalize_body { } + =item $c->finalize_cookies Finalize cookies. @@ -260,7 +277,7 @@ sub finalize_error { $name = ''; } - $c->res->output( <<"" ); + $c->res->body( <<"" ); $title @@ -324,15 +341,7 @@ Finalize headers. sub finalize_headers { } -=item $c->finalize_output - -Finalize output. - -=cut - -sub finalize_output { } - -=item $c->handler( $class, $r ) +=item $c->handler( $class, $engine ) Handles the request. @@ -357,7 +366,7 @@ sub handler { my $elapsed; ( $elapsed, $status ) = $class->benchmark($handler); $elapsed = sprintf '%f', $elapsed; - my $av = sprintf '%.3f', 1 / $elapsed; + my $av = sprintf '%.3f', ( $elapsed == 0 ? '??' : (1 / $elapsed) ); my $t = Text::ASCIITable->new; $t->setCols( 'Action', 'Time' ); $t->setColWidth( 'Action', 64, 1 ); @@ -380,7 +389,7 @@ sub handler { return $status; } -=item $c->prepare($r) +=item $c->prepare($engine) Turns the engine-specific request( Apache, CGI ... ) into a Catalyst context . @@ -388,7 +397,7 @@ into a Catalyst context . =cut sub prepare { - my ( $class, $r ) = @_; + my ( $class, $engine ) = @_; my $c = bless { request => Catalyst::Request->new( @@ -397,12 +406,18 @@ sub prepare { cookies => {}, headers => HTTP::Headers->new, parameters => {}, + secure => 0, snippets => [], uploads => {} } ), response => Catalyst::Response->new( - { cookies => {}, headers => HTTP::Headers->new, status => 200 } + { + body => '', + cookies => {}, + headers => HTTP::Headers->new, + status => 200 + } ), stash => {}, state => 0 @@ -417,36 +432,52 @@ sub prepare { $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION ); } - $c->prepare_request($r); - $c->prepare_path; + $c->prepare_request($engine); + $c->prepare_connection; $c->prepare_headers; - $c->prepare_input; $c->prepare_cookies; - $c->prepare_connection; + $c->prepare_path; + $c->prepare_action; my $method = $c->req->method || ''; my $path = $c->req->path || ''; my $hostname = $c->req->hostname || ''; my $address = $c->req->address || ''; + $c->log->debug(qq/"$method" request for "$path" from $hostname($address)/) if $c->debug; - $c->prepare_action; - $c->prepare_parameters; + if ( $c->request->method eq 'POST' and $c->request->content_length ) { + + if ( $c->req->content_type eq 'application/x-www-form-urlencoded' ) { + $c->prepare_parameters; + } + elsif ( $c->req->content_type eq 'multipart/form-data' ) { + $c->prepare_parameters; + $c->prepare_uploads; + } + else { + $c->prepare_body; + } + } + + if ( $c->request->method eq 'GET' ) { + $c->prepare_parameters; + } if ( $c->debug && keys %{ $c->req->params } ) { my $t = Text::ASCIITable->new; $t->setCols( 'Key', 'Value' ); $t->setColWidth( 'Key', 37, 1 ); $t->setColWidth( 'Value', 36, 1 ); - for my $key ( keys %{ $c->req->params } ) { - my $value = $c->req->params->{$key} || ''; + for my $key ( sort keys %{ $c->req->params } ) { + my $param = $c->req->params->{$key}; + my $value = defined($param) ? $param : ''; $t->addRow( $key, $value ); } $c->log->debug( 'Parameters are', $t->draw ); } - $c->prepare_uploads; return $c; } @@ -500,6 +531,14 @@ sub prepare_action { if ( $c->debug && @args ); } +=item $c->prepare_body + +Prepare message body. + +=cut + +sub prepare_body { } + =item $c->prepare_connection Prepare connection. @@ -536,14 +575,6 @@ Prepare parameters. =cut -sub prepare_input { } - -=item $c->prepare_input - -Prepare message body. - -=cut - sub prepare_parameters { } =item $c->prepare_path @@ -570,6 +601,39 @@ Prepare uploads. sub prepare_uploads { } +=item $c->retrieve_components + +Retrieve Components. + +=cut + +sub retrieve_components { + my $self = shift; + + my $class = ref $self || $self; + eval <<""; + package $class; + import Module::Pluggable::Fast + name => '_components', + search => [ + '$class\::Controller', '$class\::C', + '$class\::Model', '$class\::M', + '$class\::View', '$class\::V' + ], + require => 1; + + if ( my $error = $@ ) { + chomp $error; + die qq/Couldn't load components "$error"/; + } + + $self->components( {} ); + + for my $component ( $self->_components ) { + $self->components->{$component} = $component; + } +} + =item $c->run Starts the engine. @@ -604,6 +668,7 @@ Setup. sub setup { my $self = shift; + $self->retrieve_components; $self->setup_components; if ( $self->debug ) { my $name = $self->config->{name} || 'Application'; @@ -620,38 +685,34 @@ Setup components. sub setup_components { my $self = shift; - # Components - my $class = ref $self || $self; - eval <<""; - package $class; - import Module::Pluggable::Fast - name => '_components', - search => [ - '$class\::Controller', '$class\::C', - '$class\::Model', '$class\::M', - '$class\::View', '$class\::V' - ]; + my @components; + for my $component ( keys %{ $self->components } ) { - if ( my $error = $@ ) { - chomp $error; - die qq/Couldn't load components "$error"/; - } + unless ( UNIVERSAL::isa( $component, 'Catalyst::Base' ) ) { + next; + } - $self->components( {} ); - my @comps; - for my $comp ( $self->_components($self) ) { - $self->components->{ ref $comp } = $comp; - push @comps, $comp; - } + my $instance; + + eval { $instance = $component->new($self) }; + if ( $@ ) { + die( qq/Couldn't instantiate "$component", "$@"/ ); + } + + $self->components->{$component} = $instance; + + push @components, $component; + } + my $t = Text::ASCIITable->new( { hide_HeadRow => 1, hide_HeadLine => 1 } ); $t->setCols('Class'); $t->setColWidth( 'Class', 75, 1 ); - $t->addRow($_) for keys %{ $self->components }; + $t->addRow($_) for sort keys %{ $self->components }; $self->log->debug( 'Loaded components', $t->draw ) if ( @{ $t->{tbl_rows} } && $self->debug ); - $self->setup_actions( [ $self, @comps ] ); + $self->setup_actions( [ $self, @components ] ); } =item $c->state @@ -669,8 +730,8 @@ Returns a hashref containing all your data. sub stash { my $self = shift; - if ( $_[0] ) { - my $stash = $_[1] ? {@_} : $_[0]; + if ( @_ ) { + my $stash = @_ > 1 ? {@_} : $_[0]; while ( my ( $key, $val ) = each %$stash ) { $self->{stash}->{$key} = $val; } @@ -678,9 +739,6 @@ sub stash { return $self->{stash}; } -# Takes a coderef and returns an arrayref containing attributes -sub _get_attrs { attributes::get( $_[0] ) || [] } - =back =head1 AUTHOR