Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a cookie for language. I want to check if this cookie is set and to check its value to redirect the user to specific page. the cookie name is Lang and its value might be En,Fr,or Ar

if (req.http.Cookie ~ "Lang"){
//now i want to check for the cookie value
//if LANG=="Ar"
// set req.url =  req.url "CookieValue"
}

anybody know how to check for cookie value in varnish??
Thanks

share|improve this question
add comment

1 Answer 1

up vote 2 down vote accepted

Since all the cookies - both name and value - are in the req.http.Cookie string, you should be able to check for both name and value at the same time. Unfortunately, Varnish does not have any specialized methods for dealing with cookies - you must use regular expressions.

It is important to note that cookies are delimited by a semicolon and white space, for example:

cookie1=abc; cookie2=def

We know, therefore that our cookie is either at the start of req.http.Cookie, or is preceded by a semicolon and white space, and either ends with a semicolon, or is at the end of req.http.Cookie. Given this, we can construct a regex that will match our cookie and the semicolon, if any. Something like:

(^|;\s*)(Lang=En)(;|$)

Briefly, going through the above we have:

  • First set of brackets - match the start:
    • ^ means start of string
    • | means OR
    • ; is taken literally (i.e. semicolon)
    • \s means white space
    • * means one or more repetitions of the preceding character
    • Summary: either the start of the string or a semicolon followed by white space
  • Second set of brackets - match the cookie:
    • Lang is the name of the cookie
    • En is the value of the cookie
  • Third set of brackets - match the end
    • ; is taken literally (i.e. semicolon)
    • | means OR
    • $ means end of string
    • Summary: either a semicolon or the end of the string

Using the above, we can check for the cookies and perform some action on them:

if (req.http.Cookie ~ "(^|;\s*)(Lang=En)(;|$)"){
    //do something with En
} elseif (req.http.Cookie ~ "(^|;\s*)(Lang=Fr)(;|$)") {
    //do something with Fr;
}

There may be better ways, or more efficient regexes (unfortunately, varnish doesn't have user defined variables - which means you can't use regex capture groups) - but hopefully this will do the job.

Arguably, you could construct a regex with a capture group using regsub, and set that as a subdomain, perhaps something like:

set req.url = regsub(req.http.Cookie, "(?:^|;\s*)(?:Lang=(.*?))(?:;|$)", "\1.")+"example.com";

In the case of 'Lang=en', you would capture the 'en' add a period (.) and prepend to 'example.com' giving you en.example.com. I'd suggest though directly using a cookie to set the URL - without a lot of error checking - would be a very bad solution. If you just have 3 languages, a couple of if statements and a default would be much safer.

Note: the above is untested, and regexes aren't my forte - expect a few mistakes - but hopefully the premise works.

share|improve this answer
    
in [sub vcl_recv] i have added this line [set req.url = req.url "/en";] is it supposed change my request url from example.com to example.com/en ???Thanks for your help –  Alaa Alomari Jan 12 '12 at 8:08
    
a) Firstly you need a 'normalized' req.url (i.e. how do you know the url isn't currently example.com/page.php - adding /en to the end of that wouldn't be good - you could use a regex to do the replacement, but that should be asked as a different question. b) you need a plus sign (+) for concatenation in Varnish. c) changing req.url will only 'internally' change the path (i.e. a rewrite) it will not send a 301 (or 302) redirect to the client. –  cyberx86 Jan 12 '12 at 10:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.