I’m John C Bland II

Husband, Father, Tech Author, Deacon.
Founder ofย Katapult Media, and full-stack polyglot developer.
Political Free Agents Podcast Host.

I create. I launch.

YouTube Channel

I post regular fun on YouTube like me playing the bass and anything else I find fun.ย 

Get Something Built

All project work goes through Katapult Media. Business is open. Let’s chat.

UPDATE
The initial post worked but submitted forms did not. :-/ What’s a web app without form submission? (rhetorical)

So, the configs are updated below and I have tested this locally on Tomcat 7 and on a centOS server w/ Tomcat 6. The issue was with the 2nd to last line and the last. They needed to be swapped. The 2nd to last forces a 301. Swap them…all good! ๐Ÿ˜€

I really need to stop with the long titles but they are so informative! ๐Ÿ˜€

This has been a major pain for me and others, it seems. I think I found a solution and would like to lay it out for you and get feedback to see if it works for others as well.

Setup

Configuration

Initially I tried using mod_jk but it had some problems for me and I was taught the AJP way of doing things. I’m not going to recap all of that mess though. There are plenty of blog posts (here, here and here) detailing different ways to setup AJP in Apache. My config was a portion of multiple blog posts and help from multiple people with a little of my own sauce added. ๐Ÿ™‚

This is the main portion to see. It is the Railo configuration used to proxy the requests to Tomcat.

#RAILO
ProxyPreserveHost On
ProxyPassReverse / ajp://localhost:8009/
 
RewriteEngine On
RewriteRule ^(.+\.cf[cm])(/.*)?$ ajp://localhost:8009$1$2 [P]
 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^(.+/)$ ajp://localhost:8009%{REQUEST_URI}index.cfm [P]
 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule . - [L]
 
RewriteRule ^([a-zA-Z0-9/-]+)$ ajp://localhost:8009/index.cfm%{REQUEST_URI} [NE,P]
 
RewriteRule ^([a-zA-Z0-9/-]+[^/])$ $1/ [R=301,L]

I put this in an external railo.conf file and in my vhost file I include it using:

Include railo.conf

Problem

CFWheels is an amazing piece of software. I use it solely and do not want to touch CF without it. Ok…maybe I’d use FW/1 but that’s where I draw the line on frameworks. ๐Ÿ˜‰ The issue with CFWheels rewriting is it assumes a configuration even after you configure it!! That’s not how it should be but alas…I’m not on the core team. #sigh

Now, all URLs worked with the above config. I could type /forums and it would work perfectly fine. Things go wrong when you click any link generated by linkTo or do a redirectTo, basically anything that calls urlFor. Wheels takes all generated URLs and prepends index.cfm to them all. Why? The official answer was:

“I see your point but if we did that Wheels would create links it couldn’t handle on the receiving end anyway which would be just as bad, if not worse.”
– Per Djurner (source)

I respect the HECK out of Per so this isn’t a knock at all. I’m just outlining the scenario from both sides of this coin.

What’s great is I think I found the solution not requiring any Wheels updates…just a server or .htaccess update, preferably the former.

Solution

Here is the updated railo.conf:

#RAILO
ProxyPreserveHost On
ProxyPassReverse / ajp://localhost:8009/
 
RewriteEngine On
RewriteRule ^(.+\.cf[cm])(/.*)?$ ajp://localhost:8009$1$2 [P]
 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^(.+/)$ ajp://localhost:8009%{REQUEST_URI}rewrite.cfm [P]
 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule . - [L]
 
RewriteRule ^([a-zA-Z0-9/-]+)$ ajp://localhost:8009/rewrite.cfm%{REQUEST_URI} [NE,P]
 
RewriteRule ^([a-zA-Z0-9/-]+[^/])$ $1/ [R=301,L]

Wait, what’s the difference? Notice the 6th and 10th [last] line. They reference rewrite.cfm, not index.cfm. :-/ DUH! How could I have not tried that before?!?!? :-/

The other thing I did was add a reference to rewrite.cfm in Tomcats web.xml, as seen here:

<!-- RAILO -->
<servlet>
	<servlet-name>GlobalCFMLServlet</servlet-name>
	<description>CFML runtime Engine</description>
	<servlet-class>railo.loader.servlet.CFMLServlet</servlet-class>
	<init-param>
		<param-name>configuration</param-name>
		<param-value>/WEB-INF/railo/</param-value>
		<description>Configuraton directory</description>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
	<servlet-name>GlobalAMFServlet</servlet-name>
	<description>AMF Servlet for flash remoting</description>
	<servlet-class>railo.loader.servlet.AMFServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>GlobalCFMLServlet</servlet-name>
	<url-pattern>*.cfm</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>GlobalCFMLServlet</servlet-name>
	<url-pattern>/index.cfm/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>GlobalCFMLServlet</servlet-name>
	<url-pattern>/rewrite.cfm/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>GlobalCFMLServlet</servlet-name>
	<url-pattern>*.cfml</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>GlobalCFMLServlet</servlet-name>
	<url-pattern>*.cfc</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>GlobalAMFServlet</servlet-name>
	<url-pattern>/flashservices/gateway/*</url-pattern>
</servlet-mapping>

Maybe I expect too much of the frameworks I use but Wheels shouldn’t force the index.cfm without providing 100% detailed documentation on how to get around it AND clarifying in the docs setting url rewriting to “on” is ignored when Wheels deems fit. It would help if there was much more clarity if they choose to ignore configuration settings, which is still odd to me.

Request

If you’re experiencing this problem, can you try this update and let me know if it works for you as well? I only tested one site and Tomcat 7. I’d like to know if it works before going hog-wild and pushing to all of my servers.

Thanks in advance and I hope this helps someone else!