title: PSGI Response: What kinds of filehandles can be expected to work with PSGI, and Plack?
body: <p>The <a href="http://p3rl.org/PSGI" rel="nofollow">PSGI specification</a> defines the HTTP response as consisting of three parts, the third of which may be either an array reference or a filehandle. The filehandle may be:</p>
  
  <blockquote>An IO::Handle-like object or a built-in filehandle.</blockquote>
  
  <p>And the spec goes on to say:</p>
  
  <blockquote>Servers MAY check if the body is a real filehandle using fileno and Scalar::Util::reftype and if it's a real filehandle that has a file descriptor, it MAY optimize the file serving using techniques like sendfile(2).</blockquote>
  
  <p>Now I've cobbled together a command-line example using <code>plackup</code> (Plack version 0.9978), and it appears that checking if the body is a real filehandle results in a fatal error:</p>
  
  <p><code>Can't locate object method "FILENO" via package "IO::Scalar" at /usr/lib/perl5/5.10/i686-cygwin/IO/Handle.pm line 390</code></p>
  
  <p>Here's the command-line example:</p>
  
  <pre><code>plackup -MData::Dumper -MIO::Scalar -e \
  'sub { $env=shift; return [200, [], IO::Scalar-&gt;new(\Dumper $env) ] }'
  </code></pre>
  
  <p>Of course I could just not use a filehandle:</p>
  
  <pre><code>plackup --port 9999 -MData::Dumper -e \
  'sub { $env=shift; return [200, [], [Dumper $env] ] }'
  </code></pre>
  
  <p>But I'm interested in what works and what doesn't. So shouldn't Plack exercise more caution when calling <code>FILENO</code> on the handle so it wouldn't run into an exception?</p>
  
  <p>And to add another one:</p>
  
  <pre><code>plackup --port 9999 -MData::Dumper -e \
  'sub{$env=shift; $s=Dumper $env; open $fh,q(&lt;),\$s or die; return [200,[],$fh ]}'
  </code></pre>
  
  <p>Looks like the filehandle isn't recognized as such. The error message is:</p>
  
  <p><code>body should be an array ref or filehandle at /usr/lib/perl5/site_perl/5.10/Plack/Middleware/StackTrace.pm line 35</code></p>
  
  <p><strong>Update:</strong></p>
  
  <p>As ysth stated in his answer, the following will work (at least on 5.10.1 on Cygwin):</p>
  
  <pre><code>plackup -p 9999 -MData::Dumper -MIO::String -e \
  'sub { return [200, [], IO::String-&gt;new(\Dumper shift) ] }'
  </code></pre>
  
  <p>But clearly, there is an issue someplace as can be seen from the failing examples, and it will be reported once I've made up my mind what it actually is.</p>