JayAitch
JayAitch

Reputation: 175

Apache 2.4: Precedence of IF Rules?

I have, in this order, this set of rules in .htaccess, processed by Apache 2.4.33:

RewriteEngine On

RewriteCond %{HTTP_HOST}    ^(subdomain\.olddomain)\.com$ [NC]
RewriteRule ^               https://www.example.com/directory/%1%{REQUEST_URI} [R=301,L]

## for some of the specific rules below
RewriteBase /

<If "%{HTTP_HOST} =~ /^(?:.*\.)?olddomain\.(?:com|net)$/i">

    ## some other specific rules which do not fire

    RewriteRule ^               https://%1example.com/directory%{REQUEST_URI} [R=301,L]

</If>

However, it seems that the If block with the general rule set takes precedence although it follows the more specific first one rewriting to a different URL and terminated with L.

Changing (?:.*\.)? to (?:www\.)? things work as expected. Also if the first rule set is moved into the If block (more efficient code anyway, but things have evolved).

I have read, amongst others, this posting which I understand but can't apply to the case here as the first rule, if fired, should rewrite the domain/host and therefore should not match the If condition anymore.

@covener's comment to this posting mentions a precedence with regard to variables/modules, too, but is there a more general documentation? (I've read both the directive and the referenced article on expressions in TFM, noting the remark on If preceding authentication, too).

TIA for any suggestion a/o explanation.

Upvotes: 2

Views: 493

Answers (1)

covener
covener

Reputation: 17871

This looks like another subtle behavior in how directives are merged, and another one in which mod_rewrite is slightly non-standard.

Essentially what's happening here is that when the <If> matches, the enclosed RewriteRules are considered a new "configuration section" to be merged with the previous one for the modules whose directives appear.

But, mod_rewrite REPLACES previous configurations sections with new ones by default. They are not merged together. There are directives that control it under RewriteOptions.

It is really non-intuitive how directives configurations are evaluated, merged, then executed in three distinct phases. In the conf file, they just look like code that would be stepped through as encountered.

Upvotes: 1

Related Questions