In Apache does the .htaccess file override the httpd.conf for mod_rewrites?
Taken literally, the answer is "No". However, ...
In my Apache httpd.conf
file I have this declaration inside a VirtualHost
tag
If it really is directly inside the <VirtualHost>
container, ie. in a virtualhost context, then these mod_rewrite directives should override the mod_rewrite directives in your .htaccess
file - not the other way round. This behaviour cannot be changed (eg. by changing mod_rewrite inheritance with the RewriteOptions
directive).
However, if these directives are inside a <Directory>
container (which is inside your <VirtualHost>
container), ie. in a directory context (as opposed to a virtualhost context, as suggested above), then the mod_rewrite directives in your .htaccess
file will indeed completely override the mod_rewrite directives in your <Directory>
container. However, this behaviour can be changed by changing the way mod_rewrite directives are inherited. (By either setting RewriteOptions InheritBefore
in the .htaccess
file, or RewriteOptions InheritDownBefore
in the parent <Directory>
container. InheritDownBefore
requires Apache 2.4.8. However, there are other caveats with mod_rewrite inheritance to be aware of.)
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
The behaviour you are seeing (and the specific syntax of the directive used (see below) - although this might simply be a mistake if the code has never been executed?) suggests these directives are in a directory context, not a virtualhost context. So yes, the mod_rewrite directives in .htaccess
will completely override the parent directives - the mod_rewrite directives in the <Directory>
container are effectively ignored.
Aside:
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
If this was used in a virtualhost context then you'd get an erroneous double slash at the start of the URL-path, because in a virtualhost context the RewriteRule
pattern matches against the full URL-path (which includes a slash prefix). So the $1
backreference itself would already contain a slash prefix before including an additional slash in the substitution.
However, in a directory context, the RewriteRule
pattern matches against a partial path - a filesystem path less the directory-prefix (which ends with a slash) - so the path that is matched by the RewriteRule
pattern never starts with a slash in a directory context (so you need to include it in the substitution - like you have done).