Getting cgi.redirect_url in Railo on tomcat and Apache (404 redirects)

Update 15/oct/2010, 15:59:00 GMT+1: fixed a typo in the code.

I suppose you are using a custom 404 page for your websites? If you are using Railo with Tomcat, and Apache as the frontend webserver, then you probably have noticed that you cannot determine the url that was originally requested (the 404 url). Normally, this info is available in cgi.redirect_url and cgi.redirect_query_string, but those are never set if you have this Apache+Tomcat setup.
Luckily, I found a way to retrieve those cgi variables!

I have an Apache webserver, which connects to Tomcat+Railo via mod_jk. This works.
In Apache, I have a virtualhost setup like this:

<VirtualHost *:80>
    ServerName localhost     DocumentRoot /developing/somesite/     ErrorDocument 404 /404error.cfm </VirtualHost>

Now, if I call a non-existing page like http://localhost/page-does-not-exist, then Apache creates some extra "cgi variables", for example "cgi.redirect_url" and "cgi.redirect_query_string", and then calls the 404 page /404error.cfm.
The code in 404error.cfm checks those cgi variables to determine which url was requested, like this:

<cfset variables.requestedUrl = "http://#cgi.http_host##cgi.REDIRECT_URL##iif(len(cgi.REDIRECT_QUERY_STRING), de('?#cgi.REDIRECT_QUERY_STRING#'), de(''))#" />

Now, in my mod_jk setup, these variables seemed to be gone. They are always an empty string (as with all undefined cgi vars). This was a big problem for me, because I use this "requestedURL" to do some logging, and send specific content based on that url. Was an image requested? Then I return an "image-not-found.gif". Did the url start with "/page/"? Then do a &amp;lt;cfinclude template="/page.cfm" /&amp;gt;.

To fix this problem, I tried using "JkEnvVar" in Apache's httpd.conf as suggested here, to explicitly send those cgi vars, but that didn't help. I asked mister google for another 100 options, but nothing helped.
Then I dug a little deeper, and checked the request itself:

<cfdump var="#getPageContext().getRequest().getAttribute('REDIRECT_URL')#" />

That gave a Null back.

But &amp;lt;cfdump var="#getPageContext().getRequest()#" /&amp;gt; showed an interesting method getOriginalRequest(), so I tried:

<cfdump var="#getPageContext().getRequest().getOriginalRequest().getAttribute('REDIRECT_URL')#" />

And voila! There it was: "/page-does-not-exist".

This originalRequest is of type "org.apache.catalina.connector.RequestFacade" btw, and the getRequest is of type "railo.runtime.net.http.HTTPServletRequestWrap".

So now I know where I can digg those variables up, so my 404 page will work. The code I am now using in my 404 page is:

<!--- apache--->
<cfif len(cgi.REDIRECT_URL)>
<cfset requestedUrl = "http://#cgi.http_host##cgi.REDIRECT_URL##iif(len(cgi.REDIRECT_QUERY_STRING), de('?#cgi.REDIRECT_QUERY_STRING#'), de(''))#" />
<!--- IIS --->
<cfelseif refind("^[0-9]{3}", cgi.query_string)>
<cfset requestedUrl = cgi.query_string />
<!--- apache via mod_jk --->
<cfelse>
<cftry>
<cfset origRequest = getPageContext().getRequest().getOriginalRequest() />
<cfset requestedUrl = "http://#cgi.http_host##origRequest.getAttribute('REDIRECT_URL')##iif(len(origRequest.getAttribute('REDIRECT_QUERY_STRING')), de('?#origRequest.getAttribute('REDIRECT_QUERY_STRING')#'), de(''))#" />
<cfcatch>
<cfset requestedUrl = "" />
</cfcatch>
</cftry>
</cfif>

But I do think this is something that is missing in Railo, and should be corrected. So I filed a JIRA ticket for this.

del.icio.us Digg StumbleUpon Facebook Technorati Fav reddit Google Bookmarks
| Viewed 6075 times
  1. Sean Daniels

    #1 by Sean Daniels - January 9, 2011 at 2:36 AM

    Dude. Thank you for posting this! I've been trying to figure out how to do exactly this for the past hour...

    Woo hoo!
(will not be published)
Leave this field empty

draw-trap