X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FAction%2FSerializeBase.pm;h=7dfe1e8db70f54e3cc20f3664e69c790937df9a9;hb=d4611771994693e9145e19c00c4b2d5bc7b485eb;hp=e26152b28b0fdc52f2e346c901336e0c2d1ab2fc;hpb=e601addaf89882fccbc824c1a53328f0d049b32b;p=catagits%2FCatalyst-Action-REST.git diff --git a/lib/Catalyst/Action/SerializeBase.pm b/lib/Catalyst/Action/SerializeBase.pm index e26152b..7dfe1e8 100644 --- a/lib/Catalyst/Action/SerializeBase.pm +++ b/lib/Catalyst/Action/SerializeBase.pm @@ -12,7 +12,10 @@ use warnings; use base 'Catalyst::Action'; use Module::Pluggable::Object; use Data::Dump qw(dump); -use HTTP::Headers::Util qw(split_header_words); +use Catalyst::Request::REST; + +Catalyst->request_class('Catalyst::Request::REST') + unless Catalyst->request_class->isa('Catalyst::Request::REST'); __PACKAGE__->mk_accessors(qw(_serialize_plugins _loaded_plugins)); @@ -33,55 +36,35 @@ sub _load_content_plugins { $self->_serialize_plugins( \@plugins ); } - # First, we use the content type in the HTTP Request. It wins all. - my $content_type = $c->request->content_type || ''; - - # Second, we allow GET requests to tunnel the content-type as - # a query param. - if (!$content_type && $c->req->method eq "GET" && $c->req->param('content-type')) { - - $content_type = $c->req->param('content-type'); - } - - # Third, we parse the Accept header, and see if the client - # takes a format we understand. - # - # This is taken from chansen's Apache2::UploadProgress. - my $used_accept = 0; - if ( !$content_type && $c->request->header('Accept') ) { - my $accept_header = $c->request->header('Accept'); - my %accept = (); - my $counter = 0; - - foreach my $pair ( split_header_words($accept_header) ) { - - my ( $type, $qvalue ) = @{$pair}[ 0, 3 ]; - - unless ( defined $qvalue ) { - $qvalue = 1 - ( ++$counter / 1000 ); - } - - $accept{$type} = sprintf( '%.3f', $qvalue ); - } - - foreach my $type ( sort { $accept{$b} <=> $accept{$a} } keys %accept ) - { - - if ( exists $controller->config->{'serialize'}->{'map'}->{$type} ) - { - $content_type = $type; - last; - } - } - $used_accept = 1; - } + my $content_type = $c->request->preferred_content_type || ''; # Finally, we load the class. If you have a default serializer, # and we still don't have a content-type that exists in the map, # we'll use it. my $sclass = $search_path . "::"; my $sarg; - my $map = $controller->config->{'serialize'}->{'map'}; + my $map; + + my $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'}; + # If we don't have a handler for our preferred content type, try + # the default + if ( ! exists $map->{$content_type} ) { + if( exists $config->{'default'} ) { + $content_type = $config->{'default'} ; + } else { + return $self->_unsupported_media_type($c, $content_type); + } + } + if ( exists( $map->{$content_type} ) ) { my $mc; if ( ref( $map->{$content_type} ) eq "ARRAY" ) { @@ -102,11 +85,7 @@ sub _load_content_plugins { return $self->_unsupported_media_type($c, $content_type); } } else { - if ( exists( $controller->config->{'serialize'}->{'default'} ) ) { - $sclass .= $controller->config->{'serialize'}->{'default'}; - } else { - return $self->_unsupported_media_type($c, $content_type); - } + return $self->_unsupported_media_type($c, $content_type); } unless ( exists( $self->_loaded_plugins->{$sclass} ) ) { my $load_class = $sclass; @@ -115,8 +94,7 @@ sub _load_content_plugins { eval { require $load_class; }; if ($@) { $c->log->error( - "Error loading $sclass for " . $content_type . ": $!" ) - if $c->log->is_debug; + "Error loading $sclass for " . $content_type . ": $!" ); return $self->_unsupported_media_type($c, $content_type); } else { $self->_loaded_plugins->{$sclass} = 1; @@ -126,7 +104,7 @@ sub _load_content_plugins { if ($search_path eq "Catalyst::Action::Serialize") { if ($content_type) { $c->response->header( 'Vary' => 'Content-Type' ); - } elsif ($used_accept) { + } elsif ($c->request->accept_only) { $c->response->header( 'Vary' => 'Accept' ); } $c->response->content_type($content_type); @@ -139,7 +117,7 @@ sub _unsupported_media_type { my ( $self, $c, $content_type ) = @_; $c->res->content_type('text/plain'); $c->res->status(415); - if (defined($content_type)) { + if (defined($content_type) && $content_type ne "") { $c->res->body( "Content-Type " . $content_type . " is not supported.\r\n" ); } else {