Search code examples
apache.htaccessnginxmod-rewrite

.htaccess redirect based on folder


I need help with .htaccess Rewrite rules.

I have a API which can be accessed over http://api.my.domain/products/all which is working fine and is returning result.

I would like to redirect users coming to http://api.my.domain/admin to admin folder.But it is not working with current rules.

I have added this to .htaccess but it is not working correctly for admin folder.

    RewriteEngine On

RewriteCond %{Request_Filename} !-F

RewriteCond %{Request_Filename} !-d

RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteCond %{QUERY_STRING} ^$
RewriteRule ^admin admin/index.php [QSD,L]

RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ public/index.php [QSD,L]

This is the result I get when I enter http://api.my.domain/admin and is breaking all my php redirects:

http://api.drezga.hr/admin/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/admin/admin/checklogin.php

Can someone, please, tell me what I'm doing wrong? I have spent hours and I can't see it.


Solution

  • Aside: If /admin is a physical directory then you should be requesting /admin/ (with a trailing slash) to begin with, otherwise Apache/mod_dir will issue a 301 redirect to append the trailing slash.

    RewriteCond %{Request_Filename} !-F
    
    RewriteCond %{Request_Filename} !-d
    
    RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^admin admin/index.php [QSD,L]
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteRule ^ public/index.php [QSD,L]
    

    The first two conditions (RewriteCond directives) are being applied incorrectly to the first rule only. They need to apply to the last rule (the rewrite to public/index.php) then the rewrite to admin/index.php is not necessary (this should be handled by the DirectoryIndex).

    There's no need for the QSD flag since you are checking that the query string is already empty - there is no query string to discard!

    You should probably be using the -f operator on the condition, not -F (which uses subrequests and is consequently less efficient).

    Try the following instead:

    DirectoryIndex index.php
    
    RewriteEngine On
    
    RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    
    # Optimisation (prevent additional filesystem check)
    RewriteRule ^public/index\.php$ - [L]
    
    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . public/index.php [L]
    RewriteRule ^$ public/index.php [L]
    

    The RewriteCond %{REQUEST_FILENAME} !-d directive prevents requests for /admin/ being passed to public/index.php.

    The additional RewriteRule at the end is to rewrite requests for the root directory, which would otherwise be omitted because of the condition mentioned above. This could be avoided by extending the DirectoryIndex directive instead, although this could change the behaviour if you have other directories that need to be accessible (or should not be routed to public/index.php). For example:

    DirectoryIndex index.php /public/index.php