2

Is it possible to configure IIS 7 so that a single site with multiple bindings (or wildcard bindings) will launch a unique instance for each unique host name?

To explain why this is desirable, we have an application that retrieves its configuration from a remote system. The behaviour of the application is governed by this configuration and not by the 'web.config'. The application uses its host name as a key to retrieve the configuration. Currently it is a manual process to create an identical IIS site for each instance of the application, differing only by the bindings.

My thought, if it were possible, is that it would be nice to have one IIS site that effectively works as a template for an arbitrary number of dynamic sites. Whenever it is accessed by a unique host name a new instance of the site would be launched, and all further requests to that host name would go to that instance just as though I had created the site by hand.

I use IIS regularly, but only for fairly straightforward site hosting. I'd like to know if this could be configured with vanilla IIS 7, but would also welcome answers that require a plugin or 3rd party product.

Programming/architectural suggestions about changes to the app wouldn't really be appropriate for serverfault.

  • It sounds like you're suggesting that IIS create a copy of an entire website in memory on the fly upon first access. Depending on the size of the site, this seems unreasonable at it could take several minutes to copy the data. Can you clarify? – Paul Ackerman Dec 01 '12 at 15:58
  • Hi, thanks for the question. The idea isn't to copy the actual files, only the IIS site definition. All the dynamically created sites would have the same home directory and would differ only by the host name being used. – OlduwanSteve Dec 02 '12 at 20:27
  • 1
    Have you thought about streamlining the manual site creation process? IIS7 fully supports powershell for configuration. You template site could be a script to make this easier. Lots of examples of this if you look. Try http://www.iis.net/learn/manage/powershell/powershell-snap-in-creating-web-sites-web-applications-virtual-directories-and-application-pools – Clayton Dec 03 '12 at 14:29
  • Just personal preference but I think if I do have to create the site myself I'd probably go the managed API route. I can see this would be useful for some though. – OlduwanSteve Dec 03 '12 at 14:54

2 Answers2

1

From my understanding of how IIS works, I would say this is not possible out of the box.

The Windows Process Activation Service WAS sits between http.sys in the kernel and the various worker processes that run the application pools/sites.

Based on the configuration in existing files (ApplicationHost.Config/web.config) it decides where to route an incoming request. It can start an existing ApplicationPool if not already running, but it can not create a new site based on a web request.

You can plug in your own extensions into the request processing pipeline, but I think only as soon as the request has hit your worker process, not before.

You could write your own ServiceHost as a replacement for WAS, but I guess that's not a small task.

I would start using a script to create new instances of your web sites, passing in the variables. You can easily create hundreds of sites for all your different configurations.

If it has to be more dynamic, you could add a feature to your web application that detects that a new site is needed, it would show a 'come back in 30 seconds' page and send a message to a Windows Service to create a new site. The new site should be up in a few seconds and can then answer new requests.

Peter Hahndorf
  • 14,058
  • 3
  • 41
  • 58
  • Thanks, I'm probably going to end up accepting this as the answer as it is kind of what I suspected, I'm just going to wait a day or so and see if anybody else has anything to offer. Meanwhile - your idea about dynamically scripting the site creation sounds like it might have legs. The default site could handle unbound host names and, if appropriate, create a new site during the request. Then it could return a response that in some way caused the browser to refresh immediately. Thanks! – OlduwanSteve Dec 02 '12 at 20:37
1

You have a few options. First, I want to make sure that I understand correctly when you say "The application uses its host name as a key to retrieve the configuration.". By 'host name', do you mean the IIS website name, or the domain name (commonly referred to as the host name)? I assume you mean the IIS website name since you're requesting a unique IIS site for every unique domain name.

URL Rewrite gives a lot of flexibility so that you can override or create server variables at will, so if possible it would certainly make this easier if you can use something besides the IIS site name for the application settings. But ... you did ask not to offering programming/archicturial changes, so I'll come back to answering your question specifically. I just thought I would mention that in case you haven't considered the flexibility that URL Rewrite offers yet.

The way that I would handle what you've requested is to have a site called "Catch-all" which has a wildcard binding for the IP. That site should have a URL Rewrite rule to ensure that all requests, regardless of the URL, access a createsite.aspx page. The createsite.aspx page should take the domain name (Request.ServerVariables("HTTP_HOST")) and have it create the site and point to the shared folder. Use Microsoft.Web.Administration to create the site, and make sure that the app pool for that site has an identity of an administrator on the IIS box. Here's how to create the site (http://blogs.msdn.com/b/carlosag/archive/2006/04/17/microsoftwebadministration.aspx).

When the site is created it should add a host header binding for the new domain name. That way subsequent requests for that domain name will always be caught by the new site rather than the catch-all site. In other words, the catch-all site is only used the first time a particular domain name is used.

Finally, the createsite.aspx page should do a response.redirect back to the original URL, including passing through the full path and querystring. The way the end user will not realize what just happened except for a brief pause and a redirect if they happen to be watching in fiddler.

Scott Forsyth
  • 16,449
  • 3
  • 37
  • 56
  • Hi, thanks for the detail. I'll try to respond to each point in turn. First I did actually mean 'host name'. The application picks this up from the first request and uses it as a key to load its config. The goal is to have one _running_ instance per host name, but every instance is identical from the perspective of IIS. – OlduwanSteve Dec 04 '12 at 22:55
  • I think your point about URL Rewrite was based on the assumption about using website name as config key? – OlduwanSteve Dec 04 '12 at 23:08
  • The last 3 paragraphs are a useful and detailed explanation of how I could set up what I was asking about by doing some programming, which it looks like I'd have to. I think I have to give the answer to Peter Hahndorf though because he was the first to answer the question asked and he did suggest this albeit in less detail. – OlduwanSteve Dec 04 '12 at 23:25
  • @OlduwanSteve. If you're using the host name, why do you need multiple sites? The host name is always available to the site even if multiple visitors using multiple host names share the same site. Wouldn't a single site do the trick? Using a single site would be desirable for many reasons, unless I'm overlooking something. – Scott Forsyth Dec 05 '12 at 18:42
  • I can explain the last 3 paragraphs in more depth, but first I would like to confirm that you indeed need unique sites if they are identical in every way. – Scott Forsyth Dec 05 '12 at 18:43
  • The code is identical for every site, and so are all of the IIS settings, but the behaviour of the code at runtime is governed by settings which are in turn governed by the host name. For instance, the DB connection string is a setting which is configured differently for different host names. There are various legacy design decisions (static classes etc.) that would make it difficult to have these different configurations co-exist in one instance. Thanks for the offer, but the last 3 paragraphs are certainly detailed enough for me. – OlduwanSteve Dec 06 '12 at 20:52
  • I think I understand more now. The 'code' is the same, but you have a unique connection string or configuration file for each instance. If that's the case and you can't easily edit the legacy app to dynamically generate the connection string based on the host name, then the solution to auto-generate the sites may be your best bet. – Scott Forsyth Dec 07 '12 at 14:24
  • I would have a problem with running an Application Pool with administrator rights, that's why I suggest a to use a Windows service to create the new site. – Peter Hahndorf Dec 08 '12 at 09:20
  • If the not-yet-initialized sites are caught with a catch-all site that is devoted to the single purpose of creating the initialized sites, then you have a good secure situation. The new sites that are created would run with minimal permissions and would be locked down properly. – Scott Forsyth Dec 10 '12 at 14:25