PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!
Moderator: General Moderators
suspire
Forum Newbie
Posts: 6 Joined: Tue Mar 15, 2005 2:54 pm
Post
by suspire » Tue Mar 15, 2005 3:06 pm
Whats up guys.
We're trying to put up a free download and need the file to save to peoples desktop instead of going into quicktime or whatever player is setup in their browser. I've got the code to do it via Content-Disposition but, can't get it to work.
Code: Select all
<?php
$file = 'http://brashmusic.com/download/Taylor_Hollingsworth-How_Could_You_Be_So_Cold.mp3';
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename=' . basename($file));
readfile($file);
?>
Here is the link on our server:
http://brashmusic.com/download/download3.php
And the error I get:
Parse error: parse error, unexpected T_VARIABLE in /home/brashmu/public_html/download/download.php on line 1
Anybody know what the problem is?
Thanks.
feyd | Please use Code: Select all
tags where approriate when posting code. Read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url][/color]
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098 Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia
Post
by Chris Corbyn » Tue Mar 15, 2005 3:11 pm
This is the only code in your file? As in <?php is line 1 itself?
suspire
Forum Newbie
Posts: 6 Joined: Tue Mar 15, 2005 2:54 pm
Post
by suspire » Tue Mar 15, 2005 3:21 pm
Indeed.
Am I missing something?
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Tue Mar 15, 2005 3:24 pm
did you write this in DreamWeaver by chance?
Sidenote: $filename != $file
hongco
Forum Contributor
Posts: 186 Joined: Sun Feb 20, 2005 2:49 pm
Post
by hongco » Tue Mar 15, 2005 3:30 pm
...also, you need to change the first line to the path to the file, not the url
Code: Select all
$file = 'http://brashmusic.com/download/Taylor_Hollingsworth-How_Could_You_Be_So_Cold.mp3';
// should've been something like, for instance, on linux:
$file = '/home/youraccount/public_html/download/yourfile.mp3';
suspire
Forum Newbie
Posts: 6 Joined: Tue Mar 15, 2005 2:54 pm
Post
by suspire » Tue Mar 15, 2005 3:30 pm
BBEdit.
Because its calling it from the same directory and doesn't like absolute urls?
download3.php and the mp3 are in the same dir.
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Tue Mar 15, 2005 3:33 pm
you may have, for whatever reason, an "invisible" character that may be causing it. If you retype the code (not copying it) into a new page/document/whatever, does it fix the problem?
suspire
Forum Newbie
Posts: 6 Joined: Tue Mar 15, 2005 2:54 pm
Post
by suspire » Tue Mar 15, 2005 3:45 pm
gave it a retype, same error:
http://www.brashmusic.com/download/download4.php
Code: Select all
<?php
$file = "http://brashmusic.com/download/Taylor_Hollingsworth-How_Could_You_Be_So_Cold.mp3";
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename=' . basename($file));
readfile($file);
?>
suspire
Forum Newbie
Posts: 6 Joined: Tue Mar 15, 2005 2:54 pm
Post
by suspire » Tue Mar 15, 2005 3:49 pm
Got it. Thanks guys.
Code: Select all
<?php
$file = "http://www.brashmusic.com/download/Taylor_Hollingsworth-How_Could_You_Be_So_Cold.mp3";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-Description: File Transfert");
readfile($file);
?>
feyd | Please use Code: Select all
tags where approriate when posting code. Read: [url=http://forums.devnetwork.net/viewtopic.php?t=21171]Posting Code in the Forums[/url][/color]
hongco
Forum Contributor
Posts: 186 Joined: Sun Feb 20, 2005 2:49 pm
Post
by hongco » Tue Mar 15, 2005 3:50 pm
suspire wrote: BBEdit.
Because its calling it from the same directory and doesn't like absolute urls?
download3.php and the mp3 are in the same dir.
my bad, the abs url is fine
hongco
Forum Contributor
Posts: 186 Joined: Sun Feb 20, 2005 2:49 pm
Post
by hongco » Tue Mar 15, 2005 3:52 pm
suspire wrote: gave it a retype, same error:
http://www.brashmusic.com/download/download4.php
Code: Select all
<?php
$file = "http://brashmusic.com/download/Taylor_Hollingsworth-How_Could_You_Be_So_Cold.mp3";
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename=' . basename($file));
readfile($file);
?>
change filesize($filename) to filesize($file) and you should be fine
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Tue Mar 15, 2005 3:53 pm
filesize() will make the server download a remote file to check the size. I'd seriously suggest using a local path to the file if possible.
suspire
Forum Newbie
Posts: 6 Joined: Tue Mar 15, 2005 2:54 pm
Post
by suspire » Tue Mar 15, 2005 4:52 pm
Thanks to David Molamphy for the final code edits:
Here's a more user-friendly, revised version:
Code: Select all
<?php
$path = "http://www.yourdomain.com/directory/";
$filename = $path . $_GET['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-Description: File Transfert");
readfile($file);
?>
Now, all you have to do when you want to download a file, is make sure the file name is attached to the URL. You can even do this through $_POST if you don't want people to know where the file resides. So...your link will look something like:
<a href="downlad_test.php?file=myfilename.mp3">Download Me</a>
Alrighty. Hope that helps.
David Molampny
http://molanphydesign.com
Ambush Commander
DevNet Master
Posts: 3698 Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US
Post
by Ambush Commander » Tue Mar 15, 2005 5:11 pm
Err... that code is really asking for some sort of cracker to exploit it. No input validation at all! GASP!
download.php?file=../forbidden/secretinfo.txt
is one way of exploiting it: they can access any file on your server using this script. GASP!
Well, actually, they're only allowed to access what a PHP script would be allowed to access... but that's still a lot!
Here's a revised version:
Code: Select all
<?php
$path = "http://www.yourdomain.com/directory/";
$filename = basename($_GET['file']);
$file = $path . $filename;
if (!file_exists($file) OR !is_readable($file)) {
echo "File doesn't exist or is unreadable!";
exit;
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-Description: File Transfer");
readfile($file);
?>
If possible, limit what can be inside the filename to, say, alphabetical characters and numbers, and only mp3 files, so this regexp:
Code: Select all
$exp = 'i/^ї0-9a-z]+.mp3$/';
Can be used to validate.
Hmm... It just occured to me: http://www.elouai.com/force-download.php was sitting around in my bookmarks. I don't know why I didn't share it with you earlier!
Last edited by
Ambush Commander on Tue Mar 15, 2005 5:32 pm, edited 1 time in total.
feyd
Neighborhood Spidermoddy
Posts: 31559 Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA
Post
by feyd » Tue Mar 15, 2005 5:26 pm
psst.. $filename vs $file
It's also a good idea to validate that the file, at least exists and is readable by php.