Sending file over HttpContext causes browser to hang
-
23-08-2019 - |
Question
I am sending a file to the user using a HttpHandler. On all browsers, after viewing/downloading the file at least once, the browser/application on subsequent views/downloads hangs. Here is the code:
private void TransmitFile(HttpContext context, string filePath, string downloadName, bool forceDownload)
{
if (File.Exists(filePath))
{
string fileName = System.IO.Path.GetFileName(filePath);
string extension = Path.GetExtension(filePath);
FileInfo fileInfo = new FileInfo(filePath);
// set the response info/headers
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
if (forceDownload)
{
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + downloadName.Replace(" ", "_") + extension);
context.Response.BufferOutput = false;
}
string type = "";
// set known types based on file extension
if (extension != null)
{
switch (extension.ToLower())
{
case ".tif":
case ".tiff":
type = "image/tiff";
break;
case ".jpg":
case ".jpeg":
type = "image/jpeg";
break;
case ".gif":
type = "image/gif";
break;
case ".doc":
case ".rtf":
type = "Application/msword";
break;
case "pdf":
type = "Application/pdf";
break;
case "png":
type = "image/png";
break;
case "bmp":
type = "image/bmp";
break;
default:
type = "application/octet-stream";
break;
}
}
context.Response.ContentType = type;
context.Response.TransmitFile(filePath);
context.Response.Flush();
}
else
{
Immersive.Diagnostics.Log.Warn("Requested file does not exist: " + filePath, this);
Immersive.Diagnostics.Log.Warn("", this);
}
}
I have read that calling Response.Close() and Response.End() is not a good idea? Have tried both leaving in, and removing, and it still happens.
EDIT:
It seems that TransmitFile has known issues. A more thorough explanation can be found at: http://www.improve.dk/blog/2008/03/29/response-transmitfile-close-will-kill-your-application
I removed TransmitFile and changed to WriteFile, and it now works perfectly.
context.Response.WriteFile(filePath);
context.Response.Flush();
context.Response.Close();
Solution
This may be a known issue if the server you're downloading from runs Windows Server 2003 SP1.
Here is a hotfix: http://support.microsoft.com/kb/902780
Also, check if you have OutputCache
enabled on the page, if so, try the download again without it.
OTHER TIPS
Any reason you're not using the buffering? You're Flush()ing it even though you aren't using it. And yes, I think you should also do a Response.End() after the Flush().
Let me know if this works and maybe I can run some tests of my own.