An interesting oddity with mod_rewrite is that it is very
difficult[impossible?] to set environmental variables.
Because of the multiple passes apache makes through the entire rewrite
ruleset, env variables tend to end up with the prefix 'redirect_' added
to them.
At first it seemed like the issue was the difference between the Last
and the END flag for rewrite_rules:
http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule
However, there does not seem to be any set of variables which can ensure
apache will skip reprocessing htaccess rules.
The problem appears to be that the environmental variables are renamed
before checking for the end flag:
After a pass through hook_fixup is complete, the new request information
will be sent back to a special internal rewriter:
https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c#L5080
This in turn starts the whole rule checking process over again in
http_request and the request record is copied into a new record in
internal_internal_redirect - at which time the environemental variables
are renamed.
https://github.com/apache/httpd/blob/trunk/modules/http/http_request.c#L473
This then kicks back another pass through hook_fixup in mod_rewrite - at
which point mod_rewrite will detect that the END flag had been set and
so all htaccess rules are skiped:
https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c#L4843
The problem is that this is too late in the process, by this point in
time the env vars have been renamed.
I've tried hacking around with mod_rewrite and http_request to add
another check for the END flag so as to abort processing. The most
promising was to copy lines 4842 through 4847 so that they also appeared
right before the internal redirect in the same function at line 5079
https://github.com/apache/httpd/blob/trunk/modules/mappers/mod_rewrite.c#L5079
Placing it at that spot would correctly stop the rewrite processing, but
it would also stop some additional filename cleanup/directory prefix
cleanup - so where I had rules to internally redirect missing file
requests to a specific php file Apache could not find the file[but it
could load the file when directly entered]
I also tried adding some checks into http_request but they didn't seem
to be called at all.
The easiest solution would be to simply replace line 473 in http_request.c
new->subprocess_env=rename_original_env(r->pool,r->subprocess_env);
with
new->subprocess_env=r->subprocess_env;
As near as I can tell, the internal redirect logic is explictly only for
internal redirects, so there is no need to rename environemntal
variables at all.
Rather then continue fiddling with it, I am using that small change for
my own server and I wanted to find out of there was some reason for this
behaviour today? [I realise that this function may well have been called
from many places in the past and so used to need to rename the
variables- I just can't see any reason for it today]
-Gary