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

Plack::Request->content erroneously assumes it's working with seekable input #642

Closed
SineSwiper opened this issue Oct 7, 2019 · 2 comments

Comments

@SineSwiper
Copy link

Noticing errors like this:

Can't locate object method "seek" via package "IO::Handle" at ..../lib/perl5/Plack/Request.pm line 78

The content method seems to think that it can seek psgi.input, even though Plack's own Plack::Handler::FCGI module does this:

    @{$self}{qw(stdin stdout stderr)}
      = (IO::Handle->new, IO::Handle->new, IO::Handle->new);

    my %env;
    my $request = FCGI::Request(
        $self->{stdin}, $self->{stdout}, $self->{stderr},
        \%env, $sock,
        ($self->{nointr} ? 0 : &FCGI::FAIL_ACCEPT_ON_INTR),
    );

And eventually puts that into psgi.input: 'psgi.input' => $self->{stdin},

Normally, $self->{stdin} would be a FCGI::Stream object after the $request->Accept, but there are conditions where that doesn't apply:

        if (!request->svout) {
            newSVrv(request->svout = newSV(0), "FCGI::Stream");
            newSVrv(request->sverr = newSV(0), "FCGI::Stream");
            newSVrv(request->svin = newSV(0), "FCGI::Stream");
        }
        sv_setiv(SvRV(request->svout), INT2PTR(IV, fcgx_req->out));
        sv_setiv(SvRV(request->sverr), INT2PTR(IV, fcgx_req->err));
        sv_setiv(SvRV(request->svin), INT2PTR(IV, fcgx_req->in));
        FCGI_Bind(request);
        request->accepted = TRUE;

Furthermore, FCGI::Stream doesn't even support seeking, so it wouldn't work, anyway:

sub SEEK {
    require Carp;
    Carp::croak(q/Operation 'SEEK' not supported on FCGI::Stream handle/);
}
@miyagawa
Copy link
Member

miyagawa commented Oct 7, 2019

I think this used to be not a problem, because Plack::Request checks if psgix.input.buffered is set in the environment before calling seek, and otherwise slurps the input and replaces it with a temporary filehandle that does support seek.

Quick git search shows that it was changed in db1e817. You can check to see if your code works with Plack 1.0039 or before.

@miyagawa
Copy link
Member

this should be fixed with #657

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

2 participants