HOWTO: IIS 6 Request Processing Basics, Part 1

Alright, I finally got motivated enough by some questions and circumstances to do this brain-dump of IIS6 Request Processing Internals. I will most likely be missing some details here and there so I welcome followup, but I just want to get something down first and worry about completeness later. Else, I would probably never find the time to finish this...

At a high level, IIS performs a very simple task - for every requested URL, determine a handler to "handle" the request and optionally generate a response (though it is highly suggested to generate a response, for the poor web browser's sake...). Along the way, server-side binary code can execute during various phases of request processing as well as be the "handler" of the request.

How IIS Determines the Handler to handle a Request

What I am going to talk about is the "determination of the handler to handle the request" portion. Note: I am ignoring WebDAV and a couple of other complications for the sake of conceptual clarity.

The request processing sequence looks like the following:

  1. Given a URL, IIS determines the actual resource name, extension, and nearest metadata that determines the applicable "ScriptMaps" (i.e. list of resource extension to handler mappings) property for the resource.

  2. IIS checks if any wildcard application mappings are present in ScriptMaps and if so, invokes the first wildcard application mapping in ORDER from the ScriptMaps property.

    Only when the wildcard application mapping returns and tells IIS "I am NOT handling this request" does IIS invoke the next wildcard application mapping... until IIS either goes through all wildcard application mappings or some wildcard application mapping declares "I AM handling this request".

    If no wildcard application mapping handled the request, continue on; else, consider the request handled.

  3. If no wildcard application mappings declared "I am handling this request", then IIS uses the file extension of the resource and looks through the rest of the ScriptMaps property to locate the appropriate application mapping (if one exists).

    If there is a match, then IIS invokes the script engine of the associated application mapping and considers the request handled.

  4. If no application mapping handles the request and the extension is a couple of hard-coded values including .EXE or .DLL, then IIS will invoke the CGI/ISAPI directly and consider the request handled.

  5. If nothing handled the request yet, the built-in IIS Static File Handler will own the request to tie up the loose ends in the following sequence:

    1. First, the resource is checked for validity to determine if a Courtesy 302 Redirection needs to be sent. If a redirection is sent, then the request is considered handled.
    2. If the resource exists as a file, then the file will be sent as the response and the request is considered handled.
    3. If DefaultDoc is enabled, then the list of DefaultDoc names is searched to locate a possible resource. If a resource is located, then do an internal re-execute of the new DefaultDoc URL (i.e. head back up to the very beginning of this list and start processing again) and consider the request handled.
    4. If DirBrowsing is enabled, then generate a directory listing as the response and consider the request handled.
    5. If the request is still unhandled by this point, then generate the 403.14 (directory browsing is denied) custom error response and send it, handling the request.

For the security conscious - when an ISAPI DLL or CGI EXE is invoked, either as the script engine of a normal application mapping or wildcard application mapping, or directly as-is, the "Web Service Extension Restriction List" kicks in to validate that the ISAPI/CGI is enabled. If not enabled, handle with a 404.2 custom error response.

Likewise, when the Static File Handler decides to send an existent file resource, it looks up the MIMEType for the given resource extension. If it fails to match, then handle with a 404.3 custom error response.

The astute reader should realize that the key difference between a wildcard application mapping and a normal application mapping is that a wildcard application mapping can return "I am NOT handling this request" and pass the request along, while normal application mapping MUST handle the request. This distinction is what makes all ISAPI that are NOT written to be a wildcard application mapping UNABLE to function as a proper wildcard application mapping.

The Loaded IIS Request sequence

Let's look at the entire request process sequence as it applies to a juicy courtesy 302 redirection to a default.document static file which has a known MIME Type defined for ".document".

  1. Client makes request to https://server/vdir
  2. Server executes https://server/vdir and finds no application mappings. The folder exists, so a courtesy 302 redirection to https://server/vdir/ is sent and this finishes this request processing.
  3. Client follows the 302 redirection and makes another request to https://server/vdir/
  4. Server executes https://server/vdir/ and finds no application mappings. Since the resource is not a directory nor does that static file exist, DefaultDoc resolves next and IIS finds default.document.
  5. Server re-executes https://server/vdir/default.document internally on the server. No application mappings are found, the Extension has a known MIME Type, and the static file exists, so IIS serves it as a Static File.

There are lots of possibilities to discuss at this point. I will see where people want to take it...

//David