CF9 ORM and Apache’s mod_rewrite
Here’s another problem I’ve run into with ColdFusion’s ORM (there seem to be a few of these recently…).
I’ve only just started running a CF dev environment under Apache on my Mac – I was previously running IIS under VMWare. The problem comes when using Apache’s mod_rewrite for URL rewriting.
I set up a simple test scenario with the following Application.cfc:
component output="false"
{
this.name = "ormtest";
this.sessionManagement = true;
this.sessiontimeout = CreateTimeSpan(0,5,0,0);
this.ormEnabled = true;
this.datasource = "TEST";
this.ormSettings = {
cfclocation = "/model"
};
}
The model directory contains a single ORM mapping bean, user.cfc.
This runs fine and initialises without a problem. But then I add the following mod_rewrite rules into .htaccess:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !/(assets|index.cfm) [NC]
RewriteRule ^(.*)$ /index.cfm/$1 [NC,L]
This handles rewriting of SES URLs for FW/1 pages – essentially, anything that’s not in the assets folder gets index.cfm/ prepended to it behind the scenes. However, this causes the following error when loading the application:
Could not find the ColdFusion component or interface user.
It turns out that the reference to /model as the ORM’s cfclocation is also being rewritten; what is more, adding model into the RewriteCond of paths to ignore doesn’t solve the problem.
After a bit of searching, I discovered Richard Herbert had experienced what seemed to be the same problem. A quick tweet later, and he told me of the solution he’d found.
The solution is simple: create a mapping to the directory containing the ORM CFCs. So, in my example, I added the following before the ORM settings:
this.mappings = {'/model' = '/Volumes/Dev/Web/sites/ormtest/model'};
…and everything now works as it should. (Note: be sure to change the mapping to reflect the structure of your live server!)
Out of interest, I tried the same test under IIS running ISAPI_Rewrite – and it didn’t share the problem. So I assume that mod_rewrite runs at a lower level in the system than ISAPI_Rewrite: mod_rewrite will rewrite your internal CF file calls. So that’s something to be wary of…
Comments
- Matt Woodward
-
Without knowing your whole setup I can't say for sure, but I'd be willing to bet the source of your problem actually has nothing to do with mod_rewrite since CF wouldn't even be hitting your web server to find the CFC.
I bet you're running this application in a subdirectory of a virtual host's root, meaning you're accessing it via http://host/appdirectory" target="_blank">http://host/appdirectory as opposed to just http://host
This would create a need for a mapping to model since /model (or CreateObject('component', 'model.whatever') for that matter) would be looking for model to be in the host's root. Since it's not, you'd either have to access it differently (/appdirectory/model as opposed to just /model) or create a mapping as you've done.
In short, I'd be shocked if mod_rewrite has anything to do with the issue you're describing since the web server isn't even involved at that level.
- 29 August 2010, 22:09
- Reply
- Seb Duggan
-
Matt,
1. The site is running at the root of the virtual directory. I always set every site up as it's own virtual host, since that's how it will exist on the live server.
2. If I remove the mod_rewrite commands, the site works perfectly even without the mapping.
Any ideas?
- 29 August 2010, 23:42
- Reply
- Matt Woodward
-
Well, I've never used CF 9 so I can't speak to how it works, but it's surprising that it would in any way be interacting with your web server.
I still suspect something else is afoot, particularly since a *mapping* fixes the issue, since Apache wouldn't know anything about the mapping. So it sounds like you're saying you suspect the problem is with a rewrite rule on the Apache side, yet you're fixing it with a mapping on the CF side? Doesn't make logical sense to me.
As I said though, I don't use CF 9 or the ORM tool so for all I know there's something going on with things at that level. Based on my experience with Apache and mod_rewrite, however, it just seems like there has be something else at play here, but ultimately whatever fixes it fixes it I suppose.
- 29 August 2010, 23:49
- Reply
- Matt Woodward
-
I'd be curious if WITHOUT the mapping in place but WITH the rewrite rule in place you can do this:
<cfset user = CreateObject('component', 'model.user') />
If you don't get a component not found error with that, then there's definitely something going on at the ORM level in terms of how it looks for things.
- 29 August 2010, 23:56
- Reply
- Seb Duggan
-
OK, I've tried the basic component creation you suggested above. I disabled ORM, disabled the mapping, but left the rewrite rule in place.
The object is created without a problem, so there defeinitely seems to be something going on with ORM...
Also, running another test on my original example, if my RewriteCond includes "model" as a path to be ignored by the rule, I get the message originally stated; but if I take "model" out of the RewriteCond (i.e. so a request to "/model/whatever" will be rewritten), I get the error:
"Path /model specified in the cfclocation does not exist."
(Note I need to restart the CF server for each test, as once it's found the cfcocation once, it remembers it even if I change mappings etc.)
So it seems that mod_rewrite is definitely coming in to play with the ORM calls...
- 30 August 2010, 09:16
- Reply
- Matt Woodward
-
Very bizarre. Wouldn't have expected that behavior!
- 30 August 2010, 15:39
- Reply
- Seb Duggan
-
No. I didn't expect it either!
- 30 August 2010, 16:24
- Reply