faqts : Computers : Programming : Languages : PHP

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

147 of 215 people (68%) answered Yes
Recently 8 of 10 people (80%) answered Yes


To offer users a direct download of a file that is a valid MIME type

Jan 24th, 2009 09:06
Brad Kint, healthy man, dman, ha mo, Cinley Rodick, John Lim, Pavel Prishivalko, Big Al, http://www.ttnr.org

To offer users a direct download of a file that is a valid MIME type
I wanted to make a simple "Download" button that would let a user click
to get a "Save As" dialog box. In this case, the file was a registered
MIME type, an mp3 file. Referencing the file name directly got the file
all right, but it loaded it directly into WinAmp (the registered player
for mp3 file types) without letting me say where I wanted it. The same
will be true of .xls or .jpeg or any file that the browser knows how to
render or call a helper application.
In order to get the browser to let me download a file directly requires
a little smoke and mirrors. You need to fool the http server and client
browser into thinking the file you want is coming back as a attachment
of a different file type in order to save the file rather than to be
You need to have PHP3 working on your server for this to work.
1) Make a HREF to a php3 file that will pass you back a downloadable
file fo a name you specify, in this example: groovy.mp3
2) Make a PHP3 file exactly as the example shows in downloader.php3
below. We are creating a new server object that says it is an
application and an attachment of the same file name passed in (as
3) In this example both downloader.php3 and groovy.mp3 are in the
Document Root directory.
html file contents:
    <meta http-equiv="content-type"
    <title>Testing direct downloading via PHP3</title>
     <a href="downloader.php3?file=groovy.mp3">Download test</a>
downloader.php3 file contents:
// fool the http server and client browser into thinking the file name
// passed in is coming back as a application attachment to save  as a
// rather than be rendered
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$file");
if (!readfile($file))
The above advice allows a hacker to download any file on your web 
server.  Change to following to only allow current directory downloads:
if (strpos($file,'\\') !== false 
  or strpos($file,'/') !== false
  or strpos($file,':') !== false) die('Not current directory');
if (!readfile($file))
-- John
I would have liked to just use HTML and/or Javascript to do this
fake-out, but to no avail. The above works and is tested on Netscape
4.72 and IE 5.0. This was used in the following environment: Apache
1.3.12 / PHP3 3.0.15
[email protected]
It's all good and beautiful, but what about users with slow connection?
The won't be able to resume downloadding - we have an bitstream (btw it
may be useful for live content streaming :)
Maybe it's good to think about handling "partial content" HTTP 
headers? :)
Pavel P.