[Catalyst-commits] r9494 - in Catalyst-Action-REST/0.60/trunk:
lib/Catalyst/Action t
timbunce at dev.catalyst.perl.org
timbunce at dev.catalyst.perl.org
Wed Mar 11 16:46:02 GMT 2009
Author: timbunce
Date: 2009-03-11 16:46:02 +0000 (Wed, 11 Mar 2009)
New Revision: 9494
Modified:
Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm
Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm
Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t
Log:
Add content_type_stash_key to enable a stash entry to override the serialize content type.
With docs and tests.
Modified: Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm
===================================================================
--- Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm 2009-03-11 16:08:35 UTC (rev 9493)
+++ Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm 2009-03-11 16:46:02 UTC (rev 9494)
@@ -99,27 +99,30 @@
=head1 CONFIGURATION
-=over 4
+=head2 map
-=item default
+Takes a hashref, mapping Content-Types to a given serializer plugin.
-The Content-Type of the default Serialization format. This must be a
-Content-Type associated with a plugin in the "map" section below.
+=head2 default
-This is used if a requested content-type is not recognized.
+This is the 'fall-back' Content-Type if none of the requested or acceptable
+types is found in the L</map>. It must be an entry in the L</map>.
-=item stash_key
+=head2 stash_key
-We will serialize the data that lives in this location in the stash. So
-if the value is "rest", we will serialize the data under:
+Specifies the key of the stash entry holding the data that is to be serialized.
+So if the value is "rest", we will serialize the data under:
$c->stash->{'rest'}
-=item map
+=head2 content_type_stash_key
-Takes a hashref, mapping Content-Types to a given plugin.
+Specifies the key of the stash entry that optionally holds an overriding
+Content-Type. If set, and if the specified stash entry has a valid value,
+then it takes priority over the requested content types.
-=back
+This can be useful if you want to dynamically force a particular content type,
+perhaps for debugging.
=head1 HELPFUL PEOPLE
Modified: Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm
===================================================================
--- Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm 2009-03-11 16:08:35 UTC (rev 9493)
+++ Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm 2009-03-11 16:46:02 UTC (rev 9494)
@@ -53,19 +53,28 @@
$config = $controller->config;
}
$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);
- }
+ # 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;
}
+ # 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;
+ return $self->_unsupported_media_type($c, $content_type)
+ if not $content_type;
+
# carp about old text/x-json
if ($content_type eq 'text/x-json') {
$c->log->info('Using deprecated text/x-json content-type.');
Modified: Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t
===================================================================
--- Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t 2009-03-11 16:08:35 UTC (rev 9493)
+++ Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t 2009-03-11 16:46:02 UTC (rev 9494)
@@ -16,6 +16,7 @@
serialize => {
'default' => 'text/x-yaml',
'stash_key' => 'rest',
+ 'content_type_stash_key' => 'serialize_content_type',
'map' => {
'text/x-yaml' => 'YAML',
'application/json' => 'JSON',
@@ -36,16 +37,18 @@
sub test_second :Local :ActionClass('Serialize') {
my ( $self, $c ) = @_;
+ $c->stash->{'serialize_content_type'} = $c->req->params->{'serialize_content_type'};
$c->stash->{'rest'} = {
lou => 'is my cat',
};
}
+
package main;
use strict;
use warnings;
-use Test::More tests => 10;
+use Test::More tests => 16;
use Data::Serializer;
use FindBin;
use Data::Dump qw(dump);
@@ -107,4 +110,26 @@
is( $res->header('Content-type'), 'text/x-yaml', '... with expected content-type')
}
+# Make that using content_type_stash_key, an invalid value in the stash gets ignored
+{
+ my $req = $t->get(url => '/test_second?serialize_content_type=nonesuch');
+ $req->remove_header('Content-Type');
+ $req->header('Accept', '*/*');
+ my $res = request($req);
+ ok( $res->is_success, 'GET the serialized request succeeded' );
+ is( $res->content, $data, "Request returned proper data");
+ is( $res->header('Content-type'), 'text/x-yaml', '... with expected content-type')
+}
+
+# Make that using content_type_stash_key, a valid value in the stash gets priority
+{
+ my $req = $t->get(url => '/test_second?serialize_content_type=text/x-data-dumper');
+ $req->remove_header('Content-Type');
+ $req->header('Accept', '*/*');
+ my $res = request($req);
+ ok( $res->is_success, 'GET the serialized request succeeded' );
+ is( $res->content, "{'lou' => 'is my cat'}", "Request returned proper data");
+ is( $res->header('Content-type'), 'text/x-data-dumper', '... with expected content-type')
+}
+
1;
More information about the Catalyst-commits
mailing list