简体   繁体   中英

Why is `.htaccess` causing internal redirections overflow under these RewriteRules?

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.

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

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM