That one took me quite a while to understand. I’ve been building the integration tests for OpenRasta, a bunch of classes that configure a full web-server and run a real request-response scenario. This should hopefully help in limiting regressions, and may also be used in the future to ensure continuous compatibility with IIS6 on plain .net 2.0.
I’m leveraging the kernel http support present since Windows XP SP2 to create an http listener dynamically and initializing the asp.net runtime inside it, though the very useful HttpListener class.
After a lot of debugging, I discovered that my test was failing because of an encoding issue. Instead of returning the content that was sent to it by OpenRasta, an 18 bytes string, I ended up with much more than that, with line breaks in the middle. A quick look at the returned headers and it became very obvious that the system was sending me back chunked-encoding, a process by which the data is sent in blocks, each prefixed with the size, and suffixed with entity headers. The thing is, there is no support at all yet in OpenRasta for chunked encoding.
Here is the block of code causing all thesetroubles.
public void ProcessRequest(HttpContext context)
IRastaContext rastaContext = RastaConfiguration.GetService<IRastaContext>();
context.Response.Flush(); // <!-- see that one?
As you can see, I was calling Flush on the HttpResponse object in the IHttpHandler that runs the OpenRasta pipeline. I quite understand the reasoning behind switching transparently to chunked encoding when requesting a data flush, you want to clear the data queue by sending it to the client, but you do not know yet how much data you will send later. At that point, using Content-Length is not possible, and chunked encoding is the only way to achieve the desired result.
Looking at the msdn documentation for HttpResponse.Flush you will notice there is no mention of that behavior. But not to worry, other developers thought it may come handy to document, and you will find the following on the mono documentation.
HttpResponse by default will buffer all of the output before it is sent to the client. To control the delivery of the data developers can use this method (or alternatively set the HttpResponse.Buffer property to false).
If chunked transfers are enabled for this response, this will try to use the chunked transfer.
Elementary, my dear Watson.