Apache rewrite rule leading slash

Strangely enough,

RewriteRule   ^/help    help.php?q=2              [L]

The above rule fails and never matches.

This rule:

RewriteRule   ^help      help.php?q=1             [L]

Matches http://localhost/help, http://localhost//help and http://localhost///help

It appears RewriteRule never sees leading slashes of the path, and as TheCoolah said they are collapsed (to 0.. when using a .htaccess file anyway) no matter how many there are.

For the second part of the question,

RewriteRule   ^help    /help.php

I'm getting the answer from Definitive Guide to Apache Mod_rewrite

... a rewrite target that does not begin with http:// or another protocol designator is assumed to be a file system path. File paths that do not begin with a slash are interpreted as being relative to the directory in which the rewriting is taking place.

So /help.php looks in the root of the system for a file called help.php, which on my system it cannot find.

To make /help.php appear as a relative URL (relative to the root of the site) you can use the [PT] directive:

RewriteRule   ^/help    /help.php    [PT]

That directs http://localhost/help to http://localhost/help.php.


Regarding double slashes: Most Web servers silently collapse multiple slashes into a single slash early in the request processing pipeline. This is true for at least Apache, Tomcat and Jetty. Most Unix-based file systems work the same way. If you really want to check for this, you need to do something like:

RewriteCond %{REQUEST_URI} ^(.*)//(.*)$ 

help matches "help" anywhere in the path.

/help matches nothing since the rewriterule directive omits the leading slash for matching purposes (i.e., you must use ^, not / or ^/, to reference the current directory).

(This can be very confusing if you've used %{REQUEST_URI} in rewritecond because %{REQUEST_URI} does begin with a trailing slash. When matching against %{REQUEST_URI}, ^ and ^/ are equivalent and a directory name will always be preceded by a slash character regardless of whether or not it is in the top-level directory.)

The server error is caused by an infinite loop. "help" becomes "/help.php" which is then matched by the same directive that did the rewriting. So, after the first match, "/help.php" becomes "/help.php" infinitely resulting in a URL that can't be resolved.

I believe such loops can be fixed with the end flag (i.e., [end]), but that flag requires Apache 2.3.9+ whereas Apache 2.2 seems to be more common in deployment. It'd probably be better to just fix the regular expression anyway; ^help$ would seem to be the better choice here.