Search code examples
apachemod-rewriteamazon-cloudfront

Apache RewriteRule on application hosted in subfolder leads to infinite loop


I'm currently hosting a PHP application on Apache. This application is behind a CloudFront distribution that sends all requests with cms/* to my application.

I used the following .htaccess file and hoped to make things work:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /cms
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
</IfModule>


SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1


<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>

I get an Internal Server Error and in the Apache Error logs this can be found: AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error.

What am I doing wrong?


Solution

  • My CMS is running in the document root of the Apache server.

    If the CMS is in the document root then you should remove the RewriteBase /cms directive entirely.

    The presence of RewriteBase /cms results in the request being internally rewritten to /cms/index.php (not /index.php) and if this file does not exist then you will naturally get a rewrite-loop (the preceding condition checks that the request does not map to a file or directory).

    In other words (with some additional improvements):

    DirectoryIndex index.php
    
    RewriteEngine on
    
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php [L]
    

    DirectoryIndex is likely already set in the server config, although it is necessary here.

    The first RewriteRule directive is an optimization to prevent unnecessary filesystem checks when the request is rewritten.

    There is no need to traverse and capture the entire URL-path in the last RewriteRule directive (ie. ^(.*)). The regex . (a single dot) is sufficient, and more efficient.

    No need for the <IfModule mod_rewrite.c> wrapper, unless these directives are optional.