Reputation: 2945
I've written the following code in my htaccess file:
RewriteRule ^(.*)/$ $1
RewriteCond %{REQUEST_URI} !^index.php.*$
RewriteRule ^(.*)$ /index.php?route=$1 [END]
It works perfect for every path, except for directories that exist. For example, if I enter http://localhost/profilepic
and such directory actually exists, it redirects to http://localhost/profilepic/?route=profilepic
, but I want it to be implicitly converted to http://localhost/index.php?route=profilepic
.
Thanks in advance.
Upvotes: 1
Views: 104
Reputation: 786081
Here is another way you can have your rules without turning off DirectorySlash
(considered a security hole):
RewriteEngine On
# remove trailing slash for non-directories
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?)/+[?\s]
RewriteRule ^(.+?)/$ /$1 [R=301,L]
# routing for directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+?)/$ /index.php?route=$1 [L]
# routing for non directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+?)/?$ /index.php?route=$1 [L]
Upvotes: 1
Reputation: 143946
The reason this is happening is because of mod_dir and the DirectorySlash
directive. Essentially, if it sees a URI without a trailing slash, and it maps to an existing directory, then it'll redirect the request so that it has the trailing slash. Since mod_dir and mod_rewrite are both in different places in URL-file processing pipeline, both mod_dir and mod_rewrite get applied to the same URL. That's why you end up with a redirect and a weird URL with the query string.
If you absolutely must have directories without trailing slashes, then you need to turn of DirectorySlash
. The problem with turning it off is that there is an information disclosure security concern that will make it so people can look at the contents of a directory even if you have an index file. That means you have to make up for mod_dir using mod_rewrite.
So get rid of the rule:
RewriteRule ^(.*)/$ $1
and replace it with these rules:
DirectorySlash Off
# redirect direct requests that end with a slash to remove the slash.
RewriteCond %{THE_REQUEST} \ /+[^\?\ ]+/($|\ |\?)
RewriteRule ^(.*)/$ /$1 [L,R]
# internally add the trailing slash for directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/ [L]
Upvotes: 1