Forum Moderators: phranque

Message Too Old, No Replies

Strange .htaccess RewriteRule Behaviour.

         

premasagar

9:06 pm on Aug 30, 2006 (gmt 0)

10+ Year Member



I have the following (and only) rule in the .htaccess file at the top level of my domain:
RewriteRule ^(educationŠportfolioŠcontact)/(.*)$ /index.php?section=$1&path=$2 [L]

For example, a request to:
www.example.com/education/stuff/
actually serves the page:
www.example.com/index.php?section=education&path=stuff
The browser's address bar keeps the request url as it was and everything works fine, except...

If the url has no trailing slash, e.g:
www.example.com/education/stuff
then the browser's address bar changes to:
www.example.com/education/stuff?section=education&path=stuff
...which I don't want to happen!

I notice that it only happens if a file actually exists at:
www.example.com/education/stuff/index.php
Any requests to non-existent paths work as expected.

I don't quite understand this behaviour. Can anyone suggest a way to stop this happening and to have the second example (with no trailing slash) behave the same as the first example?

Thanks,
Premasagar.

jdMorgan

11:42 pm on Aug 30, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This looks like mod_dir is acting to add the required trailing slash to the directroy-path, and then mod_rewrite kicks in to rewrite to the script URL. Then the pending mod_dir redirect occurs, exposing your script path.

But I don't understand why the mod_dir redirect isn't happening before you even get to the mod_rewrite code. Without a thorough code review of httpd.conf and all of your .htaccess files --something that we can't really support on this forum-- it's impossible to tell where the problem is.

If you're on Apache 1.x, it could be a loadmodule order problem: modules loaded last are executed first, and you'd want mod_dir to act before mod_rewrite.

A work-around would be to put code in your top-level .htaccess file to "manually" append a trailing slash to any URL-path that looks like a directory-type-path, i.e. contains no file extension.

Then change your rewrite-to-script rule to accept the trailing slash.

Jim

premasagar

12:03 am on Aug 31, 2006 (gmt 0)

10+ Year Member



Cool. Thanks for your thoughts on this, Jim.

P.

Caterham

1:27 am on Aug 31, 2006 (gmt 0)

10+ Year Member



You can also put your rules into per-server context instead of per-dir context or don't use existing foldernames or the directive DirectorySlash [httpd.apache.org], depending upon your apache version.

You might also try this patch which should be the same for trunk and the 2.2/2.0 branches:

Index: modules/mappers/mod_dir.c
===================================================================
--- modules/mappers/mod_dir.c (revision 420983)
+++ modules/mappers/mod_dir.c (working copy)
@@ -116,6 +116,11 @@
return DECLINED;
}

+ /* skip after internal redirects from mod_rewrite */
+ if (!strcmp(r->handler, "redirect-handler")) {
+ return DECLINED;
+ }
+
d = (dir_config_rec *)ap_get_module_config(r->per_dir_config,
&dir_module);