views:

833

answers:

2

If you use an WebHandler inheriting IHttpAsyncHandler, you shouldn't notice that under undetermined specific circumstances the browser MS IE6 won't display it, the request will never finish. Is there a fix for it?

+3  A: 

I'll answer it myself, but i took 3 days to solve it when I first met this problem.

When the image is requested through the "src" property of an "img" HTML tag, in certain conditions the browser MS IE6 needs the Content-Length to finish the request and display the result.

Synchronous ASHX generated images, automatically includes the "Content-Length" HTTP header, but the Asynchronous version does not. So when you are writing the output, write it first to an Memory Stream, read the total length, write it as an HTTP header, and then write the Memory Stream to the output.

Like this:

using (Image resizedImage = generateImage())
{
 using (MemoryStream memoryStream = new MemoryStream())
 {
  resizedImage.Save(memoryStream, ImageFormat.Jpeg);
  context.Response.AddHeader("Content-Length", memoryStream.Length.ToString());
  memoryStream.WriteTo(context.Response.OutputStream);
 }
}

I have tcpdumped both the Synchronous and the Asynchronous versions of my code and I noticed 2 more differences between them:

1) The asynchronous handler divides the answer in 3 TCP packets, instead of a single one.

2) The synchronous version uses a different "Keep-Alive" header (I can't remember which one)

Jader Dias
+1  A: 

The HTTP spec outlines how a client should determine the length of a request (in particular when content-length is not used). IIRC if the content length header is not present, and the response is not chunked, then the end of the request is detected by when the connection is closed (which might indicate why the keep-alive behavior was changed- you can't use keep-alive if the connection lifetime is used to indicate request length). I would expect ASP.NET to take care of this automatically though. Perhaps there is some call you are missing that tells ASP.NET that the response is complete.

It seems that generating the entire content so you can add the content-length header before going async defeats the purpose of using an async HttpHandler in the first place.

Frank Schwieterman
No, I'm not generating the entire content before going async. The header is only generated after the callback.
Jader Dias
just an fyi, the spec is at http://www.ietf.org/rfc/rfc2616.txt you're interested in section 4.4
Frank Schwieterman