PSGI Answer: What types of file descriptors can be expected to work with PSGI and Plack?

The PSGI specification defines an HTTP response as consisting of three parts, the third of which can be either an array reference or a file descriptor. The descriptor file may be:

An object of type IO :: Handle or a built-in file descriptor.

And the specification further states:

Servers MAY verify that the body is a real file descriptor using fileno and Scalar :: Util :: reftype, and if it is a real file descriptor with a file descriptor, it MAY optimize the file using methods such as sendfile (2).

Now I have combined the command line example using plackup(Plack version 0.9978), and it seems that checking if the body is a real file descriptor leads to a fatal error:

Can't locate object method "FILENO" via package "IO::Scalar" at /usr/lib/perl5/5.10/i686-cygwin/IO/Handle.pm line 390

Here is an example command line:

plackup -MData::Dumper -MIO::Scalar -e \
'sub { $env=shift; return [200, [], IO::Scalar->new(\Dumper $env) ] }'

Of course, I just could not use the file descriptor:

plackup --port 9999 -MData::Dumper -e \
'sub { $env=shift; return [200, [], [Dumper $env] ] }'

But I'm interested in what works and what doesn’t. Therefore, should you be careful when using a function FILENOin a descriptor so that it does not fall into the exception?

And add one more:

plackup --port 9999 -MData::Dumper -e \
'sub{$env=shift; $s=Dumper $env; open $fh,q(<),\$s or die; return [200,[],$fh ]}'

It seems that the file descriptor is not recognized as such. Error message:

body should be an array ref or filehandle at /usr/lib/perl5/site_perl/5.10/Plack/Middleware/StackTrace.pm line 35

Update:

As ysth said in his answer, the following will work (at least 5.10.1 on Cygwin):

plackup -p 9999 -MData::Dumper -MIO::String -e \
'sub { return [200, [], IO::String->new(\Dumper shift) ] }'

But, obviously, there is a problem that can be seen from unsuccessful examples, and will be reported as soon as I decided that it really is.

+3
3

, Plack. , , fileno, , getline. FILENO, (, ), , fileno . Plack::Middleware::Lint->validate_res Plack::Util->is_real_fh.

Plack .

, IO:: Scalar, IO:: Scalar:: FILENO, undef.

sub IO::Scalar::FILENO { return }

IO:: Scalar, , .

, Plack, . - , :

bless $fh, "IO::Handle";

, IO:: Handle. , , .

+8

. Plack , . , Plack , () PSGI. (PSGI!= Plack, HTTP!= Apache)

PSGI , - . / 2-3 , . 2-3 N M, N * 2-3 .

" ", "IO:: Handle-like object, getline". -, , Plack, - , Plack - PSGI. Lint, , .

:

a) IO:: Scalar - , getline(), . , - , . , Plack:: Util:: is_real_fh, → fileno, , , .

b) PerlIO in-memory filehandle - . " ", in-memory . , Lint (, -E production plackup), . , Lint , .

, , , , FAQ. psgi-specs.

+9

Looks like an error in IO :: Scalar. Report it and insteaad uses IO :: String or the native support for memory files added in 5.8.

0
source

All Articles