HTTP.SYS, IIS, and the 100 continue

Question:

Hi David,

"My Company" is a leading middleware provider for mobile multiplayer games. Cutsomer like Disney, THQ etc.

The backend is built on .NET. We went live in the US with W2K3/IIS6 which is great.

But we have a major IIS6 issue. The handsets connect through HTTP/POST and sometimes the Server answers with "100 continue" and this leads to crashes on certain phones.

In IIS5 we wrote an ISAPI filter - which works well.

Question:

1) Is IIS6 sending the "100 continue". We assume yes ... (due to file must exist)

2) Will an ISAPI Extension be able to fullfill this?

I would really apprciate your help.

thanks,

Answer:

<soapbox>

Actually, I would frame it differently - this is probably NOT a "major IIS6 issue".

Clients which advertise to be HTTP/1.1 compliant and then crash on "100 continue" are the real problem (they are not following public specifications), and servers that allow such broken clients are also a part of the problem.

Technically, these phones should just keep crashing until the consumer gets sick of it and switches to another phone that works correctly. This is the way to get the phone manufacturers to write/use properly implemented networking protocol stacks - when their customers hit their pocketbooks. As middleware, it should not differ if the consumer uses one phone or another to run your games... as long as the consumer has *A* phone that runs your games.

On the other hand, if the server keeps hacking to work around client-side bugs, the phone manufacturers never get wind of their problems and have ZERO incentive to fix their phones, leading to accumulation of server-side hacks over time that increase server maintenance costs for you.

Thus, it is in your best interest to notify and get phone manufacturers to fix their buggy software.

I understand that business pressures can force you to compromise and otherwise work-around such issues in the spirit of "making things work", but I just want to remind you of the implications of your actions on your long-term interests.

</soapbox>

On Windows Server 2003, it is a cooperation between IIS6 in user mode and HTTP.SYS in kernel mode that drives HTTP request/response serving. Logically speaking:

  • HTTP.SYS picks up data off the network, parses it into HTTP requests, identifies which Application Pool it belongs, and places it into its queue.
  • IIS6 user mode worker process picks up requests from the queue of its Application Pool, processes each by running either a user-supplied ISAPI/CGI or the built-in IIS Static File Handler, and hands the response back to HTTP.SYS to send over the wire.

A "100 continue", like a "400 Bad Request" or a Kernel Response Cache Hit, is special in that HTTP.SYS transparently handles it in kernel mode without notifying user mode of anything. In addition, ISAPI Extensions cannot interact with any response output - they can only generate response output, not see results of response output. Thus, an ISAPI Extension will never be able to interact with requests that generate "100 continue" nor "100 continue" responses themselves to suppress them.

On IIS6, the only way to inject user mode processing into these transparent request handlings of HTTP.SYS is to run in IIS5 Compatibility Mode and use an ReadRawData/SendRawData ISAPI Filter. ReadRawData forces HTTP.SYS to hand the raw data off the network into user mode for filtering PRIOR to parsing that user mode output into HTTP requests to place into queues.

Of course, this method completely defeats the purpose of running IIS6 with Application Pools and process isolation (a single failure in this filtering user mode process halts the entire server)... but such is the server-side compromise when the client is buggy...

FYI: This approach will not work on Vista Server/IIS7. HTTP.SYS will no longer hand raw data off the network into user mode for filtering prior to parsing, so it will be impossible for user mode code to know that a request which triggers the automatic "100 continue" happened.

//David