Coldbox and Url Rewriting with Tomcat

Hi everyone

I’m porting an application from CommondBox + Undertow to Tomcat 8.5.

I have a problem with Url Rewriting: Tomcat appears to behave differently than Undertow.

While with Undertow it works flawlessly, under Tomcat I always get a 404 error.

tomcat-sesurl

I have created a small application for isolating and debug the problem (In my main application I have multiple Coldboxes inside “apps” directory). If you need it, I can let you download it.

This is structure:

I configure urlrewrite.xml like this:


<rule>
    <condition type="request-uri" operator="notequal">/(index.cfm[...]).*</condition>
    <condition type="request-filename" operator="notdir"/>
    <condition type="request-filename" operator="notfile"/>
    <from>^/manager/(.+)$</from>
    <to type="passthrough">/apps/manager/index.cfm/$1</to>
</rule>

I added this to my /WEB-INF/web.xml for Tomcat:

  <filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    <init-param>
      <param-name>logLevel</param-name>
      <param-value>DEBUG</param-value>
    </init-param>
    <init-param>
      <param-name>confReloadCheckInterval</param-name>
      <param-value>1</param-value>
    </init-param>
    <init-param>
      <param-name>confPath</param-name>
      <param-value>/config/urlrewrite.xml</param-value>
    </init-param>
  </filter>
  
  <filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

All rewritten urls work, except for Coldbox: I’ve got little rule for prevent cache assets that works like a charm.

In log file i see that the filter is correctly applied:

[...] org.tuckey.web.filters.urlrewrite.RuleBase DEBUG: conditions match
[...] org.tuckey.web.filters.urlrewrite.substitution.MatcherReplacer DEBUG: found 1
[...] org.tuckey.web.filters.urlrewrite.substitution.MatcherReplacer DEBUG: replaced sb is /apps/manager/index.cfm/user/new
[...] org.tuckey.web.filters.urlrewrite.RuleExecutionOutput DEBUG: needs to be forwarded to /apps/manager/index.cfm/user/new

Any idea?

OS: Windows
Java Version: Java 8
Tomcat Version: Tomcat 8.5
Lucee Version: 5.3.8.201

I solved this momentarily, but so I cannot use the Router.cfc

<rule>
    <from>^/manager/(.*)/(.*)</from>
    <to type="passthrough" qsappend="true">/apps/manager/index.cfm?event=$1.$2</to>
</rule>

Tomcat 8.5 was end of main support in Q3 - 2016
Unless you have been keeping up the patches on this,

Tomcat and Undertow are two different Java servers.
Command box uses undertow, Lucee uses Tomcat (So does ACF and nearly everyone else)

My suggestion is
Upgrade to Tomcat 9.X series included with lucee installer or use any tomcat binary or build scratch any 9.X version.

As for URL Rewriting, Apache HTTPD in front of your tomcat lucee install is blindly simple.

# If it's a real file (and we haven't proxied to Tomcat, so it must be static), just serve it:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule . - [L]

# Require trailing slash at this point:
RewriteRule ^(.+[^/])$ $1/ [R=301,L]

# Everything else must be a URL path, which is rewritten andto Tomcat Lucee:
# MUST COME AFTER ANY OTHER FIXED/EXPECTED REWRITES!
RewriteRule . ajp://%{HTTP_HOST}:8009/index.cfm%{REQUEST_URI} [NE,P]
2 Likes

Did you try to set loglevel to debug and enabling status, so you can see what Tuckey is doing by accessing the tuckey status page?

Out of curiosity, was there an issue in CommandBox/Undertow, or was Tomcat just something you already were using in prod?

While you can configure Tuckey in Tomcat, it’s a bit of a pain. Most people on Tomcat use Nginx/Apache/etc to rewrite their URLs.

Indeed, we use NGINX for URL rewriting…

But it would totally awesome if we could do it suiccessfully / easily within Tomcat.
Just to reduce the stack we have to use.

@Gavin_Baumanis as of Apache Tomcat 9.0.62 you can ditch Nginx if that is all you are using it for is URL rewriting.

**check out **Apache Tomcat 9 (9.0.62) - The rewrite Valve

2 Likes

You can already do it easily within CommandBox (both Tuckey rewrites and Undertow’s predicate langauge are supported out of the box). Perhaps Tomcat is the thing you need to be dropping from your stack :wink:

There’s no problem with the CommandBox, Brad.
I’m using CommandBox for development. Now, in production, I have to deploy under Tomcat, as per the customer’s requests.

Thanks.

Ok, i solve the problem.

I add this line in web.xml, in “servlet-mapping” section:

<servlet-mapping>
    [...]
    <url-pattern>/apps/public/index.cfm/*</url-pattern>
</servlet-mapping>

Probably just the lines:

<servlet-mapping>
    <url-pattern>/index.cfm/*</url-pattern>
    <url-pattern>/index.cfml/*</url-pattern>
</servlet-mapping>

they are not enough to send .cfm pages to Tomcat.

@bdw429s I believe you should add this advice in the Coldbox documentation.

Thanks everyone for the help!

Yes, SES urls in subfolders don’t work on stock Tomcat. Yet another thing that we’ve made “just work” in CommandBox :wink:. This really has nothing to do with ColdBox though, it’s how you configure your servlet to process .cfm mappings.

2 Likes

Actually since Tomcat version 4, the rewrite valve has been there

Even the very dated version that ships with the cfdistro.zip that commandbox downloads, Tomcat 8.5.12 has rewrite capabilities.