Forum Moderators: phranque

Message Too Old, No Replies

RewriteCond variables

         

midoegypt

2:10 pm on Jul 12, 2010 (gmt 0)

10+ Year Member



hello,

i'm trying to make .htaccess read variables like
%{QUERY_STRING}
%{HTTP_COOKIE}
but they can't be together in one RewriteCond !

code example:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_COOKIE} !id=123456
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

this code works ok, while

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_COOKIE} !id=%{QUERY_STRING}
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

doesn't work. it reads only %{HTTP_COOKIE} but cannot read %{QUERY_STRING} at the same RewriteCond.

any idea about this ?

jdMorgan

3:13 pm on Jul 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You cannot use a server variable in a regular-expressions pattern.

In fact, there is no universal way to compare two variables in mod_rewrite.

The best solution is to pick one or the other variable, test it, and then if appropriate, rewrite the request to a script that can compare the two variables and take the desired action.

If that is not desirable, then you can try using "atomic back-references" to 'compare' the two variables based on commutativity. That is, there is no direct 'compare' function, but if var1+var2 == var1+var1, then var1== var2. Atomic back-references are only available in later version of POSIX regex, and in PCRE. So be aware that code that depends on them will fail if ported to an older (Apache 1.3.x) server.

Example:

# If request has not already been rewritten
RewriteCond $1 !^index\.php$
# and if the cookie is not blank and is not equal to the query string
RewriteCond %{HTTP_COOKIE}>%{QUERY_STRING} !^([^>]+)>\$1$
# then rewrite the request to index.php
RewriteRule ^(.*)$ index.php [QSA,L]

This example will not rewrite if the cookie is blank, so be sure that that is what you want.

Further, this example will rewrite requests for *all* types of resources if the cookie is not blank and the cookie and query string do not match exactly. So, your script will have to handle all requests, including those for images, CSS files, JavaScript files, robots.txt, sitemap.xml, etc. Again, be sure that that is what you intended.

Otherwise, you will need to modify this example code and/or add additional RewriteConds to do what you want...

Again, this example code will only work on servers that support atomic back-references, and some do not.

Jim

midoegypt

4:55 pm on Jul 12, 2010 (gmt 0)

10+ Year Member



hi Jim ,

thanks for replying but that is not working because %{HTTP_COOKIE} returns the value of all cookies for this domain.
i want to read just single cookie eg: $_COOKIE['id'] in php but in the apache file.

why they made it so complicated?! php is too easy and full of functions !

jdMorgan

11:58 pm on Jul 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well, then you'll need to parse the cookie string, which is a built-in feature of PHP, but not mod_rewrite:

# If request has not already been rewritten
RewriteCond $1 !^index\.php$
# get the "id" cookie (assumes semicolon-delimited string) and the "id" query string parameter
RewriteCond %{HTTP_COOKIE}>%{QUERY_STRING} ^([^;]*;)*id=([^;]+)[^>]*>([^&]*&)*id=([^&]+)(&.+)?$
# and if the id cookie is not blank and is not equal to the id in the query string
RewriteCond %2>%4 !^([^>]+)>\$1$
# then rewrite the request to index.php
RewriteRule ^(.*)$ index.php [QSA,L]

mod_rewrite is "hard" because it is a collection of server configuration directives, and not a scripting language. There's no reason you couldn't modify your existing script or write a "wrapper" script in PHP, invoke it unconditionally, and take over almost all of the server's functions if you'd like. The only problem is that you'd need a much faster server, because your PHP code will be hundreds or thousands of times slower than the native server code and its modules.

Said another way, mod_rewrite contains a limited number of simple functions, but it is very fast.

The cookie and query string parsing above assumes that the cookies are delimited by semi-colons and the query string name/value pairs are delimited by ampersands. The patterns are coded so that the values to be extracted from these strings can be at the beginning, in the middle, or at the end of these strings. If you use different delimiters, adjust the regex patterns to suit.

And another reminder for readers that this code can only work on servers with regex libraries which support atomic back-references... :)

Jim

midoegypt

12:52 am on Jul 13, 2010 (gmt 0)

10+ Year Member



thank you so much Jim for your time.

i could make a solution which does the job right now, but may be risky !
I may try to find another way for solving it :D