I'm trying to configure a URL scheme that a) allows the ".html" extension to be omitted and b) sends 403 (Forbidden) errors under certain conditions. However, with the following setup:
Options +MultiViews
RewriteRule ^foo/bar$ - [F]
If I request /foo/bar
I get a 404 (Not Found) error complete with a 'None could be negotiated' line in the error log. Requesting /foo/bar.html
does work, so I'm guessing that the content-negotiation is taking 'priority' over the RewriteRule and keeps looking for alternative URLs until it finds a 200. In fact, I've pretty much confirmed that by testing with a bar.txt
file and a RewriteRule that only targets the .html file.
So, is there a way of modifying mod_negotiation's behaviour to 'give up' as soon as it encounters a Forbidden error?
UPDATE
NB: It looks as though I can workaround the problem by disabling MultiViews and using mod_rewrite instead e.g.
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]
but I'm guessing that's less efficient, and it's a lot more config to deal with
Based on the fact that you're omitting your leading slash from
^foo
, I'm guessing that this is configured in a<Directory>
block orhtaccess
file?That's actually the cause of the problem in this case; in that context, the rewrite rules are applied after the request has been mapped to the file system (and the
.html
has been tacked on).From the docs:
Move your
RewriteRule
configuration up to the<VirtualHost>
context (and modify your match accordingly, from^foo/bar$
to^/foo/bar$
), and it should work as expected.