Reputation: 11
I have an asp.net web page to serve large file downloads to users. The page is hosted on IIS7, Windows Server 2008.
The strange thing is that users can download at good speeds (2MB/s) when I don't add a content-length response header but as soon as I add this header, download speed drops to somewhere around 35kbps/s.
This is the code:
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/octet-stream";
//speed drops when I add this line:
//Response.AddHeader("Content-Length", new FileInfo(filepath).ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
Response.TransmitFile(filepath);
Response.Flush();
Of course I can leave the content-length out but the user will not know how big the file is and how long the download will take...which is annoying.
Any idea what can cause this big change in download speed?
Thanks in advance for any insights!
Upvotes: 1
Views: 6295
Reputation: 6811
Response.AddHeader("Content-Length", ...) is a catastrophe!
We used .NET 4.0 and experienced plenty of weird & random download corruptions. We narrowed down to a discrepancy of the content length in the response header sent to the client. We don't know why, may be a .NET 4.0 bug? But as soon as we commented out the line of code Response.AddHeader("Content-Length", ...) all issues disappeared.
EDIT: may be discrepancy in content-length is unavoidable when IIS7 Dynamic Compression is enabled.
Upvotes: 0
Reputation: 22006
I've used the following code recently ...
Response.AddHeader("Content-disposition", "attachment; filename=" + attachment.Filename);
Response.AddHeader("Content-length", attachment.Filedata.Length.ToString());
Response.ContentType = attachment.ContentType;
Response.OutputStream.Write(attachment.Filedata.ToArray(), 0, attachment.Filedata.Length);
Response.End();
(my attachments are actually stored in a database table in this case, but it's just writing a byte array to the output stream)
rather than your approach ...
Response.TransmitFile(filepath);
The transfer speed seems pretty good. I've downloaded 3.5MB in a matter of seconds from the live website. (not just locally!)
I know I should be using a HttpHandler rather than hijacking the Response, but this works for now. Also, I should probably read the byte array in chunks to avoid taking up too much memory. I will go back at some point and rework it a little.
So, you could try using Response.OutputStream.Write
or writing a HttpHandler instead.
Anyway, I hope that helps you out.
Upvotes: 1