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]



Reply via email to