清漆VCL – 正则表达式评估

过去几天我一直在努力解决这个问题:

基本上,我想向客户端浏览器发送一个形式为foo [sha1oftheurl] = [randomvalue]的cookie,当且仅当cookie尚未设置时.

例如如果客户端浏览器请求“/page.html”,则HTTP响应将如下所示:
resp.http.Set-Cookie =“foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6 = ABCD;”

然后,如果相同的客户端请求“/index.html”,HTTP响应将包含一个标头:
resp.http.Set-Cookie =“foo14fe4559026d4c5b5eb530ee70300c52d99e70d7 = QWERTY;”

最后,客户端浏览器将有2个cookie:
foo4c9ae249e9e061dd6e30893e03dc10a58cc40ee6 = ABCD
foo14fe4559026d4c5b5eb530ee70300c52d99e70d7 = QWERTY

现在,这本身并不复杂.以下代码执行此操作:

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;
}

但是,此代码未考虑Cookie已存在的情况.我需要在生成随机值之前检查Cookie是否不存在.所以我想到了这段代码

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();
    }
}

问题是Varnish在运行时不计算正则表达式.当我尝试编译时会导致此错误

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

人们可以建议通过匹配cookie的“abtest”部分甚至“abtest [a-fA-F0-9] {40}”来解决我的问题:

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

但是这段代码匹配任何以“abtest”开头并包含40个字符的十六进制字符串的cookie.这意味着如果客户端首先请求“/page.html”,然后“/index.html”,即使尚未设置“/index.html”的cookie,条件也会评估为true.

我在bug报告中找到了phk或其他人说明计算正则表达式非常昂贵,这就是为什么在编译期间对它们进行评估的原因.考虑到这一点,我认为没有办法实现我想要的方式.

有没有办法解决这个问题,除了写一个vmod?

谢谢你的帮助!

-Hugues

有一招!

改变条件

if(!req.http.Cookie ~ req.http.regex)

至:

if(!req.http.Cookie ~ {"" + req.http.regex + ""})

这会将其切换到CSTR.

相关文章

正则替换html代码中img标签的src值在开发富文本信息在移动端...
正则表达式
AWK是一种处理文本文件的语言,是一个强大的文件分析工具。它...
正则表达式是特殊的字符序列,利用事先定义好的特定字符以及...
Python界一名小学生,热心分享编程学习。
收集整理每周优质开发者内容,包括、、等方面。每周五定期发...