Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Rewrite rules: How to check for host name in cookies?

I am setting a cookie using rewrite rules, and that is working (simplified for the sake of brevity):

RewriteCond %{QUERY_STRING} set_cookie=1 [NC]
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI}?skip=1 [QSA,NE,NC,L,CO=test_%{HTTP_HOST}:tmp:%{HTTP_HOST}:5:/]

This one sets a cookie with the name test_{host_name}. Now I want to read that cookie value the next request. I tried this (and some variants), but that does not seem to work.

RewriteCond %{QUERY_STRING} skip [NC]
RewriteCond %{HTTP_COOKIE} ^.*test_%{HTTP_HOST}=tmp.*$ [NC] 
RewriteRule ^(.*)$ - [L]

When I was googling, I found an article that stated the following:

If you are wondering, "Why not use %{HTTP_HOST} instead of corz.org, create universal code?", as far as I know, it's not possible to test one server variable against another with a RewriteCond without using Atomic Back References and some serious POSIX 1003.2+ Jiggery-Pokery.

I guess that's my problem, but I am sort of at a loss on how to solve it. Any help is greatly appreciated.

Regards, Joost.

like image 778
jberculo Avatar asked Sep 25 '14 19:09

jberculo


People also ask

What is RewriteRule * F?

F|forbidden The following rule will forbid .exe files from being downloaded from your server. RewriteRule "\.exe" "-" [F] This example uses the "-" syntax for the rewrite target, which means that the requested URI is not modified. There's no reason to rewrite to another URI, if you're going to forbid the request.

What is $1 in Apache rewrite rule?

$1 represents the match from the first set of parentheses in the RewriteRule regex, not in the RewriteCond regex.

What is RewriteBase Apache?

RewriteBase allows you to adjust the path that mod_rewrite automatically prefixes to the result of a RewriteRule . A rewrite within the context of . htaccess is done relative to the directory containing that . htaccess file. The immediate result of the RewriteRule is still relative to the directory containing the .


2 Answers

There's a useful trick in this area. It is simple regex, but a unique kind of mod_rewrite style.

Note I am not too careful about the matching here especially in the first condition -- this is for illustration in the 2nd condition:

RewriteEngine ON
RewriteCond %{HTTP_COOKIE} test_([^;]*)=tmp.*$
RewriteCond %1<>%{HTTP_HOST} ^(.+)<>\1
RewriteRule .* - [F]

The novel part (for mod_rewrite) is that you can only use variables/backrefs in the first argument, but you can use backrefs (for the current expression, not the preceding one) in the 2nd parameter.

The little <> is just something unlikely to appear as a separator.

like image 119
covener Avatar answered Sep 23 '22 04:09

covener


I have found a solution. This part in my original question

RewriteCond %{QUERY_STRING} skip [NC]
RewriteCond %{HTTP_COOKIE} ^.*test_%{HTTP_HOST}=tmp.*$ [NC] 
RewriteRule ^(.*)$ - [L]

should be replaced by the following

RewriteCond %{QUERY_STRING} skip [NC]
RewriteCond %{HTTP_HOST}@@%{HTTP_COOKIE} ^([^@]*)@@.*test_\1=tmp.* [NC]
RewriteRule ^(.*)$ - [L]

Only the second RewriteCond has changed. Its left hand side (%{HTTP_HOST}@@%{HTTP_COOKIE}) concatenates the http host and cookie values, using @@ as glue (@@ doesn't really mean something, it's just unlikely to be used in a normal host or cookie string).

The right hand side (^([^@]*)@@.*test_\1=tmp.*) matches everything to the first "@", which is the host name, and then checks if it can be found somewhere in the cookie values, preceded by "test_" and followed by "=tmp".

like image 43
jberculo Avatar answered Sep 24 '22 04:09

jberculo