Mailing List Archive

Meaning of RewriteRules in adjacent <If> sections
Some comments and a question about the manual's discussion
of RewriteRules in immediately adjacent <If> sections.

In mod_rewrite.html (https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html),
the section "Per-directory Rewrites" includes these notes with example:

==========
• By default, mod_rewrite overrides rules when merging sections belonging to the same context. The RewriteOptions directive can change this behavior, for example using the Inherit setting.

• The RewriteOptions also regulates the behavior of sections that are stated at the same nesting level of the configuration. In the following example, by default only the RewriteRules stated in the second If block are considered, since the first ones are overridden. Using RewriteOptions Inherit forces mod_rewrite to merge the two sections and consider both set of statements, rather than only the last one.

<If "true">
# Without RewriteOptions Inherit, this rule is overridden by the next
# section and no redirect will happen for URIs containing 'foo'
RewriteRule foo http://example.com/foo [R]
</If>
<If "true">
RewriteRule bar http://example.com/bar [R]
</If>
==========

Comment #1: in the text, the three occurrences of "RewriteOptions"
are linked to an incorrect URL
( https://httpd.apache.org/docs/2.4/mod/rewrite.html#rewriteoptions
instead of
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions ).

Very minor comment #2: The text says "the RewriteRules stated in the second If block"
and "the first ones", but there's only _one_ RewriteRule in each If block.

Question: in the example, despite the wording "stated at the same
nesting level of the configuration", are the two <If> sections supposed to be
embedded in _separate_ (.htaccess or <Directory>) contexts, rather
than being immediately adjacent?

The text seems rather to imply that the description/example is supposed to be as it is,
but then the behaviour described is somewhat "counter-intuitive", i.e., I don't see how
I could have deduced it from the descriptions of RewriteOptions and <If>.
The description of RewriteOptions Inherit at
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
does explicitly mention the case of per-directory context, and then
only talks about merging rules from the _parent_ context, not from
_sibling_ contexts.

Richard.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: Meaning of RewriteRules in adjacent <If> sections [ In reply to ]
> The text seems rather to imply that the description/example is supposed to be as it is,
> but then the behaviour described is somewhat "counter-intuitive", i.e., I don't see how
> I could have deduced it from the descriptions of RewriteOptions and <If>.
> The description of RewriteOptions Inherit at
> https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
> does explicitly mention the case of per-directory context, and then
> only talks about merging rules from the _parent_ context, not from
> _sibling_ contexts.

I think the root cause of all of this is that rewrite barely made
sense in non-htacess directory contexts, and then was tolerated in
Location, and then further tolerated in <If>. So code/doc that were
primarily about htaccess now apply differently. Further, if it was
intuitive it would probably omitted from the docs.

Maybe there should be a prominent "warn" type note about using Rewrite
in <if>, outside of RewriteOptions. It's often necessary because
there are no lower level primitives that you can use inside <If> to
take the same actions as mod_rewrite.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: Meaning of RewriteRules in adjacent <If> sections [ In reply to ]
On Fri, 2023-01-20 at 15:05 +1100, Richard Walker wrote:
> Comment #1: in the text, the three occurrences of "RewriteOptions"
> are linked to an incorrect URL
> ( https://httpd.apache.org/docs/2.4/mod/rewrite.html#rewriteoptions
> instead of
> https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
>  ).

Fixed in r1906839 in Trunk. Thank you.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
Re: Meaning of RewriteRules in adjacent <If> sections [ In reply to ]
On 20 Jan 2023, at 3:05 pm, Richard Walker <richard.walker@ardc.edu.au> wrote:
> In mod_rewrite.html (https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html),
> the section "Per-directory Rewrites" includes these notes with example:
>
> ==========
> • By default, mod_rewrite overrides rules when merging sections belonging to the same context. The RewriteOptions directive can change this behavior, for example using the Inherit setting.
>
> • The RewriteOptions also regulates the behavior of sections that are stated at the same nesting level of the configuration. In the following example, by default only the RewriteRules stated in the second If block are considered, since the first ones are overridden. Using RewriteOptions Inherit forces mod_rewrite to merge the two sections and consider both set of statements, rather than only the last one.
>
> <If "true">
> # Without RewriteOptions Inherit, this rule is overridden by the next
> # section and no redirect will happen for URIs containing 'foo'
> RewriteRule foo http://example.com/foo [R]
> </If>
> <If "true">
> RewriteRule bar http://example.com/bar [R]
> </If>
> ==========
>
> ...
> Question: in the example, despite the wording "stated at the same
> nesting level of the configuration", are the two <If> sections supposed to be
> embedded in _separate_ (.htaccess or <Directory>) contexts, rather
> than being immediately adjacent?
>
> The text seems rather to imply that the description/example is supposed to be as it is,
> but then the behaviour described is somewhat "counter-intuitive", i.e., I don't see how
> I could have deduced it from the descriptions of RewriteOptions and <If>.
> The description of RewriteOptions Inherit at
> https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
> does explicitly mention the case of per-directory context, and then
> only talks about merging rules from the _parent_ context, not from
> _sibling_ contexts.

OK, I've now done what I should already have done: I tested
the example to see how it behaves. I was able to test using 2.4.54.

I created a directory, created .htaccess within it and inserted the
example configuration preceded by "RewriteEngine On", and then accessed
the two URLs ending in .../foo and .../bar.

I confirm that with the example as given, the URL ending .../foo
gives a 404, and the URL .../bar gives the 302 rewrite correctly.

Sanity check #1: I changed the flags to "[R,L]": no change in behaviour.

Sanity check #2: I swapped the order of the two
<If> sections; I confirm that it is indeed "second one wins".

Sanity check #3: I restored the two <If> sections to the original order,
and copy/pasted the RewriteRule from the body of the first <If> into
the body of the second. Now both URLs perform the rewrite correctly.

I then restored the two <If> sections to the original content, and then
put a copy of the whole first <If> section after the second. (So, foo, then bar,
then foo again.) I confirm that it is indeed "last one wins".

So far, so consistent with the comment "Without RewriteOptions Inherit,
this rule is overridden by the next section".

_However_: I then restored the content of .htaccess to the initial setup,
and inserted "RewriteOptions Inherit" between
"RewriteEngine On" and the first <If> section, and repeated
the initial test. There is _no_ change in behaviour!

And then I repeated the test using "RewriteOptions InheritBefore".
Again, no change in behaviour.

So: it seems that the comment "Without RewriteOptions Inherit,
this rule is overridden by the next section" isn't quite right:
it seems rather to be the case that "_With or without_ RewriteOptions Inherit,
this rule is overridden by the next section" ....

Richard.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org