From: Tomas Doran Date: Wed, 1 Sep 2010 22:03:45 +0000 (+0100) Subject: Add a json_options key to the REST controller X-Git-Tag: 0.86~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Action-REST.git;a=commitdiff_plain;h=838f49dc89f8bef88c3a3dc9841473555f71bb82 Add a json_options key to the REST controller --- diff --git a/Changes b/Changes index fab2f3f..51079dc 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ + Add rest_serializer_json_options config key useable to set options + like relaxed => 1 to be passed to the JSON serializer (Ton Voon) Make Data::Dumper unserializer safer by using a Safe compartment (Ton Voon) diff --git a/lib/Catalyst/Action/Deserialize/JSON.pm b/lib/Catalyst/Action/Deserialize/JSON.pm index b9a40df..215f959 100644 --- a/lib/Catalyst/Action/Deserialize/JSON.pm +++ b/lib/Catalyst/Action/Deserialize/JSON.pm @@ -4,7 +4,7 @@ use Moose; use namespace::autoclean; extends 'Catalyst::Action'; -use JSON qw( decode_json ); +use JSON; our $VERSION = '0.85'; $VERSION = eval $VERSION; @@ -23,7 +23,13 @@ sub execute { } if ( $rbody ) { - my $rdata = eval { decode_json( $rbody ) }; + my $json = JSON->new->utf8; + if (my $options = $controller->{json_options}) { + foreach my $opt (keys %$options) { + $json->$opt( $options->{$opt} ); + } + } + my $rdata = eval { $json->decode( $rbody ) }; if ($@) { return $@; } diff --git a/lib/Catalyst/Controller/REST.pm b/lib/Catalyst/Controller/REST.pm index 4c017d8..2c0cb17 100644 --- a/lib/Catalyst/Controller/REST.pm +++ b/lib/Catalyst/Controller/REST.pm @@ -146,6 +146,12 @@ Uses L to generate JSON output. It is strongly advised to also have L installed. The C content type is supported but is deprecated and you will receive warnings in your log. +You can also add a hash in your controller config to pass options to the json object. +For instance, to relax permissions when deserializing input, add: + __PACKAGE__->config( + json_options => { relaxed => 1 } + ) + =item * C => C If a callback=? parameter is passed, this returns javascript in the form of: $callback($serializedJSON); diff --git a/t/json.t b/t/json.t index 673c0a9..35d6059 100644 --- a/t/json.t +++ b/t/json.t @@ -10,7 +10,7 @@ use utf8; eval 'use JSON 2.12'; plan skip_all => 'Install JSON 2.12 or later to run this test' if ($@); -plan tests => 9; +plan tests => 11; use_ok 'Catalyst::Test', 'Test::Serialize'; @@ -36,4 +36,14 @@ for ('text/x-json', 'application/json') { is_deeply($mres_post->content, $exp, "POST data matches"); } +{ + my $t = Test::Rest->new('content_type' => 'application/json'); + my $json_data = '{ "sushi":"is good for monkey", }'; + my $mres_post = request($t->post(url => '/monkey_put', data => $json_data)); + ok( ! $mres_post->is_success, "Got expected failed status due to invalid JSON" ); + + my $relaxed_post = request( $t->post(url => "/monkey_json_put", data => $json_data)); + ok( $relaxed_post->is_success, "Got success due to setting relaxed JSON input" ); +} + 1; diff --git a/t/lib/Test/Serialize/Controller/JSON.pm b/t/lib/Test/Serialize/Controller/JSON.pm new file mode 100644 index 0000000..fcc07a3 --- /dev/null +++ b/t/lib/Test/Serialize/Controller/JSON.pm @@ -0,0 +1,29 @@ +package Test::Serialize::Controller::JSON; + +use namespace::autoclean; +use Moose; + +BEGIN { extends qw/Catalyst::Controller::REST/ }; + +__PACKAGE__->config( + 'stash_key' => 'rest', + 'json_options' => { + relaxed => 1, + }, + 'map' => { + 'text/x-json' => 'JSON', + }, +); + +sub monkey_json_put : Path("/monkey_json_put") : ActionClass('Deserialize') { + my ( $self, $c ) = @_; + if ( ref($c->req->data) eq "HASH" ) { + my $out = ($c->req->data->{'sushi'}||'') . ($c->req->data->{'chicken'}||''); + utf8::encode($out); + $c->res->output( $out ); + } else { + $c->res->output(1); + } +} + +1;