Monday, August 19, 2013

Understanding virtual host mapping in WebSphere Application Server

Together with the context root, the virtual host assigned to a Web module determines under which URLs that Web module will be accessible. In WebSphere, a virtual host is simply a set of host aliases, where each alias specifies a host name (or a * wildcard to match any host name) and a port number. Configuring virtual hosts is pretty straightforward, but problems may occur if there are multiple virtual host definitions that have overlapping host aliases, i.e. if the same host name/port combination is matched by multiple virtual hosts.

To see why this happens, it is important to understand how virtual host mapping in WebSphere works internally. Each application server maintains a map with the following structure:

{ host alias → { context root → Web module } }

That means that for each host alias, there is a separate map that maps from the context root to the Web module. Entries in these data structures are created (resp. removed) as Web modules are started (resp. stopped). Note that at this point wildcards are not replaced yet.

To illustrate how this works, consider the following sample topology:

  • A WebSphere application cluster with two members running on hosts and and listening on port 9080.
  • A Web server having two host names and and listening on port 80.
  • Two Web modules module1 (with context root /app1) and module2 (with context root /app2) that are expected to answer requests on host names and respectively.

If one further assumes that module1 and module2 should also accept requests sent directly to and (i.e. without going through the Web server), then one would define the following virtual hosts:

  • vhost1 with aliases and *:9080.
  • vhost2 with aliases and *:9080.

module1 would be mapped to vhost1 and module2 would be mapped to vhost2. Both cluster members would then build the following map internally:

AliasContext rootWeb module

The structure of the map described above implies that mapping a request to a Web module is a two-step process. WebSphere will first match the Host header of the incoming request. At this point, wildcards are processed. WebSphere will then use the corresponding { context root → Web module } map to look up the Web module based on the path part of the URL.

In the example shown above, the fact that the same host alias appears in multiple virtual host definition doesn't cause any issue. Any request sent directly to the application servers via port 9080 will be routed correctly to the expected Web module.

Now consider a slightly different virtual host configuration:

  • vhost1 with aliases and *:9080.
  • vhost2 with aliases, and

This will result in the following map:

AliasContext rootWeb module

In this case, things will not work as expected. In fact, requests for will not be routed to module1. As noted earlier, WebSphere will first match the Host header against the host aliases. The value of that header ( matches both *:9080 and, but WebSphere will select the second one because it is more specific than the alias with the wildcard. WebSphere will then look at the { context root → Web module } map for that alias. The problem is that this map now contains a single entry mapping /app2 to module2, i.e. there is no entry matching /app1/index.html.

The conclusion is that when configuring virtual hosts, a problem will occur if one virtual host has an alias of the form host:port and another one has an alias *:port with the same port number.

Tuesday, August 6, 2013

Quote of the day

You say rivers of wine flow in heaven,
is heaven a tavern to you?
You say two huris await each believer there,
is heaven a brothel to you?

Attributed to Omar Khayyám. Retweeted by Fazıl Say.