SeinopSys
SeinopSys

Reputation: 8937

mod_rewrite rewriting files that exist even when it should not

I have the following .htaccess file, which is producing quite a strange behavior.

DirectoryIndex index.php index.html
AddCharset UTF-8 .html
AddCharset UTF-8 .php
AddCharset UTF-8 .css
AddCharset UTF-8 .js

AddType image/svg+xml svg

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /Hunpony/

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule ^(.*)\/$ $1 [R=301] # Remove trailing slash
RewriteRule ^$ do.php?do=news [QSA] # Default page
RewriteRule ^([\wáéíóöőúüű.]+|-?\d+)(?:\/((?:[\wáéíóöőúüű]+|-?\d+)(?:\/(?:[\wáéíóöőúüű]+|-?\d+))?))?\/?$ do.php?do=$1&data=$2 [NC,L,QSA]
</IfModule>

ErrorDocument 404 /Hunpony/404

I thought those RewriteConds would prevent Apache from performing a rewrite if the requested file exists, but this does not seem to be the case.

This file is placed in the /Hunpony/ subfolder of my sever, alongside do.php, which handles page requests. This is an example how the redirect works: it redirects /Hunpony/profile/1/setings to /Hunpony/do.php?do=profile&data=1/settings. The catch is that I also want to allow dots in the first match, so /Hunpony/f.a.q would be redirected to /Hunpony/do.php?do=f.a.q&data=.

The problem I'm facing is that for some odd reason, the site's favicon (/Hunpony/favicon.ico) is returning a 404 error, despite the fact that it's linked where it's supposed to be.

The only possible explanation I can think of is that Apache rewrites /Hunpony/favicon.ico to /Hunpony/do.php?do=favicon.ico&data=, even though the file exists on the server, and since in do.php there's no special case for a page named favicon.ico, it defaults to the 404 error page. Other resources of the page are not affected by this, since they're under sub-directories which have no dots in their name.

Upvotes: 1

Views: 83

Answers (1)

anubhava
anubhava

Reputation: 785146

It is due to the fact the fact that RewriteCond only applies to the very next RewriteRule. You can have your rules like this:

DirectoryIndex index.php index.html
AddCharset UTF-8 .html
AddCharset UTF-8 .php
AddCharset UTF-8 .css
AddCharset UTF-8 .js

AddType image/svg+xml svg
ErrorDocument 404 /Hunpony/404
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /Hunpony/

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]

RewriteRule ^(.+?)/$ $1 [L,R=301]

RewriteRule ^$ do.php?do=news [QSA,L]

RewriteRule ^([\wáéíóöőúüű.]+|-?\d+)(?:\/((?:[\wáéíóöőúüű]+|-?\d+)(?:\/(?:[\wáéíóöőúüű]+|-?\d+))?))?\/?$ do.php?do=$1&data=$2 [NC,L,QSA]
</IfModule>

Upvotes: 1

Related Questions