httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Graham Leggett <minf...@sharp.fm>
Subject mod_rewrite: RewriteEngine off doesn't work in a directory context
Date Sat, 06 Nov 2010 00:39:36 GMT
Hi all.

In mod_rewrite, we have the RewriteEngine directive, that in theory is  
able to switch the engine on and off. In practise however, you can  
switch it on, but once on globally, you cannot switch it off again -  
the directive has no effect.

This directive stores this flag in two places - the server config, or  
the directory config, leading to the server contradicting itself - one  
RewriteEngine directive, two places where this is stored:

     if (cmd->path == NULL) { /* is server command */
         sconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
     }
     else                   /* is per-directory command */ {
         dconf->state = (flag ? ENGINE_ENABLED : ENGINE_DISABLED);
     }

When an attempt is made to turn the engine off in the directory scope,  
the server scope stays active, you can't switch it off.

mod_rewrite hooks into two different hooks to do its magic, the  
translate_name hook for global rewrite rules, and the fixups hook for  
per-directory rewrite rules. In turn, the translate_name hook only  
looks for the flag in the global content, while the fixups hook only  
looks up the flag in the directory context. An attempt to turn off  
RewriteEngine in a directory leaves the engine on globally.

By way of example, this leads to this confusion:

# turn engine on in global scope
RewriteEngine on
RewriteRule ...
<Location /foo>
   # turn off engine in directory scope (but contradictory global  
scope stays enabled)
   RewriteEngine off
   # at this point, global rewrites are still on (!!!)
</Location>

This leads to the extremely (for us) undesirable situation where we  
cannot turn off global rewrite rules, they run on every single  
subrequest, including subrequests where we explicitly want the engine  
switched off.

Turns out we do need two copies of the flags - mod_rewrite has code  
that runs at the server scope only (specifically the code inside  
run_rewritemap_programs()). What we're doing wrong, when we set the  
flag at server scope, is that we're forgetting to also set the flag at  
directory scope at the same time, removing the contradiction.

This still doesn't fix the problem. Turns out that mod_rewrite suffers  
the config-merge bug, where if RewriteOption is set, RewriteEngine is  
also reset at the same time. This has been masked to date because the  
RewriteEngine directive didn't work as above.

The attached fix does two things, both are required or the problem  
isn't fixed:

- Adds *_set variables, so that config merge works properly.
- Sets the server-and-directory flags at the same time, or the  
directory flag only, and uses the directory flag were possible, and  
the server flag in run_rewritemap_programs(). This makes RewriteEngine  
and RewriteOption work properly.

Looking in bugzilla it looks like the following reports may be  
affected by this: PR46743, PR50004, PR39313.

Does this patch make sense?

Regards,
Graham
--

Mime
View raw message