Mobile app version of vmapp.org
Login or Join
Moriarity557

: Apache rewrite rule set for "whitelist or catchall" in .htaccess On the dev version of a LAMP site (Apache 2.4 on Debian 8.5), my Apache rewrite rules implement a "whitelist then catch-all"

@Moriarity557

Posted in: #Apache2 #Htaccess #ModRewrite

On the dev version of a LAMP site (Apache 2.4 on Debian 8.5), my Apache rewrite rules implement a "whitelist then catch-all" concept.
Specifically, images from images/, stylesheets from css/, javascript from /js, and a few named files are served directly as static files, and all other requests go to index.php.

The rule-set is in the <VirtualHost block in the .conf file for this site:

RewriteEngine on
RewriteCond "%{REQUEST_URI}" "!^(/index.php|/robots.txt|/favicon.ico)$"
RewriteCond "%{REQUEST_URI}" "!^/images/(.*).(jpg|png|jpeg|gif)$"
RewriteCond "%{REQUEST_URI}" "!^/css/(.*).css$"
RewriteCond "%{REQUEST_URI}" "!^/js/(.*).js$"
RewriteRule ^(.*)$ /index.php/ [L]


And this works as intended. (It is based on this SO Q&A and adapted to work in the central config rather than in .htaccess.)

The problem is the test server (Ubuntu 16.04) has to imitate production, and production requires use of .htaccess instead of central configuration, and this rule-set does not work in .htaccess. So the question is how to get the same effect in .htaccess.

I turned on AllowOverride all in the <Directory /srv/www/site1> block in apache2.conf and put a .htaccess file in /srv/www/site1 (which is the DocumentRoot value for this site). And based on this apache doc, removed initial slashes from the paths and filenames in the conditions. Also put LogLevel info rewrite:trace8 in the VH definition to debug this problem.

Here is the current .htaccess:

Options -Indexes +FollowSymLinks
AddDefaultCharset UTF-8
RewriteEngine on
# RewriteBase "/"
# AccepthPathInfo on
RewriteCond "%{REQUEST_URI}" "!^(robots.txt|favicon.ico|css/styles.css)$"
RewriteCond "%{REQUEST_URI}" "!^index.php"
RewriteCond "%{REQUEST_URI}" "!^css/(.*).css$"
RewriteCond "%{REQUEST_URI}" "!^images/(.*).(jpg|png|jpeg|gif)$"
RewriteCond "%{REQUEST_URI}" "!^js/(.*).js$"
RewriteRule ^(.*)$ /index.php/ [L]


And getting http 500. Apache error log shows it's looping the rules until it hits a redirect limit, and creating a bad path like "index.php/index.php/index.php/..."

I've found a very large number of pages about URL rewriting but few are helpful on this.

EDIT: Solved by w3dk - thank you! Applied the solution below and corrected my misspelling of "AcceptPathInfo", then it works.

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Moriarity557

1 Comments

Sorted by latest first Latest Oldest Best

 

@Jamie184

RewriteEngine on
RewriteCond "%{REQUEST_URI}" "!^(/index.php|/robots.txt|/favicon.ico)$"
RewriteCond "%{REQUEST_URI}" "!^/images/(.*).(jpg|png|jpeg|gif)$"
RewriteCond "%{REQUEST_URI}" "!^/css/(.*).css$"
RewriteCond "%{REQUEST_URI}" "!^/js/(.*).js$"
RewriteRule ^(.*)$ /index.php/ [L]



The format of your initial directives are OK for .htaccess as well. However, in .htaccess you will need an additional condition to prevent a rewrite loop after rewriting to index.php.


RewriteCond "%{REQUEST_URI}" "!^index.php"



I can see you've tried to do this in your second code block, however, the value of REQUEST_URI is the same whether you are coding directly in the server config or in .htaccess - it still begins with a slash. So, the above negated condition would always be true (like all the other conditions in the second block) and so the RewriteRule is always processed.

However, you could just add another RewriteRule to the start of your first code block:

RewriteRule ^index.php - [L]


So, put all together, this becomes:

RewriteEngine on

RewriteRule ^index.php - [L]

RewriteCond "%{REQUEST_URI}" "!^(/index.php|/robots.txt|/favicon.ico)$"
RewriteCond "%{REQUEST_URI}" "!^/images/(.*).(jpg|png|jpeg|gif)$"
RewriteCond "%{REQUEST_URI}" "!^/css/(.*).css$"
RewriteCond "%{REQUEST_URI}" "!^/js/(.*).js$"
RewriteRule ^(.*)$ /index.php/ [L]



# AccepthPathInfo on



And AcceptPathInfo will need to be enabled if it isn't already.

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme