Varnish regular expression evaluated at compile time.

Hugues Alary hugues.alary at gmail.com
Wed Oct 10 23:41:00 CEST 2012


Hi there,

I have been struggling for the past few days with this problem:

Basically, I want to send to a client browser a cookie of the form
foo[sha1oftheurl]=[randomvalue]. If and only if the cookie has not already
been sent.

e.g. If a client browser requests "/page.html", the HTTP response will be
like:
resp.http.Set-Cookie = "foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6=ABCD;"

then, if the same client request "/index.html", the HTTP response will
contain a header:
resp.http.Set-Cookie = "foo14fe4559026d4c5b5eb530ee70300c52d99e70d7=QWERTY;"

In the end, the client browser will have 2 cookies:
`foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6=ABCD`
`foo14fe4559026d4c5b5eb530ee70300c52d99e70d7=QWERTY`


Now, that, is not complicated in itself. The following code does it:

import digest;
        import random;

 sub vcl_recv()
{
 ## We compute the sha1 of the requested URL and store it in
req.http.Url-Sha1
set req.http.Url-Sha1 = digest.hash_sha1(req.url);
                set req.http.random-value = random.get_rand();
}

sub vcl_deliver()
{
 ## We create a cookie on the client browser by creating a "Set-Cookie"
header
## In our case the cookie we create is of the form foo[sha1]=[randomvalue]
 ## e.g for a URL "/page.html" the cookie will be
foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6=[randomvalue]
 set resp.http.Set-Cookie = {""} + resp.http.Set-Cookie +
"foo"+req.http.Url-Sha1+"="+req.http.random-value;
 }


However, this code does not take into account the case where the Cookie
already exists. I need to check that the Cookie does not exists before
generating a random value. So I thought about this code:

import digest;
        import random;

 sub vcl_recv()
 {
## We compute the sha1 of the requested URL and store it in
req.http.Url-Sha1
 set req.http.Url-Sha1 = digest.hash_sha1(req.url);
                set req.http.random-value = random.get_rand();

                set req.http.regex = "abtest"+req.http.Url-Sha1;

 if(!req.http.Cookie ~ req.http.regex)
{
 set req.http.random-value = random.get_rand();
}
 }


The problem is that Varnish does not compute Regular expression at run
time. Which leads to this error when I try to compile:

Message from VCC-compiler:
Expected CSTR got 'req.http.regex'
(program line 940), at
('input' Line 42 Pos 31)
        if(req.http.Cookie !~ req.http.regex) {
------------------------------##############---

Running VCC-compiler failed, exit 1

VCL compilation failed


One could propose to solve my problem by matching on the "abtest" part of
the cookie or even "abtest[a-fA-F0-9]{40}":

                if(!req.http.Cookie ~ "abtest[a-fA-F0-9]{40}")
{
 set req.http.random-value = random.get_rand();
}

But this code matches any cookie starting by 'abtest' and containing an
hexadecimal string of 40 characters. Which means that if a client requests
"/page.html" first, then "/index.html", the condition will evaluate to true
even if the cookie for the "/index.html" has not been set.

I found in bug report phk or someone else stating that computing regular
expressions was extremely expensive which is why they are evaluated during
compilation. Considering this, I believe that there is no way of achieving
what I want the way I've been trying to.

Is there any way of solving this problem, other than writting a vmod?

Thanks for your help!

-Hugues
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.varnish-cache.org/lists/pipermail/varnish-misc/attachments/20121010/2d46712b/attachment-0001.html>


More information about the varnish-misc mailing list