How To: Enable Jetty's built in URL rewriting functionality - getrailo/railo GitHub Wiki

Although Tuckey UrlRewriteFilter is a popular and flexible way to rewrite URLs, it is possible to do URL rewriting with a standard Jetty distribution - this article explains the steps required to get this going.

Configuring jetty-rewrite

  1. First, make sure you have the jetty-rewrite-[version].jar in your {jetty}/lib directory. This file should be present whether you have Railo Express or a standalone version of Jetty.

  2. Locate your start.ini (most likely in root Jetty directory) and open it with your preferred text editor. Then find the "Start classpath OPTIONS" section and add rewrite to the list. For example: OPTIONS=Server,jsp,jmx,resources,websocket,ext,plus,rewrite

  3. Below this should be the "Configuration files" section. Inside this, uncomment the line for etc/jetty-rewrite.xml (or add it if it's missing).

  4. The etc/jetty-rewrite.xml file is where the handler is configured and rules are setup.

    The existing etc/jetty-rewrite.xml contains an assortment of samples, and there is some limited documentation on the Jetty site to explain these.

    For a simpler example, see the section "Sample jetty-rewrite.xml" below.

  5. Once you have configured your start.ini and jetty-rewrite.xml appropriately, restart jetty.

    If you have any syntax errors in your XML file, it will stall immediately - if Jetty launches but your rewrite does not work, the issue is likely with your rule's pattern matching.

Note: There is a bug in previous versions of Jetty which prevented replacements containing query strings from working. If you wish to use query strings (such as in the example below), you should make sure you are on Jetty v8.1.5 or newer.

Getting the Path Info

When you rewrite the URL, as far as Railo is concerned, it is receiving the request as if made to the replacement URL, but sometimes there are times when you want to rewrite the URL but still obtain the original requested path.

Fortunately, Jetty stores this value for you. In the sample file below, it is the line <Set name="originalPathAttribute">requestedPath</Set> that configured this.

To obtain this value inside Railo, you can use the following:

<cfset PathInfo = getPageContext().getRequest().getAttribute('requestedPath') />

And you now have the originally requested path, to work with as necessary.

Unfortunately, it's not quite that simple - if the URL has not been rewritten there will be no value for requestedPath which results in getAttribute returning a null value.

Also, if the original URL was of the form /index.cfm/path/info the index.cfm segment will be included, but path info is only the part which comes after the script name, so the script name should be removed.

Here is a snippet to deal with these issues, as well as first checking whether the standard PATH_INFO variable is populated:

<cfif len(CGI.PATH_INFO)>
	<cfset PathInfo = CGI.PATH_INFO />
<cfelse>
	<cfset PathInfo = getPageContext().getRequest().getAttribute('requestedPath') />
	
	<cfif isNull(PathInfo)>
		<cfset PathInfo = "" />
	<cfelseif PathInfo.startsWith(CGI.SCRIPT_NAME)>
		<cfset PathInfo = PathInfo.substring(len(CGI.SCRIPT_NAME)) />
	</cfif>
</cfif>

Sample jetty-rewrite.xml

Here's a simple example file which can be used to convert /section/item into /index.cfm?action=section.item

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">

	<Get id="oldhandler" name="handler"/>

	<Set name="handler">
		<New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
			<Set name="handler"><Ref id="oldhandler"/></Set>
			<Set name="rewriteRequestURI">true</Set>
			<Set name="rewritePathInfo">false</Set>
			<Set name="originalPathAttribute">requestedPath</Set>

			<Call name="addRule">
				<Arg>
					<New class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule">
						<Set name="regex">/(?!index\.cfm|favicon\.ico|ui)(\w+)[.:/]([\w-]+)</Set>
						<Set name="replacement">/index.cfm?action=$1.$2</Set>
						<Set name="terminating">true</Set>
					</New>
				</Arg>
			</Call>

		</New>
	</Set>

</Configure>
⚠️ **GitHub.com Fallback** ⚠️