[techtalk] mod_rewrite

Almut Behrens almut_behrens at yahoo.com
Mon Apr 23 06:23:30 EST 2001


Hi all,

I'm new to the list. While doing a google search, I accidentally came
across a link to linuxchix... I browsed a little through the archives
and quickly concluded that this is definitely something worth
subscribing ;)

While browsing, the message "mod_rewrite" somehow caught my attention,
because related issues were repeatedly causing me headaches, too...
I haven't seen any responses yet, so that'll be my first attempt at
being helpful here, just in case you haven't found a solution in the
meantime :)
OK, enough preliminary blah-blah.



On Fri, 20 Apr 2001 15:50:34 +1000, Mary Gardiner wrote:

> Can anyone talk me through this use of mod_rewrite in apache?
> 
> Diary entries[1] have urls that look like
> /diary/diary.php?year=01&month=04&day=20&sub=1
> and I want to rewrite
> /diary/01/04/20/1/
> to that.
> 
> Month indices look like
> /diary/month.php?year=01&month=04
> and I want to rewrite
> /diary/01/04/
> to that.
> 
> Currently the config looks like:
> RewriteEngine  on
> RewriteBase    /diary/
> RewriteRule ^[^/]+/[^/]+/$ month.php?year=$1&month=$2
> RewriteRule ^[^/]+/[^/]+/[^/]+//[^/]+/$ coat.php?year=$1&month=$2&day=$3&sub=$4

I believe the problem is that you need to use parentheses to tag/enclose the
subpatterns to extract ($1, $2, ...), e.g.

  RewriteRule ^([^/]+)/([^/]+)/$ month.php?year=$1&month=$2

Another minor thing that would prevent the second rule from working
correctly is the double slash, which I assume is just a typo:

  RewriteRule ^[^/]+/[^/]+/[^/]+//[^/]+/$ coat.php?year=$1&month=$2&day=$3&sub=$4
                                ^^
it probably should be:

  RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ coat.php?year=$1&month=$2&day=$3&sub=$4

Other than that, things should be fine.
For reasons of efficiency, however, it might be worth considering to
specify your rewrite rules not in per-directory context, but rather in
server context, i.e. outside of any <Directory> or <Location> tags.
If there's no specific reason for doing it *in* per-directory context
(such as wanting to use .htaccess files), I'd prefer not doing it.
It'll be faster then, and generally less problematic in the long run...

The advantage would be that it then operates directly during the early
URL level translation phases of the apache processing cycle, considerably
simplifying things. For per-directory rewriting, apache has to perform some
weird substitutions on the physical directory paths, followed by an
internal redirect on the rewritten path/URL (see the explanation in the
mod_rewrite docs for details, or else take a close look at what the
module is outputting to the logs when set to "RewriteLogLevel 9" --
it's quite informative, actually).

In this case, you'd have to change your rules to something like

  RewriteEngine  on
  RewriteRule  ^/diary/([^/]+)/([^/]+)/$  /diary/month.php?year=$1&month=$2

In particular, you no longer need to (and cannot) use RewriteBase here,
so you have to explicitly specify the leading "/diary/" stuff, on the
substitution side too. The additional keystrokes will keep you away
from potential trouble elsewhere ;)

Also, you might need to use the RewriteRule flags [L] and/or [PT], the
latter depending on whether the rewritten URL needs to be internally
passed through to later additional processing steps, like
authorization/access control.

(another side note: don't let yourself be fooled by the fact that
<Location> directives are specified in terms of URLs. With respect to
rewriting, they nevertheless internally deal with the physical paths,
so the same weird back-and-forth <Directory> mechanics apply here, too)


As to the other "FollowSymlinks" issue you mentioned in your follow-up
post, I'm not sure what the problem is that apache is complaining
about, as you clearly had "Options FollowSymlinks" specified. I suspect
it's an indirect result of things having gone wrong at the rewriting
level already. Hopefully that'll work out by itself once the rewriting
issue is resolved...

Good luck,

- Almut




More information about the Techtalk mailing list