Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

File Download

by Anonymous Monk
on Apr 26, 2000 at 06:04 UTC ( [id://9155]=perlquestion: print w/replies, xml ) Need Help??

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

I tried the following code to allow somebody to download a file from a non-public or non-htdocs dir. However, the browser's dialog box prompts for the cgi script's filename instead of the actual file. Anyway workaround
open(FILE, $file); binmode(FILE); print "Content-type: application/x-unknown\n\n"; print < FILE >; close FILE;

Replies are listed 'Best First'.
RE: File Download
by t0mas (Priest) on Apr 26, 2000 at 11:44 UTC
    I use the following code to snippet to pour out a RTF file i generate in an app of mine: The user clicks on a link like Download file
    print "Content-type: application/rtf\r\n"; print header(-type => 'application/rtf'); print $doc;
    Content-type tells the web-server _how_ to send the file while the header(-type ... tells the receiving browser what to do with it. $doc contains the RTF file contents. /t0mas
Re: File Download
by guice (Scribe) on Apr 26, 2000 at 08:30 UTC
    The only way around that is to redirect the browser to the location of the file. The only reason the browser is showing the script name as the name of the file is cause it's the script that it's actually sending the download to the browser. From what the browser sees, it doesn't know it's downloading another file.

    -- philip
    We put the 'K' in kwality!

      Not necessarily... All you need is for the httpd daemon to have read access on the file. I took care of the paths, filenames, sizes, etc by using this little snippet:
      sub DownloadFile { # $filepath is the directory # $filename is the name of the file my ($filepath,$filename) = @_; chdir($filepath) || return(0); my $filesize = -s $filename; # print full header print "Content-disposition: inline; filename=$filename\n"; print "Content-Length: $filesize\n"; print "Content-Type: application/octet-stream\n\n"; # open in binmode open(READ,$filename) || die; binmode READ; # stream it out binmode STDOUT; while (<READ>) { print; } close(READ); # should always return true return(1); }
      I hope that's useful. It has a few extra steps that aren't reeeaalllly needed, but its nice to be on the safe side.

      Cheers!

        The crucial part is the "Content-disposition" parameter.

        Incidentally, you should use
        Content-disposition: attachment; filename=file

        Instead of "inline" if you really want the save-as box to pop up. It probably won't make any difference, but it could if the user has a program set up to handle the content-type you're returning (for example, if you're returning a pdf file).

        Incidentally, the RFC on HTTP/1.1 only defines behavior with "attachment". (And that only in an appendix under "Additional Features")

        could elaborate on how to implement this? thanks! fromsir
Re: File Download
by Anonymous Monk on Apr 26, 2000 at 12:13 UTC
    Try leaving the script, change the way its accessed.

    eg
    http://blah/cgi-bin/filedl.pl/myfile.txt
    will prompt to save as "myfile.txt".

    If you want you can still use arguments
    http://blah/cgi-bin/filedl.pl/myfile.txt?file=myfile.txt
      You don't even need to include the file name as an argument, just get it from the $ENV{'PATH_INFO'} variable. This gives you any extra text following the script name in the URL.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://9155]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2024-04-19 08:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found