7

In my Apache httpd.conf file I have this declaration inside a VirtualHost tag.

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.shanestillwell.com$ [NC]
RewriteRule ^(.*)$ http://www.shanestillwell.com/$1 [L,R=301]

And this inside my .htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

The rule in my httpd.conf seems to be ignored. Are the rules in .htaccess wiping out the httpd.conf rewrite rule?

3 Answers 3

4

Generally your settings in .htaccess file inside a directory overrides httpd.conf file settings. You can disable this effect by editing your httpd.conf file and change the following line

  <Directory ...> 
  AllowOverride all

to

    <Directory ...> 
    AllowOverride none

This will prevent .htaccess file from overriding httpd.conf settings. So the settings in .htaccess file will have no effect.

3
  • I have AllowOverride All, but I think in this case it's because the .htaccess catches the request and redirects it before it hits the rules in the http.conf file. See stackoverflow.com/questions/3557040/… Sep 4, 2010 at 2:36
  • 1
    "Generally your settings in .htaccess file inside a directory overrides httpd.conf file settings." - this statement is false (or at best misleading) without further information/context. The question is specifically discussing mod_rewrite. The mod_rewrite directives in the .htaccess file will only override the mod_rewrite directives in httpd.conf if the directives in httpd.conf are also in a <Directory> container. Unfortunately, this has not actually been stated in the question. The context in which these directives are used is everything.
    – MrWhite
    Apr 14, 2018 at 0:52
  • "This will prevent .htaccess file from overriding httpd.conf settings. So the settings in .htaccess file will have no effect." But what if I want the rules in .htaccess to be applied too? i.e. I want to merge the two rulesets.
    – Thayne
    Sep 10, 2019 at 1:13
3

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).

1

if you have a <Directory ...> with AllowOverride all then whatever you have on your .htaccess file will be replacing any previous rule.

It could be in your httpd.conf or on your virtualhost as long as it point to / or to your domain path.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .