From: t0m Date: Mon, 29 Jun 2009 22:45:33 +0000 (+0100) Subject: Rewrite REST _METHOD action handling to fake being a real action, and ergo appear... X-Git-Tag: fixes_5_80_forward_stats_warnings X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=refs%2Ftags%2Ffixes_5_80_forward_stats_warnings;p=catagits%2FCatalyst-Action-REST.git Rewrite REST _METHOD action handling to fake being a real action, and ergo appear in the stats table as you would expect. I like what this does, but my implementation here is hideous.. --- diff --git a/lib/Catalyst/Action/REST.pm b/lib/Catalyst/Action/REST.pm index 26c4933..d887f22 100644 --- a/lib/Catalyst/Action/REST.pm +++ b/lib/Catalyst/Action/REST.pm @@ -91,58 +91,60 @@ sub dispatch { my $controller = $c->component( $self->class ); my $method = $self->name . "_" . uc( $c->request->method ); - if ( $controller->can($method) ) { - $c->execute( $self->class, $self, @{ $c->req->args } ); - return $controller->$method( $c, @{ $c->req->args } ); - } else { - if ( $c->request->method eq "OPTIONS" ) { - return $self->_return_options($c); - } else { - my $handle_ni = $self->name . "_not_implemented"; - if ( $controller->can($handle_ni) ) { - return $controller->$handle_ni( $c, @{ $c->req->args } ); - } else { - return $self->_return_not_implemented($c); - } - } + + if (my $code = $controller->can($method)) { + $c->execute( $self->class, $self, @{ $c->req->args } ) if $code; + local $self->{reverse} = $self->{reverse} . "_" . uc( $c->request->method ); + local $self->{code} = $code; + + return $c->execute( $self->class, $self, @{ $c->req->args } ); } -} + if ($c->request->method eq "OPTIONS") { + local $self->{reverse} = $self->{reverse} . "_" . uc( $c->request->method ); + local $self->{code} = sub { $self->can('_return_options')->($self->name, @_) }; + return $c->execute( $self->class, $self, @{ $c->req->args } ); + } + my $not_implemented_method = $self->name . "_not_implemented"; + local $self->{code} = $controller->can($not_implemented_method) + || sub { $self->can('_return_not_implemented')->($self->name, @_); }; -sub _return_options { - my ( $self, $c ) = @_; + local $self->{reverse} = $not_implemented_method; - my @allowed = $self->_get_allowed_methods($c); - $c->response->content_type('text/plain'); - $c->response->status(200); - $c->response->header( 'Allow' => \@allowed ); + $c->execute( $self->class, $self, @{ $c->req->args } ); } -sub _get_allowed_methods { - my ( $self, $c ) = @_; - - my $controller = $self->class; - my $methods = Class::Inspector->methods($controller); +my $_get_allowed_methods = sub { + my ( $controller, $c, $name ) = @_; + my $class = ref($controller) ? ref($controller) : $controller; + my $methods = Class::Inspector->methods($class); my @allowed; foreach my $method ( @{$methods} ) { - my $name = $self->name; if ( $method =~ /^$name\_(.+)$/ ) { push( @allowed, $1 ); } } return @allowed; +}; + +sub _return_options { + my ( $method_name, $controller, $c) = @_; + my @allowed = $controller->$_get_allowed_methods($c, $method_name); + $c->response->content_type('text/plain'); + $c->response->status(200); + $c->response->header( 'Allow' => \@allowed ); } sub _return_not_implemented { - my ( $self, $c ) = @_; + my ( $method_name, $controller, $c ) = @_; - my @allowed = $self->_get_allowed_methods($c); + my @allowed = $controller->$_get_allowed_methods($c, $method_name); $c->response->content_type('text/plain'); $c->response->status(405); $c->response->header( 'Allow' => \@allowed ); $c->response->body( "Method " . $c->request->method . " not implemented for " - . $c->uri_for( $self->reverse ) ); + . $c->uri_for( $method_name ) ); } 1;