Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Varnish C VRT变量/函数_C_Varnish_Varnish Vcl - Fatal编程技术网

Varnish C VRT变量/函数

Varnish C VRT变量/函数,c,varnish,varnish-vcl,C,Varnish,Varnish Vcl,我开始学习varnish,在我们的配置中遇到了对C代码中VRT函数的引用(以及网络上的示例),但我找不到相关文档(据我所知,我的C知识是不存在的)。这是我能找到的最好的,但只是原型: 下面是我们使用的一个例子(我已经发现很多次了,它似乎是从网上复制的): 那么什么是HDR_BEREQ和vrt_magic_string_end 这将是一个相当长的答案,因为关于你的问题,有相当多的话要说。首先,关于VCL中C代码的一些细节: 实现strtolower可能是不必要的;标准vmod具有std.tolow

我开始学习varnish,在我们的配置中遇到了对C代码中VRT函数的引用(以及网络上的示例),但我找不到相关文档(据我所知,我的C知识是不存在的)。这是我能找到的最好的,但只是原型:

下面是我们使用的一个例子(我已经发现很多次了,它似乎是从网上复制的):

那么什么是HDR_BEREQ和vrt_magic_string_end


这将是一个相当长的答案,因为关于你的问题,有相当多的话要说。首先,关于VCL中C代码的一些细节:

  • 实现strtolower可能是不必要的;标准vmod具有std.tolower功能。如果您正在运行Varnish 3,则应使用此选项。(也就是说,这似乎意味着你可能正在使用清漆2,谁知道呢?)
  • 您对
    VRT\u SetHdr
    的呼叫似乎没有必要。我看不出这与set bereq.http.X-Varnish-TeraWurfl=“no1”之间有什么区别
  • 我的一些答案可能不太准确,因为不清楚你们用的是什么版本的清漆,但我会猜

    现在,来回答您的问题:

  • 这里是什么?它来自哪里?它在任何地方都没有定义,我也找不到关于它的任何东西
  • sp
    是Varnish中的惯用用法,表示会话指针。它的类型为
    struct sess
    ,包含有关正在进行的请求的一些上下文。根据您使用的Varnish版本的不同,这可能有或多或少的上下文,因此很难真正定义范围。在Varnish 2中,会话包含从工作区到请求状态(以及其间的很多)的所有内容。清漆4将这一点大大分开了

    我猜你用的是清漆2或清漆3。在清漆4中,您将传递一个名为
    ctx
    的东西

    在任何情况下,从配置的角度来看,您真正需要知道的关于
    sp
    的唯一一件事是,它始终是任何
    VRT
    函数的第一个参数

  • VRT\u r\u请求url做什么?为什么它的前缀是VRT_uu,r是什么(我看到也有VRT_ul_u函数)。它从哪个结构获取数据
  • VRT代表VCLRunTime。它是在Varnish二进制文件本身内部实现的一组函数。函数签名和一些不透明结构通过头文件暴露给VCL。VCL编译器使用此头文件以及它从VCL生成的C代码的输出来创建可加载到Varnish中的共享对象。此外,还有一个TCL脚本(Varnish 4中的Python),它将不同的VCL内置项和变量与VRT函数相关联

    r和l代表right和left,这与在表达式中计算变量的位置有关。因为VCL不允许任何类型的“复杂”表达式(如加法或减法;除非将max_restarts设置为无界值,否则它肯定无法接近图灵完成),所以实际上只有两个位置可以访问变量:在右侧,或在左侧。例如:

    set req.url = req.url + "/"
    
    将编译为

    VRT_l_req_url(sp, VRT_r_req_url(sp), "/", vrt_magic_string_end);
    
    左侧对req.url的访问导致编译器调用VRT_l_req_url,右侧的访问导致编译器使用VRT_r_req_url

    一个更简单的思考方法可能是l表示“设置”,r表示“获取”(或者“读取”,如果您愿意的话)。但它真的意味着左和右

    要将其绑定到代码段中,请执行以下操作:

    strtolower((char *)VRT_r_req_url(sp));
    
    VRT\u r\u req\u url
    返回表示
    req.url
    值的
    const char*
    。此指针被强制转换到
    char*
    以删除
    const
    限定符。(此强制转换是您的配置中的一个错误。)强制转换指针被发送到
    strtolower
    ,然后将字符串小写

    出于几个原因,这是一辆马车
    VRT\u r\u req\u url
    返回了一个
    const char*
    ,因此您不应该修改它。我不认为这会破坏任何东西,但这违反了API合同。此外,您写入
    req.url
    的方式是通过
    VRT\u l\u req\u url
    接口,而不是直接在
    strtolower
    实现中。因此,正确的方法是使用std.tolower vmod,或者在会话工作区中复制URL,修改该副本,然后将其与VRT_l_req_URL一起存储

    另外,
    strtolower
    实现不需要
    if(isupper(*c))
    检查。此检查仅用于混淆处理器的分支预测器
    tolower(3)
    在基本上每个实现中都使用无分支的查找表,没有小写等价物的字符(如数字)将不会被转换

  • 是否所有这些VRT函数都是并行的,以便在C块之外获得与req.url等价的变量
  • 对。所有VRT函数实现函数调用或变量查找。但我想你的意思是“在C区内”

  • 是否有文档说明了所有这些功能?例如,我也看过几次这个:
  • 那么什么是HDR_BEREQ和vrt_magic_string_end

    有一些文档,但其中相当一部分需要源代码分析。如果你能说出你使用的是什么版本的清漆,我可以给你指一些文件,这些文件可能有助于理解发生了什么

    HDR\u BEREQ
    告诉
    VRT\u SetHdr
    使用包含将发送到后端的请求的特定工作区

    vrt\u magic\u string\u end
    是一个哨兵。基本上,所有可以接受一个字符串参数的函数也可以接受一组串接的字符串
    VRT_l_req_url(sp, VRT_r_req_url(sp), "/", vrt_magic_string_end);
    
    strtolower((char *)VRT_r_req_url(sp));
    
    sub detectmobile {
      C{
        VRT_SetHdr(sp, HDR_BEREQ, "\020X-Varnish-TeraWurfl:", "no1", vrt_magic_string_end);
      }C
     }
    
    log req.url + " " + req.http.Wookies + "ha!"
    
    VRT_log(sp, VRT_r_req_url(sp), " ", VRT_GetHdr(sp, HDR_REQ, "\10Wookies:"), "ha!", vrt_magic_string_end);
    
    #include <ctype.h>
    static void 
    strtolower(char *c)
    {
      while (*c != '\0) {
        *c++ = tolower(*c);
      }
    }
    
    C{
      #include <ctype.h>
      static void 
      strtolower(const char *c, char *obuf)
      {
        while (*c != '\0') {
          *obuf++ = tolower(*c++);
        }
        *obuf = '\0';
      }
    }C
    
    ...
    
    if (req.url ~ "[A-Z]") {
      C{
        const char *url = VRT_r_req_url(sp);
        size_t urllen = strlen(url) + 1;
        char obuf[urllen];
    
        strtolower(url, obuf, urllen);
        VRT_l_req_url(sp, obuf, vrt_magic_str_end);
      }C
    }