Update - 10/98
An intrepid soul, Jeff Schwartz of myVcard.com, has braved the Microsoft.com 
enforced-registration policy to search their Knowledge Base 
and provide us with proof that MS has known about this bug since March 
and still hasn't fixed it.

Read their explanation in its original form at this URL:
    http://support.microsoft.com/support/kb/articles/q182/3/15.asp
or read the content from our local mirror.

Note that this document suggests some possible work-arounds to 
this bug. HOWEVER, __none__ of those workarounds are useful
for IE 4.01 - MacOS.


Executive summary
There is a well-known method for "forcing" a file download
to the browser (documented below). It works reliably with Netscape's
Navigator browser, but fails with all tested versions of MS Internet
Explorer. 


Discussion
Lots of CGI authors know how to "force" a browser to download
a file. For Navigator, simply issue the following HTTP headers:

  Content-type: text/tab-separated-values; name="somefilename" 
  Content-disposition: filename="somefilename" 
  Content-length: length_in_bytes

Some people say the content-type should be application/octet-stream;
some people say the content-length header is not required. Navigator
seems to work with all variations of this theme; when it receives
the headers, it pops up a file dialog prepopulated with the
name "somefilename" and asks the user where to save the file.

MSIE, on the other hand, fails miserably at this task. This has
been known by the CGI community for a long time; common wisdom
in the comp.infosystems.www.authoring.cgi newsgroup seems to
be "use Navigator if you want to download data files via CGI."

Well, the other night I did some research to figure out why
Microsoft's latest and greatest MacOS browser, 4.01, still 
doesn't know how to download a file in this manner. What I found
is really quite surprising.

I used Peter Lewis' fabulous CGI debugging tool, OTSessionWatcher.
(See http://www.stairways.com/otsessionwatcher/ -- note, MacOS only!)
It captures TCP data streams to show what's going on behind the
scenes. That is, it shows you the data before your browser mangles
it.

First up let's look at a request-and-response using Navigator.
In this example, I'm POSTing a form that results in a data file
being sent back to me (whereupon Navigator saves the file to disk).

  POST /myscript.cgi HTTP/1.0  
  Referer: whatever
  Connection: Keep-Alive  
  User-Agent: Mozilla/4.06 (Macintosh; I; PPC, Nav)  
  Host: whatever
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
  image/png, */*  
  Accept-Encoding: gzip  
  Accept-Language: en  
  Accept-Charset: iso-8859-1,*,utf-8  
  Content-type: application/x-www-form-urlencoded  
  Content-length: 75  
    
  form=variables&are=encodedhere


Now the response... Navigator puts up a file dialog and 
asks where to save the file. The default name is the one
given in the headers, "links.tab".

  HTTP/1.0 200 OK  
  Date: Wed, 09 Sep 1998 03:56:40 GMT  
  Server: someserver/2.3  
  MIME-version: 1.0  
  Content-type: text/tab-separated-values; name="links.tab" 
  Content-disposition: filename="links.tab" 
  Content-length: 619
 
  (the contents of the downloaded file appear here)


Using the same form with MSIE, a very weird thing happens.
First the request, which appears to be OK.

  POST /myscript.cgi HTTP/1.1  
  Host: whatever  
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
  image/xbm, image/x-jg, */*  
  Accept-Language: en  
  Connection: Keep-Alive  
  Referer: whatever 
  User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Mac_PowerPC)  
  UA-OS: MacOS  
  UA-CPU: PPC  
  Content-length: 73  
  Content-type: application/x-www-form-urlencoded  
  Extension: Security/Remote-Passphrase  
    
  form=variables&are=encodedhere


The only difference from Navigator's request is that IE is 
using (or attempting to use) HTTP/1.1 instead of 1.0.

Now for the response. This is where it gets weird.

  HTTP/1.1 100 Continue  

  HTTP/1.1 200 OK  
  Date: Wed, 09 Sep 1998 03:58:40 GMT  
  Server: someserver/2.3  
  MIME-version: 1.0  
  Connection: close  
  Content-type: text/tab-separated-values; name="links.tab" 
  Content-disposition: filename="links.tab" 
  Content-length: 619 
   
  (the file contents we'd like to download appear here)

Bingo. There's the file. Pity IE ignores it and for totally
unknown reasons issues a second, duplicate request.

  POST /myscript.cgi HTTP/1.1  
  Host: whatever
  Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
  image/xbm, image/x-jg, */*  
  Accept-Language: en  
  Connection: Keep-Alive  
  Referer: whatever
  User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Mac_PowerPC)  
  UA-OS: MacOS  
  UA-CPU: PPC  
  Content-length: 73  
  Content-type: application/x-www-form-urlencoded  
  Extension: Security/Remote-Passphrase  
    
  form=variables&are=encodedhere


And now part II of the response ?!

  HTTP/1.1 100 Continue  
    
  HTTP/1.1 200 OK  
  Date: Wed, 09 Sep 1998 03:58:42 GMT  
  Server: someserver/2.3  
  MIME-version: 1.0  
  Connection: close  
  Content-type: text/html 
   
  <HTML><HEAD><TITLE>Error!</TITLE></HEAD> 
  <BODY><DIV ALIGN=CENTER>The file you requested did not 
  exist.</DIV></BODY></HTML> 

In this test, the error message immediately above is what
gets saved to disk. The second request fails because the 
CGI in question is only able to send the requested file out
once. If MSIE was able to not ignore the file the first time
it is received, we wouldn't have a problem -- but due to some
bug in MSIE, whether it's related to keep-alive or some
inability to grok content-type headers other than GIF, JPEG,
and HTML, the browser chokes on this exchange.


Feedback
Comments, corrections, etc., are welcome. Please send all 
feedback to browsers @ sitefoundry . com.