perlquestion
hardburn
<p>I'm trying to write out a filehandle using Dancer2. The data may come from a live video stream, so the filehandle must be streamed in chunks, not returned all at once.</p>
<p>The documention for Dancer2::Manual has this to say about <code>send_file()</code>:</p>
<p>"You can use around to get all the content (whether a filehandle if it's a regular file or a full string if it's a scalar ref) and decide what to do with it"</p>
<p>This and the example code suggests to me that I can pass the filehandle as the first argument to <code>send_file()</code>, and then the <code>around</code> callback will get the filehandle as its second argument. Here's an attempt at that:</p>
<code>
return send_file( $in_fh,
streaming => 1,
content_type => $mime_type,
callbacks => {
around => sub {
my ($writer, $content) = @_;
my $buf = '';
while( read( $content, $buf, VID_READ_LENGTH ) ) {
$writer->write( $buf );
}
}
},
);
</code>
<p>This results in the error:</p>
<code>
Device::WebIO::Dancer:5371] error @2014-08-13 18:01:28> Route exception: isa check for "path_info" failed: GLOB(0x222a5c8) is not a string! at (eval 197) line 27.
</code>
<p>OK, so the first argument can't be a filehandle. Maybe I can pass a dummy string as a scalar ref (which is documented to work) and then have the callback use <code>$in_fh</code> directly as a closure:</p>
<code>
return send_file( \'foo',
streaming => 1,
content_type => $mime_type,
callbacks => {
around => sub {
my ($writer, $content) = @_;
my $buf = '';
while( read( $in_fh, $buf, VID_READ_LENGTH ) ) {
$writer->write( $buf );
}
}
},
);
</code>
<p>But the output of this is "foo", as if the callback is not being used at all.</p>
<p>OK, let's try passing a dummy file and see if the callback is called:</p>
<code>
return send_file( '/dev/zero',
streaming => 1,
system_path => 1,
content_type => $mime_type,
callbacks => {
around => sub {
my ($writer, $content) = @_;
my $buf = '';
while( read( $in_fh, $buf, VID_READ_LENGTH ) ) {
$writer->write( $buf );
}
}
},
);
</code>
<p>Even with <code>system_path</code> and <code>/dev/zero</code> existing on my system, this gives an HTTP 404 error.</p>
<p>Is there any way to coerce Dancer2 into streaming the filehandle? It feels like this shouldn't require callbacks at all, just:
<code>
return send_file( '$in_fh,
streaming => 1,
content_type => $mime_type,
);
</code>
<!-- Node text goes above. Div tags should contain sig only -->
<div class="pmsig"><div class="pmsig-195718">
<hr />
<p>"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, <i>Myst: The Book of D'ni</i>.</p>
</div></div>