benface benface - 2 months ago 11
Apache Configuration Question

How to make mod_rewrite redirect properly in a subdirectory without specifying the path?

Here's my issue:

Let's say I have a website,

www.example.com
. I have an application
subdir
located in a subdirectory of that domain's document root:

/home/example/public_html/subdir/


subdir
contains this
.htaccess
:

# Redirect trailing slash if not a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /subdir/$1 [L,R=301]


It works. If I go to http://www.example.com/subdir/not_a_directory/ (obviously assuming
not_a_directory
is not a directory), I get redirected to http://www.example.com/subdir/not_a_directory which is what I want.

But I don't want to have to specify
subdir
in the rewrite rule or anywhere in the
.htaccess
. I want to be able to change my application's path without breaking anything. I tried the following...

# Redirect trailing slash if not a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [L,R=301]


But I get redirected to: http://www.example.com/home/example/public_html/subdir/not_a_directory

I kind of understand why that happens (a relative path for the rewrite rule returns a file system path, whereas an absolute or root-absolute path returns a URL), but I cannot figure out how to achieve what I'm looking for.

Isn't there any way to have the capture group in
RewriteRule
include the
subdir
part of the path? I also tried setting
RewriteBase /
but it doesn't seem to change anything.

Rewrite rules confuse me a lot, so any help would be greatly appreciated. Thank you!

Answer

You can use this rule without specifying subdir anywhere in .htaccess:

RewriteEngine On

# Remove trailing slash if not a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(/.+)/$
RewriteRule /$ %1 [L,R=301,NE]

Capturing path from RewriteCond %{REQUEST_URI} allows us to capture full URI path.