skip to Main Content

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


  1. 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:

    RewriteCond %{HTTP:Sec-Fetch-Dest} ^$ [NC]
    

    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.

    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
    

    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:

    Login or Signup to reply.
  2. 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.

    1. All the four mentioned headers are empty
    2. All the four mentioned headers are missing (you wanted this one to work)

    I am suggesting a more concise code using mod_setenvif

    SetEnvIf ^Sec-Fetch-(Dest|Mode|Site|User)$ ^$ aTEST
    Header set x-test "1" env=aTEST
    

    Note how we can combine all four headers in single regular expression instead of 4 different RewriteCond directives in your shown mod_rewrite rule.


    For testing I have used following curl commands on my locally running Apache:

    curl -IL -H 'localhost/'
    curl -IL -H 'Sec-Fetch-Dest: foo' 'localhost/'
    curl -IL -H 'Sec-Fetch-Mode: bar' 'localhost/'
    

    We will get x-test: 1 shown in response only for the first command.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search