plack / Plack

PSGI toolkit and server adapters
http://plackperl.org/
Other
486 stars 214 forks source link

Can't locate object method "seek" ... if Content-Type header is omitted #655

Closed davewood closed 3 years ago

davewood commented 3 years ago

curl -X POST -d '{}' https://dtdev:8080/v1/dnscheck

this works because curl sends a default Content-Type header but if I make curl omit the default header I get this error.

curl -X POST -d '{}' https://dtdev:8080/v1/dnscheck -H 'Content-Type:'

Can't locate object method "seek" via package "Apache2::RequestRec" at /usr/share/perl5/Plack/Request.pm line 78.
        Plack::Request::content(Dancer2::Core::Request=HASH(0x560b03b5a4f8)) called at /usr/share/perl5/Plack/Request.pm line 85
        Plack::Request::raw_body(Dancer2::Core::Request=HASH(0x560b03b5a4f8)) called at /usr/share/perl5/Dancer2/Core/Request.pm line 98
        Dancer2::Core::Request::body(Dancer2::Core::Request=HASH(0x560b03b5a4f8)) called at /usr/share/perl5/Dancer2/Core/Request.pm line 185
        Dancer2::Core::Request::deserialize(Dancer2::Core::Request=HASH(0x560b03b5a4f8)) called at /usr/share/perl5/Dancer2/Core/Request.pm line 170
        Dancer2::Core::Request::data(Dancer2::Core::Request=HASH(0x560b03b5a4f8)) called at /usr/share/perl5/Dancer2/Core/Request.pm line 76
        Dancer2::Core::Request::new("Dancer2::Core::Request", "env", HASH(0x560b03ae5d00), "is_behind_proxy", 0, "serializer", Dancer2::Serializer::JSON=HASH(0x560b03887980)) called at /usr/share/perl5/Dancer2/Core/App.pm line 1572
        Dancer2::Core::App::build_request(Dancer2::Core::App=HASH(0x560b034716f8), HASH(0x560b03ae5d00)) called at /usr/share/perl5/Dancer2/Core/App.pm line 1441
        Dancer2::Core::App::dispatch(Dancer2::Core::App=HASH(0x560b034716f8), HASH(0x560b03ae5d00)) called at /usr/share/perl5/Dancer2/Core/App.pm line 1395
        Dancer2::Core::App::__ANON__() called at /usr/share/perl5/Dancer2/Core/App.pm line 36
        Dancer2::Core::App::__ANON__(CODE(0x560b03ae59d0)) called at /usr/share/perl5/Dancer2/Core/App.pm line 1395
        eval {...} called at /usr/share/perl5/Dancer2/Core/App.pm line 1397
        Dancer2::Core::App::__ANON__(HASH(0x560b03ae5d00)) called at /usr/share/perl5/Plack/Middleware/FixMissingBodyInRedirect.pm line 50
        Plack::Middleware::FixMissingBodyInRedirect::call(Plack::Middleware::FixMissingBodyInRedirect=HASH(0x560b03a7e760), HASH(0x560b03ae5d00)) called at /usr/share/perl5/Plack/Component.pm line 50
        Plack::Component::__ANON__(HASH(0x560b03ae5d00)) called at /usr/share/perl5/Plack/Middleware/Head.pm line 10
        Plack::Middleware::Head::call(Plack::Middleware::Head=HASH(0x560b03a7f1e0), HASH(0x560b03ae5d00)) called at /usr/share/perl5/Plack/Component.pm line 50
        Plack::Component::__ANON__(HASH(0x560b03ae5d00)) called at /usr/share/perl5/Plack/Handler/Apache2.pm line 87
        Plack::Handler::Apache2::call_app("Plack::Handler::Apache2", Apache2::RequestRec=SCALAR(0x560afcf56cd0), CODE(0x560b03a7e7c0)) called at /home/foo/MyApp/lib/MyApp/REST/Transport/Apache.pm line 12
        MyApp::REST::Transport::Apache::handler(Apache2::RequestRec=SCALAR(0x560afcf56cd0)) called at -e line 0
        eval {...} called at -e line 0
miyagawa commented 3 years ago

seems to be a Dancer bug and should be reported there.

davewood commented 3 years ago

thank you for the pointer. -> https://github.com/PerlDancer/Dancer2/issues/1566

miyagawa commented 3 years ago

actually, re-reading the stacktrace the error does occur inside Plack. it seems you're using Apache mod_perl2 and i assume the error won't happen in a non mod_perl environment. Which version of mod_perl are you using?

davewood commented 3 years ago
rts@dtdev:~$ perl -Mmod_perl2\ 999
mod_perl2 version 999 required--this is only version 2.000010.
BEGIN failed--compilation aborted.
miyagawa commented 3 years ago

this is probably a bug in Plack::Handler::Apache2 but I personally haven't touched mod_perl2 for quite a while and have no resource available to look into fixing it. if someone can take a look and send a patch i can happily review and merge it.

haarg commented 3 years ago

I think this is a bug in Plack::Request or HTTP::Entity::Parser.

Plack::Handler::Apache2 provides a psgi.input that doesn't support ->seek, and it also doesn't set psgix.input.buffered so this should be fine. Plack::Request tries to parse this using HTTP::Entity::Parser. If no content type is provided, HTTP::Entity::Parser does nothing and makes no changes to the env hash. If a content type is provided it will try to parse the body, possibly using a fallback noop parser. It also replaces psgi.input with a Stream::Buffered if psgix.input.buffered is false. This replacement does happen for unsupported content types, just not when the content type is not specified.

Plack::Request then assumes it can call ->seek on psgi.input. But if no content type was provided, psgix.input.buffered and psgi.input won't have been updated, and ->seek isn't guaranteed to work.

miyagawa commented 3 years ago

ah that sounds about right - can anyone supply a patch for that? :)

haarg commented 3 years ago

Does it seem better to have Plack::Request cope with a non-buffered input after attempting to parse the body, or should HTTP::Entity::Parser always set up psgi.input to be buffered?

miyagawa commented 3 years ago

i think i prefer fixing HTTP::Entity::Parser to behave in a more consistent manner. @kazeburo ?

miyagawa commented 3 years ago

The fix for this has been released to CPAN in 1.0048.

aldot commented 3 years ago

Does that handle e.g. CONTENT_TYPE=1 somewhat gracefully?

miyagawa commented 3 years ago

i don't know what you mean but it's handled the same as when Content-Type: foo was specified.