Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Downloads not working for some customers?


mhormann

Recommended Posts

It seems that downloads don't work for some customers using MS Internet Exploder (sorry: Explorer) versions 4.01, or 5.5—6.0.

 

Mostly if you are serving SSL, i.e. have ALL your shop running as 'https://bla-bla'.

 

I've done some testing with different files, file types and browsers with entelite who helped me a lot finding the issues.

 

In short:

 

1. osC's download.php (in /catalog/) doesn't give a content length, so browsers aren't able to show a file size or progress bar and cannot estimate d/l time.

 

2. MS acknowledge some of their bugs, but in priciple, the behaviour will NOT be changed in IE since they say it's not a bug but a feature...

 

3. Some MSIE versions will show (and sometimes even download) the WEB PAGE as suggested filename. Instead of the actual file.

 

4. On secure connections, MSIE will NOT accept files that have the "Pragma: no-cache" flag set (which is usually done). They state their browser IS caching (which is true: think of 'Temporary Internet Files') so they SHOULD NOT cache if the server says so. Unfortunately, that makes some versions also to NOT ALLOW SAVING.

 

So we have to find a way to stay as close to all relevant RFCs and other standards but still somehow circumvent this behaviour.

 

Entelite and I tested a lot, and as a result, I should suggest the following change in '/catalog/download.php' (which hopefully makes it's way into the base...):

 

In 'download.php', find this part:

// Now send the file with header() magic
?header("Expires: Mon, 26 Nov 1962 00:00:00 GMT");
?header("Last-Modified: " . gmdate("D,d M Y H:i:s") . " GMT");
?header("Cache-Control: no-cache, must-revalidate");
?header("Pragma: no-cache");
?header("Content-Type: Application/octet-stream");
?header("Content-disposition: attachment; filename=" . $downloads['orders_products_filename']);

 

and modify to:

// Now send the file with even more header() magic;-)
?// Date in the past
?header("Expires: Mon, 26 Nov 1962 00:00:00 GMT");
?// always modified
?header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
?// HTTP/1.1
?header("Cache-Control: private, no-store, must-revalidate, max-age=0");
?header("Cache-Control: post-check=0, pre-check=0", false); // false=don't overwrite but add header
?// HTTP/1.0
?// header("Pragma: no-cache");
?header("Pragma: "); // for stupid IE+SSL problem (IE thinks it mustn't save on SSL if no-cache is set)
?// Content stuff
?header("Content-Length: " . filesize(DIR_FS_DOWNLOAD . $downloads['orders_products_filename']));
?header("Content-Type: application/octet-stream");
?header("Content-Disposition: attachment; filename=\"" . $downloads['orders_products_filename'] . "\"");

 

This will show filesize for the browsers, allowing them to show progress, and it is also most compatible with modern HTTP/1.1 systems, EXCEPT for the "Pragma: " (nothing but a blank). I'm still checking if it would be better to use "Pragma: public" instead but wouldn't want that for other reasons.

 

Please be VERY EXACT when making this patch as some IE versions even choke on things like 'Content-Type' not spelled Upper-Lowercase...

 

DON'T leave the "Pragma" directive out, because PHP might already have generated a "Pragma" header, so you want to overwrite that!

 

Modern systems would read the HTTP/1.1 Cache-Control and behave as intended (not caching, not storing but allowing a private cache on the target system). It appears that HTTP/1.0 caching systems don't stumble over this, but of course this might have to be investigated further.

 

We have tested this variant with...

 

File types:

ZIP

EXE

PDF

 

Servers:

Apache ? / Debian Linux ? / PHP ?

Apache 1.3.27 / SuSe Linux 2.4.21-260 / PHP 4.3.1

Apache 1.3.31 / Windows/XP-SP1 / PHP 4.3.9

 

Browsers:

Opera 7.54

MSIE 6.0.2800.1106.xpsp2.030422-1633 (what a number)

FireFox 1.0

Netscape 7.2

 

...and it ran smoothly.

 

Of course, we cannot test against each and every combination, so it would be nice if those of you who implement this change would jot down their test results in this form (name and versions)...

 

Webserver

OS

PHP

Browser

 

Offered "open/save" dialog (y/n)?

Showed correct filename (y/n)? — If NO: What did it show instead?

Showed correct filetype (y/n)? — If NO: What did it show?

Showed correct filesize (y/n)?

Suggested correct filename.ext for "save" (y/n)? — If no: What instead?

Displayed progress bar (y/n)?

Did it suddenly "hang" during download (y/n)?

Was the downloaded file the SIZE that it stated (y/n)?

Did the downloaded file have the correct CONTENT (y/n)?

 

...and append your results here in this thread. Thanks!

 

I'd be also very interested in behaviour of these browsers:

Netscape 4.79 (any platform)

Konqueror (Linux)

Safari (Mac)

MSIE (Mac)

 

Thank you for helping all of us making the "downloadable goods business" a better experience for our customers! (And having less complaints ourselves ;)

 

Matthias

I don't want to set the world on fire—I just want to start a flame in your heart.

 

osCommerce Contributions:

Class cc_show() v1.0 – Show Credit Cards, Gateways

More Product Weight v1.0

Link to comment
Share on other sites

Thanks for this update to the download.php. I've been struggling with customer emails over this one, a certain percentage simply can't get the file. I'm hoping this solves it. I've tested it on OSX and it worked as desired on both Safari and Mozilla (and so did the old download.php):

 

Apache 1.x web server

Mac OSX 10.3.7

PHP 4.3

Safari 1.2.4 and Mozilla 1.0

 

Offered "open/save" dialog (y/n)? Safari (no), Mozilla (yes)

Showed correct filename (y/n)? Safari (yes), Mozilla (yes)

Showed correct filetype (y/n)? Safari (yes), Mozilla (yes)

Showed correct filesize (y/n)? Too fast to tell.

Suggested correct filename.ext for "save" (y/n)? Safari (n/a), Mozilla (yes)

Displayed progress bar (y/n)? Too fast to tell.

Did it suddenly "hang" during download (y/n)? No

Was the downloaded file the SIZE that it stated (y/n)? Yes

Did the downloaded file have the correct CONTENT (y/n)? Yes

 

Thanks,

Ryan

Link to comment
Share on other sites

Thanks for this update to the download.php. I've been struggling with customer emails over this one, a certain percentage simply can't get the file. I'm hoping this solves it. I've tested it on OSX and it worked as desired on both Safari and Mozilla (and so did the old download.php):

 

Apache 1.x web server

Mac OSX 10.3.7

PHP 4.3

Safari 1.2.4 and Mozilla 1.0

 

Offered "open/save" dialog (y/n)? Safari (no), Mozilla (yes)

Showed correct filename (y/n)? Safari (yes), Mozilla (yes)

Showed correct filetype (y/n)? Safari (yes), Mozilla (yes)

Showed correct filesize (y/n)? Too fast to tell.

Suggested correct filename.ext for "save" (y/n)? Safari (n/a), Mozilla (yes)

Displayed progress bar (y/n)? Too fast to tell.

Did it suddenly "hang" during download (y/n)? No

Was the downloaded file the SIZE that it stated (y/n)? Yes

Did the downloaded file have the correct CONTENT (y/n)? Yes

 

Thanks,

Ryan

 

 

I'm not sure if this is related to your problem, however, there is an issue with MS S/W as well as 2checkout not authorizing. See my FAQ at

http://www.flowhelp.com/webstore/download_faq.html for details.

Hope this helps.

DHansen

Link to comment
Share on other sites

  • 5 months later...

i have no problems with downloads with IE and one of my customers all they do is sell downloads. both to mac, windows and linux boxes

Link to comment
Share on other sites

  • 2 months later...
i have no problems with downloads with IE and one of my customers all they do is sell downloads. both to mac, windows and linux boxes

 

 

I sell MP3 and FLAC files as downloads. The files are organised by album with both MP3 and FLAC files in the same folder.

I can download MP3 files of 11MB

I cannot download FLAC files of 15MB Error 500

I cannot download an MP3 of 23MB Error 500

 

I have the following code to download in chunks

CODE

// We could also loop with fread($fp, 4096) to save memory or we could use the following ammemdment

$chunksize = 32 * 1024;

$buffer = '';

$handle = fopen(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'], 'rb');

if ($handle === false) { echo 'ERROR...'; die; }

while (!feof($handle)) {

$buffer = fread($handle, $chunksize);

echo $buffer;

}

fclose($handle);

}

?>

CODE END

 

What could be causing it to fail between 11MB and 15MB?

 

Strange.....Any ideas anyone

 

Steve

Link to comment
Share on other sites

After further testing I find I can download small FLAC files, so the suffix or the attributes are not an issue. I was convinced that downloading in chunks would solve the size issue but that would appear not to to be the case.

 

Any suggestions?

 

Steve

Link to comment
Share on other sites

After further testing I find I can download small FLAC files, so the suffix or the attributes are not an issue. I was convinced that downloading in chunks would solve the size issue but that would appear not to to be the case.

 

Any suggestions?

 

Steve

More testing. I can download files of any size via either the http or the https address of a test flac file from a page with html links to that flac file.

 

Does this mean that the php is causing the problem when it comes to a certain size?

 

Any light on the matter anyone?

 

Steve

Link to comment
Share on other sites

More customer feedback...Safari on a Mac doesn'y work, no link appears

I have found that although the link appears on the checkout_success page, IE thinks the file is called "download" with no suffix.

 

Why doesn't the whole world use Firefox?

 

More light on my problem with FLAC files and the recurring 500 ERROR

 

I can, using a stripped down download.php, download both MP3 and FLAC files of any size.

 

It would seem that somehow the session info for FLAC files is being lost, even though the FLAC file hyperlink appears on the checkout_success page in the same way as an MP3 file does

 

Weird

 

And to cap it all off my ISP won't give me the path to the error logs

 

Think I'll take the dog for a walk

 

Steve

Link to comment
Share on other sites

  • 1 month later...
I sell MP3 and FLAC files as downloads. The files are organised by album with both MP3 and FLAC files in the same folder.

I can download MP3 files of 11MB

I cannot download FLAC files of 15MB Error 500

I cannot download an MP3 of 23MB Error 500

 

I have the following code to download in chunks

CODE

// We could also loop with fread($fp, 4096) to save memory or we could use the following ammemdment

$chunksize = 32 * 1024;

$buffer = '';

$handle = fopen(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'], 'rb');

if ($handle === false) { echo 'ERROR...'; die; }

while (!feof($handle)) {

$buffer = fread($handle, $chunksize);

echo $buffer;

}

fclose($handle);

}

?>

CODE END

 

What could be causing it to fail between 11MB and 15MB?

 

Strange.....Any ideas anyone

 

Steve

 

 

 

 

Hi,

 

Thank you for your code.

Befor I added your code the max. download filesize has been ca. 1.900 kb !

I normally use only MP3 files 3 / 5 MB zip and it works fine now.

After I added your script I tried 34.247 kb zip file, and it worked fine too with this conditions.

 

I added:

 

header("Content-type: application/x-zip-compressed");

header("Content-type: application/zip-compressed");

header("Content-type: application/x-zip");

header("Content-type: application/zip");

 

In PHP.ini I changed this three conditions:

 

max_execution_time = 30 changed to 60

max_input_time = 60 changed to 120

upload_max_filesize = 2M changed to 16 M

 

 

and I changed this.

 

// We could also loop with fread($fp, 4096) to save memory

// readfile(DIR_FS_DOWNLOAD . $downloads['orders_products_filename']);

 

$chunksize = 32 * 1024;

$buffer = '';

$handle = fopen(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'], 'rb');

if ($handle === false) { echo 'ERROR...'; die; }

while (!feof($handle)) {

$buffer = fread($handle, $chunksize);

echo $buffer;

}

fclose($handle);

}

?>

 

Everything works fine.

 

Thank you again.

Butch of Berlin

Link to comment
Share on other sites

And if you have all of your osC admin behind https and you try to download a backup of your database you'd have had the same problem, for the same reason.

 

In admin/backup.php, fine this code:

 

header('Content-type: application/x-octet-stream');

header('Content-disposition: attachment; filename=' . $backup_file);

 

and put this line inbetween them:

 

header("Pragma: ");

 

Vger

Link to comment
Share on other sites

Thanks for this update to the download.php. I've been struggling with customer emails over this one, a certain percentage simply can't get the file. I'm hoping this solves it. I've tested it on OSX and it worked as desired on both Safari and Mozilla (and so did the old download.php):

 

Apache 1.x web server

Mac OSX 10.3.7

PHP 4.3

Safari 1.2.4 and Mozilla 1.0

 

Offered "open/save" dialog (y/n)? Safari (no), Mozilla (yes)

Showed correct filename (y/n)? Safari (yes), Mozilla (yes)

Showed correct filetype (y/n)? Safari (yes), Mozilla (yes)

Showed correct filesize (y/n)? Too fast to tell.

Suggested correct filename.ext for "save" (y/n)? Safari (n/a), Mozilla (yes)

Displayed progress bar (y/n)? Too fast to tell.

Did it suddenly "hang" during download (y/n)? No

Was the downloaded file the SIZE that it stated (y/n)? Yes

Did the downloaded file have the correct CONTENT (y/n)? Yes

 

Thanks,

Ryan

 

Hi, I am trying to get my download working. Can you past your download.php that I could see the full example and how do I run that dowload test for different browsers.

 

 

Mant thanks in advance

Link to comment
Share on other sites

Hi, I am trying to get my download working. Can you past your download.php that I could see the full example and how do I run that dowload test for different browsers.

Mant thanks in advance

<?php

/*

$Id: download.php,v 1.9 2003/02/13 03:01:48 hpdl Exp $

 

osCommerce, Open Source E-Commerce Solutions

http://www.oscommerce.com

 

Copyright © 2003 osCommerce

 

Released under the GNU General Public License

*/

 

include('includes/application_top.php');

 

if (!tep_session_is_registered('customer_id')) die;

 

// Check download.php was called with proper GET parameters

if ((isset($HTTP_GET_VARS['order']) && !is_numeric($HTTP_GET_VARS['order'])) || (isset($HTTP_GET_VARS['id']) && !is_numeric($HTTP_GET_VARS['id'])) ) {

die;

}

 

// Check that order_id, customer_id and filename match

$downloads_query = tep_db_query("select date_format(o.date_purchased, '%Y-%m-%d') as date_purchased_day, opd.download_maxdays, opd.download_count, opd.download_maxdays, opd.orders_products_filename from " . TABLE_ORDERS . " o, " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " opd where o.customers_id = '" . $customer_id . "' and o.orders_id = '" . (int)$HTTP_GET_VARS['order'] . "' and o.orders_id = opd.orders_id and opd.orders_products_download_id = '" . (int)$HTTP_GET_VARS['id'] . "' and opd.orders_products_filename != ''");

if (!tep_db_num_rows($downloads_query)) die;

$downloads = tep_db_fetch_array($downloads_query);

 

// MySQL 3.22 does not have INTERVAL

list($dt_year, $dt_month, $dt_day) = explode('-', $downloads['date_purchased_day']);

$download_timestamp = mktime(23, 59, 59, $dt_month, $dt_day + $downloads['download_maxdays'], $dt_year);

 

// Die if time expired (maxdays = 0 means no time limit)

if (($downloads['download_maxdays'] != 0) && ($download_timestamp <= time())) die;

// Die if remaining count is <=0

if ($downloads['download_count'] <= 0) die;

// Die if file is not there

if (!file_exists(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'])) die;

 

// Now decrement counter

tep_db_query("update " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " set download_count = download_count-1 where orders_products_download_id = '" . (int)$HTTP_GET_VARS['id'] . "'");

 

// Returns a random name, 16 to 20 characters long

// There are more than 10^28 combinations

// The directory is "hidden", i.e. starts with '.'

function tep_random_name()

{

$letters = 'abcdefghijklmnopqrstuvwxyz';

$dirname = '.';

$length = floor(tep_rand(16,20));

for ($i = 1; $i <= $length; $i++) {

$q = floor(tep_rand(1,26));

$dirname .= $letters[$q];

}

return $dirname;

}

 

// Unlinks all subdirectories and files in $dir

// Works only on one subdir level, will not recurse

function tep_unlink_temp_dir($dir)

{

$h1 = opendir($dir);

while ($subdir = readdir($h1)) {

// Ignore non directories

if (!is_dir($dir . $subdir)) continue;

// Ignore . and .. and CVS

if ($subdir == '.' || $subdir == '..' || $subdir == 'CVS') continue;

// Loop and unlink files in subdirectory

$h2 = opendir($dir . $subdir);

while ($file = readdir($h2)) {

if ($file == '.' || $file == '..') continue;

@unlink($dir . $subdir . '/' . $file);

}

closedir($h2);

@rmdir($dir . $subdir);

}

closedir($h1);

}

 

// Now send the file with header() magic

 

$dl_name = $downloads['orders_products_filename'];

 

header("Pragma: public");

 

header("Cache-Control: no-store, no-cache, must-revalidate");

header("Cache-Control: post-check=0, pre-check=0", false);

header('Content-Transfer-Encoding: none');

 

header("Expires: Mon, 26 Nov 1962 00:00:00 GMT");

header("Last-Modified: " . gmdate("D,d M Y H:i:s") . " GMT");

header('Content-Type: application/octet-stream; name="' . $dl_name . '"');

header('Content-Disposition: attachment; filename="' . $dl_name . '"');

header("Content-Length: " . filesize(DIR_FS_DOWNLOAD . $dl_name));

 

if (DOWNLOAD_BY_REDIRECT == 'true') {

// This will work only on Unix/Linux hosts

 

 

 

 

tep_unlink_temp_dir(DIR_FS_DOWNLOAD_PUBLIC);

$tempdir = tep_random_name();

umask(0000);

mkdir(DIR_FS_DOWNLOAD_PUBLIC . $tempdir, 0777);

symlink(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'], DIR_FS_DOWNLOAD_PUBLIC . $tempdir . '/' . $downloads['orders_products_filename']);

tep_redirect(DIR_WS_DOWNLOAD_PUBLIC . $tempdir . '/' . $downloads['orders_products_filename']);

} else {

// This will work on all systems, but will need considerable resources

// We could also loop with fread($fp, 4096) to save memory

$chunksize = 32 * 1024;

$buffer = '';

$handle = fopen(DIR_FS_DOWNLOAD . $downloads['orders_products_filename'], 'rb');

if ($handle === false) { echo 'ERROR...'; die; }

while (!feof($handle)) {

$buffer = fread($handle, $chunksize);

echo $buffer;

}

fclose($handle);

}

?>

 

To run the test, just open the catalog up in the dufferent OS and browser combinations and report back the results when you try and download

 

Steve

Link to comment
Share on other sites

  • 7 months later...

I'm going to say 'bless you child' for doing the trouble-shooting. It took me 12 pages before I found this post..but it has been found and it IS fixed now.

 

THANK YOU, THANK YOU, THANK YOU!!

 

Gonna add some more search terms: download with IE not working, IE quirk, https IE no download, no file download with SSL.

 

Claire

Link to comment
Share on other sites

  • 5 years later...

Thank you!!!!! Your code example, specifically the one below, fixed all of the errors I was having. This thread was my lifesaver.

 

$dl_name = $downloads['orders_products_filename'];

 

header("Pragma: public");

 

header("Cache-Control: no-store, no-cache, must-revalidate");

header("Cache-Control: post-check=0, pre-check=0", false);

header('Content-Transfer-Encoding: none');

 

header("Expires: Mon, 26 Nov 1962 00:00:00 GMT");

header("Last-Modified: " . gmdate("D,d M Y H:i:s") . " GMT");

header('Content-Type: application/octet-stream; name="' . $dl_name . '"');

header('Content-Disposition: attachment; filename="' . $dl_name . '"');

header("Content-Length: " . filesize(DIR_FS_DOWNLOAD . $dl_name));

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...