Hack 60 Run Other Web Servers

figs/expert.gif figs/hack60.gif

Here's how to run another web server, in addition to IIS, on the same machine without conflict over who gets port 80.

Ever have problems when you try to run more than web server on the same machine? Or have you run some other web-enabled software together with IIS, only to find that one or both of them break? The problem here is socket pooling, a feature of IIS 5 and later that causes IIS to bind to all IP addresses configured on the server, even on a multihomed machine with more than one network card. The funny thing is that socket pooling even binds IIS to IP addresses that aren't yet assigned to any web site on the machine?even if there's no Default Web Site configured to respond to All Unassigned IP addresses by default. This behavior not only prevents other HTTP software from coexisting with IIS, but it can also cause IIS to return errors to clients. A workaround that sometimes works is to set the HTTP port number for the other software to something nonstandard, such as 8099, but that won't work in most cases unless clients using that software also use that port to connect. By default, however, IIS won't let any other application listen on port 80 (the standard HTTP port), even if it's listening on an IP address that is not used by IIS.

Disabling Socket Pooling in IIS 5

Socket pooling is enabled on IIS 5, by default, but it can be disabled to allow other HTTP-enabled third-party software to run side-by-side with IIS, each responding to requests sent to different IP addresses. There are two ways to do disable socket pooling in IIS 5. First, you can edit the metabase by using the MetaEdit utility [Hack #54]. By default, the setting for socket pooling is defined in the metabase schema, but you can use MetaEdit to create a new metabase key called DisableSocketPooling in the location /LM/W3SVC and assign it the value of true (1). In other words, the default value for DisableSocketPooling in the schema is false (0), which means it is false to say socket pooling is enabled. Don't you love those double negatives?

The other way to disable socket pooling is to use the adsutil.vbs script included in C:\Inetpub\adminscripts [Hack #59]. Type the following command:

cscript C:\Inetpub\adminscripts\adsutil.vbs set w3svc/disablesocketpooling true

You should see the response DisableSocketPooling: (BOOLEAN) True. Now, stop IIS services by typing net stop iisadmin /y (which also stops the dependent WWW Publishing Services). Then, restart them by typing net start w3svc (which also starts the parent IIS Admin Service). Socket pooling is now disabled. If you like, you can use MetaEdit to verify that the key has been added.

Disabling Socket Pooling in IIS 6

The DisableSocketPooling metabase key is also valid in IIS 6 but, interestingly enough, changing it from 0 to 1 doesn't do anything. That's because socket-pooling functionality has been moved from the Winsock HTTP listener used in IIS 5 to the new kernel mode HTTP driver (http.sys). As a result, you have to use a nifty little utility called Httpcfg.exe to disable it.

This utility is found in the /Support/Tools folder on your Windows Server 2003 product CD, so begin by inserting this CD and double-clicking on /Support/Tools/SUPTOOLS.MSI to install these tools on your server. Next, open a command prompt and type httpcfg set iplisten -i w.x.y.z:n to add IP address w.x.y.z and port number n to the IP inclusion list for http.sys. This inclusion list specifies which IP addresses http.sys listens on and is initially empty by default, which means that IIS listens to all IP addresses (not none, as you might suspect). However, once you add an IP address and port number (i.e., a socket) to the inclusion list, http.sys will now listen only on the specified socket and ignore all others, leaving them available for other applications to listen on. You can add as many sockets to the inclusion list as you choose, and you can display a list of listening sockets at any time by typing httpcfg query iplisten at a command prompt.

Don't forget to restart IIS after modifying the list, because http.sys reads this list only on startup. You don't have to restart all IIS services, only the HTTP Service (a subcomponent of the WWW Publishing Services and a service not displayed in the Services console). To restart the HTTP Service, type net stop http /y to stop it and net start w3svc to start it. Note that if you have problems afterwards starting any web sites on your IIS machine, you probably forgot to add their IP addresses to the inclusion list.

Other Reasons to Disable Socket Pooling

If running third-party HTTP software together with IIS isn't your cup of tea, there are other reasons why you might want to disable socket pooling. The bandwidth-throttling feature of IIS that is configured through Internet Services Manager throttles bandwidth to all web sites running on IIS equally. The same is true of the performance-tuning settings configured through the GUI. If you prefer to configure these settings on a per-site basis, you have to disable socket pooling before it will work. This is not obvious from the GUI, which presents separate throttling and performance options for each site. The fact that these features don't work as advertised has been an open secret among the IIS community for a long time. They work only when socket pooling is disabled, and it's enabled by default.