[Catalyst] Bug in Catalyst::finalize_headers()
Bernhard Graf
catalyst2 at augensalat.de
Sun May 6 11:02:51 GMT 2007
Next episode from my attempts in writing a serialization view class:
After I learned that finalize_body() can read from an object (that
can('read')) or from a file handle, I implemented the idea of sending
data through a pipe.
In short the View class does:
package CatalystX::View::DBIC;
use IO::Pipe;
sub process {
my ($self, $c) = @_;
[...]
$pipe = new IO::Pipe;
if ($pid = fork()) { # here's the parent
$pipe->reader; # parent reads from child
$c->response->body($pipe);
return;
}
# here's the child
$pipe->writer; # child writes to parent
# read from the DBIC result set
while ($row = $rs->next) {
# write formatted (e.g. CSV) data into pipe
$pipe->write($self->format($row, $columns));
}
close $pipe;
exit(0);
}
The idea is that process() sets up the pipe, forks a sub process that
does the long lasting reading from db and writeing into a pipe, whereas
the parent stores the other end of the pipe handle into
$c->response->body() and returns immediatly. Then finalize_body() would
hopefully read from the pipe and write data to the browser as soon as
the child process stores the first lines into the pipe.
Unfortunately this failed. Firefox only stored about 930 bytes, then
dropped the connection whereas Konqueror didn't write anything.
Many hours later I discovered the reason: The response header had a line
Content-Length: 0
Aaargh!
This header line is automatically created by this code in
Catalyst::finalize_headers():
if ( my $stat = stat $c->response->body ) {
$c->response->content_length( $stat->size );
}
Apparently this assumes that $c->response->body is a filehandle of a
regular file, but you can stat any kind of file (remember: "in UNIX
everything is a file") and for a pipe $stat->size is 0!
I fixed the code and now it works as expected, though chunked
transfer coding*) would be a nice feature in the absence of a
Content-Length header.
A patch against the svn trunk is attached.
*) http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
--
Bernhard Graf
-------------- next part --------------
A non-text attachment was scrubbed...
Name: catalyst_finalize_headers.patch
Type: text/x-diff
Size: 819 bytes
Desc: not available
Url : http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070506/9b1b84f0/catalyst_finalize_headers-0001.bin
More information about the Catalyst
mailing list