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 http://server/vdir
  2. Server executes http://server/vdir and finds no application mappings. The folder exists, so a courtesy 302 redirection to http://server/vdir/ is sent and this finishes this request processing.
  3. Client follows the 302 redirection and makes another request to http://server/vdir/
  4. Server executes http://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 http://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

Comments (26)

  1. Hugh says:

    Could you comment more on the IIS 6 authentication process? I know that by the time ASP.NET receives a work item in its queue that IIS has already authenticated the user and leaves that token as a part of the queue item.

    Is this authentication and static file handling all handled by Iisw3adm.dll and its subordinates?

  2. David Wang says:

    Hugh – can you describe what information you are looking for?

    To me, explanation of the authentication process has no relations to your current question, so I do not know what you are asking about.

    And please be clear between authentication and authorization.

    //David

  3. Hugh says:

    David:

    When I refer to authentication I mean only that. I don’t think I mentioned authorization in my question.

    My confusion is about the sequence of events from the time an HTTP request is received by http.sys until it is handed off to an application pool’s w3wp.exe worker process (if at all).

    Question One, who does the authentication; the kernel-mode driver or the user-mode worker process? I’m assuming the driver because of its apparent ability to serve static and cached content without loading w3wp.exe.

    Question Two, what is the interprocess bridge between these two?

    Thanks,

    Hugh

  4. David Wang says:

    Hugh – for broad details, I suggest that you read the IIS6 Architecture Section on MSDN:

    http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/843df643-1dbb-4fb6-910d-ec1965fa9e43.mspx

    Downloadable version:

    http://www.microsoft.com/downloads/details.aspx?displaylang=en&familyid=80A1B6E6-829E-49B7-8C02-333D9C148E69

    A1: Authentication is done by user mode. IIS does not cache authenticated requests to static files. See this blog entry on how kernel response caching works.

    http://blogs.msdn.com/david.wang/archive/2005/07/07/HOWTO_Use_Kernel_Response_Cache_with_IIS_6.aspx

    A2: None. Kernel mode is not a "process" and you cannot have "interprocess bridge" without two processes

    I really cannot help with any more information because I still do not understand what you are looking for.

    //David

  5. John says:

    Your request processing sequence indicates a wildcard application mapping would be able to signal IIS that it isn’t going to handle a request, leaving IIS to continue down it’s list.

    The question I have is, if I’m using an HttpModule in .NET 2.0 as a wildcard processor, how can I get it to signal that it isn’t going to handle a request? I want this module to be activated for every file request (existing or not) but there are certain extensions (like .gif or .cs) that I’d like it to bail out on and pass back to IIS to serve.

    Do you know what method or property I can set to reject certain requests?

    Thanks!

  6. DenisV says:

    Is it possible to handle virtaul directory (via VirtualPathProvider) with IIS 6? When i used IIS 5.1 everything was ok, but now with IIS 6.0 i can handle only virtual files, but not directories.

  7. David.Wang says:

    DenisV – No reason why it should not work; depends on how you configured IIS to capture those requests into ASP.Net.

    //David

  8. DenisV says:

    IIS 5.1: In order to handle virtual directory i add new extenson .* and set aspnet_isapi.dll as a handler (MyWebSite -> Properties->Home Directory->Configuration).

    IIS 6.0: It is impossible to do the same (i get error message: wrong extension), so i use wildcard application mecahnism with same handler aspnet_isapi.dll. My application can handle virtual files, but not directories.

  9. David.Wang says:

    DenisV – IIS6 supports multiple wildcard application mappings per URL; IIS5/5.1 only supports one per URL. This is why the UI changed (using .* extension is really a hack you don’t want to use), to allow you to specify multiple wildcard application mappings.

    It sounds like you have "Check if File Exists" checked. Uncheck that. If you have ASP.Net path validation, make sure it is not interfering.

    Otherwise, please detail the exact URL that is working and not working, at what URL node did you make the Application mapping change, and what non-default ISAPI Filters, wildcard application mappings, and HttpHandler/HttpModule you are using. Also ASP.Net version.

    I suspect it was not working the way you imagined before; thus you did not recreate the conditions.

    //David

  10. DenisV says:

    Of course i had option "Check if File Exists" uncheked. .NET Framework version 2.0.50727.42. I use only default ISAPI filters.

    Detailed situaton:

    I have xml with virtual folders (let it be VirFolder1 and VirFolder2). Each folder has some files. Request http://localhost/VirFolder1/<anyVirtualfile>.aspx”>http://localhost/VirFolder1/<anyVirtualfile>.aspx is ok. But http://localhost/VirFolder1/ returns 404 HttpException.  Moreover, my C# code in Virtual Path Provider didn’t run.

    Now i decide to check RawUrl in Application_BeginRequest. If this is virtual directory then Response.Redirect(<default page for virtual folder>).

    Thanks for help David.

  11. David.Wang says:

    DenisV – sounds like by-design behavior to me. Depending on ASP.Net configuration, proper "/" resolution can be short-circuited by the wildcard application mapping.

    http://blogs.msdn.com/david.wang/archive/2005/10/15/Why_Wildcard_application_mapping_can_disable_Default_Document_resolution.aspx

    Doesn’t matter if it worked on IIS5.1; child URL execution and *-scriptmap was a hack on IIS5/5.1 with several flaws and some arbitrary behaviors that people have depended on. We replaced child URL execution in IIS6 to support many other desirable behaviors that unfortunately required loss of some of those arbitrary behaviors… but since they weren’t detailed before, these changes are by-design.

    //David

  12. Edmund.C says:

    Hi I currently have a IIS 6.0 webserver that is running 350+ websites but for some reason.. after hitting the 300+ mark, the responses of the websites becomes very sluggish and I do not know why and what could be doing this.

    I have check/investigated the processes on the server and there are no activity for each individual application pool that each website is on.

    Is this a request/respond issue with IIS 6.0? or is there something I can do to tweak it so that websites can respond quicker?

    Any type of a reply from you is most appreciated thanks.

    -> Edmund <-

  13. David Wang says:

    I finally have enough blog entries about various portions of IIS6 request processing that I can stitch…

  14. marco says:

    i hope you can help me. i have tomcat isapi_redirect.dll as isapi filter.

    i have some *.exe in my cgi-dir with basic authentication. when i access the .exe via IE it authenticates me and displays the html output propertly.

    i have a jakarta redirect filter isapi_redirect.dll under the jakarta virtual directory. it also has basic authentication. the web service extension jakarta has a green arrow up which means the tomcat redirect is working.

    but when i tried to input valid user and password (same user and password i used in authenticating cgi-dir), it continuously prompts me for user/password until it returns authentication failure.

    if i set the jakarta /isapi_redirect.dll to anonymous authentication it works.

    what have i done wrong? please help me, i want to make the authentication work on jakarta.

  15. icewalker3d@yahoo.com says:

    i hope you can help me. i have tomcat isapi_redirect.dll as isapi filter.

    i have some *.exe in my cgi-dir with basic authentication. when i access the .exe via IE it authenticates me and displays the html output propertly.

    i have a jakarta redirect filter isapi_redirect.dll under the jakarta virtual directory. it also has basic authentication. the web service extension jakarta has a green arrow up which means the tomcat redirect is working.

    but when i tried to input valid user and password (same user and password i used in authenticating cgi-dir), it continuously prompts me for user/password until it returns authentication failure.

    if i set the jakarta /isapi_redirect.dll to anonymous authentication it works.

    what have i done wrong? please help me, i want to make the authentication work on jakarta.

    icewalker3d@yahoo.com

  16. Rodney says:

    Configuring IIS6 in the context of VS.NET (2003). I can’t find a lot about IIS6 Application Settings and i don’t think you touch on my particular problem in you blog:

    I have a website (www.domain.com) and 3 subfolders/virtual directories virutal1, virtual2, virtual 3. how do i default to http://www.domain.com/virtual1? ie.. when http://www.domain.com is typed, browser goes to http://www.domain.com/virtual com. (There’s not really a need for content at the http://www.domain.com root.)

    I have tried using the redirection settings but to no avail.

    Thanks in advance for any help

  17. Joel says:

    David,

    You never responded to an above question posted by John on January 6

    (http://blogs.msdn.com/david.wang/archive/2005/10/14/HOWTO_IIS_6_Request_Processing_Basics_Part_1.aspx#511422)

    I have more or less the same question.  I’d like to set up a wildcard mapping to an httpmodule, but only have that module handle all files within certain folders within my app and not others.  If the request is, for example, for a .jpg file in some folders, i’d like the httpmodule to proclaim "I am not handling this request" and have it pass to the static file handler.  However, in other folders, I’d like to have the httpmodule handle it and generate a response itself.    I know I could do this by creating virtual directories for the folders I want handled by the httpmodule, but I’d to have it all running as one application (for example to give the httpmodule access to the session state of the app).

    So is there a way for the httpmodule to reject a request and have it pass back to the static file handler?

    Thanks muchly for any advice.

  18. David.Wang says:

    It’s a 10K entry!

    //David

  19. Twinkle says:

    Hi David,

    QUESTION : IIS is logging 200 instead of 404 in IIS log file

    Application : ASP

    IIS version : 6

    I have custom error handle – "error.asp" file, which I use to display a user friedly message.

    For missing files I would like to log 404 in IIS log file. But because I have error.asp file IIS logs it as 200 ok, so I am using:

          response.status = "404 Not Found"

    This works in my Development environment but not in the Test environment.

    In Development environment its logging:

    document=9999 – 401

    document=9999 – 404

    But in Test environment its logging

    document=9999 – 200

    Can you tell me what difference I have in both the IIS because according to me everything looks same?

    Thanks

    Twinkle

  20. Madhu says:

    We have constant deadlocks in IIS (under Windows 2003 Server). Our application involves web service calls. We are in the process of investigating the cause. Is it possible to find out the calls which are causing this deadlock ? We are using the Debugdiag tool currently to check…

    Thanks in advance

  21. Madhu says:

    We have constant deadlocks in IIS (under Windows 2003 Server). Our application involves web service calls. We are in the process of investigating the cause. Is it possible to find out the calls which are causing this deadlock ? We are using the Debugdiag tool currently to check…

    Thanks in advance

  22. David.Wang says:

    Madhu – DebugDiag is able to identify and diagnose deadlocks.

    //David

  23. gopesh says:

    I have one IIS

    2 tomcats

    one application in one tomcat

    one application in another

    i need to redirect to both application from IIS

    both tomcat have seperate redirector dlls,seperate workers2.properties and two entry in registry……….

    jakarta

    and jakarta1 are two virtual directories and 2 websites each refering to each virtual….

    for 1 IIS to tomcat its workin fine… but i want the other one to IIS is to be done…

    any one suggest

  24. John Bailo says:

    I am trying to set up some URL rewrite code on an IIS 6.0 serer (httphander).

    If I set up a virtual directory, with a wild card handler to aspnet_isapi.dll it works fine, with the urlrewriter transforming the URL to variables in aspx.

    However, if I set up the same wildcard application mapping at the root/website level, the wild card handler does not seem to fire and I get a 404 error.

    Any reason why?

  25. Вот именно с этой статьи начинаю читать этот блог. +1 подписчик 🙂

  26. David Kelly says:

    Hi David,

    I am really stuck and have spent hours trying to figure this out. I have IIS6 running in IIS5 isolation mode. I’ve checked and recheked for any application mappings and simply cannot download a zip file.

    Is there a possibility that because I am on the same network that somehow I am being authenticated – i have only anonymouse acces enabled?

    Could isape rewrite be interfering ?

    I’ve tried both .exe and .zip and neither work. I have checked the logs and I have 200 0 0 for http status codes

    I’ve checked and do not have url scan installed (at least as far as I can tell)

    I’m tortured here trying to figure this out – any suggestions/direction would be most appreciated.