http://www.perlmonks.org?node_id=26739


in reply to Downloading things from a database

You can actually get away with not knowing the content-type, you just default to application/octet-stream. Give the following a try, it is very nice. All you will need to do is perform a length() on the data and give a filename.

--eric
use CGI; my $size = length ($blob); my $filename = 'good_data.txt'; print CGI::header( -Content-Disposition => "attachment; filename=$filename", -Content-Type => 'application/octet-stream', -Content-Length => $size, -Pragma => 'no-cache', -Expires => 0 ); print $blob;

Replies are listed 'Best First'.
RE: Re: Downloading things from a database
by merlyn (Sage) on Aug 08, 2000 at 09:42 UTC
    Pragma: no-cache is for client to server, not server to client. Don't add it to code like this. It gives the impression that it is doing something, and then the next person adds it as well. {sigh}

    -- Randal L. Schwartz, Perl hacker

RE: Re: Downloading things from a database
by Fastolfe (Vicar) on Aug 09, 2000 at 00:19 UTC
    Note that using the generic application/octet-stream MIME type for information you want the browser to simply save and not render won't always work under some (all?) versions of Internet Explorer. IE has a tendency of taking the MIME type with a grain of salt and doing further examination of the file's extension to determine whether or not IE should attempt to render the content internally. MS Office files (e.g. .doc) are notoriously difficult to bring up a "Save As" dialog, because some versions of IE insist on rendering it in an embedded MS Word window.
      What about very large files? As I see in my tests, this type of download use a lot of memory. Is there a was to do this without using a lot of system resources? Thanks
        Yes, this would take a lot of memory if you read in a large file to a string first.
        To force download of a large file, just print the file as you read it in like this:

        if(-e $file) { if(open(SESAME, "< $file")) { print "Content-Disposition: attachment; filename=$file\n"; print "Content-Type: application/octet-stream\n"; print "Content-Length: " . (-s $file) . "\n\n"; while(<SESAME>) { print $_; } close(SESAME); } else { print "Content-Type: text/html\n\nError: Could not read from f +ile\n"; } } else { print "Content-Type: text/html\n\nError: invalid filename\n"; }