In brief, what is different about a virtual directory that is also set as a Web Application? I can have a virtual directory, and then optionally set it to be a Web Application. Beyond updating the metabase, what does IIS do that causes the virtual directory to "be" a Web application? And how is the runtime behavior or capabilities different between a virtual directory that is not also a Web application, and one that is a Web application?
Is there anything different (in terms of runtime behavior or capabilities) between a Web Application defined on a Web Site root virtual directory, as compared to a Web Application additionally defined on a virtual directory beneath a Web Site root virtual directory (i.e., a "web application within a web application")?
This is an often asked question and point of confusion. I will clarify the terms from an IIS perspective.
What's in a Name?
The generic terms "web application", "virtual directory", "virtual server", and "web site" are inconsistently defined between servers/applications/platforms, so you have to understand the term's meaning in each server/application/platform and translate appropriately. In fact, even Microsoft products do not standardize on a common meaning for those terms, and due to historical legacy of each product, they will likely never change, converge, nor standardize. Sigh.
For example, a Sharepoint "Virtual Server" is the same as an IIS "Web Site" and not to be confused with Microsoft's "Virtual Server" virtualization platform, which hosts virtual machines - who themselves can end up hosting Sharepoint Virtual Servers aka IIS Web Sites. Confused yet? Good. 🙂
IIS's terminology does not include the term "Virtual Server". When most people talk about "Virtual Server" they are often thinking of an IIS Web Site, or something that answers HTTP requests to host their logical website, which consists of a single application codebase.
An IIS Web Site is a mapping between a <IP:Port:Hostname> Binding triplet and a "root" Web Application (defined shortly) that responds to "/". The Web Site is how IIS figures out whether it should handle any given HTTP request and if so, with what configuration. Since this determination directly affects how a HTTP request is handled, all Binding definitions MUST be unique on a IIS machine. You do not want two Web Sites potentially fighting over the same request, right? Now, the Binding triplet is different than the "Friendly Name", which is an optional string meant for User's identification benefit. It can be "Default Web Site" or anything else, and since it is optional and not used for request handling determination, it can be duplicate or not defined.
For example, suppose you have the following Web Sites with the following Binding triplets. This is what each means:
- :80: - across all IPs of all NICs, handle port 80 traffic, regardless of Host header
- 126.96.36.199:443 - only requests to IP 188.8.131.52 on port 443
- :80:Domain2.com - across all IPs of all NICs, handle port 80 traffic for requests with Host header of Domain2.com
With this configuration, when IIS receives any request, it knows from TCP/IP which IP:Port the request is meant for, and if the data is unencrypted, it can decipher the Host: header, and with these three pieces of information, it can determine if it matches any Web Site's Binding definition (or none) and route/handle accordingly. If it matches nothing, a "400 Bad Request" response is returned.
SSL Host Header (sidetrack)
At this point, I will briefly digress on another topic, SSL Host Headers.
Technically, there is no such thing as SSL Host Header. From the perspective of the SSL Specification, host headers do not exist because they are defined in the HTTP specification and not TCP where SSL operates.
When IIS receives any request, it only knows the IP:Port that request is destined for. In order to determine the Host header of a request, IIS must decipher the request's payload data. And to do that for an SSL request, IIS has to first decrypt the payload data by using a Server Certificate to complete the SSL handshake with the Client. However, IIS needs to know the Host header in order to know which Binding, and hence which Server Certificate, to use to decrypt the payload data and decipher the Host header. This is clearly a Catch-22.
So, how does IIS implement "SSL Host Headers"? It breaks the Catch-22 by requiring all sites using SSL Host Headers for a given Binding must be configured to use the same Server Certificate. That way, when IIS gets a IP:Port of a request, it can unambiguously use that now-synchronized Server Certificate to first decrypt the Host: header, and THEN decide which Web Site matches the IP:Port:Host Binding and route the request to it.
A Web Application is a mapping between a name in the virtual namespace (i.e. the URLs "/", "/App", or "/cgi-bin") and its runtime properties. These runtime properties tell IIS how to execute a request which belongs in the virtual namespace. Common runtime properties include:
- Whether user's application code is to be executed "In Process", "Out of Process", or "Pooled" [for IIS 4/5/5.1/6 in IIS5 Compatibility Mode] or specific Application Pood ID [for IIS6 in Worker Process Isolation Mode and IIS7]
- Process Identity used to execute program code
- Monitoring/Recycling Metrics
By default, whenever you create a Web Site and define the Binding (and optionally the Friendly Name), IIS also creates a "root" Web Application for "/" and asks you for a Virtual Directory mapping (defined shortly). This is because people commonly create a Web Site to host a Web Application which consists of files located at same physical directory, so defining all three features make sense... but the three concepts are definitely different.
A Virtual Directory is a mapping between a name in the virtual namespace (i.e. the URLs "/", "/App", or "/cgi-bin") and a corresponding physical name (i.e. the Filesystem name "C:\inetpub\wwwroot\App"). It allows IIS to calculate a physical resource name for any given virtual name and provide it to the handler of the request.
For example, suppose "/" maps to the physical name "C:\inetpub\wwwroot". A request for "/default.asp" refers to the physical name "C:\inetpub\wwwroot\default.asp".
The astute reader should realize that the mapping provided by a Virtual Directory is merely a "recommendation" by IIS to the request's handler - the actual handler of a request can do whatever mapping it wants with the virtual and physical names provided.
In the case of /default.asp, IIS first goes through this process to figure out the handler. Suppose it ends up being ASP.DLL - it will honor the physical name C:\inetpub\wwwroot\default.asp and execute the script contained within it to generate a response.
However, the handler or its script code can choose to implement its own name mapping scheme to process a given request. For example, some people write ASP pages like "redir.asp" which return different responses based on template HTML stored within a SQL database depending on the querystring. i.e. /redir.asp?id=1 will load up some template HTML in SQL and generate a HTML response. Clearly, Virtual Directory is only a hint/recommendation provided by IIS to the request handler, which can do whatever it wants with the information.
Given the above information, the answers to your questions are straight forward.
A plain Virtual Directory provides a virtual/physical name mapping and MUST inherit and use the runtime settings defined at its nearest parent to execute code contained within it.
A Virtual Directory that is also a Web Application has the option to inherit from its nearest parent AND customize runtime settings to execute code contained within it.
Clearly, if you do not customize runtime settings, then it is not necessary to create a Web Application. And if you create a Web Application and customize runtime settings, then behavior of code execution may be different than a plain Virtual Directory (assuming that the inherited settings by the Virtual Directory do not match the customized settings of the Web Application).
As for differences between a "root" Web Application and a nested Web Application within another Web Application or Virtual Directory. IIS does not treat them differently since Web Applications are just runtime settings. However, application platforms running on top of IIS may choose to interpret the "application root" of an Web Application differently and behave accordingly. For example, ASP.Net uses "Web Application" to delimit the boundaries of its applications, so if you nest a Web Application within another, you end up with two different ASP.Net Web Applications.