Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Force download -- Repost

by Anonymous Monk
on Apr 03, 2004 at 03:14 UTC ( #342219=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Before we continue, I just want you to know that by "force download" I mean the DOWNLOAD and SAVE as box appears, not upload files to their computer without them knowing.

I have a directory of files containing nearly all types of files (sounds, images, text, html, exes) and I want to force a download for that link when they click on the link for that file. I've been told 'application/octet-stream' is how you force ANY file to download rather than load in the screen (like images typically load to screen, right?).

The link forces a download right now, but it tries to download the CGI script itself without the extension instead of the file I'm telling it to. It's requesting action on a file "filemanager" instead of let's say image.gif or sound.wav. Does anyone see where I went wrong? I am linking to in like <a href="filemanager.cgi?dl=$_">download!</a> and $_ does indeed contain what I expect it to. I've done testing to be sure my variable contains what it should, and it does.

Where did I go wrong?

# $dl_file is absolute path to uploaded directory where files are kept my $download = url_param('dl'); if ($download ne "") { if (exists $uploadedfiles{$download}) { my($file, $type, $time, $size) = split(/::/, $uploadedfiles{$down +load}); my $load_file = join("", $dl_file, $file); print header(-type=>'application/octet-stream', -attachment=>"$load_file", -expires=>'-1d'); print start_html); print end_html; exit; } else { print header, start_html("ERROR"); print qq(<center>Does not exist!</center>); print end_html; exit; } }

Replies are listed 'Best First'.
Re: Force download -- Repost
by Kozz (Friar) on Apr 03, 2004 at 03:27 UTC
    Your main problem is that you're only outputting the header and not the contents of the file itself. If you're going to output your own mime-type header like this, you would then need to open the file in question (use binmode()) in chunks, outputting those chunks to the browser as they are read.
    my $buffer; open(DOWNLOAD, "< /path/requested_file") or die "Could not read file: +$!"; binmode(DOWNLOAD); while( read(DOWNLOAD, $buffer, 4096) ){ print $buffer; } close(DOWNLOAD);
    "Forcing a download" is really a function of the browser, and results from the browser's decision on how to handle the particuar mime type you send. You may want to also try "application/binary" in addition to the "application/octet-stream". In your code, I think that using 'join' is a bit of overkill when you can concatenate the strings as
    my $load_file = $dl_file . $file;
    Also, I would get rid of the start_html and end_html bit -- unnecessary, and I suppose could mess up your headers, too.
      Thank you for your suggestions but it's still producing the same output as before. It enforces a DOWNLOAD/SAVE AS popup without the filename (but it pops up with the script name without the extension).

      I added your buffer and print codes and commented out the HTML headers. It didn't error out so I assume it could find the file, it's just not producing ANYTHING other than a popup without a file.

      Any other suggestions?

Re: Force download -- Repost
by sgifford (Prior) on Apr 03, 2004 at 08:53 UTC
    Node 61642 seems to have nearly the same question; perhaps some of the ideas there will work for you?
•Re: Force download -- Repost
by merlyn (Sage) on Apr 03, 2004 at 10:48 UTC
    Please, give up the notion that you can "force" anything on the web. Instead, provide your link, have the proper MIME type, and let me steer. Don't take over the wheel for me. I will resent it and either not visit your site again, or do it only with regret.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      I wasn't asking what you liked and didn't like, I couldn't care less. And why give up a notion when you're wrong? There is a PHP script that does just this, problem is converting it to CGI. Will I give up when I know it's possible? No I won't, and you really need to stop being pessimistic and let people do what they want. We aren't here to live up to your "expectations", so you can quit trying to tell us to do this or that. When questions are answered you typically have two responses. 1) You promote yourself by telling people to check out your page (very shamefull and it's obvious your an attention whore) and 2) You always have an attitude even though your "disclaimer" says otherwise. You seem to think you're better than the rest of us and that shows in your posts and it's very disrespectful to not only the one who made the post but to all others who have to read what you write.

        we had a similar discussion here, too - if you weren't aware. But on a sidenote...uhm....

        mr/s Anonymous Monk, you might wanna check your very own perl book library, if you have one. You'll probably find merlyn's name on some of the covers or certainly in the credits. Like what he says or not, he undoubtedly knows a good deal about this stuff, and there's no need to attack him personally, ("whore", etc.) because you don't like the answer he's given.

        and btw...
        "you really need to ... let people do what they want."

        i think, that was merlyn's point.

        What? You can't take some constructive criticism? merlyn's comment was valid advice.

        Next time you want to berate someone here, show some intestinal fortitude and post using your registered account. It's Monks like you that give the Anonymous Monks a bad rap.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://342219]
Approved by sulfericacid
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2017-09-21 23:27 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (254 votes). Check out past polls.