> Randolf Richardson wrote:
> >> I know that it's possible(and arguably best practice) to use Apache to
> >> download large files efficiently and quickly, without passing them through
> >> mod_perl. However, the data I need to download from my application is both
> >> dynamically generated and sensitive so I cannot expose it to the internet
> >> for anonymous download via Apache. So, I'm wondering if mod_perl has a
> >> capability similar to the output stream of a java servlet. Specifically, I
> >> want to return bits and pieces of the file at a time over the wire so that
> >> I can avoid loading the entire file into memory prior to sending it to the
> >> browser. Currently, I'm loading the entire file into memory before sending
> >> it and
> >>
> >> Is this possible with mod_perl and, if so, how should I go about
> >> implementing it?
> >
> >     Yes, it is possible -- instead of loading the entire contents of a
> > file into RAM, just read blocks in a loop and keep sending them until
> > you reach EoF (End of File).
> >
> >     You can also use $r->flush along the way if you like, but as I
> > understand it this isn't necessary because Apache HTTPd will send the
> > data as soon as its internal buffers contain enough data.  Of course,
> > if you can tune your block size in your loop to match Apache's output
> > buffer size, then that will probably help.  (I don't know much about
> > the details of Apache's output buffers because I've not read up too
> > much on them, so I hope my assumptions about this are correct.)
> >
> >     One of the added benefits you get from using a loop is that you can
> > also implement rate limiting if that becomes useful.  You can
> > certainly also implement access controls as well by cross-checking
> > the file being sent with whatever internal database queries you'd
> > normally use to ensure it's okay to send the file first.
> >
>
> You can also :
> 1) write the data to a file
> 2) $r->sendfile(...);
> 3) add a cleanup handler, to delete the file when the request has been served.
> See here for details : 
> http://perl.apache.org/docs/2.0/api/Apache2/RequestIO.html#C_sendfile_
>
> For this to work, there is an Apache configuration directive which must be 
> set to "on". I
> believe it is called "UseSendFile".
> Essentially what senfile() does, is to delegate the actual reading and 
> sending of the file
> to Apache httpd and the underlying OS, using code which is specifically 
> optimised for this
> purpose.  It is much kore efficient than doing this in a read/write loop by 
> yourself, at
> the cost of having less fine control over the operation.

        Thank you André, this is an excellent solution.

        One comment I'd like to add is that it appears that steps 1 and 3
can be eliminated if a file is basically being copied (because the
data is pre-existing in its entirety in a file already), hence
resulting in even better performance due to even fewer resources and
CPU cycles being consumed.

Randolf Richardson - rand...@inter-corporate.com
Inter-Corporate Computer & Network Services, Inc.
Beautiful British Columbia, Canada
http://www.inter-corporate.com/


Reply via email to