Forum Moderators: coopster

Message Too Old, No Replies

headers and downloading files

         

jackvull

3:19 pm on Jun 28, 2005 (gmt 0)

10+ Year Member



Hi I have a page that is used to track the download of files. Unfortunately when I now try to download a file, Windows displays the open or save dialogue but the file to save is called download.htm instead of the actual fiel I want it to download an unsure why.
Can anyone see anything wrong with this code:

<?php
ob_start();

include 'functions1.php';

if (isset($_GET["filename"])) {

$filename = $_GET["filename"];
$filename = str_replace('/', '', $filename); //security
$filename = str_replace('\\', '', $filename); //security
$type = $_GET["type"];
$path = "";

function getfiletype($type,&$path) {

if ($type == "mix") {
$path = "./Folder1/";
}
elseif ($type == "vj") {
$path = "./Folder2/";
}
elseif ($type == "track") {
$path = "./Folder3/";
}
elseif ($type == "leach") {
$path = $filename; //i.e. link from another website, so just use what's in the database.
}
else {
$path = "";

//log error and exit script
//Write error to log file
$time = date( "d M Y H:i:s" );
$errfile = fopen( "errors.txt", "a" );
fputs($errfile, "$time, type get instruction is blank in download.php \r\n");
fclose( $errfile );

test("File does not exist. The error has been logged and will be fixed as soon as possible");
}

//return $path;
}

function isleach($type,$path,&$filename) {

if ($type == "leach") {
$filename = $path; //just get the link

}
else {
$filename = $path.$filename; //get the pathname from function getfiletype() and then append the filename
//this is so the security checks are used
}
}

//$strFileName = basename($filename);
$pathinfo = pathinfo($filename);
$strFileType = $pathinfo['extension'];

switch ($strFileType) {
case 'asf':
$ContentType = 'video/x-ms-asf';
break;
case 'avi':
$ContentType = 'video/avi';
break;
case 'doc':
$ContentType = 'application/msword';
break;
case 'zip':
$ContentType = 'application/zip';
getfiletype($type,$path);
isleach($type,$path,$filename);
break;
case 'xls':
$ContentType = 'application/vndms-excel';
break;
case 'gif':
$ContentType = 'image/gif';
break;
case 'jpg':
case 'jpeg':
$ContentType = 'image/jpeg';
break;
case 'wav':
$ContentType = 'audio/wav';
break;
case 'mp3':
$ContentType = 'application/octet-stream'; //force download rather than stream as the next line would have done.
//$ContentType = 'audio/mpeg3';
getfiletype($type,$path);
isleach($type,$path,$filename);
break;
case 'rm':
$ContentType = 'application/octet-stream'; //force download rather than stream.
getfiletype($type,$path);
isleach($type,$path,$filename);
break;
case 'ram':
$ContentType = 'audio/x-pn-realaudio'; //stream it
getfiletype($type,$path);
isleach($type,$path,$filename);
break;
case 'mpg':
case 'mpeg':
$ContentType = 'video/mpeg';
break;
case 'rtf':
$ContentType = 'application/rtf';
break;
case 'htm':
case 'html':
$ContentType = 'text/html';
break;
case 'asp':
$ContentType = 'text/asp';
break;
case 'mov':
$ContentType = 'video/quicktime';
break;
case 'txt':
$ContentType = 'text/plain';
break;
default:
//Handle All Other Files
$ContentType = 'application/octet-stream';

}

//-----------------------------------------
//Code to record the download in database
//-----------------------------------------
include("session.php");

$sSQL = "INSERT INTO downloads (link, ip, timestamp) VALUES ('".$filename."', '".$_SERVER[REMOTE_ADDR]."', now())";
mysql_query($sSQL) or die(mysql_error());

//-----------------------
//Get link and download
//-----------------------
if (file_exists($filename)) {

$bytes = filesize("$filename");
header("Content-Type: $ContentType");
//header ("Content-Type: application/octet-stream");
header("Content-disposition: attachment; filename=\"$filename\"");
header("Content-length: $bytes");

//-------------------------------------
//Read the file and output to browser
//-------------------------------------
readfile("$filename");

}
else {

//log error and exit script
//Write error to log file
$time = date( "d M Y H:i:s" );
$errfile = fopen( "errors.txt", "a" );
fputs($errfile, "$time, file does not exist in download.php: $filename \r\n");
fclose( $errfile );

test("File does not exist. The error has been logged and will be fixed as soon as possible");

}
}

else {

//log error and exit script
//Write error to log file
$time = date( "d M Y H:i:s" );
$errfile = fopen( "errors.txt", "a" );
fputs($errfile, "$time, filename is blank in download.php \r\n");
fclose( $errfile );

test("File does not exist. The error has been logged and will be fixed as soon as possible");

}

?>

Thanks!

gliff

4:10 pm on Jun 28, 2005 (gmt 0)

10+ Year Member



Can anyone see anything wrong with this code:

It's poorly formatted and way too long for a Webmaster World post :)

You'll want to set the "Content-Disposition" header

header ("Content-Disposition: attachment; filename=yourfilename.jpg");

Where yourfilename.jpg is the name you want the user to be prompted with.

jackvull

10:28 am on Jul 1, 2005 (gmt 0)

10+ Year Member



Yeah sorry, when I submitted it, all the indentation was removed.
The script doesn't seem to run very efficiently. It works, but takes 5-10 seconds before the download prompt appears. Do you know of any reason why this might happen?

jackvull

11:02 am on Jul 1, 2005 (gmt 0)

10+ Year Member



I'm guessing it might be to do with ob_flush() as this delays the header being sent until the entire script has run but it doesn't seem that much logic to test so looking for a way round this unless that is not the issue!
Thanks.

jackvull

11:23 am on Jul 1, 2005 (gmt 0)

10+ Year Member



The other thing I noticed is that it seems to be rtelated to the size of the file to download. For example a 10Mb file brings up the download dialogue in 1 second but a 60Mb file takes 10 seconds before the dialogue is shown. Now, there is something in my script that reads file size but should that affect it?