Why IIS6 can send invalid HTTP Responses

Question:

Hello All,

My client has a IIS 6.0 with some static pages configured in it. My application is a middleware that sits in between the browser client and the IIS 6.0 Web server.

Now, my problem is that IIS 6.0 is always sending Responses without Content-Length , but with Connection: Keep-Alive header set. And to top it all, there is no chunked encoding either. Because of this, my middleware is not able to decide on whether the response is completely sent or not.

Why is this happening in IIS 6.0 ? Can this be patched ? If yes, how ?

Is not that a deviation from standard ? How is this generally handled by other middlewares ?

Any help and clues on this would be appreciated.

Regards

Answer:

Can you give the IIS configuration as well as exact request that triggers this? In particular, the applicable ScriptMap setting for the specific URL, any ISAPI Filters installed globally/per-site, as well as the requested URL + request headers.

It is possible for middleware running on IIS to make it generate such responses.

For static files, IIS static file handler knows and sends the content-length header. So, I suspect that you have something configured on IIS which is altering this behavior - I suspect your pages are not being handled by the IIS static file handler but some other ISAPI.

Response:

Hi Wang,

I am told that the responses, though static, are served by a Servlet engine.

Here is a sample request and its response header.

Would this mean that the ISAPI filter configuration has a problem ?

I am a novice on IIS and i am not sure how it works. Can you give me a sample Script map setting that may do this ?

Since i dont have access to the webserver settings i am not able to get the IIS settings.

I am doubly sure that the middleware (it runs outside the IIS) does not do anything with this since the same response is sent even when we access it directly without the middleware.

 GET /servlet/nbTest HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; DigExt)
Host: 192.168.2.69
Connection: Keep-Alive

HTTP/1.1 200 OK
Date: Tue, 28 Feb 2006 01:05:55 GMT
Server: Microsoft-IIS/6.0
Content-Type: text/html

Thanks

My Response:

I see... now, just to be clear on the terminology, we have:

  • The browser client which makes a request to your middleware client
  • The middleware client makes a request to IIS
  • IIS routes requests to a custom ISAPI DLL configured for the Servlet Engine
  • The custom ISAPI DLL forwards requests to the Servlet Engine middleware and sends the Servlet Engine's responses back to IIS, who sends it back to the [middleware] client

The issue you describe would be with either the custom ISAPI DLL or the Servlet Engine middleware since it generates the response that IIS sends. The issue has nothing to do with IIS other than it mapping the request to/from the custom ISAPI DLL which works with the Servlet Engine middleware.

This is the power and pitfall of ISAPI - while it can control the entire HTTP response as well affect connection status, it can also easily goof things up and generate invalid HTTP responses.

If GET /servlet/nbTest HTTP/1.1 is handled by the IIS Static File Handler, I expect more response headers than what you showed (for example, ETag: , Content-Length: , or Last-Modified: headers). The absence of those response headers tell me that your response was generated by a custom ISAPI DLL and NOT generated by the IIS Static File Handler. This sort of configuration matches up with the typical IIS setup for Servlets and JSP, which include:

  1. Custom ISAPI Filter steals requests to a certain namespace (such as /servlet) from IIS and route it to a custom ISAPI Extension
  2. Custom ISAPI Extension which hijacks the entire request and then uses WinHttp/WinSock/etc to forward the request to the Servlet Engine that is listening on some other port
  3. Custom ISAPI Extension reads the Servlet Engine's output and writes the response back to IIS

Thus, what you observed suggest issues in either

  • The Servlet Engine not generating proper HTTP responses for the given request, or
  • The Custom ISAPI Extension or ISAPI Filter is altering the request/response

In either case, you need to obtain support for those custom ISAPI DLLs or the Servlet Engine since IIS has little involvement other than being configured to invoke those ISAPIs. The Servlet Engine is responsible for generating proper HTTP, and an ISAPI owns generating a proper HTTP response as soon as it usurps control from IIS.

For example, according to RFC 2616 Section 4.4, your response without Content-Length, without Transfer-Encoding and without media type multipart/byteranges would be valid IF the server (i.e. IIS) closes the connection... but since the ISAPI took control of the request, it owns generating a proper HTTP response and/or closing the connection.

//David