Tobias Henoeckl wrote:
Hi,
the CGI::Application documentation said, feature requests should be sent to this mailing list, so that's why I'm posting here. Sorry if I dont't know about recent topics here (is there a web archive available anywhere?)
This is the place. The archives are at:
http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
which it mentions at the bottom of each message from the list.
We stepped into memory problems using CGI::Application, as our application had to deliver a file to the customer after doing some calculations and access control. It worked well until our customer started to serve *really* huge files, wich were slurped into memory by the run mode handler and then returned for delivery.
As far as I could see there is no way supplied in CGI::Application to stream a file directly from the file system to the user agent.
I fixed the problem with the attached patch, that allows to return not only a string or string reference, but also a file handle. It should be compatible with the previous version as far as I can see.
Using this patch I can now use the following code to deliver the file, without having it in memory:
sub myhandler { my $self = shift;
do_many_things();
$self->header_props( -type => 'application/octet-stream', '-Content-length' => -s $filename, -Application => $filename, '-Content-Disposition' => "attachment; filename=\"$filename\"", );
open my $fh, "</home/hoeni/Muenchen_10685x9166.jpg" || die; return $fh }
I think that this is a really good idea. Although not necessary. You could alternatively do this:
$self->header_type('none'); print "Content-Type: application/octet-stream\n"; #print the other headers here...
open my $fh, "</home/hoeni/Muenchen_10685x9166.jpg" || die;
while(my $line = <$fh>) { print $line }; return;
at the end of your runmode. But I think I like your idea better.
The file is not given to cgiapp_postrun() with would make no sense here.
Well, it might... what if I wanted to close the filehandle, or release on lock on it, etc.
If you implement this, it would be handy for the user of the lib to have kind of $self->stream_file($filename, $optionalmimetype) method which would do the above things and open and return a filehandle so the above code could be reduced to:
do_many_things(); return($self->stream_file($filename, 'application/octet-stream'));
I think I like this idea the best, although I'm not sure it belongs in the the C::A core. If we implement the idea of returning a filehandle instead of just text, then I would encourage you to implement this as a plugin. CGI::Application::Plugin::Stream anyone? For information on plugins see http://twiki.med.yale.edu/twiki2/bin/view/CGIapp/Plugins on the wiki.
+ if (ref($body) ne 'GLOB') { + # Support scalar-ref for body return + $bodyref = (ref($body) eq 'SCALAR') ? $body : \$body;
One question: if you are just checking for a GLOB, will that catch class based file handles like the IO::* family?
-- Michael Peters Developer Plus Three, LP
--------------------------------------------------------------------- Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]