Eu tenho lutado nos últimos dias com esse problema:
Basicamente, desejo enviar para o navegador do cliente um cookie com o formato foo[sha1oftheurl]=[randomvalue]
se e somente se o cookie ainda não tiver sido definido.
por exemplo. Se um navegador do cliente solicitar "/page.html", a resposta HTTP será como:
resp.http.Set-Cookie = "foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6=ABCD;"
então, se o mesmo pedido de cliente "/index.html", a resposta HTTP conterá um cabeçalho:
resp.http.Set-Cookie = "foo14fe4559026d4c5b5eb530ee70300c52d99e70d7=QWERTY;"
No final, o navegador do cliente terá dois cookies:
%código%
foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6=ABCD
Agora, isso não é complicado por si só. O código a seguir faz isso:
import digest;
import random; ##This vmod does not exist, it's just for the example.
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;
}
No entanto, esse código não leva em consideração o caso em que o cookie já existe. Eu preciso verificar se o Cookie não existe antes de gerar um valor aleatório. Então eu pensei sobre esse código:
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();
}
}
O problema é que o Varnish não calcula a expressão Regular no tempo de execução. O que leva a esse erro quando tento compilar:
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
Poder-se-ia propor resolver o meu problema fazendo a correspondência na parte "mais" do cookie ou até mesmo "abtest [a-fA-F0-9] {40}":
if(!req.http.Cookie ~ "abtest[a-fA-F0-9]{40}")
{
set req.http.random-value = random.get_rand();
}
Mas este código corresponde a qualquer cookie iniciado por 'abtest' e contendo uma string hexadecimal de 40 caracteres. O que significa que, se um cliente solicitar "/page.html" primeiro, "/index.html", a condição será avaliada como verdadeira mesmo que o cookie para o "/index.html" não tenha sido definido.
Eu encontrei no bug report phk ou alguém declarando que as expressões regulares de computação eram extremamente caras e é por isso que elas são avaliadas durante a compilação. Considerando isso, acredito que não há como conseguir o que eu quero do jeito que estou tentando.
Existe alguma maneira de resolver este problema, além de escrever um vmod?
Obrigado pela sua ajuda!
-Hugues