Can't locate object method "seek" ... if Content-Type header is omitted
davewood opened this issue · 12 comments
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
seems to be a Dancer bug and should be reported there.
thank you for the pointer. -> PerlDancer/Dancer2#1566
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?
rts@dtdev:~$ perl -Mmod_perl2\ 999
mod_perl2 version 999 required--this is only version 2.000010.
BEGIN failed--compilation aborted.
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.
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.
ah that sounds about right - can anyone supply a patch for that? :)
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?
i think i prefer fixing HTTP::Entity::Parser to behave in a more consistent manner. @kazeburo ?
The fix for this has been released to CPAN in 1.0048.
Does that handle e.g. CONTENT_TYPE=1 somewhat gracefully?
i don't know what you mean but it's handled the same as when Content-Type: foo
was specified.