Dancer
Dancer copied to clipboard
forward()ed POST request loses body?
Running this simple test case app, which outputs the request body, forward()
s to another route and outputs the request body again:
#!/usr/bin/env perl
use 5.012;
use Dancer;
use DDP;
set serializer => 'JSON';
post '/foo' => sub {
warn "foo running";
p request->body;
forward '/bar';
};
post '/bar' => sub {
warn "Bar running";
p request->body;
return "Response from bar";
};
dance;
and hitting it with curl:
[davidp@supernova:~]$ curl http://localhost:3000/foo -H "Content-Type: application/json" -d '{"beer":true}'
Response from bar
it outputs:
[davidp@supernova:~/tmp/dancer-forward-testcase]$ perl test.pl
>> Dancer 1.3513 server 367711 listening on http://0.0.0.0:3000
== Entering the development dance floor ...
foo running at test.pl line 12.
"{\"beer\":true}"
Bar running at test.pl line 18.
""
Reported by @fleetfootmike - thanks Mike!
Ah, Dancer::Request->forward() doesn't copy the raw body over, but it does copy the deserialized params over, so dumping the deserialised value:
#!/usr/bin/env perl
use 5.012;
use Dancer;
use DDP;
set serializer => 'JSON';
post '/foo' => sub {
warn "foo running";
p request->body;
p params->{beer}, as => 'beer in foo';
forward '/bar';
};
post '/bar' => sub {
warn "Bar running";
p request->body;
p params->{beer}, as => 'beer in bar';
return "Response from bar";
};
dance;
shows that params->{beer}
is still set after the forward:
[davidp@supernova:~/tmp/dancer-forward-testcase]$ perl test.pl
>> Dancer 1.3513 server 370232 listening on http://0.0.0.0:3000
== Entering the development dance floor ...
foo running at test.pl line 12.
"{\"beer\":true}"
beer in foo
1 (JSON::PP::Boolean) (read-only)
Bar running at test.pl line 19.
""
beer in bar
1 (JSON::PP::Boolean) (read-only)
So, the impact looks limited - params will be retained etc, but the raw body may not be.
@fleetfootmike points out that it also causes a spurious deserialisation error at loglevel core
, caused by the body being empty:
[373113] core @0.000080> request: POST /bar from 127.0.0.1 in /usr/local/share/perl/5.32.1/Dancer/Handler.pm l. 58
[373113] core @0.000285> [hit #2]Unable to deserialize request body with Dancer::Serializer::JSON=HASH(0x556cf43f7970) :
malformed JSON string, neither tag, array, object, number, string or atom, at character offset 0 (before "(end of string)") at /usr/share/perl5/JSON.pm line 190. in /usr/local/share/perl/5.32.1/Dancer/Serializer.pm l. 102
One possibly-reasonable solution to the spurious error would be for Dancer::Serializer->process_request
to not attempt to deserialize an empty body... one would assume that shouldn't break anything for anyone...
The lack of the body on a forwarded request is the real issue, though.
OTTOMH, a simple fix should be to add ``$new_request->{_http_body} = $request->{_http_body}to
D::Request->forward()`