Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File downloads in IE6

I've come across a rather interesing (and frustrating) problem with IE6. We are serving up some server generated pdfs and then simply setting headers in PHP to force a browser download of the file. Works fine and all, except in IE6 but only if the windows user account is set to standard user (ie. not administrator).

Since this is for a corporate environment, of course all their accounts are setup this way. Weird thing is, that in the download dialog, the Content-Type is not recognized:

header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );
header( 'Cache-Control: public' );
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/pdf' );
header( 'Content-Disposition: attachment; filename="xxx.pdf"' );
header( 'Content-Transfer-Encoding: binary' );
echo $content;
exit;

I also tried writing the file content to a temporary file first so I could also set the Content-Length in the header but that didn't help.

like image 289
Jan Gorman Avatar asked Jan 24 '23 03:01

Jan Gorman


1 Answers

These headers are bogus!

Content-Transfer-Encoding: binary

This header is copied from e-mail headers. It doesn't apply to HTTP simply because HTTP doesn't have any other mode of transfer than binary. Setting it makes as much sense as setting X-Bits-Per-Byte: 8.

Cache-control: pre-check=0, post-check=0

These non-standard values define when IE should check whether cached content is still fresh. 0 is the default, so setting it to 0 is waste of time. These directives apply only to cacheable content, and Expires:0 and must-revalidate hint that you wanted to make it non-cacheable.

Content-Description: File Transfer

This is another e-mail copycat. By design this header doesn't affect download in any way. It's just informative free-form text. It's technically as useful as X-Hi-Mom: I'm sending you a file! header.

header( 'Cache-Control: must-revalidate, pre-check=0, post-check=0' );
header( 'Cache-Control: public' );

In PHP second line completely overwrites the first one. You seem to be stabbing in the dark.

What really makes a difference

Content-Disposition: attachment

You don't have to insert filename there (you can use mod_rewrite or index.php/fakefilename.doc trick – it gives much better support for special characters and works in browsers that ignore the optional Content-Disposition header).

In IE it makes difference whether file is in cache or not ("Open" doens't work for non-cacheable files), and whether user has plug-in that claims to support type of file that IE detects.

To disable cache you only need Cache-control:no-cache (without 20 extra fake headers), and to make file cacheable you don't have to send anything.

NB: PHP has horrible misfeature called session.cache_limiter which hopelessly screws up HTTP headers unlesss you set it to none.

ini_set('session.cache_limiter','none'); // tell PHP to stop screwing up HTTP
like image 81
Kornel Avatar answered Jan 28 '23 11:01

Kornel