01/10/2018, 17:21

Download file và lỗi Content-Length mismatch trong ngôn ngữ PHP

Bạn có một hàm download dùng để cho download file trên server của bạn về máy người dùng. Tuy nhiên, người dùng download file có thể không install được hoặc là có thể không unzip được. Nếu bạn dùng Fidder để debug bạn sẽ thấy xuất hiện lỗi “Content-Length mismatch: Response Header ...

Bạn có một hàm download dùng để cho download file trên server của bạn về máy người dùng. Tuy nhiên, người dùng download file có thể không install được hoặc là có thể không unzip được. Nếu bạn dùng Fidder để debug bạn sẽ thấy xuất hiện lỗi “Content-Length mismatch: Response Header claimed…” như hình bên dưới:

Nếu bạn gặp lỗi trên thì có thể bạn đã thiếu 2 lệnh sau trong hàm download file của bạn:

ob_clean(); 
flush(); 

Đoạn mã sau là những dòng lệnh mình dùng để tránh lỗi này:

function download_file($dir_path = ', $file_name = ')
{
	$allowed_ext = array (
		'nme' => 'application/octet-stream',

		// archives
		'zip' => 'application/zip',

		// documents
		'pdf' => 'application/pdf',
		'doc' => 'application/msword',
		'xls' => 'application/vnd.ms-excel',
		'ppt' => 'application/vnd.ms-powerpoint',
		'txt' => 'text/plain',

		// executables
		'exe' => 'application/octet-stream',
		'msi' => 'application/octet-stream',


		// images
		'gif' => 'image/gif',
		'png' => 'image/png',
		'jpg' => 'image/jpeg',
		'jpeg' => 'image/jpeg',

		// audio
		'mp3' => 'audio/mpeg',
		'wav' => 'audio/x-wav',

		// video
		'mpeg' => 'video/mpeg',
		'mpg' => 'video/mpeg',
		'mpe' => 'video/mpeg',
		'mov' => 'video/quicktime',
		'avi' => 'video/x-msvideo',
		'wmv' => 'video/x-ms-wmv',
		'flv' => 'video/x-flv'
		);

		
		// Make sure program execution doesn't time out
		// Set maximum script execution time in seconds (0 means no limit)
		set_time_limit(0);

		// get full file path (including subfolders)
		$file_path = $dir_path . $file_name;

		if (!file_exists($file_path)) {
			die("File does not exist. Make sure you specified correct file name.");
		}

		// file size in bytes
		$fsize = filesize($file_path);

		// file extension
		$fext = strtolower(getFileExtension($file_name));

		// check if allowed extension
		if (!array_key_exists($fext, $allowed_ext)) {
			die("Not allowed file type.");
		}

		// get mime type
		if ($allowed_ext[$fext] == ')
		{
			$mtype = ';
			// mime type is not set, get from server settings
			if (function_exists('mime_content_type'))
			{
				$mtype = mime_content_type($file_path);
			}
			else if (function_exists('finfo_file'))
			{
				$finfo = finfo_open(FILEINFO_MIME); // return mime type
				$mtype = finfo_file($finfo, $file_path);
				finfo_close($finfo);
			}
			if ($mtype == ')
			{
				$mtype = "application/force-download";
			}
		}
		else
		{
			// get mime type defined by admin
			$mtype = $allowed_ext[$fext];
		}

		// set headers
		
		header("Pragma: public"); // required 
		header("Expires: 0"); 
		header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
		header("Cache-Control: private",false); // required for certain browsers
		header("Content-Description: File Transfer");
		header("Content-Type: " . $mtype);
		header("Content-Disposition: attachment; filename="" . $file_name . """);
		header("Content-Transfer-Encoding: binary");
	
		header("Content-Length: $fsize"); 
		ob_clean(); 
		flush(); 

		// download
		// @readfile($file_path);
		$file = @fopen($file_path,"rb");
		if ($file)
		{
			while(!feof($file))
			{
				print(fread($file, 1024*8));
				flush();
				if (connection_status()!=0)
				{
					@fclose($file);
					die();
				}
			}
			@fclose($file);
		}
}

Have fun:D


0