homepage Welcome to WebmasterWorld Guest from 54.205.189.156
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe to WebmasterWorld
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Using custom environment variables in .htaccess
DrDoc




msg:1510578
 7:39 pm on Oct 26, 2004 (gmt 0)

In my httpd.conf I have defined a couple different environment variables using the SetEnv directive. This works fine in my Perl and PHP scripts, but not in my .htaccess file.

For example, say that I have the following line in my httpd.conf:
SetEnv foo bar

How can I access the foo variable (in my .htaccess file) in the same manner I can access variables like REQUEST_URI, HOST_NAME, etc?

Well, actually... it's not just to be able to access through mod_rewrite, but to use elsewhere too:

php_value include_path ".:MY_CUSTOM_ENVIRONMENT_VARIABLE_HERE/public_html"

 

DrDoc




msg:1510579
 7:50 pm on Oct 26, 2004 (gmt 0)

In addition... This doesn't work either:
RewriteRule .* http://www.google.com/search?q=[b]%{ENV:MyEnvVar}[/b] [L,R=301]

:(

jdMorgan




msg:1510580
 8:55 pm on Oct 26, 2004 (gmt 0)

You're probably running into a "processing order" problem here, similar to DJJoe's problem in this thread: [webmasterworld.com...]

The problem is that Apache apparently processes per-server rules first, then per-directory rules, and finally config rules. See the mod_rewrite "Internal Processing - API Phases" section. I have not experimented with this in-depth, and my statement is based soley on this and the other thread. But you might want to experiment with defining and referencing variables at all three levels to find out which levels can inherit from which other levels.

Also be aware that at each level, mod_setenv may be processed before mod_rewrite or vice-versa, depending on reverse-LoadModule-order in Apache pre-2.0 and depending on priority settings in Apache 2.0 and above. That is, each module reads and interprets your configuration files, and handles only the directives it understands. So, within each file, you can specify the order that directives for one module are processed, but you cannot specify what order the directives will be processed by the modules. This is hard to describe, but for example there is no difference at all in order of execution between

RewriteRule (.*)\.html$ /$1.php [L]
ErrorDocument 404 /error404.html

-and-

ErrorDocument 404 /error404.html
RewriteRule (.*)\.html$ /$1.php [L]

because each module will read that code and handle only the directives that it understands, and the code itself does not determine the order that the modules will be called. That is determined as described above.

How this may affect you is if you use two different modules to set and test variables. The code

SetEnv foo bar
... (additonal logic)
RewriteCond %{ENV:foo} ^bar$
RewriteRule ^.*$ /isbar.php?why=foo

may or may not work, depending on whether mod_setenv or mod_rewrite processes the code first. A better solution might be:

RewriteRule .* - [E=foo:bar]
... (additional logic)
RewriteCond %{ENV:foo} ^bar$
RewriteRule ^.*$ /isbar.php?why=foo

This would guarantee that the variable would be set before it was tested, because both functions are being handled by the same Apache module.

Jim

DrDoc




msg:1510581
 9:30 pm on Oct 26, 2004 (gmt 0)

What you're saying completely makes sense... Unfortunately I do not have the option of setting the environment variable by mod_rewrite in my .htaccess file.

I've had similar problems before (where the order of the included modules made a difference)...

The modules are currently loaded in the following order:
LoadModule access_module modules/mod_access.so 
LoadModule auth_module modules/mod_auth.so
LoadModule auth_anon_module modules/mod_auth_anon.so
LoadModule auth_dbm_module modules/mod_auth_dbm.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule cern_meta_module modules/mod_cern_meta.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule usertrack_module modules/mod_usertrack.so
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule asis_module modules/mod_asis.so
LoadModule info_module modules/mod_info.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
LoadModule imap_module modules/mod_imap.so
LoadModule actions_module modules/mod_actions.so
LoadModule speling_module modules/mod_speling.so
LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule rewrite_module modules/mod_rewrite.so

I tried putting mod_env first, but that made no difference. Any other suggestions as to what I could do?

DrDoc




msg:1510582
 9:55 pm on Oct 26, 2004 (gmt 0)

<Directory> and .htaccess are loaded in order of "shortest match"... So, for a path like
/foo/bar it will:
  • Apply any directives for <Directory />
  • Apply anything found in /.htaccess
  • Apply any directives for <Directory /foo>
  • Apply anything found in /foo/.htaccess
    ...etc

    So, if I set the environment variables in <Directory />, load mod_rewrite last... shouldn't the environment variable exist by the time it gets down to the .htaccess file in the end folder?

  • jdMorgan




    msg:1510583
     10:15 pm on Oct 26, 2004 (gmt 0)

    > jd: mod_setenv may be processed before mod_rewrite or vice-versa, depending on reverse-LoadModule-order

    > Dr: I tried putting mod_env first, but that made no difference. Any other suggestions as to what I could do?

    The key here is the word "reverse". In Pre-2.0 Apache, modules loaded first are run last. Try putting mod_setenv *after* mod_rewrite.

    > <Directory> and .htaccess are loaded in order of "shortest match"...
    > So, if I set the environment variables in <Directory />, load mod_rewrite last... shouldn't the
    > environment variable exist by the time it gets down to the .htaccess file in the end folder?

    I don't know, I've never been down this path before. All I can offer is possibly-related clues remembered from other threads and other problems... I hope they may help. If not, at least they bump your thread up... ;)

    Jim

    DrDoc




    msg:1510584
     10:30 pm on Oct 26, 2004 (gmt 0)

    pre 2.0 Apache

    Well, this is 2.0 :)
    Tried putting it last anyway... and no love.

    Now, a related question which hasn't been addressed yet... If we disregard mod_rewrite for a sec -- is there a way I can use env variables (or any variables for that matter) in other places, for example when setting the PHP include_path in .htaccess?

    DrDoc




    msg:1510585
     8:41 pm on Oct 27, 2004 (gmt 0)

    Anyone know about the variable question? I've looked all over the place, but not been able to find a for-sure answer to it. In fact, I haven't been able to find a place even beginning to talk about it :(

    coopster




    msg:1510586
     11:54 pm on Oct 27, 2004 (gmt 0)

    I have been playing with this for a bit. Can't get any SetEnv variable to work in a RewriteRule. Nor can I check it in a RewriteCond. If I use RewriteRule itself to set the ENV: variable, then all is well. But using SetEnv, no cigar. This works...

    RewriteRule .* - [E=foo:bar] 
    RewriteCond %{ENV:foo} ^(.*)$
    RewriteRule ^.*$ index.php?why=foo&q=%1 [L]

    I have the index.php script dump out my superglobals...


    $_GET:
    Array
    (
    [why] => foo
    [q] => bar
    )
    $_SERVER
    Array
    (
    [REDIRECT_foo] => bar
    [REDIRECT_STATUS] => 200
    [foo] => bar
    .
    .
    .
    )

    ...but this does not work...

    SetEnv foo bar 
    RewriteCond %{ENV:foo} ^(.*)$
    RewriteRule ^.*$ index.php?why=foo&q=%1 [L]



    $_GET:
    Array
    (
    [why] => foo
    [q] =>
    )
    $_SERVER
    Array
    (
    [REDIRECT_foo] => bar
    [REDIRECT_STATUS] => 200
    [foo] => bar
    .
    .
    .
    )
    I can see that the foo environment variable is set, but why didn't rewrite recognize it and put it into the query string ($_GET)?
    coopster




    msg:1510587
     12:02 am on Oct 28, 2004 (gmt 0)

    Oh yeah, about the best I've found so far regarding where and when we can use the environment variables has been in the opening paragraphs of the Apache Environment Variables [httpd.apache.org] documentation.

    It also answers the question I just raised... "Does Rewrite talk to SetEnv variables"? No.


    URL Rewriting

    The %{ENV:...} form of TestString in the RewriteCond allows mod_rewrite's rewrite engine to make decisions conditional on environment variables. Note that the variables accessible in mod_rewrite without the ENV: prefix are not actually environment variables. Rather, they are variables special to mod_rewrite which cannot be accessed from other modules.


    DrDoc




    msg:1510588
     12:44 am on Oct 28, 2004 (gmt 0)

    Actually, it doesn't answer the question about whether mod_rewrite can read the SetEnv variables...

    The %{ENV:...} form of TestString in the RewriteCond allows mod_rewrite's rewrite engine to make decisions conditional on environment variables. (It doesn't explicitly say that the rewrite engine can make decisions based only on environment variables created by mod_rewrite itself. Instead, it simply states "environment variables" in general, which I take as any environment variable.) Note that the variables accessible in mod_rewrite without the ENV: prefix are not actually environment variables. (This sentence has nothing to do with the environment variables. Instead, it states that other variables, such as %{REQUEST_URI}, %{HTTP_HOST}, etc, are mod_rewrite specific, and not generally accessible.) Rather, they are variables special to mod_rewrite which cannot be accessed from other modules.
    Emphasis by me

    In fact, under "Special Notes" it states:
    There is the special format: %{ENV:variable} where variable can be any environment variable. This is looked-up via internal Apache structures and (if not found there) via getenv() from the Apache server process.

    That tells me I should be able to set the variable using SetEnv, and then be able to access it using %{ENV:variable} in mod_rewrite.

    So, that's problem number one -- how to access any environment variable in mod_rewrite.
    Problem number two is slightly different -- how to access any variable anywhere in the .htaccess file (if it is at all possible). For example, something like:
    php_value include_path ".:/usr/lib/php:[b]%{My_Environment_Variable}[/b]"

    coopster




    msg:1510589
     1:13 am on Oct 28, 2004 (gmt 0)

    You're right, now that I read that again, it does seem to be the other way around. I played with that simple test for quite some time trying to read the variable to no avail.

    DrDoc




    msg:1510590
     6:20 pm on Oct 28, 2004 (gmt 0)

    This is frustrating :)
    And I haven't been able to find an example of anyone else doing this either.
    If I don't have a solution by the weekend, I'm gonna file it as an Apache/mod_rewrite bug :)

    Global Options:
     top home search open messages active posts  
     

    Home / Forums Index / Code, Content, and Presentation / Apache Web Server
    rss feed

    All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
    Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
    WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
    © Webmaster World 1996-2014 all rights reserved