currupt media files after download using headers


#1

Hi all,

Can anyone help with a perlexing problem.

I have a web site undr construction which offers media for download. I have used 10 or 15 different combinations of headers to prompt a download dialogue box and enable the user to download onto their machine. They all work fine with .mp3 files, .wma files, .jpegs, etc. etc. but when it comes to .wmv files or .zip files they get corrupted and won’t play or un-zip. Media Player gives a file corrupt message about half-way through playing the movie file and ‘un-zip’ -ing the zip files gives an unexplained “End Of File” warning message. I suspect that something is being added to the file making it unreadable.

I have used

readfile($file);
fpassthru(($file);
fopen($file) - with all combinations of “r”, “rb” etc.
echo ($file);

and many others.

There must be something peculiar about video media and downloading in this way.

I am using php 4.3.3 and Apache on a Window’s machine on a home (localhost) server environment.

Can anyone please give me a hint on where to look for a solution???

Regards,

Nick.


#2

Do you have the MIME headers set correctly in your server configuration? Are you sending the proper headers with each file? Is it only you who has the problem? Do the files work correctly when not downloaded? Do you have zlib.output_compression on or off?

Maybe this will give you some help with your wmv files: http://www.microsoft.com/windows/window … erver.aspx

Since you didn’t post source code, it’s like giving you a haircut over the telephone.


#3

Hi,

Thanks for your reply. This is an example of the code I have been using. It is just one example of many different combinations of headers I have tried, as well as various combinations of different ways of reading the file and sending it through the output buffer. This method of sending it through the output buffer however, is preferable to me because it allows me to update a mysql database just before the fclose function, so that the database is only updated if the file download is completed and not before (in case the downlaod gets cancelled or interrupted for example).

<?php $filename = "../some/path/to/movie.wmv"; (OR .zip for that matter) header("Content-type: application/force-download"); header("Content-Transfer-Encoding: Binary"); header("Content-length: ".filesize($filename)); header("Content-disposition: attachment; filename=".basename($filename)); if ($fp=fopen($filename, "rb")) { while(!feof($fp)) { echo fgets($fp, 4096); } // some php code which updates mysql db } //close file fclose($fp); ?>

As I said, works a treat for .mp3 files, text files, images etc. but .wmv files and .zip files get corrupted.

So far, I have added the following to the httpd.conf file and the mime.types files in the configuration folder for Apache - same problem.

AddType video/x-ms-asf asf asx
AddType audio/x-ms-wma wma
AddType audio/x-ms-wax wax
AddType video/x-ms-wmv wmv
AddType video/x-ms-wvx wvx

I have also altered the DefaultType to application/octet-stream - same problem

The movie files play normally on the server when accessed directly with media player, and if I call the download through Apache simply by calling

<?php header ("Location: ../some/path/movie.wmv"); ?>

then the movie downloades perfectly and is not corrupted - only I don’t want to use ths method because it allow no scope to update my database after the download is completed.

I am sure it is the server settings because if I upload this exact same code to a remote server, it works fine - just corrupts on my localhost, testing server.

I confess to not knowing what zlib.output compression is.

I have come across another problem which I think is directly related. The above php code using fopen and echo fgets etc. works well albeit currupting the movie files. However, I am getting the filename for the download from a $_SESSION variable. If I use session_start before and define

$filename = $_SESSION[filename];

then even worse!! - the server stalls and gives a ‘Cannot find server or DNS error’

Thanks for your interest - really look forward to your reply.

Pertwee.


#4

Just found zlib.output compression in the php.ini file - it was set to ‘off’

I experimentally turned it on and tried the downloads again. The only difference was that the code downloaded a 1byte script with the same name as the page calling the code so I turned it back off.


#5

Since it works correctly on your remote server, but not on your local server, look for differences. Make sure that they are running the same version of PHP. fgets() is a binary safe as of PHP 4.3. If your local server is running an earlier version, it may be choking on the binary data.

Also, why not use fpassthru()?

What shows up in your logs for an aborted transfer?


#6

Thanks for all your help so far, version of php is 4.3.3 (same as remote server). I have used fpassthru() with the same problem.

The Apache access.log shows the following line after a download of a corrupted file:

192.168.0.5 - - [25/May/2004:18:24:28 -0700] “GET /test_site/download.php HTTP/1.1” 200 8009085

The error.log shows no data entry for th download.

What do you mean by ‘choking on the binary data’? Someone else suggested that might be a problem but never expanded on this.

Still cannot for the life of me figure out why the local server should corrupt a .zip file. I am under the impression that any server should be configured for this no matter what the contents of the .zip file are. I have tried tiny .zip files in case it’s a filesize issue - same problem. Also, doesn’t seem to matter what content is in the ziped file - get the same error message when try to unzip it, which is an “Unexpected end of file” messgae in Windows XP, or “Error: invalid compressed data to inflate” with WinZip.

Any other thoughts?

Pertwee.