use warnings;
use base 'Catalyst::Action';
+use Moose::Util qw(does_role);
+use Catalyst::ControllerRole::SerializeConfig;
use Module::Pluggable::Object;
-use Data::Dump qw(dump);
-use Catalyst::Request::REST;
-
-Catalyst->request_class('Catalyst::Request::REST')
- unless Catalyst->request_class->isa('Catalyst::Request::REST');
+use Catalyst::RequestRole::REST;
+use Catalyst::ResponseRole::REST;
+use Catalyst::Utils ();
__PACKAGE__->mk_accessors(qw(_serialize_plugins _loaded_plugins));
my $self = shift;
my ( $search_path, $controller, $c ) = @_;
+ Catalyst::RequestRole::REST->meta->apply($c->request)
+ unless does_role($c->request, 'Catalyst::RequestRole::REST');
+
+ Catalyst::ResponseRole::REST->meta->apply($c->response)
+ unless does_role($c->response, 'Catalyst::ResponseRole::REST');
+
unless ( defined( $self->_loaded_plugins ) ) {
$self->_loaded_plugins( {} );
}
my $sarg;
my $map;
- my $config;
+ Catalyst::ControllerRole::SerializeConfig->meta->apply($controller)
+ unless does_role($controller, 'Catalyst::ControllerRole::SerializeConfig');
+
+ my $config = $controller->serialize_config;
- if ( exists $controller->config->{'serialize'} ) {
- $c->log->info("Using deprecated configuration for Catalyst::Action::REST!");
- $c->log->info("Please see perldoc Catalyst::Action::REST for the update guide");
- $config = $controller->config->{'serialize'};
- } else {
- $config = $controller->config;
+ $map = $config->{map};
+
+ # pick preferred content type
+ my @accepted_types; # priority order, best first
+ # give top priority to content type specified by stash, if any
+ my $content_type_stash_key = $config->{content_type_stash_key};
+ if ($content_type_stash_key
+ and my $stashed = $c->stash->{$content_type_stash_key}
+ ) {
+ # convert to array if not already a ref
+ $stashed = [ $stashed ] if not ref $stashed;
+ push @accepted_types, @$stashed;
}
- $map = $config->{'map'};
- # If we don't have a handler for our preferred content type, try
- # the default
-
- my ($content_type) = grep { $map->{$_} } @{$c->request->accepted_content_types};
-
- unless ( defined $content_type ) {
- if( exists $config->{'default'} ) {
- $content_type = $config->{'default'} ;
- } else {
- return $self->_unsupported_media_type($c, $content_type);
- }
+ # then content types requested by caller
+ push @accepted_types, @{ $c->request->accepted_content_types };
+ # then the default
+ push @accepted_types, $config->{'default'} if $config->{'default'};
+ # pick the best match that we have a serializer mapping for
+ my ($content_type) = grep { $map->{$_} } @accepted_types;
+
+ unless ($content_type) {
+ $c->response->unsupported_media_type;
+ return;
}
# carp about old text/x-json
$sclass .= $mc;
#}
if ( !grep( /^$sclass$/, @{ $self->_serialize_plugins } ) ) {
- return $self->_unsupported_media_type($c, $content_type);
+ $c->response->unsupported_media_type($content_type);
+ return;
}
} else {
- return $self->_unsupported_media_type($c, $content_type);
+ $c->response->unsupported_media_type($content_type);
+ return;
}
unless ( exists( $self->_loaded_plugins->{$sclass} ) ) {
my $load_class = $sclass;
if ($@) {
$c->log->error(
"Error loading $sclass for " . $content_type . ": $!" );
- return $self->_unsupported_media_type($c, $content_type);
+ $c->response->unsupported_media_type($content_type);
+ return;
} else {
$self->_loaded_plugins->{$sclass} = 1;
}
return $sclass, $sarg, $content_type;
}
-sub _unsupported_media_type {
- my ( $self, $c, $content_type ) = @_;
- $c->res->content_type('text/plain');
- $c->res->status(415);
- if (defined($content_type) && $content_type ne "") {
- $c->res->body(
- "Content-Type " . $content_type . " is not supported.\r\n" );
- } else {
- $c->res->body(
- "Cannot find a Content-Type supported by your client.\r\n" );
- }
- return undef;
-}
-
-sub _serialize_bad_request {
- my ( $self, $c, $content_type, $error ) = @_;
- $c->res->content_type('text/plain');
- $c->res->status(400);
- $c->res->body(
- "Content-Type " . $content_type . " had a problem with your request.\r\n***ERROR***\r\n$error" );
- return undef;
-}
-
1;
=head1 NAME