Search code examples
apache.htaccessmod-rewritemodel-view-controller

Htaccess : URL Rewriting not causing 404 on nonexisting pages and not working as expected


Server path is:

FTP : htaccess is in root/ and index.php is in root/www/.

Real path (using getcwd) : index.php is in /home/mysite/www. I'm using a clustered web hosting.

Here is the code I wrote (working) to have readable links:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#Https redirect

Options All -Indexes 
#Prevents access to server files -- unusual behavior doesn't stop if removed

RewriteRule (^azazaz|placeholdercateg)/?([0-9]+)?/?$ /index.php?category=$1&page=$2 [NC,L]
#Internally redirects mysite.com/placeholdercateg to mysite.com/index.php?category=placeholdercateg or mysite.com/placeholdercateg/pagenumber to mysite.com/index.php?category=placeholdercateg&page=pagenumber

RewriteRule (^azazaz|placeholdercateg)/?(^azaza|placeholderaction)/?([0-9]+)/?([0-9]+)?$ /index.php?category=$1&action=$2&id=$3&postid=$4 [NC,L]
#Same as first RewriteRule, but for user interaction

Problem 1 : (solved, see below) For some reason, if someone enters index.php in the URL-to-be-rewritten (e.g : mysite.com/placeholdercateg/index.php), the URL changes itself to mysite.com/www/placeholdercateg, then if they enter index.php again, it changes itself to mysite.com/www/www/placeholdercateg ad infinitum. As expected, though, mysite.com/index.php is met with 404.

Problem 2 : Another unusual behavior that I can't wrap my head around : nonexisting pages aren't met with 404 (eg : mysite.com/icanliterallywriteanything/notevenkidding/placeholdercateg), the page just shows mysite.com/placeholdercateg but the URL still shows up as changed.

It's rather distressing and I'd like to fix these issues. Any suggestions?

  • What is (^azazaz) for?

I don't understand why, but the first statement in a RewriteRule always leads to a 404 error in my case, even if it's something that is supposed to exist. For example, if the RewriteRule is (^placeholdercateg)/etc and I go to mysite.com/placeholdercateg, it's an immediate 404.

This is why I use "azazaz" as the first statement and "placeholdercateg" as the second, as it only blocks the first statement and the rule works for the second. I would also like to know more about this, but this is not my primary concern at the moment.

  • Why haven't you tried to use already existing files or folders to rewrite your URLs?

Because there aren't. I'm using an MVC pattern.

  • Do you have any other Rules apart from these?

(added)

  • Mention path of your index.php and htaccess also where are they residing in server.

(added)

Attempt : mysite.com/index.php ==> index.php is accessed (home page)

Attempt : mysite.com/placeholdercateg/index.php ==> 404 not found (problem 1 solved)

Attempt : mysite.com/anythingreally/reallyanything/etc/placeholdercateg/ ==> placeholdercateg page is accessed


Solution

  • With your shown attempts, samples; please try following htaccess Rules in your rule file. Make sure to clear your browser cache before testing your URLs.

    RewriteEngine On
    Options All -Indexes -MultiViews
    
    #Https redirect
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,NE,R=301]
    
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^index.php/?$ - [F,NC,L]
    
    #Prevents access to server files -- unusual behavior doesn't stop if removed
    #Internally redirects mysite.com/placeholdercateg to mysite.com/index.php?category=placeholdercateg or mysite.com/placeholdercateg/pagenumber to mysite.com/index.php?category=placeholdercateg&page=pagenumber
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (^azazaz|placeholdercateg)/?([0-9]+)?/?$ /home/mysite/www/index.php?category=$1&page=$2 [NC,L]
    
    #Same as first RewriteRule, but for user interaction
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (^azazaz|placeholdercateg)/?(^azaza|placeholderaction)/?([0-9]+)/?([0-9]+)?$ /home/mysite/www/index.php?category=$1&action=$2&id=$3&postid=$4 [NC,L]
    
    ##New rules for non-existing uris.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^.*/([\w-]+)/?$ /$1? [R=301,L]
    RewriteRule ^(.*)/?$ index.php?param=$1 [QSA,L]