Wednesday, November 18, 2009

Webmachine 1.5: virtual host dispatching

We recently tagged and pushed the webmachine-1.5 release, which has a number of minor bugfixes and one major new feature: resource dispatching on Host as well as on URL. There was a healthy discussion on the webmachine mailing list about this, and I think that the compromise solution that was created is a good one. The description from the changeset is quite good documentation of the new feature in my opinion.

dispatch rules can now take two different forms:

The old form: {PathMatchSpec, Module, Paramters}
The new form: {HostMatchSpec, [{PathMatchSpec, Module, Parameters}]}

The former is equivalent to the latter with HostMatchSpec={['*'],'*'}

HostMatchSpec is matched against one of (in order of preference):
X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Server, Host

HostMatchSpec can have two forms:
{[HostPart], PortSpec}
The latter is equivalent to the former with PortSpec='*'

The list of host parts is matched against the hostname extracted from
a header in much the same way that PathMatchSpec is matched against
the path.


{[], root_resource, [x]}.
{['*'], [{[], root_resource, [x]}]}.
{{['*'],'*'}, [{[], root_resource, [x]}]}.
Will each match the root path of any host.

{["example","com"], [{[], root_resource, [x]},
{["static"], static_resource, [y]}]}.
Will dispatch the root of to root_resource and to static_resource.

{['*',"example","com"], [{[], root_resource, [x]},
{["static"], static_resource, [y]}]}.
Will do the same as above, but also for any subdomains of

{{[host,"local"], 8000}, [{[], res_A, [x]}]}.
{{[host,"local"], 8001}, [{[], res_B, [x]}]}.
Will dispatch requests to ?.local:8000/ to res_A and requests
to ?.local:8001/ to resB, binding the host part immediately
preceding ".local" to 'host', such that
wrq:get_path_info(host, ReqData) would return the matched string.

Some notable features of this approach include complete backward compatibility (allowing new host-specific rules to be added to old URL-only dispatch lists without rewriting the entire list) and bringing the same simple pattern-matching style of dispatch to the host portion of the problem.

You may also be interested to see a new site for Webmachine at

That site is currently just a different structure on the documents from the bitbucket wiki, but it is likely to grow over time.

As of this release, we are doing away with private development branches by default, and expect to work against the bitbucket tip by default. Making that same change for Riak has certainly paid off, and we hope that with Webmachine it will also allow people to more easily get involved and work against the active codebase.