3

Only thee following directives in the .htaccess file

SetEnvIf _ .* SSS=1

  <If "%{ENV:SSS} -eq 1">
    Header set MyHeader 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-%{SSS}e'
  </If>
  <Else>
    Header set MyHeader 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy-%{SSS}e'
  </Else>

Looking into the response headers the condition is never met. Whatever I try, -eq. -ne, ==, != etc.

At the same time -%{SSS}e always shows 1 in any condition.

If has "high priority" and executes while SSS is undefined? Well,

<If "%{ENV:SSS} == ''">

always evaluates to true xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-1. How that is possible - In the evaluation variable is not defined, but within the condition processing it is?

Where do I make mistake - unable to find any clue what's wrong.

Why I do that in general - I need to check if specific conditions are met using rewriterules setting variables [E:VAR:VAL], and after that processing I check final conditions to set specific headers. But this If condition messes everything because if is being executed out of order?

Update: all the variables set in the course of working on .htaccess are defined within the If or Else when their execution starts, but the If condition evaluation seems to be performed before those variables got defined.

I do not care how to achieve the result - is there any other way to conditionally execute Header set command with variable injection without using If?

7
  • Check the note on "Environment variable ordering" here, httpd.apache.org/docs/2.4/expr.html#functions Commented Aug 29 at 14:02
  • Thanks. that's why I use SetEnvIf. Possible to legitimately defer the If to evaluate the last? If this is an actual issue... Commented Aug 29 at 14:04
  • Aside: SetEnvIf _ .* SSS=1 - What is the underscore (first argument) referencing here? This doesn't set the env var "unconditionally", if that is the intention? Commented Aug 29 at 17:07
  • 1
    @MrWhite google is our friend. Here it is serverfault.com/a/288468 I obviously did not read comments! If you'll put "SetEnvIf _" into the google search (with quotes) you'll see more examples. Commented Aug 29 at 18:45
  • 1
    "you'll see more examples" - the more examples reference this question! And other (what look-like) copies/translations of this question!? lol Commented Aug 29 at 19:15

2 Answers 2

4

Looked up the issue might be in apaches If directive evaluates conditions before any requests but the variables aren't readable until requests are processed

If that's the issue this might work better

SetEnvIf _ .* SSS=1
Header always set MyHeader 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-%{SSS}e' "expr=%{ENV:SSS} == '1'"
Header always set MyHeader 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy-%{SSS}e' "expr=%{ENV:SSS} != '1'"
Sign up to request clarification or add additional context in comments.

Comments

1

Apache <If> expressions are not very intuitive. They result in unexpected behaviour in several scenarios, which greatly lessens their usefulness. The <If> expression itself is processed very early, but the contents of the <If> block (the section) is merged (very) late. mod_headers (Header directive) is also processed late.

As noted in the Apache Docs (linked to by @C3roe in comments) setting an environment variable in .htaccess (regardless of method) is too late to be picked up by the <If> expression. The docs suggest the use of SetEnvIf in a vitualhost context. However, by the time the section is merged it is set.

Fortunately, the Header directive itself has a mechanism for setting headers conditionally based on environment variables, as @evanhu96 pointed out in his answer. It's a little unclear from the example in the question, but if you just need to determine whether an environment is set (regardless of value) then you don't need an expression. For example, the following only sets the header if the SSS env var is set.

Header set MyHeader 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-%{SSS}e' env=SSS

I need to check if specific conditions are met using rewriterules setting variables [E:VAR:VAL]

Note that the use of mod_rewrite can further complicate matters. Depending on the specific directives, a loop by the rewrite engine can occur, renaming environment variables with a REDIRECT_ prefix. This can be circumvented in some cases with the use of the END lag (as opposed to L).

(Note that the syntax is [E=VAR:VAL].)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.