Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

forward()ed POST request loses body? #1233

Open
bigpresh opened this issue Mar 2, 2022 · 3 comments
Open

forward()ed POST request loses body? #1233

bigpresh opened this issue Mar 2, 2022 · 3 comments

Comments

@bigpresh
Copy link
Member

bigpresh commented Mar 2, 2022

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!

@bigpresh
Copy link
Member Author

bigpresh commented Mar 2, 2022

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)

@bigpresh
Copy link
Member Author

bigpresh commented Mar 2, 2022

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...

@bigpresh
Copy link
Member Author

bigpresh commented Mar 2, 2022

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}toD::Request->forward()`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant