You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Gary Mort <ga...@gmail.com> on 2014/05/29 22:34:20 UTC
Is there a reason for internal_internal_redirect to rename env variables?
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
Re: Is there a reason for internal_internal_redirect to rename env
variables?
Posted by Gary Mort <ga...@gmail.com>.
On 05/29/2014 04:38 PM, Eric Covener wrote:
> On Thu, May 29, 2014 at 4:34 PM, Gary Mort <ga...@gmail.com> wrote:
>> An interesting oddity with mod_rewrite is that it is very
>> difficult[impossible?] to set environmental variables.
> In per-directory context only, right?
>
I believe so. For my structure I have a single .htaccess file in my
root directory. A request to http://localhost/static/missing.png will
be rewritten internally so instead of trying to load the non-existent
file static/missing.png it will instead execute actions/badmedia.php
There is only a single .htaccess file in the root web directory[ie there
is no static/.htaccess file or actions/.htaccess file].
What threw me initially was that I made the assumption that
"per-directory" context meant that there were multiple .htaccess files,
when in fact as far as I can tell it just means that for each file
pattern, apache will reprocess the request with the ruleset specific to
that context.
ie for apache processing, there are 3 sets of rules:
One for the root directory
One for the static sub-directory, which is inherited from the root
One for the actions sub-directory, which is inherited from the root
Even though the rulesets all come from the same file, internally Apache
considers them independent and thus 'per-directory' refers to the
internal processing?
The renaming of env variables causes a lot of confusion...searching
around initially I saw many people banging their head into the same issue:
http://stackoverflow.com/questions/3050444/when-setting-environment-variables-in-apache-rewriterule-directives-what-causes
The only real solution seems to be to write a rewrite rule for every
variable.
Ie if I want to potentially set an env variable called:
OriginalMediaFile then I would also need to have
|RewriteCond %{ENV:REDIRECT_OriginalMediaFile} !^$
RewriteRule .* - [E=OrginalMediaFile:%{ENV:REDIRECT_OriginalMediaFile}]|
Since I was setting potentially up to 20 variables, I didn't want to
maintain that list which was why I looked into trying to get Apache to
honor the 'END' flag before renaming the variables. Since that didn't
work, I figured I'd ask to see if there was a strong reason for renaming
those variables in Apache 2.4.9 - since it's just a one line code change
to fix it if there isn't.
Re: Is there a reason for internal_internal_redirect to rename env variables?
Posted by Eric Covener <co...@gmail.com>.
On Thu, May 29, 2014 at 4:34 PM, Gary Mort <ga...@gmail.com> wrote:
> An interesting oddity with mod_rewrite is that it is very
> difficult[impossible?] to set environmental variables.
In per-directory context only, right?
--
Eric Covener
covener@gmail.com