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.