You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Nick Gearls <ni...@gmail.com> on 2011/12/19 15:40:08 UTC

mod_substitute buggy execution order

Directive execution order is performed in a very strange way in 
mod_substitute.

Look at the following example:

    Substitute  "s/aaa/global/inq"
    <Location /test/>
      Substitute  "s/aaa/local/inq"
    </Location>

If I have "aaa" in a page, I expect it to be replaced by "global".
No luck, it is replaced by "local".

Even more crazy:

    <Location /test/>
      Substitute  "s/aaa/local1/inq"
    </Location>
    <Location /test/>
      Substitute  "s/aaa/local2/inq"
      Substitute  "s/aaa/local3/inq"
    </Location>

I expect the first directive to execute and see "local1".
No luck again, it is replaced by "local2" - yes, not "local3".

The merging of directive by Apache is performed in the following order: 
global, local1, local2, local3
but directives are executed in the following order: : local2, local3, 
local1, global

Am I confused or should we fix that?

Thanks,

Nick


Re: Fwd: mod_substitute buggy execution order

Posted by "William A. Rowe Jr." <wr...@rowe-clan.net>.
On 12/20/2011 1:44 AM, Nick Gearls wrote:
> That's very different from other modules.
> Most (all?) modules do the opposite: first global, then local - ex: rewrite
> 
> Furthermore, narrowing does not work the way you expect as
> 
>    <Location /test/>
>      Substitute  "s/aaa/local1/inq"
>    </Location>
>    <Location />
>      Substitute  "s/aaa/local2/inq"
>      Substitute  "s/aaa/local3/inq"
>    </Location>
> 
> will end up with "local2" which is not the narrowest-scope.
> 
> I understand your concern, but this definitely breaks the usual way of working which thus
> introduces an inconsistency with other modules .

This is clearly broken, if you in fact tested this particular example.

But again, I'm not sure we can alter the behavior without silently breaking
existing configurations.  It doesn't seem very well thought out, but again
it's already been replaced.

>> mod_substitute is gone from 2.4
> Is it replaced by mod_sed? What is the logic there?

It's an independently developed module, I can't tell you offhand
how it behaves.

We might be safer backporting mod_sed to 2.2 and deprecating mod_substitute
in that tree for users who need the correct behavior.

In any case, patches to the docs to clarify this behavior for the users
would absolutely be welcome!!!

Fwd: mod_substitute buggy execution order

Posted by Nick Gearls <ni...@gmail.com>.
That's very different from other modules.
Most (all?) modules do the opposite: first global, then local - ex: rewrite

Furthermore, narrowing does not work the way you expect as

    <Location /test/>
      Substitute  "s/aaa/local1/inq"
    </Location>
    <Location />
      Substitute  "s/aaa/local2/inq"
      Substitute  "s/aaa/local3/inq"
    </Location>

will end up with "local2" which is not the narrowest-scope.

I understand your concern, but this definitely breaks the usual way of 
working which thus introduces an inconsistency with other modules .

> mod_substitute is gone from 2.4
Is it replaced by mod_sed? What is the logic there?

Thanks,

Nick


-------- Original Message --------
Subject: 	Re: mod_substitute buggy execution order
Date: 	Mon, 19 Dec 2011 15:34:41 -0600
From: 	William A. Rowe Jr. <wr...@rowe-clan.net>
To: 	dev@httpd.apache.org
CC: 	Nick Gearls <ni...@gmail.com>



On 12/19/2011 8:40 AM, Nick Gearls wrote:
>  Directive execution order is performed in a very strange way in mod_substitute.
>
>  Look at the following example:
>
>     Substitute  "s/aaa/global/inq"
>     <Location /test/>
>       Substitute  "s/aaa/local/inq"
>     </Location>
>
>  If I have "aaa" in a page, I expect it to be replaced by "global".
>  No luck, it is replaced by "local".

Not a bug.  {global} is broader scope than /test/ URI.  Therefore the
server is performing the narrowest-scope replacements, first.

Otherwise, there would be no way to fine-tune the results in more
narrow contexts!

>  Even more crazy:
>
>     <Location /test/>
>       Substitute  "s/aaa/local1/inq"
>     </Location>
>     <Location /test/>
>       Substitute  "s/aaa/local2/inq"
>       Substitute  "s/aaa/local3/inq"
>     </Location>
>
>  I expect the first directive to execute and see "local1".
>  No luck again, it is replaced by "local2" - yes, not "local3".
>
>  The merging of directive by Apache is performed in the following order: global, local1,
>  local2, local3
>  but directives are executed in the following order: : local2, local3, local1, global
>
>  Am I confused or should we fix that?

I think this is fine.  It certainly should be documented, and we could
process replacements in last-to-first order within the same scope, but
I'm not sure that makes a huge difference (and would be inappropriate
to change this late in 2.2).  Since mod_substitute is gone from 2.4, I
doubt there is really an opportunity to change this anymore.




Re: mod_substitute buggy execution order

Posted by "William A. Rowe Jr." <wr...@rowe-clan.net>.
On 12/19/2011 8:40 AM, Nick Gearls wrote:
> Directive execution order is performed in a very strange way in mod_substitute.
> 
> Look at the following example:
> 
>    Substitute  "s/aaa/global/inq"
>    <Location /test/>
>      Substitute  "s/aaa/local/inq"
>    </Location>
> 
> If I have "aaa" in a page, I expect it to be replaced by "global".
> No luck, it is replaced by "local".

Not a bug.  {global} is broader scope than /test/ URI.  Therefore the
server is performing the narrowest-scope replacements, first.

Otherwise, there would be no way to fine-tune the results in more
narrow contexts!

> Even more crazy:
> 
>    <Location /test/>
>      Substitute  "s/aaa/local1/inq"
>    </Location>
>    <Location /test/>
>      Substitute  "s/aaa/local2/inq"
>      Substitute  "s/aaa/local3/inq"
>    </Location>
> 
> I expect the first directive to execute and see "local1".
> No luck again, it is replaced by "local2" - yes, not "local3".
> 
> The merging of directive by Apache is performed in the following order: global, local1,
> local2, local3
> but directives are executed in the following order: : local2, local3, local1, global
> 
> Am I confused or should we fix that?

I think this is fine.  It certainly should be documented, and we could
process replacements in last-to-first order within the same scope, but
I'm not sure that makes a huge difference (and would be inappropriate
to change this late in 2.2).  Since mod_substitute is gone from 2.4, I
doubt there is really an opportunity to change this anymore.