coldbox, tomcat, and SES urls

Hello,

I know this topic has come up before, but I can't find a definitive
answer anywhere. I would like to use Apache, Tomcat 6, Coldfusion 9,
and Coldbox 3.0 for my application, and I want to use SES urls. The
problem comes when trying to proxy a request from Apache to tomcat
that looks like /index.cfm/handler/function -- because that is not a
real file or path.

I've seen a solution that involves some new rewrite rules, and
extension of the SES interceptor, but I couldn't ever get that to
work, and CB3.0 seems ever more different. Will Coldbox ever
officially support this method?

In the Coldbox book (written for 2.6.3), Luis comments that it should
be easy to overcome the tomcat (or jetty or...) limitiation by
creating a servlet mapping for index.cfm. Has anyone used this? I'm
not an expert on servlets or tomcat -- can anyone provide more details
on this implementation?

I can't be the only person to want to use SES urls on a non-jrun
implementation. How are you all doing it?

Thanks,
Scott

Here is some info for you. This is not coldbox related but server setup related.
Tomcat/Jetty and other by the book servelt containers do not allow the full SES mappings, so you have to do a little more. There are several posts out there that can show you how to do it. Here are some guides

http://tech.tjandrawibawa.org/blog/2009/11/06/railo-on-apache-tomcat-windows-part-3-getting-url-rewriting-works-for-coldbox/

The easiest approach you can do is open the tomcat web.xml and add the servlet mapping for this: index.cfm/*

Then you can proxy results from apache to tomcat using this approach.

Read this also:
http://forums.coldboxframework.com/index.cfm?event=ehMessages.dspMessages&threadid=9D95C883-FF65-CEF6-655A32868AE05487

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

You can easily configure Tomcat to process /index.cfm/* as a URL so it
handles these SES URLs. I'm working on a large ColdBox app right now
that uses SES URLs throughout, running on Tomcat.

Thanks Sean and Luis. I now have a servlet-mapping setup. Is there something I need to do to get CF to interpret the pages? If I hit the actual file path, cfml is interpreted, but if I use the servlet mapping, the code itself is returned as plain text.

Thanks again,
Scott

Show us your servlet-mapping - sounds like you haven't got it set up right.

My application is under webapps/ROOT

I added my servlet mapping after the standard one:

default / default /index.cfm/*

Thanks,
Scott

OK, I saw your servlet-mapping and it looked fine.

When you say "If I hit the actual file path, cfml is interpreted, but
if I use the servlet mapping, the code itself is returned as plain
text.", could you be more specific?

What URLs *exactly* are you hitting?

Without the servlet-mapping, you'd just get a file not found error from Tomcat.

Perhaps your Apache setup is not correct?

Hi Sean,

I created a file called test.cfm that lives in the root. It merely dumps the value now().

When I hit http://localhost:8080/test.cfm, I get a timestamp, e.g.

{ts ‘2010-04-26 11:17:00’}

When I hit http://localhost:8080/index.cfm/test.cfm, I get code returned in plain text:

All of this is hitting tomcat directly. I get the same results if I proxy from Apache.

I’ve tried putting the servlet-mapping definition in tomcat/conf/web.xml and also in WEB-INF/web.xml. The results are the same.

Thanks,
Scott

Well, /index.cfm/test.cfm doesn't make sense as a URL. I'm not even
sure what it would try to run... maybe /index.cfm with the string
"/test.cfm" in CGI.PATH_INFO? Or maybe it would look for a directory
called "index.cfm" in the web root and try to run test.cfm inside
that?

At this point, without access to your server - or a lot more
information from you - it's really hard to say what might be
misconfigured (but it's definitely a misconfiguration since SES URLs
work just fine on Tomcat for a variety of frameworks).

Well, /index.cfm/test.cfm doesn’t make sense as a URL.

Isn’t that the point of this discussion? I thought that the servlet mapping was to ‘trick’ tomcat into thinking that was a valid url?

At this point, without access to your server - or a lot more
information from you - it’s really hard to say what might be
misconfigured (but it’s definitely a misconfiguration since SES URLs
work just fine on Tomcat for a variety of frameworks).

I’m not sure where to go from here - this wasn’t supposed to be difficult. I have tomcat, straight out of the box, with an added servlet mapping in tomcat/conf/web.xml (should I delete any existing mappings?). The code all lives under the ROOT webapp (other folders in webapps have been deleted).

In apache, i’m using mod_ajp to proxy requests to tomcat using modified Coldbox .htaccess rules:

#Images, css, javascript and docs, add your own extensions if needed.
RewriteCond %{REQUEST_URI} .(bmp|gif|jpe?g|png|css|js|txt|pdf|doc|xls|xml|ico|php|asp|htm|html|xml|swf)$
RewriteRule ^(.*)$ - [NC,L]

#The ColdBox index.cfm/{path_info} rules.
RewriteRule ^$ index.cfm [QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ajp://localhost:8009/index.cfm%{REQUEST_URI} [P,L] #this is the only modified line

I’m sure I’m missing something brutally obvious. I appreciate your patience.

Thanks,
Scott

The search engine friendly urls that the servlet mapping are designed
for are of the form /index.cfm/article/bob-the-builder which would
invoke index.cfm and then pass article and bob-the-builder as url
parameters to index.cfm. Your inclusion of test.cfm seems to be
telling the app server something like, "go find test.cfm and then pass
it to index.cfm", basically requesting two pages. The difference is
that in my example, it is not looking for any particular coldfusion
page besides index.cfm but rather sending the rest of the url request
in as a set of parameters.

Hope that clarifies things.

Judah

Well, /index.cfm/test.cfm doesn't make sense as a URL.

Isn't that the point of this discussion? I thought that the servlet mapping
was to 'trick' tomcat into thinking that was a valid url?

Your URL has two filenames in it. It is not a sensible URL.

    RewriteCond %\{REQUEST\_FILENAME\} \!\-f
    RewriteCond %\{REQUEST\_FILENAME\} \!\-d
    RewriteRule ^\(\.\*\)$ ajp://localhost:8009/index\.cfm%\{REQUEST\_URI\}

[P,L] #this is the only modified line

This will rewrite /index.cfm/test.cfm to /index.cfm/index.cfm/test.cfm
which is probably not what you want.

Here's the RewriteRules that I use with ColdBox:

ProxyPreserveHost On
ProxyPassReverse / ajp://localhost:8009/

RewriteEngine On
# handle static assets without rewrite:
RewriteRule ^.*\.(bmp|gif|htc|jpe?g|ico|png|css|js|txt|pdf|doc|xls|xml)$ - [L]
# pass site root request thru directly:
RewriteRule ^/?$ ajp://localhost:8009/ [P,L]
# pass test and build requests thru directly:
RewriteRule ^/(core|mxunit|tests|railo-context)/(.*)$
ajp://localhost:8009/$1/$2 [P,L]
# pass all .cfm / .cfc requests thru:
RewriteRule ^/(.*\.cf[cm].*)$ ajp://localhost:8009/$1 [P,L]
# pass all others thru as assumed routes:
RewriteRule ^/(.*)$ ajp://localhost:8009/index.cfm/$1 [P,L]

Running thru the 5 rules:
1. Apache handles status assets
2. Pass default top-level URL direct to Tomcat (and ColdBox)
3. Pass certain directories thru unchanged (these are not ColdBox
apps, just regular CFML)
4. Pass any .cfm / .cfc requests thru unchanged
5. Prepend index.cfm to other requests and pass to Tomcat

With these rules, your URL is passed to ColdBox and the route is
/test.cfm (so ColdBox will fail to find a matching handler unless you
have an explicit route mapping /test.cfm to a ColdBox event).

Make sense?

Thanks, everyone, for your input. I wanted to let you know that I resolved the issue. The problem was that my servlet mapping pointed to the default servlet, not the CF servlet. I also had to move the servlet mapping to my WEB-INF/web.xml file instead of the tomcat/conf/web.xml

Thanks again.
Scott

This helped me greatly. Thank you for the post.

I am using the Railo4 Beta, with the latest Coldbox and ContentBox as of this writing, along with Apache 2.4.3. Everything everwhere that I read said to use AJP like so:

# Mod_jk settings JkWorkersFile conf/workers.properties JkMount /*.cfm default JkLogFile "E:/Logs/Apache/mod_jk.log" JkLogLevel error

But combined with the rewrite rules packaged with Coldbox/Contentbox, they simply do not work. Once I used your ruleset, I was able to move through much better!

Thanks for taking the time to put the info up.

  • CP/WB