Gust van de Wal
Gust van de Wal

Reputation: 5291

htaccess not behaving like expected

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

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:

http://127.0.0.1/test/contact               ->         http://127.0.0.1/test/index.php
http://127.0.0.1/test/contact/              ->         http://127.0.0.1/test/index.php
http://127.0.0.1/test/contact.png           ->         http://127.0.0.1/test/view.php
http://127.0.0.1/test/contact.png?a         ->         http://127.0.0.1/test/contact.png?a

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:

http://127.0.0.1/test/contact               ->         http://127.0.0.1/test/view.php
http://127.0.0.1/test/contact/              ->         Error 500
http://127.0.0.1/test/contact.png           ->         http://127.0.0.1/test/view.php
http://127.0.0.1/test/contact.png?a         ->         http://127.0.0.1/test/contact.png?a

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 /contact/ 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 a 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.

Upvotes: 1

Views: 40

Answers (1)

anubhava
anubhava

Reputation: 786081

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]

Upvotes: 3

Related Questions