httpd.conf variables : What is the difference between ${var} and %{var}?
What is the difference between ${var}
and %{var}
in httpd.conf?
How and when would one use ${}
and %{}
?
http://httpd.apache.org/docs/2.4/configuring.html mentions :
The values of variables defined with the Define of or shell environment variables can be used in configuration file lines using the syntax ${VAR}.
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html mentions:
Server-Variables:These are variables of the form %{ NAME_OF_VARIABLE }
and
RewriteMap expansions:These are expansions of the form ${mapname:key|default}.
Will ${VAR}
be used everywhere in httpd.conf, except in mod_rewrite directive's (like RewriteCond, RewriteRule but except for RewriteMap expansions which use ${}
as in RewriteRule ^/ex/(.*) ${examplemap:$1} )
Would a variable set in httpd.conf using SetEnvIf
Directive, for use in same httpd.conf, be used as ${var}
except when the variable is used with mod_rewrite directive's, where the variable would be used as %{var}
?
Solution 1:
What is the difference between ${var} and %{var} in httpd.conf?
Pretty much everything. There's no hard-and-fast rule that says "$
does x, %
does y", because they do different things depending on where and how they're used.
Will ${VAR} be used everywhere in httpd.conf, except in mod_rewrite directive's
No - ${VAR}
is applied as a replacement in every location throughout the config, even in a mod_rewrite related line. These can only be defined at startup using the -D
option passed to the httpd binary, or the Define
directive.
This can be done because those variables must not contain a :
character, whereas the RewriteMap
usage must contain a :
character. This allows for the $
to be used in extremely different ways with no conflict - the parser sees the :
and knows that it's not supposed to be replacing that.
Would a variable set in httpd.conf using SetEnvIf Directive, for use in same httpd.conf, be used as ${var} except when the variable is used with mod_rewrite directive's, where the variable would be used as %{var}?
No. Environment variables are not the same as variables set via -D
or Define
- they're a completely separate per-request context (those are the ones you're setting with SetEnvIf
), that only certain directives will use. They're specifically mentioned where supported - in mod_rewrite they're %{ENV:variable}
, in logs they're %{variable}e
, and a lot of directives have a logic check that looks like env=variable
.
So, basically; it's a confusing mess - a testament to the web server's history over the past couple decades. Probably the main thing that's confusing you is that mod_rewrite's syntax doesn't extend to any other part of the config in any way; it's all different. The main point to take from all this is that there isn't a governing 'rule' to make all of this make sense - a $
in one spot means something completely different from a $
in another spot.
A few handy reference points:
- If you're looking to set a variable statically when Apache starts, use
Define
and${VAR}
to replace once, on Apache's startup. This is mostly useful for when you want to do something like share config files between a development and production environment - but it's not to be confused with the use of the$
fromRewriteMap
, which always contains a:
. - If you're looking to work with variables in specific requests, then environment variables are what you're after - but you cannot make assumptions about the syntax that you'll use to get at them when used with a specific directive. You'll need to check the documentation for that directive.
- When mod_rewrite is in question, throw out everything you thought you knew about variables and their syntax. It has its own set of variables in
%{VAR}
, you can get at your 'normal' environment variables with%{ENV:VAR}
, and you can set environment variables with[E=VAR]
.
Solution 2:
I have looked at source code of mod_rewrite, and found that notes in comments (do_expand function):
/* variable lookup */
else if (*p == '%') {
...
/* map lookup */
else { /* *p == '$' */
so it looks, like % are for exact variables, while $ are for lookups in hash tables ("maps"). also, all mod_rewrite expansions are completely independed from core -- whole expansion done in module by itself.
I was thought earlier, but that was wrong:
${} vars are uses environment of project, and evaluated at time of config parse.
%{} vars are uses environment of request, and evaluated at time request parsed. mod_rewrite uses %{} symantic to prevent config-time interpolation made by httpd core.