skip to Main Content

I am making an API in which I had those .htaccess rules to make “friendly URLs”, so I can make Endpoints that doesn’t depend on the presence of a file that matches the URI:

Options -MultiViews

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L,NC,QSA]

    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule . /index.php [L,NC,QSA]
</IfModule>

The intent of the first rule is: “if requested filename (in the URL) is not an existing file or directory, then redirect to index.php. It works very well for that matter.

The intent for the second rule is: “if requested filename is an existing directory, then redirect to index.php. It also works like a charm.

The problem is that now, I need to fit in a Frontend developed with React.js by another developer, so I need to apply some exceptions to those rules. I tried the following changes to the second .htaccess rule:

RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !^/directory_a.*
RewriteCond %{REQUEST_URI} !^/directory_a/directory_b.*
RewriteRule . /index.php [L,NC,QSA

…which intent is like: “if requested filename is an existing directory, and requested URI doesn’t start with /directory_a neither with /directory_a/directory_b, then and only then redirect to index.php. The rule works, but it isn’t enough, because it still redirects existing files within those directories. So, in order to fix that, I tried the following:

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !^/directory_a.*
RewriteCond %{REQUEST_URI} !^/directory_a/directory_b.*
RewriteRule . /index.php [L,NC,QSA

…almost the same than the previous modification, but asking for existing files as well. Here, I guess the conditions would work (expressed as pseudo-code) like this (but I’m not sure about it at all), prioritizing OR over AND:

IF ( is_existing_file OR is_existing_directory )
AND NOT uri.startswith( '/directory_a' )
AND NOT uri.startswith( '/directory_a/directory_b' )

…anyway, this is not working: it makes the Apache server to crash with an HTTP 500 (Internal Server Error) that throws the following error in error_log:

AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use ‘LimitInternalRecursion’ to increase the limit if necessary. Use ‘LogLevel debug’ to get a backtrace.

…I wonder why this happens at all, and if is it possible to achive what I am trying to achieve here via .htaccess

My API is deployed in DocumentRoot, as well as it’s index.php and .htaccess file.

2

Answers


  1. Chosen as BEST ANSWER

    It seems that excluding index.php in the conditions, solves the problem. Thanks, @DusanBajic :-)

    Options -MultiViews
    
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L,NC,QSA]
    
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteCond %{REQUEST_URI} !^/index.php$
        RewriteCond %{REQUEST_URI} !^/directory_a.*
        RewriteCond %{REQUEST_URI} !^/directory_a/directory_b.*
        RewriteRule . /index.php [L,NC,QSA]
    </IfModule>
    

  2. You may use these rules:

    Options -MultiViews
    
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
    
        # ignore rules below this for URIs starting with /directory_a/
        RewriteCond %{THE_REQUEST} s/+directory_a[/?s]
        RewriteRule . - [L]
    
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
    
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule . /index.php [L]
    </IfModule>
    

    Note that we are using THE_REQUEST here, which doesn’t change after executing rewrite rules. REQUEST_URI on the other hand gets updated after executing rewrite rules

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search