php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43306 File Download Problem.
Submitted: 2007-11-15 18:17 UTC Modified: 2008-09-25 04:51 UTC
Votes:35
Avg. Score:4.6 ± 0.8
Reproduced:31 of 31 (100.0%)
Same Version:13 (41.9%)
Same OS:11 (35.5%)
From: d dot tas40 at chello dot nl Assigned:
Status: No Feedback Package: Scripting Engine problem
PHP Version: 5.2.5 OS: Windows XP
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2007-11-15 18:17 UTC] d dot tas40 at chello dot nl
Description:
------------
File Download Problem.

Reproduce code:
---------------
// set headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: $mtype");
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $filesize);

// 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);
}

Expected result:
----------------
It works fine with PHP v5.2.3/4 but after I updated my PHP version to 5.2.5 it doesn't work..

I click on the download link, but the downloaded file always corrupt.. 

xxx.rar: The archive is either in unknown format or damaged!
xxx.rar: The archive is either in unknown format or damaged!



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-11-15 22:46 UTC] jani@php.net
Are you sure there aren't any errors happening there? Check the file you downloaded using e.g. notepad..
 [2007-11-23 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2008-01-12 17:08 UTC] webmaster at anpera dot net
I have a similar problem with PHP 5.2.4 / 5.2.5 with Apache2.2 under Windows 2003.

Downloaded files are missing exactly 15 bytes at the end. ZIP and RAR files can't be opened correctly after download but definitely are okay on the server's hard drive.

With
$filesize=filesize($filename)+15;
the downloads are working.



$size = @filesize($filename)+15;
header('Pragma: public');
[...]
header("Content-Length: $size");
$fp = @fopen($filename, 'rb');
[...]
while (!feof($fp)){
	echo fread($fp, 8192);
}
fclose($fp);
[...]
flush();
 [2008-09-25 02:54 UTC] alphajet1024 at hotmail dot com
I have the very same problem, but my host server is PHP Version 4.3.11 with Linux OS, i use the following code snippest to recieve the file from form and upload it to a BLOB field in SQL, the code works fine with all file extensions, except rar and zip files, they mostly are corrupted.

upload.php
<?php
if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0)
{
$fileName = $_FILES['userfile']['name'];
$tmpName  = $_FILES['userfile']['tmp_name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];

$fp      = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = addslashes($content);
fclose($fp);

if(!get_magic_quotes_gpc())
{
    $fileName = addslashes($fileName);
}

include('conf.php');
// open database connection
$connection = mysql_connect($host, $user, $pass) 
or die ('Unable to connect!');
// select database
mysql_select_db($db) 
or die ('Unable to select database!');

$query = "INSERT INTO upload (name, size, type, content ) ".
"VALUES ('$fileName', '$fileSize', '$fileType', '$content')";

mysql_query($query) or die('Error, query failed ' . mysql_error());
?> 

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

download.php
<?php
if(isset($_GET['id'])) 
{
// if id is set then get the file with the id from database
include('conf.php');
// open database connection
$connection = mysql_connect($host, $user, $pass) 
or die ('Unable to connect!');
// select database
mysql_select_db($db) 
or die ('Unable to select database!');
$id    = $_GET['id'];
$query = "SELECT name, type, size, content " .
         "FROM upload WHERE id = '$id'";

$result = mysql_query($query) or die('Error, query failed');
list($name, $type, $size, $content) = mysql_fetch_array($result);
header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$name");
}
php echo $content; 
?>
 [2008-09-25 04:51 UTC] lbarnaud@php.net
Please try without any Content-Length header, your HTTP server is probably using a chunked transfert encoding. Also try with a Content-Type like 'application/octet-stream'.

Also check the character_set_* variables in your MySQL connection, the server may try to convert the query or the results if some variables do not match (blobs are binary but queries and results are not).
 [2008-10-23 09:54 UTC] arasan at mahiti dot org
I've used this code but the download rate is very slow compared to ordinary download. whether there is any way to overcome this?
 [2008-12-24 18:31 UTC] jon at jonraivala dot com
Using strlen of the blob instead of filesize in the header works for me.

Example - 

header("Content-Length: ".strlen($blob_data));

Hope this helps someone.
 [2009-04-03 04:30 UTC] marcell at equylybra dot com
Also having issues using the same script. I get no errors when downloading files with sizes below 20Mb.

From 20Mb files are perfectly downloaded via FTP but are saved with a corrupted file size (0Kb) when downloaded via PHP. Tryed the solution proposed by "webmaster at anpera dot net" too but I had no success.

Tryed without Content-Lenght header with no effect. Also tryed with different Content-Types (e.g. 'application/octet-stream','application/force-download','application/zip').

I am on PHP 5.2.8 with Apache 2.2.11 under Linux
 [2009-05-06 18:56 UTC] fali68 at yahoo dot com
I have the same issue with PHP 4.449 and 4.1.2.0 mysql. and worked fine with pervious version. can somone shed some light on this?
here is the code I'm using
mysql_select_db($database_tred, $conn);
$query = sprintf("SELECT * FROM Files WHERE Files.FileID = %s", $TID_Recordset1);
$result = MYSQL_QUERY($query, $tred)or die(mysql_error());
$data = MYSQL_RESULT($result,0,"filename"); 
$type = MYSQL_RESULT($result,0,"filetype");
$filesize =  MYSQL_RESULT($result,0,"filesize");
$file = MYSQL_RESULT($result,0,"bin_data");
if($result) {
header("Content-Tranfer-Encoding: binary");
header("Content-Disposition: attachment; filename= $data");
header("Content-length: $filesize");
header("Content-Description: PHP Generated Data");
print ($file);
 [2009-07-02 12:03 UTC] manish at sakshiinfosys dot com
Hello,

I have created Mobile Software Secured download website.

When user click on download link that time opening box to Download file.

When Download Click on 'OK' button that time Succesfully downloaded after Deleted that file and directory.

But, When Download Click on 'Cancel' Button that time also Deleted that file and directory. Actually Click on 'Cancel' button and user not Downloaded.

Please i have need to help to Why we know file downloaded Successfully or not.

If you can not understand my problem than aslo reply me.

Thanks & Regards
Manish Bhuva
 [2011-10-17 04:32 UTC] hoangdangal at yahoo dot com
let try this , i think it's ok

$file = @fopen($download_location,"rb");
if($fopen != NULL)
{		
        header("Pragma: public");
	header("Expires: 0");
	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
	header("Cache-Control: public");
	header("Content-Description: File Transfer");
	header("Content-Type: application/force-download",FALSE);
	header("Content-Type: application/x-zip-compressed",FALSE);
	header("Content-Type: application/download", FALSE); 
	header("Content-Disposition: attachment; filename=\"$this->FileName\"");
	header("Content-Transfer-Encoding: binary");
	header("Content-Length: " . filesize($download_location) + 100);			
	fpassthru($fopen);			
	fclose($fopen);
	exit();
}
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 25 07:02:14 2014 UTC