I searched for hours, but it seems Apache has no solution for my need. I need to check if a request header is present and depending on it I want to define a rewrite rule. I can check if the header value is empty, but if the header doesn’t exist such condition doesn’t consider the existence of the header. I already tried if else directive, but also no success, because Apache seems to have its focus only on the value.
This works if header value is empty but not if these headers don’t exist.
RewriteCond %{HTTP:Sec-Fetch-Dest} ^$ [NC]
RewriteCond %{HTTP:Sec-Fetch-Mode} ^$ [NC]
RewriteCond %{HTTP:Sec-Fetch-Site} ^$ [NC]
RewriteCond %{HTTP:Sec-Fetch-User} ^$ [NC]
RewriteRule ^.*$ - [ENV=TEST:true]
header set x-test "1" env=TEST
2
Answers
You are correct, you cannot differentiate between an HTTP request header that is present but empty or does not exist at all – you would have to assume it does not exist in both cases, which would be the correct action in the majority (all?) of cases. (I’m not aware of any request headers where an empty value is considered a positive value?)
For example:
The above condition will be successful if the
Sec-Fetch-Dest
HTTP request header exists but is empty or is not present at all on the HTTP request.I’m not sure why you state that this does not work if the headers "don’t exist". This should be processed the same whether all the headers don’t exist or are all empty, which is arguably the correct action.
None of these headers permit an empty value, so assuming they don’t exist when they are empty is certainly the correct action in this case.
Further reading:
As mentioned in comments above that your shown code should work as is to set request header
x-test
for both the cases i.e.I am suggesting a more concise code using
mod_setenvif
Note how we can combine all four headers in single regular expression instead of 4 different
RewriteCond
directives in your shownmod_rewrite
rule.For testing I have used following
curl
commands on my locally running Apache:We will get
x-test: 1
shown in response only for the first command.