Javid
Javid

Reputation: 2945

Redirect to index.php in root

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

Answers (2)

anubhava
anubhava

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

Jon Lin
Jon Lin

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

Related Questions