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

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have links to files (images, txts, pdfs, etc) on my server which I want to invoke the download box to appear. The options are OPEN or SAVE AS. I want all files to open in the download box whether it's an image, sound file or .zip. I searched the web and came across the stuff I'll post below. Problem is, it's in PHP. Can someone help me write this for CGI?
From the reader comments at php.net/manual http://www.php.net/manual/en/function.header.php (I'm not being a RTFM smartass, I just happened to be there very recently) simon dot lee at terago dot ca 28-May-2002 05:50 Additional notes to my workaround on Q266305: I have tested my findings with PDF, XLS, DOC and ZIP. However JPG an +d GIF didn't make IE pop up the download box. By changing content type from "octet-stream" to "force-download" (or some undefined type), it will work. Of course, we need to take care of other browsers too. Here + is the improved code, hope it helps: header("Content-type: application/force-download"); if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE")) header("Content-Disposition: filename=$myfile" . "%20"); // For IE else header("Content-Disposition: attachment; filename=$myfile"); / +/ For Other browsers Note: If you are using session together with this download, you will + need to add the following line BEFORE the code above to make IE work: session_cache_limiter("");

Replies are listed 'Best First'.
Re: PHP to CGI
by inman (Curate) on Mar 31, 2004 at 08:47 UTC
    You have already answered your own question! Adjust the mime-type to something other than is configured on the windows client by default and it will force a download.

    The key to the open/download issue is the difference in the way that IE deals with mime-types. When your Perl app returns content, IE has no choice but to believe the mime-type header supplied. IE compares the mime-type supplied in the content header and acts according to the settings for that mime-type.

    Your application (e.g. /myapp/download.cgi?file1) returns a file (stream of bytes) which just happens to be a Word document:

    1. Setting the Content-type header to application/msword will cause IE to recognise the stream of bytes as a Word document and take the default action. This is probably loading it up in the same window
    2. Setting the mime-type to application/msword-download will cause IE to look for information relating to the application/msword-download mime-type and take action accordingly. Since there is no mime-type information set, IE will take the default action of asking you to save or open the file.
    The mime-type / content / action relationship is configured in the registry of the Windows client. The HKCR/.extension keys map the mime-type to a document extension.
    HKCR\.doc "Content Type"="application/msword"

      IE has no choice but to believe the mime-type header supplied

      Actually, IE tends to ignore MIME types whenever it bloddy well feels like it. Which is a big problem, because server admins sometimes set everything to a default MIME type of 'text/plain', even though they are returning HTML, but IE DWIMs it to parsing the HTML. This will look fine to the people using IE, but browsers which correctly obey the MIME type will display the HTML as text. It's even worse when binary files are being sent as plaintext.

      ----
      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

Re: PHP to CGI
by DamnDirtyApe (Curate) on Mar 31, 2004 at 07:17 UTC

    Not sure about the session_cache_limiter() thing, but all the header() stuff can be accomplished through the CGI module's header() function. Have a look.


    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche
Re: PHP to CGI
by revdiablo (Prior) on Mar 31, 2004 at 07:32 UTC
    Can someone help me write this for CGI?

    Please note that CGI is not a programming language. CGI is an interface. Anything can run as a CGI -- a Perl program, a C program, a Bash shell script, or even a PHP script. Saying "help me write this for CGI" is quite ambiguous and not very helpful.

    If you have a specific question about doing something CGI-related in Perl, we're all ears, but something overly broad and not very well-researched is likely to be ignored, or even worse, scorned.