Gust van de Wal Gust van de Wal - 1 year ago 113
Apache Configuration Question

htaccess not behaving like expected

I'm creating an htaccess with which I want to achieve 3 things:

  • remove trailing slash

  • redirect all requests that aren't
    files to index.php

  • redirect all files to view.php if the query string doesn't begin with

At the moment it looks like this

RewriteEngine On
RewriteBase /test/
RewriteRule ^(.*)/$ $1 [N] # remove trailing slash

RewriteCond %{REQUEST_URI} !\.(css|ico|jpg|js|php|png)$ # if it isn't one of the files
RewriteRule . "index.php" [L] # then redirect to index

RewriteCond %{QUERY_STRING} !^a($|&) # if query doesn't start with a
RewriteRule . "view.php" [L] # then redirect to view

This way, the following test cases should be true: -> -> -> ->

When I try these out on this site, it shows me exactly these results.
In practice, however, when I'm trying out URLs, It completely breaks: -> -> Error 500 -> ->

It seems as if the script always looks at the query-related part first, although with that in mind, it still doesn't make much sense to me that
breaks. When I remove the query-related part though, the rest does work.

Did I forget about something? Is there a rule concerning the order of operation that I'm not aware of? Did I make a typo?

All input is appreciated!

P.S. I know that I will have to add a query that starts with an
for all local images, stylesheets, scripts and AJAX-calls. I'm doing this so that when people view media in a separate tab, I can create a fancy page around it, allowing people to navigate through all the media that is publicly present on the server.

Answer Source

Issues with your code:

  1. First all non-css/js/image requests are routed to index.php and then anything without ?a is routed to view.php so eventually index.php won't be used at all. You need to use a negated condition in last rule for anything that doesn't have .php extension..
  2. mod_rewrite syntax doesn't allow inline comments.
  3. You need R flag in first rule to change URL in browser.

You can use this code in /test/.htaccess:

RewriteEngine On
RewriteBase /test/

# if not a directory then remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [L,NE,R=301]

RewriteCond %{REQUEST_URI} !\.(css|ico|jpe?g|js|php|png)$
RewriteRule . index.php [L]

RewriteCond %{QUERY_STRING} !(^|&)a [NC]
RewriteRule !\.php$ view.php [L,NC]
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download