Tomcat: Directory Aliases

This is the next in my series of short posts related to configuring Tomcat, as I work on getting a Tomcat/ACF10 development environment stood up next to my existing Apache/JRun/ACF9 application stack. See the first post in the series for a bit of background.

We’ll look here at how to set up directory “aliases” in Tomcat, providing something equivalent to Apache httpd’s Alias and AliasMatch directives. In my current Apache setup, I use several such directives to make shared folders appear as if they were local folders in similar locations across multiple apps. Back in the first post of this series, I touched on our directory structure and how those folders appear within the applications; I’ll summarize that here again:

  • appGroup1
    • common
    • app1a (http://localhost/app1a/)
    • app1b (http://localhost/appab/)
    • app1c (http://localhost/app1c/)
  • appGroup2
    • common
    • app2a (http://localhost/app2a/)
    • app2b (http://localhost/app2b/)
    • app2n (http://localhost/app2n/)
  • app3 (http://localhost/app3/)
  • shared

Within each of the application groups “appGroup1″ and “appGroup2″, the “common” folder contains assets shared by the applications in the corresponding group; this folder is aliased into each of the individual applications within the group to appear as if it were nested below the application folder (e.g., http://localhost/app1a/common, http://localhost/app1b/common). All of the applications reference the “shared” folder as a root level folder “/shared” (i.e., as http://localhost/shared).

One way to implement this in Tomcat is via the aliases attribute of the Context element in file ./cfusion/runtime/conf/server.xml. The server.xml file created as part of installing ACF10 has a Context element within the Host element for “localhost”, but it is commented out (relying on default values for the relevant attributes). Uncomment that element and add the needed aliases. Aliases are specified as a comma-delimited list of a=b pairs, where “a” is a virtual path and “b” is the path to which requests to “a” are to be mapped.

As an example based on our needs above, we need URL requests to /shared to be mapped to directory /[path to]/shared, so the alias for that virtual directory would be specified as /shared=/[path to]/shared.

Per the Tomcat docs, the alias path “a” must start with a leading “/”, and the directory to which it is mapped must be an absolute path (also beginning with a leading “/”). Tomcat then searches for requested resources within the first virtual directory where the specified alias matches the path. For our examples above, then, well need to set up several aliases:

  • /shared=/[path to]/shared
  • /app1a=/[path to]/appGroup1/app1a
  • /app1a/common=/[path to]/appGroup1/common

Aliases analogous to the second and third above, would be set up for each of the applications within each application group. In my playing with this so far, Tomcat doesn’t seem to care which of those second and third entries in the above list comes first, using the most specific alias. Putting all of that together then, we’d end up with something like this:

<Context
   ...
   aliases="/shared=/[path to]/shared,/app1a=/[path to]/appGroup1/app1a,/app1a/common=/[path to]/appGroup1/common"
   ...
   >
   ...
</Context>

Make the needed configuration changes, bounce your server, and throw together a quick file to verify that resources are being retrieved as expected.

A couple final notes on this:

  1. This is a really quick-and-dirty way to include a folder from a user’s home directory as a location Web documents can be retrieved from. Just set up an alias like /~ron=/Users/ron/Sites and you’re there. Note that this doesn’t get you to the point where Java Web apps can be served from home directories; we’ll look into that in another post.
  2. There are other possibly better ways to accomplish this same end result (e.g.,. with a separate Context for each application). We’ll look into some of that in a future post, as well.

Tomcat: Default Web Document List

This is the sixth in my series of short posts covering the different aspects of setting up a development environment based on Tomcat and Adobe’s ColdFusion 10 application server stack. For background on this, see the initial post in the series.

The list of default documents the server will provide is specified in ./cfusion/runtime/conf/web.xml and then replaced (if specified) in the ./WEB-INF/web.xml file within each defined context. As all of the ColdFusion configuration is handled at the context level, it makes sense to make this particular change also at the context level. Find the welcome-file-list element toward the end of file ./cfusion/wwwroot/WEB-INF/web.xml and add the needed entries:

<welcome-file-list ...>
   <welcome-file>index.shtm</welcome-file>
   <welcome-file>index.cfm</welcome-file>
   <welcome-file>index.html</welcome-file>
   <welcome-file>index.htm</welcome-file>
   ...
</welcome-file-list>

Note that order does matter here: the first file found from the list will be served up when the request does not specify the file name. As shown above, we’ll look for index.shtm (which necessitates enabling SSI to function), then index.cfm, then static HTML pages index.html and index.htm. This sequence is specific to how our applications are configured; adjust accordingly per your own configuration needs.

Make the needed changes and restart the server.

Tomcat: Enabling SSI

This is the fifth in my series detailing my efforts to stand up a Tomcat/ACF10 development environment next to my existing Apache/JRun/ACF9 stack. For background, see the first post in the series.

Enabling Tomcat’s ability to process server-side includes (SSI) requires changes to two configuration files. File ./cfusion/runtime/conf/web.xml contains definitions for both a filter and a servlet for processing SSI’s, as well as a pair of corresponding servlet-mapping and filter-mapping definitions for filenames matching the *.shtml pattern. Uncomment either the filter or the servlet element (but not both), and the corresponding -mapping element. Modify the -mapping element based on the naming conventions you use and/or add additional -mapping elements, as needed.

If you decide to go the filter route on this, you should also note that the default web.xml file’s definition of the filter determines whether to run files through the SSI processing based on the MIME-type of the file. You will almost certainly have to also uncomment, and possibly supplement, the entry/entries in the MIME-type mappings in the same file.

The second file that requires a tweak, per the Tomcat SSI How-To, is ./cfusion/runtime/conf/server.xml. As noted in the docs, only contexts configured as “privileged” can use the SSI capabilities. Add the privileged="true" attribute to Context element for the ColdFusion context:

<Context
   path="/"
   docBase="/Applications/ColdFusion10/cfusion/wwwroot"
   ...
   privileged="true"
>
...
</Context>

Throw together a quick test SSI file, bounce your server, and verify that it works.

I clearly have some additional homework to do on this one, as I dont yet understand the benefits and drawbacks of the filter-vs-servlet choice above. More to come on that.

Tomcat: Restricting Access by IP

This is the fourth in my series detailing my efforts to stand up a Tomcat/ACF10 development environment next to my existing Apache/JRun/ACF9 stack. For background, see the first post in the series.

A couple items have struck me in wading around in the Tomcat docs and configuration files: the flexibility and power of Tomcat, along with the fact that there are often multiple ways to do quite a few things when it comes to configuring Tomcat. Restricting access to applications and content available via Tomcat is no exception: there are at least three ways to accomplish this. For now, primarily in the interest of getting our dev environment up and running as quickly as we can, we’ll take the simplest approach. As with access logging, we’ll configure a valve within ./cfusion/runtime/conf/server.xml. This valve will restrict access to only requests coming from the localhost:

<Host name="localhost" ... >
   ...
   <Valve
      className="org.apache.catalina.valves.RemoteAddrValve"
      allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1"
   />
   ...
</Host>

See the docs for details on this valve, but it is very straightforward: just a regex identifying the IP addresses to be allowed. Requests from any addresses not listed in the allow attribute will be blocked.

Clearly, you’d not place such a restriction on a production box, but in a dev environment I typically do not want to allow access to other boxes under normal circumstances. You’ll note that this is an all-or-nothing approach; in reality, it is more likely that we will want to at least open access to specific folders for specific addresses occasionally. This approach won’t provide that flexibility but we will return to this topic for another approach later in this series.

Make the change shown above, bounce your server, and verify that access from other systems on your network are no longer able to access pages/apps on your dev box.