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