Fixing download issues with Internet Explorer 7

By: David Clegg

Abstract: This article outlines an issue discovered with serving CodeCentral downloads to Internet Explorer 7, and details the steps taken to diagnose the problem, and the solution used to overcome it

    The problem

It was reported that there were problems downloading CodeCentral submissions using Internet Explorer 7. This particular issue only occurred if the user entered the download URL directly into the Internet Explorer address bar (for example, http://cc.codegear.com/Download.aspx?id=23610), and not if the download was invoked from the details page for the submission (in this case, http://cc.codegear.com/item/23610). When the download URL was used directly in the address bar, an error dialog was displayed.

Hide image

The problem didn’t occur in other browsers, or in Internet Explorer 7 if a download manager such as Free Download Manager was used.

    Investigating the cause

The first hint of a problem was that the File Download dialog is only presented to the user when the download is initiated from the item submission page. When the download link is entered directly into the address bar, this dialog is not shown.

Hide image

Another telling sign was the difference in the progress dialog shown for each of the download methods used. When using the download link from the submission item page, the name of the file is shown.

Hide image

When the download URL is entered into the address bar, the name of the page serving the download is shown.

Hide image

Using the excellent HTTP debugging tool, Fiddler, I was able to capture the HTTP request and response information exchanged between the browser and the CodeCentral servers.

Here are the request and response headers when invoking the download from the submission page:-

GET /Download.aspx?id=23610 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
application/x-ms-application, application/vnd.ms-xpsdocument,
application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash,
*/*
Referer: http://cc.codegear.com/item/23610
Accept-Language: en-nz
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; 
.NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; FDM; MS-RTC LM 
8; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
Connection: Keep-Alive
Host: cc.codegear.com
Pragma: no-cache

HTTP/1.1 200 OK
Date: Thu, 18 Dec 2008 05:29:38 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Content-Length: 543407
Content-disposition: attachment; filename=23610_pocketcaddy.ZIP
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application\octet-stream

And here are the request and response headers when entering the download link into the address bar:-

GET /Download.aspx?id=23610 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
application/x-ms-application, application/vnd.ms-xpsdocument,
application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash,
*/*
Accept-Language: en-nz
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; 
.NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; FDM; MS-RTC LM 8;
.NET CLR 3.5.30729; .NET CLR 3.0.30618)
Host: cc.codegear.com
Connection: Keep-Alive

HTTP/1.1 200 OK
Date: Thu, 18 Dec 2008 05:37:29 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Content-Length: 543407
Content-disposition: attachment; filename=23610_pocketcaddy.ZIP
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application\octet-stream

The only difference between the two request headers is that the first approach included the Referer: http://cc.codegear.com/item/23610 and Pragma: no-cache headers. Using Fiddler to intercept the request and changing it to ensure the same headers were sent in both cases did not fix the problem, so the issue obviously resided elsewhere. And in both cases, the response headers returned were the same, so that wasn’t the cause either.

    The solution

After discussing the issue with my fellow CDN team members, Jonathan Benedicto referred me to a download link for one of his products. This produced the following request/response headers:-

GET /download.php?product=Components4PHPFree HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
application/x-ms-application, application/vnd.ms-xpsdocument,
application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash,
*/*
Accept-Language: en-nz
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; 
.NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; FDM; MS-RTC LM 8;
.NET CLR 3.5.30729; .NET CLR 3.0.30618)
Host: www.jomitech.com
Connection: Keep-Alive

HTTP/1.1 200 OK
Connection: close
Date: Wed, 17 Dec 2008 22:42:55 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: PHP/5.2.2
Content-type: application/octet-stream
Content-Disposition: attachment; filename=ComponentsForPHPFree101.exe
Content-length: 699729

In addition to the Connection: close header value, the interesting point to note was the absence of the Cache-control, Pragma, and Expires header values. These are inserted by CodeCentral as a result of the following code:-

Response.Cache.SetCacheability(HttpCacheability.NoCache);

This was done to ensure that browsers don’t use caching to return the requested file, ensuring the latest version is always served from CodeCentral, and is one of the recommended techniques for ASP.NET applications to disable caching for a particular page. The headers inserted as a result of using this seemed to match the advice provided in the Microsoft Knowledgebase article discussing how to prevent caching in Internet Explorer.

Further investigation revealed that it was the Cache-control: no-cache response header that was causing the behaviour exhibited in Internet Explorer 7.

The solution was to replace the call setting the cacheability of the page with one that sets the Expires header to a date in the past, which should ensure that the browser always requires that the page response is fetched from the server rather than from its local cache.

Response.AppendHeader('Expires', 'Sun, 17 Dec 1989 07:30:00 GMT');

Server Response from: ETNASC01