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.