Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions lib/Dancer/Handler.pm
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ sub handle_request {
Dancer::SharedData->request($request);

# deserialize the request body if possible
$request = Dancer::Serializer->process_request($request)
if Dancer::App->current->setting('serializer');
if (Dancer::App->current->setting('serializer')) {
$request = Dancer::Serializer->process_request($request);
return $self->render_response unless $request;
}


# read cookies from client

Expand Down
3 changes: 2 additions & 1 deletion lib/Dancer/Request.pm
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ sub _build_params {
%$previous, %{$self->{_query_params}},
%{$self->{_route_params}}, %{$self->{_body_params}},
};

# there may be new parameters in need of _decode()ing
$self->{_params_are_decoded} = 0;
}

# Written from PSGI specs:
Expand Down
9 changes: 7 additions & 2 deletions lib/Dancer/Serializer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,21 @@ sub process_request {

my $old_params = $request->params('body');

# try to deserialize
# deserialize
my $new_params;
eval {
$new_params = engine->deserialize($request->body)
};
if ($@) {
Dancer::Error->new(
code => 400,
title => "Bad request",
message => "Deserialization failed",
)->render;
Dancer::Logger::core "Unable to deserialize request body with "
. engine()
. " : \n$@";
return $request;
return;
}

if(!ref $new_params or ref $new_params ne 'HASH'){
Expand Down
50 changes: 50 additions & 0 deletions t/02_request/19_decode_added_params.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use Dancer ':tests';
use Dancer::Test;
use Test::More;
use Dancer::ModuleLoader;
use LWP::UserAgent;

plan skip_all => "skip test with Test::TCP in win32" if $^O eq 'MSWin32';
plan skip_all => 'Test::TCP is needed to run this test'
unless Dancer::ModuleLoader->load('Test::TCP' => "1.30");

plan skip_all => 'JSON is needed to run this test'
unless Dancer::ModuleLoader->load('JSON');

plan tests => 2;

my $unicode = "\x{30dc}\x{a9}";

Test::TCP::test_tcp(
client => sub {
my $port = shift;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
POST => "http://127.0.0.1:$port/foo/$unicode",
[
Host => 'localhost',
Content_Type => 'application/json',
],
to_json({ foo => 'bar' }),
);
my $res = $ua->request($request);
ok $res->is_success, 'Successful response from server';
is $res->content, 1, 'Correct content';
},
server => sub {
my $port = shift;
use Dancer ':tests';
set(
apphandler => 'Standalone',
port => $port,
show_errors => 0,
startup_info => 0,
charset => 'utf-8',
serializer => 'JSON',
);
post '/foo/*' => sub {
params->{splat}[0] eq $unicode;
};
Dancer->dance;
},
);
8 changes: 4 additions & 4 deletions t/14_serializer/02_request_json.t
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ BEGIN {
set 'serializer' => 'JSON', 'show_errors' => 1;

get '/' => sub { { foo => 'bar' } };
post '/' => sub { params };
post '/' => sub { scalar params };
put '/' => sub { param("id") };
get '/error' => sub { send_error( { foo => 42 }, 401 ) };
get '/error_bis' => sub { send_error( 42, 402 ) };
get '/json' => sub {
content_type('application/json');
to_json( { foo => 'bar' } )
+{ foo => 'bar' };
};

response_content_is [ PUT => '/',
Expand All @@ -41,8 +41,8 @@ my $res = dancer_response
(
POST => '/',
{
params => { foo => 1 },
headers => [ 'Content-Type' => 'application/json' ]
headers => [ 'Content-Type' => 'application/json' ],
body => to_json({ foo => 1 }),
}
);

Expand Down
4 changes: 2 additions & 2 deletions t/14_serializer/04_request_xml.t
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ SKIP: {
my $res = dancer_response(
POST => '/',
{
params => { foo => 1 },
headers => [ 'Content-Type' => 'text/xml' ]
headers => [ 'Content-Type' => 'text/xml' ],
body => to_xml({ foo => 1 }),
}
);
is_deeply(
Expand Down
81 changes: 81 additions & 0 deletions t/14_serializer/19_deserialization_failure.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use Dancer ':tests';
use Dancer::Test;
use Test::More;
use Dancer::ModuleLoader;
use LWP::UserAgent;

plan skip_all => "skip test with Test::TCP in win32" if $^O eq 'MSWin32';
plan skip_all => 'Test::TCP is needed to run this test'
unless Dancer::ModuleLoader->load('Test::TCP' => "1.30");

plan skip_all => 'JSON is needed to run this test'
unless Dancer::ModuleLoader->load('JSON');

plan tests => 3;

set serializer => 'JSON';

my $data = { foo => 'bar' };

Test::TCP::test_tcp(
client => sub {
my $port = shift;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
PUT => "http://127.0.0.1:$port/deserialization",
[
Host => 'localhost',
Content_Type => 'application/json'
],
to_json($data),
);
my $res = $ua->request($request);
ok $res->is_success, 'Successful response from server';
is_deeply from_json($res->content), $data, 'Correct content';
},
server => sub {
my $port = shift;
use Dancer ':tests';
set(
apphandler => 'Standalone',
port => $port,
show_errors => 0,
startup_info => 0,
);
put '/deserialization' => sub { $data };
Dancer->dance;
},
);

Test::TCP::test_tcp(
client => sub {
my $port = shift;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
PUT => "http://127.0.0.1:$port/deserialization",
[
Host => 'localhost',
Content_Type => 'application/json'
],
# broken JSON
'{ "foo": "bar", }',
);
my $res = $ua->request($request);
is $res->code, 400, '400 bad request';
},
server => sub {
my $port = shift;
use Dancer ':tests';
set(
apphandler => 'Standalone',
port => $port,
show_errors => 1,
startup_info => 0,
);
put '/deserialization' => sub { $data };
Dancer->dance;
},
);