php readfile() and fopen() damaged/corrupt download

Long time lurker first time poster,

Im done pulling my hair out over this, so i figured i would swallow the pride and ask the experts, I have read in excess of 20 similar issues here and tried all fixes solutions but im getting the same results.

Im using PHP for users to download items, however i have tried readfile and fopen but EVERY download is corrupt, sometimes 0 in size other times the correct(ish) size, But always damaged or corrupt

Can someone take a peek at this code and tell me whats wrong with it, ive scoured it so many times now im probably just missing something rediculously simple, ..... as usual

Any help would be greatly appreciated.

(contents of /loap.php can be shown if needed)

EDIT : Resolved Just a quick update for anyone who stumbled across this, I managed to get this working ...... I had tried many different variations of certain commands, but it seems i had missed trying with "ob_clean()" and "ob_end_flush()" with fopen(), .. It did the trick and as i expected it was a simple fix Thanks for the help Twisty, you poked at my inspiration ;)

<?php 
require_once('../secura/load.php');

function get_remote_file_size($url, $readable = true){
   $parsed = parse_url($url);
   $host = $parsed["host"];
   $fp = @fsockopen($host, 80, $errno, $errstr, 20);
   if(!$fp) return false;
   else {
       @fputs($fp, "HEAD $url HTTP/1.1\r\n");
       @fputs($fp, "HOST: $host\r\n");
       @fputs($fp, "Connection: close\r\n\r\n");
       $headers = "";
       while(!@feof($fp))$headers .= @fgets ($fp, 128);
   }
   @fclose ($fp);
   $return = false;
   $arr_headers = explode("\n", $headers);
   foreach($arr_headers as $header) {
			 $s = "Content-Length: ";
       if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
           $return = trim(substr($header, strlen($s)));
           break;
       }
   }
   
   return $return;
}

function get_ext($name)

{

	$fn = get_basename($name);

	return (strpos($fn, '.') ? strtolower(substr(strrchr($fn, '.'), 1)) : '');

}
function get_basename($name)



{

	return basename(str_replace('\\', '/', $name));

}

function get_filesize_unit($size)



{

	$size = max(0, $size);

	static $u = array('&nbsp;B', 'KB', 'MB', 'GB');

	for ($i=0; $size >= 1024 && $i < 4; $i++)

	{

		$size /= 1024;

	}

	return number_format($size, 1).' '.$u[$i];

}



///////////////////////////////////////////////////////////////////////////////////////////////

function find_mime_type($ext)

{

	static $mime_types = array(

		'application/andrew-inset' => array('ez'),

		'application/mac-binhex40' => array('hqx'),

		'application/mac-compactpro' => array('cpt'),

		'application/mathml+xml' => array('mathml'),

		'application/msword' => array('doc'),

		'application/octet-stream' => array('bin', 'dms', 'lha',

			'lzh', 'exe', 'class', 'so', 'dll', 'dmg'),

		'application/oda' => array('oda'),

		'application/ogg' => array('ogg'),

		'application/pdf' => array('pdf'),

		'application/postscript' => array('ai', 'eps', 'ps'),

		'application/rdf+xml' => array('rdf'),

		'application/smil' => array('smi', 'smil'),

		'application/srgs' => array('gram'),

		'application/srgs+xml' => array('grxml'),

		'application/vnd.mif' => array('mif'),

		'application/vnd.mozilla.xul+xml' => array('xul'),

		'application/vnd.ms-excel' => array('xls'),

		'application/vnd.ms-powerpoint' => array('ppt'),

		'application/vnd.wap.wbxml' => array('wbxml'),

		'application/vnd.wap.wmlc' => array('wmlc'),

		'application/vnd.wap.wmlscriptc' => array('wmlsc'),

		'application/voicexml+xml' => array('vxml'),

		'application/x-bcpio' => array('bcpio'),

		'application/x-cdlink' => array('vcd'),

		'application/x-chess-pgn' => array('pgn'),

		'application/x-cpio' => array('cpio'),

		'application/x-csh' => array('csh'),

		'application/x-director' => array('dcr', 'dir', 'dxr'),

		'application/x-dvi' => array('dvi'),

		'application/x-futuresplash' => array('spl'),

		'application/x-gtar' => array('gtar'),

		'application/x-hdf' => array('hdf'),

		'application/x-javascript' => array('js'),

		'application/x-koan' => array('skp', 'skd', 'skt', 'skm'),

		'application/x-latex' => array('latex'),

		'application/x-netcdf' => array('nc', 'cdf'),

		'application/x-sh' => array('sh'),

		'application/x-shar' => array('shar'),

		'application/x-shockwave-flash' => array('swf'),

		'application/x-stuffit' => array('sit'),

		'application/x-sv4cpio' => array('sv4cpio'),

		'application/x-sv4crc' => array('sv4crc'),

		'application/x-tar' => array('tar'),

		'application/x-tcl' => array('tcl'),

		'application/x-tex' => array('tex'),

		'application/x-texinfo' => array('texinfo', 'texi'),

		'application/x-troff' => array('t', 'tr', 'roff'),

		'application/x-troff-man' => array('man'),

		'application/x-troff-me' => array('me'),

		'application/x-troff-ms' => array('ms'),

		'application/x-ustar' => array('ustar'),

		'application/x-wais-source' => array('src'),

		'application/xhtml+xml' => array('xhtml', 'xht'),

		'application/xslt+xml' => array('xslt'),

		'application/xml' => array('xml', 'xsl'),

		'application/xml-dtd' => array('dtd'),

		'application/zip' => array('zip'),

		'audio/basic' => array('au', 'snd'),

		'audio/midi' => array('mid', 'midi', 'kar'),

		'audio/mpeg' => array('mpga', 'mp2', 'mp3'),

		'audio/x-aiff' => array('aif', 'aiff', 'aifc'),

		'audio/x-mpegurl' => array('m3u'),

		'audio/x-pn-realaudio' => array('ram', 'ra'),

		'application/vnd.rn-realmedia' => array('rm'),

		'audio/x-wav' => array('wav'),

		'chemical/x-pdb' => array('pdb'),

		'chemical/x-xyz' => array('xyz'),

		'image/bmp' => array('bmp'),

		'image/cgm' => array('cgm'),

		'image/gif' => array('gif'),

		'image/ief' => array('ief'),

		'image/jpeg' => array('jpeg', 'jpg', 'jpe'),

		'image/png' => array('png'),

		'image/svg+xml' => array('svg'),

		'image/tiff' => array('tiff', 'tif'),

		'image/vnd.djvu' => array('djvu', 'djv'),

		'image/vnd.wap.wbmp' => array('wbmp'),

		'image/x-cmu-raster' => array('ras'),

		'image/x-icon' => array('ico'),

		'image/x-portable-anymap' => array('pnm'),

		'image/x-portable-bitmap' => array('pbm'),

		'image/x-portable-graymap' => array('pgm'),

		'image/x-portable-pixmap' => array('ppm'),

		'image/x-rgb' => array('rgb'),

		'image/x-xbitmap' => array('xbm'),

		'image/x-xpixmap' => array('xpm'),

		'image/x-xwindowdump' => array('xwd'),

		'model/iges' => array('igs', 'iges'),

		'model/mesh' => array('msh', 'mesh', 'silo'),

		'model/vrml' => array('wrl', 'vrml'),

		'text/calendar' => array('ics', 'ifb'),

		'text/css' => array('css'),

		'text/html' => array('html', 'htm'),

		'text/plain' => array('asc', 'txt'),

		'text/richtext' => array('rtx'),

		'text/rtf' => array('rtf'),

		'text/sgml' => array('sgml', 'sgm'),

		'text/tab-separated-values' => array('tsv'),

		'text/vnd.wap.wml' => array('wml'),

		'text/vnd.wap.wmlscript' => array('wmls'),

		'text/x-setext' => array('etx'),

		'video/mpeg' => array('mpeg','3gp','mp4', 'mpg', 'mpe'),

		'video/quicktime' => array('qt', 'mov'),

		'video/vnd.mpegurl' => array('mxu', 'm4u'),

		'video/x-msvideo' => array('avi'),

		'video/x-sgi-movie' => array('movie'),

		'x-conference/x-cooltalk' => array('ice')

	);
	foreach ($mime_types as $mime_type => $exts)
	{
		if (in_array($ext, $exts))
		{
			return $mime_type;
		}
	}
	return 'text/plain';
}
$id = $_GET['id'];
$error = false;
$error = (!$product->is_product($id)?$products->error:$error);
$error =(!$purchases->is_purchased($_SESSION['uid'],$id)?$purchases->error:$error);
if(!$error){
$file = $product->details($id);
$filepath = $file['file'];
$fname=get_basename($filepath);
if (fopen($filepath,r) || (file_exists($filepath)) ){
if (@filesize($filepath)){
$fsize =filesize($filepath);
}
else
{
$fsize =  get_remote_file_size($filepath); 
}
$ext= get_ext($fname);
$ctype= find_mime_type($ext);
header('Content-Type:'. $ctype );
header('Content-Length: ' . $fsize);
header('Content-Disposition: attachment; filename=' . $fname);
ob_clean();
$file = fopen($filepath,'r');
ob_end_flush();
fpassthru($file);
set_time_limit(0);
}else{
return  'File Doesn\'t Exist';  } // exist fxn....
}
echo $error;
?>

Upvotes: 3

Views: 1456

Answers (2)

AamirR
AamirR

Reputation: 12198

Make sure you do not have any code executed after the last line readfile(FILE_NAME)

In my case, I had to add die(); or exit(); as the last line, because MVC framework continues to render the view after readfile

Upvotes: 0

Just a quick update for anyone who stumbled across this, I managed to get this working ......

I had tried many different variations of certain commands, but it seems i had missed trying with ob_clean() and ob_end_flush() with fopen() , .. It did the trick and as i expected it was a simple fix

Thanks for the help Twisty, you poked at my inspiration ;)

The corrected and working code has been updated in the OP

Upvotes: 1

Related Questions