<VirtualHost *:80>
ServerName railo.corfield.org
DocumentRoot /Users/scorfield/Sites
ProxyPreserveHost On
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
Instead of using the basic ProxyPass, we're going to use the 'proxy' option of RewriteRule to rewrite just CFML requests as first step. We need to turn the rewrite engine on and then replace the forward proxying directives with a rewrite rule:
ServerName railo.corfield.org
DocumentRoot /Users/scorfield/Sites
ProxyPreserveHost On
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
<VirtualHost *:80>
ServerName railo.corfield.org
DocumentRoot /Users/scorfield/Sites
ProxyPreserveHost On
ProxyPassReverse / ajp://localhost:8009/
RewriteEngine On
RewriteRule ^/(.*\.cf[cm])$ ajp://localhost:8009/$1 [P]
</VirtualHost>
The rewrite rule says: "Match any complete URL that ends in .cfm or .cfc and send it to Tomcat via AJP". The [P] flag means "proxy this request and stop processing rules". Don't forget to restart Apache for the change to take effect:
ServerName railo.corfield.org
DocumentRoot /Users/scorfield/Sites
ProxyPreserveHost On
ProxyPassReverse / ajp://localhost:8009/
RewriteEngine On
RewriteRule ^/(.*\.cf[cm])$ ajp://localhost:8009/$1 [P]
</VirtualHost>
sudo apachectl restart
Now our CFML requests are being processed by Tomcat but everything else is being processed by Apache.
Normally, SES URLs are handled in CFML applications by looking at the CGI variable PATH_INFO and processing that. We can't quite get there but we could arrange for that part of the path to be passed as part of the query string instead. To do that, we add a second rewrite rule that handles URLs where .cfm (or .cfc) is present but not at the end of the URL:
RewriteRule ^/(.*\.cf[cm])(/.*)$ ajp://localhost:8009/$1?path_info=$2&%{QUERY_STRING} [P]
This isn't ideal (because CGI.PATH_INFO does not contain the information we need) but at least we can now get at it via URL.PATH_INFO. You can use any name for the URL variable to avoid possible collisions with your own URL variables (but of course whatever you use in the rewrite rule must match what you use in your code!). Unfortunately, you'll have to modify code that relies on CGI.PATH_INFO to use URL.PATH_INFO instead, e.g., the SES URL processing in Fusebox 5.5 (around line 66 of myFusebox.cfc). It's a pity we cannot set CGI variables in CFML because then we could force CGI.PATH_INFO back to a correct value!
If anyone knows of a better solution, please let me know!

11 responses so far ↓
1 dave // Mar 30, 2009 at 1:33 PM
http://www.deliciouscoding.com/post.cfm?entry=5-railo-on-leopard-setting-up-sites-and-editing-server-files
2 dave // Mar 30, 2009 at 1:42 PM
<servlet>
<servlet-name>FUServlet</servlet-name>
<display-name>FriendlyURLServlet</display-name>
<description>Translates friendly URLs to objects</description>
<servlet-class>com.blueriver.sava.FriendlyURLServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FUServlet</servlet-name>
<url-pattern>/go/*</url-pattern>
</servlet-mapping>
3 Matt Woodward // Mar 31, 2009 at 3:09 PM
Also, once you're proxying you shouldn't need to specify a document root for your virtual hosts ... unless I'm missing something about your configuration. Apache doesn't need to know where the documents are since it's just proxying out to Tomcat anyway.
4 Sean Corfield // Mar 31, 2009 at 3:33 PM
5 Matt Woodward // Mar 31, 2009 at 4:29 PM
6 Damon Gentry // Apr 16, 2009 at 5:24 AM
Craig's post is at:
http://craigkaminsky.blogspot.com/2009/04/mango-blog-on-aptana-cloud-with-railo.html
7 Tony Garcia // Apr 18, 2009 at 7:07 AM
I've been playing around with Tomcat and deployed Railo on it as the ROOT app (as you described in your posts) running a ColdBox app. as you know, ColdBox SES urls take on the form of "index.cfm/handler/action." I found that I could get these form of URLs to work in Tomcat by just adding the following servlet mapping in the app's web.xml file:
<servlet-mapping>
<servlet-name>CFMLServlet</servlet-name>
<url-pattern>/index.cfm/*</url-pattern>
</servlet-mapping>
By doing this, I can still use the cgi.PATH_INFO variable, as well.
8 Sean Corfield // Apr 18, 2009 at 11:26 AM
9 Tom Chiverton // Apr 21, 2009 at 4:03 AM
10 Sean Corfield // Apr 21, 2009 at 7:08 AM
11 Tom Chiverton // Jun 4, 2009 at 11:05 AM
ProxyPreserveHost On
ProxyPassReverse / ajp://localhost:8009/
RewriteEngine On
RewriteRule ^/(.*\.cf[cm])$ ajp://localhost:8009/$1 [P,L]
RewriteRule ^/flashservices/gateway(.*)$ ajp://localhost:8009/flashservices/gateway$1 [P,L]
RewriteRule ^/messagebroker/(.*)$ ajp://localhost:8009/messagebroker/$1 [P,L]
RewriteRule ^/flex2gateway/(.*)$ ajp://localhost:8009/flex2gateway/$1 [P,L]
RewriteRule ^/openamf/gateway/(.*)$ ajp://localhost:8009/openamf/gateway/$1 [P,L]
Leave a Comment