Neta
Neta

Reputation: 901

htaccess Redirect Causes Errors

I'm working on a website that has been built sloppily.

The website is filled with regular links that are translated into the corresponding .php pages by the .htaccess page.

This is it:

RewriteEngine on

RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1

RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2

<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>

First of all, I would love some help regarding whether or not this page has everything it should. I've never messed with it before.

Secondly and my main issue, if, for example, I would write the address www.thewebsite.com/foobar.html, it would be translated into www.thewebsite.com/cat.php?cat=foobar by the .htaccess page, and it would give a database error (and reveal information about the database).

I've put a check into cat.php which checks if the category exists, but I can't redirect the user to the 404 error page. There's a page called 404.shtml in the website, but redirecting the user to it causes the .htaccess to just change it again to cat.php?cat=404.

Is the way they used the .htaccess page normal? Should I change this system? And how are users sent to error pages? From what I understood the server should be doing it on its own?

I would love some clarification... There is some much about this subject I don't understand.

Update:

This is my new .htaccess page

RewriteEngine on

RewriteRule ^error.php?err=(.*)$ Error$1.html

# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]

RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1

RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2

<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>

Because the redirecting is in the code and the user cannot see it, I allowed myself to write the link in a non-clean way. I tried turning it into a clean URL but the following does not do anything:

RewriteRule ^error.php?err=(.*)$ Error$1.html

Can someone please help me understand why? I thought since error.php is a real page, I should put it before the conditional but it didn't work. BTW, I saw in an article about .htaccess that the page should start with Options +FollowSymLinks. It seems to me that everyone sort of has their own way of writing it. Is there a guide or something like that, which I can be sure is authentic and covers all the bases there is about .htaccess?

Thank you so much!!

Upvotes: 0

Views: 205

Answers (2)

Chris
Chris

Reputation: 136918

Using rewrite rules to work around links to .html pages that don't exist is unusual in my experience, but it's really just a different take on "pretty" URLs, e.g. www.thewebsite.com/foobar/ gets routed to cat.php?cat=foobar on the backend.

Your 404 issue is different. You need to be able to display error pages.

One option here is to rewrite requests as long as they don't request an existing file. This is very common for serving up static content like images, CSS files, and the like. To do this, you can use the -d and -f options to RewriteCond, which apply when requesting a directory and file respectively:

RewriteEngine On
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]

Now, requests to 404.shtml should go through, because you're requesting an existing file on the filesystem.

Note that the RewriteConds only apply to the single RewriteRule that immediately follows. For additional RewriteRules, also include additional RewriteConds.

Upvotes: 1

anubhava
anubhava

Reputation: 785108

Your regex is wrong anywhere. Literal dot needs to be escaped using otherwise it will match any character. Also it is better to use L and QSA flags to end each rule properly.

RewriteEngine on
RewriteBase /

RewriteRule ^koral/([^/]+)/?$ page.php?name=$1 [L,QSA]

RewriteRule ^([^.]+)\.html/([^/]+)/([^/]+)/([^/]*)/?$ cat.php?cat=$1&page=$2&order=$3&dir=$4 [L,QSA]

RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]

RewriteRule ^([^/]+)/([^.]+)\.html$ product.php?cat=$1&product=$2 [L,QSA]

Upvotes: 1

Related Questions