Apache2-REST
view release on metacpan or search on metacpan
lib/Apache2/REST/Handler.pm view on Meta::CPAN
sub handle{
my ( $self , $stack , $req , $resp ) = @_ ;
#warn "Handling ".Dumper($stack)."\n" ;
if ( 0 == @$stack ){
my $method = $req->method();
## Check auth first
if ( $self->isAuth($method , $req )){
unless( $self->can($method)){
$resp->message('Method '.$method.' not implemented');
$resp->status(HTTP_NOT_IMPLEMENTED);
return HTTP_NOT_IMPLEMENTED ;
}
my $res = undef;
eval{
$res = $self->$method($req,$resp) ;
};
if ( $@ ){
my $err = $@ ;
Apache2::REST::ErrorOutputRegistry->instance()->getOutput($self->conf()->Apache2RESTErrorOutput())->handle($err,$resp, $req);
$resp->status(HTTP_INTERNAL_SERVER_ERROR);
return HTTP_INTERNAL_SERVER_ERROR ;
}
$resp->status($res) ;
return $res ;
}else{
$resp->status(HTTP_UNAUTHORIZED) ;
$resp->message('method unauthorized') ;
return HTTP_UNAUTHORIZED ;
}
}
my $fragment = shift @$stack ;
my $subh = $self->buildNext($fragment , $req ) ;
unless( $subh ){
$resp->status(HTTP_NOT_FOUND);
$resp->message('Resource not found for '.$fragment) ;
return HTTP_NOT_FOUND ;
}
return $subh->handle($stack , $req , $resp ) ;
}
=head2 buildNext
This method is responsible for building the handler handling the next fragment.
It is given the fragment to build an handler for as well as the Request.
The default implementation builds a handler of class $this->class().'::'.$frag
It _must_ return undef when the resource is not found.
Called like this by the framework:
$this->buildNext($frag , $req ) ;
Overriding use cases:
- Build a dynamic handler.
For instance if the fragment is an item ID, you might want to build an item handler with this particular item. See L<Apache2::REST::Handler::test> for an example.
- Rerouting outside of the handler classes space.
If you want to escape the default class resolution mecanism.
=cut
sub buildNext{
my ( $self , $frag , $req ) = @_ ;
## default implementation
my $newC = $self->class().'::'.$frag ;
eval "require $newC;";
if ( $@ ){
warn "Class $newC not found: $@\n" ;
return undef ;
}
return $newC->new($self) ;
}
=head2 isAuth
Given a method and a request, returns true if this method is allowed.
The default implementation delegates to the parent.
Nothing is allowed by default. So you need to override this method at least once.
It is called by the framework like this (for instance):
$this->isAuth('GET' , $req) ;
=cut
sub isAuth{
my ( $self , $method , $req ) = @ _;
if ( $self->parent()){
return $self->parent()->isAuth($method , $req ) || 0 ;
}
return 0 ;
}
=head2 new
You can override this in subclasses. Do not forget to call $class->SUPER::new() ;
=cut
sub new{
my ( $class , $parent ) = @_ ;
my $self = {
'parent' => $parent ,
};
# Enforce the presence of the _conf attribute.
if ( $parent ){
$self->{'_conf'} = $parent->conf() ;
}else{
$self->{'_conf'} = Apache2::REST::Conf->new() ;
}
return bless $self , $class ;
}
( run in 0.612 second using v1.01-cache-2.11-cpan-e1769b4cff6 )