VMOD标准-Varnish标准模块

SYNOPSIS

import std [as name] [from "path"]

真正的随机(真实的Lo,真实的嗨)

实数舍入(实数r)

VOID COLLECT(Header HDR,字符串SEP=“,”)

字符串查询排序(字符串)

弦乐演奏者(弦乐S)

弦乐(弦乐S)

字符串strstr(字符串s1,字符串s2)

Bool fnMatch(字符串模式,字符串主题,BOOL路径名,BOOL无转义,BOOL句点)

字符串文件读取(字符串)

BLOB BLOBREAD(字符串)

Bool FILE_EXISTS(字符串路径)

Bool Healthy(后端BE)

内部端口(IP IP)

持续时间( [STRING s] , [DURATION fallback] , [REAL real] , [INT integer] )

字节(字节 [STRING s] , [BYTES fallback] , [REAL real] , [INT integer] )

整型整数( [STRING s] , [INT fallback] , [BOOL bool] , [BYTES bytes] , [DURATION duration] , [REAL real] , [TIME time] )

IP IP(字符串S, [IP fallback] ,BOOL Resolve=1, [STRING p] )

实实在在的( [STRING s] , [REAL fallback] , [INT integer] , [BOOL bool] , [BYTES bytes] , [DURATION duration] , [TIME time] )

时间时间( [STRING s] , [TIME fallback] , [REAL real] , [INT integer] )

字符串strftime(时间时间,字符串格式)

无效原木(字符串S)

VOID syslog(int优先级,字符串S)

空时间戳(字符串S)

布尔语法(实数)

字符串getenv(字符串名称)

布尔CACHE_REQ_BODY(字节大小)

VOID LATE_100_CONTINUE(BOOL延迟)

无效set_ip_tos(Int Tos)

无效回滚(HTTP H)

Bool BAN(字符串)

字符串BAN_ERROR()

现在时间()

持续时间Timed_Call(SUB)

Int real2teger(实数r,int回退)

Time real2time(Real r,时间回退)

Int time2teger(时间t,int回退)

实时2Real(时间t,实际回退)

DESCRIPTION

vmod_std 包含基本功能,这些功能是Varnish的一部分,但由于体系结构的原因,这些功能更适合VMOD。

数值函数

真正的随机(真实的Lo,真实的嗨)

返回介于 lohi

此函数使用varnishd中的“Testable”随机生成器,它允许运行确定性测试(请参见 debug.srandom CLI命令)。此函数不应用于加密应用程序。

示例::

set beresp.http.random-number = std.random(1, 100);

实数舍入(实数r)

四舍五入实数 r 设置为最接近的整数,但从零开始四舍五入(请参见 round(3) )。

字符串函数

VOID COLLECT(Header HDR,字符串SEP=“,”)

折叠多个 hdr 将标题转换为一个长标题。默认分隔符 sep 是折叠标题时使用的标准逗号分隔符,另外还有一个空格用于美观的打印。

折叠集管时应小心。尤其是坍塌 Set-Cookie 会在浏览器端导致意想不到的结果。

vbl.使用 hdr 从… obj.http 触发VCL故障。

示例:

std.collect(req.http.accept);
std.collect(req.http.cookie, "; ");

字符串查询排序(字符串)

出于缓存规范化的目的对查询字符串进行排序。

示例::

set req.url = std.querysort(req.url);

弦乐演奏者(弦乐S)

转换字符串 s 变成大写的。

示例::

set beresp.http.scream = std.toupper("yes!");

弦乐(弦乐S)

转换字符串 s 转换为小写。

示例::

set beresp.http.nice = std.tolower("VerY");

字符串strstr(字符串s1,字符串s2)

返回从字符串的第一个匹配项开始的字符串 s2 在字符串中 s1 ,或者如果为空字符串 s2 找不到。

请注意,比较区分大小写。

示例::

if (std.strstr(req.url, req.http.restrict)) {
        ...
}

这将检查内容是否 req.http.restrict 发生在 req.url

Bool fnMatch(字符串模式,字符串主题,BOOL路径名,BOOL无转义,BOOL句点)

BOOL fnmatch(
   STRING pattern,
   STRING subject,
   BOOL pathname=1,
   BOOL noescape=0,
   BOOL period=0
)

Shell样式的模式匹配;返回 true 如果 subject 火柴 pattern ,在哪里 pattern 可以包含通配符,如 *?

匹配是通过实现 fnmatch(3) 在你的系统上。大多数系统上的模式匹配规则包括:

  • * 匹配任意字符序列

  • ? 匹配单个字符

  • 方括号表达式,如 [abc][!0-9] 根据基本正则表达式( not pcre2(3) Regexen),除了 ! 用于字符类求反,而不是 ^

如果 pathnametrue, then the forward slash character / is only matched literally, and never matches `` *, ``? or a bracket expression. Otherwise, / may match one of those patterns. By default, * 路径名*为 true

If noescape is true, then the backslash character \ is matched as an ordinary character. Otherwise, \ is an escape character, and matches the character that follows it in the pattern. For example, \\ matches \ when noescape is true, and \\ when false. By default, noescape is false.

如果 periodtrue, then a leading period character . only matches literally, and never matches *, ? or a bracket expression. A period is leading if it is the first character in subject; if pathname is also true, then a period that immediately follows a / is also leading (as in `` /.``)。默认情况下, periodfalse

std.fnmatch() 调用VCL失败并返回 false 如果其中任何一个 patternsubjectNULL --例如,如果指定了未设置的标头。

示例:

# Matches URLs such as /foo/bar and /foo/baz
if (std.fnmatch("/foo/\*", req.url)) { ... }

# Matches URLs such as /foo/bar/baz and /foo/baz/quux
if (std.fnmatch("/foo/\*/\*", bereq.url)) { ... }

# Matches /foo/bar/quux, but not /foo/bar/baz/quux
if (std.fnmatch("/foo/\*/quux", req.url)) { ... }

# Matches /foo/bar/quux and /foo/bar/baz/quux
if (std.fnmatch("/foo/\*/quux", req.url, pathname=false)) { ... }

# Matches /foo/bar, /foo/car and /foo/far
if (std.fnmatch("/foo/?ar", req.url)) { ... }

# Matches /foo/ followed by a non-digit
if (std.fnmatch("/foo/[!0-9]", req.url)) { ... }

文件(系统)函数

字符串文件读取(字符串)

读取文本文件并返回包含内容的字符串。

整个文件在第一次调用时被缓存,随后的调用将返回此缓存内容,即使在此期间文件已更改。

对于二进制文件,请改用std.blobread()。

示例::

synthetic("Response was served by " + std.fileread("/etc/hostname"));

考虑到文件的全部内容都出现在返回的字符串中,包括可能导致无效标头的换行符 std.fileread() 用于形成标题。在这种情况下,您可能需要修改字符串,例如使用 regsub() (见 VCL ):

set beresp.http.served-by = regsub(std.fileread("/etc/hostname"), "\R$", "");

BLOB BLOBREAD(字符串)

读取任何文件并返回包含内容的BLOB。

整个文件在第一次调用时被缓存,随后的调用将返回此缓存内容,即使在此期间文件已更改。

Bool FILE_EXISTS(字符串路径)

退货 true 如果路径或PATH指向的文件存在, false 否则的话。

示例::

if (std.file_exists("/etc/return_503")) {
        return (synth(503, "Varnish is in maintenance"));
}

类型检查功能

Bool Healthy(后端BE)

退货 true 如果后端 be 是健康的。

内部端口(IP IP)

返回IP地址的端口号 ip 。总是会回来的 0 对于一个 *.ip 变量,当地址是Unix域套接字时。

类型转换函数

这些函数都具有相同的格式::

TYPE type([arguments], [fallback TYPE])

恰恰是世界上 arguments 必须提供(除了可选的 fallback ),它将被转换为 TYPE

如果转换失败, fallback 将返回,如果未指定回退,则VCL将失败。

持续时间( [STRING s] , [DURATION fallback] , [REAL real] , [INT integer] )

DURATION duration(
   [STRING s],
   [DURATION fallback],
   [REAL real],
   [INT integer]
)

从字符串、实数或整型参数返回持续时间。

对于字符串 s 论据, s 必须通过以下方式量化 ms (毫秒), s (秒), m (分钟), h (小时),d``(天),  ``w (周)或 y (年)单位。

realinteger 参数以秒为单位。

如果转换为 s 论证失败, fallback 如果提供,将返回,否则将触发VCL失败。

转换自 realinteger 争论从来不会失败。

只有一位 srealinteger 可能会给出参数或触发VCL故障。

示例:

set beresp.ttl = std.duration("1w", 3600s);
set beresp.ttl = std.duration(real=1.5);
set beresp.ttl = std.duration(integer=10);

字节(字节 [STRING s] , [BYTES fallback] , [REAL real] , [INT integer] )

BYTES bytes(
   [STRING s],
   [BYTES fallback],
   [REAL real],
   [INT integer]
)

从字符串、实数或整型参数返回字节。

一根线 s 参数可以用乘数来量化 (k (公斤), m (百万), g (千兆), t (太拉)或 p (善待动物组织))。

realinteger 参数以字节为单位。

如果转换为 s 论证失败, fallback 如果提供,将返回,否则将触发VCL失败。

如果参数为负值、太小或太大而无法表示,则其他转换可能会失败。再说一遍, fallback 如果提供,将返回,否则将触发VCL失败。

real 论据将向下舍入。

只有一位 srealinteger 可能会给出参数或触发VCL故障。

示例::

std.cache_req_body(std.bytes(something.somewhere, 10K));
std.cache_req_body(std.bytes(integer=10*1024));
std.cache_req_body(std.bytes(real=10.0*1024));

整型整数( [STRING s] , [INT fallback] , [BOOL bool] , [BYTES bytes] , [DURATION duration] , [REAL real] , [TIME time] )

INT integer(
   [STRING s],
   [INT fallback],
   [BOOL bool],
   [BYTES bytes],
   [DURATION duration],
   [REAL real],
   [TIME time]
)

从字符串、BOOL或其他数量返回一个int。

如果转换为 s 论证失败, fallback 如果提供,将返回,否则将触发VCL失败。

A bool 参数将作为0返回 false 和1个 true 。这一转变永远不会失败。

为. bytes 参数,则将返回字节数。这一转变永远不会失败。

A duration 参数将向下舍入为秒数并返回。

A real 参数将向下舍入并返回。

为. time 参数,则将返回自Unix纪元(1970-01-01 00:00:00 UTC)以来的秒数。

durationrealtime 如果参数因太小或太大而无法表示,则转换可能会失败。如果是的话, fallback 如果提供,将返回,否则将触发VCL失败。

只有一位 sboolbytesdurationrealtime 可能会给出参数或触发VCL故障。

示例:

if (std.integer(req.http.foo, 0) > 5) {
        ...
}

set resp.http.answer = std.integer(real=126.42/3);

IP IP(字符串S, [IP fallback] ,BOOL Resolve=1, [STRING p] )

转换字符串 s 设置为系统库函数返回的第一个IP号 getaddrinfo(3) 。如果转换失败, fallback 将被返回,否则将发生VCL故障。

该IP地址包括一个端口号,可以通过以下命令找到 std.port() 默认为80。可以将默认端口设置为不同的值 p 争论。它将在以下情况下被覆盖 s 包含IP地址和端口号或服务名称。

什么时候 s 两者都包含,则语法为 address:portaddress port 。如果地址是数字IPv6地址,则必须用方括号括起来,例如 [::1] 80[::1]:http 。这个 fallback 也可以同时包含地址和端口,但其默认端口始终为80。

如果 resolve 是假的, getaddrinfo(3) 被调用时使用 AI_NUMERICHOSTAI_NUMERICSERV 要避免根据系统的 getaddrinfo(3) 或nsSwitch配置。这使得“数字”IP字符串和服务的转换成本更低。

示例::

if (std.ip(req.http.X-forwarded-for, "0.0.0.0") ~ my_acl) {
        ...
}

实实在在的( [STRING s] , [REAL fallback] , [INT integer] , [BOOL bool] , [BYTES bytes] , [DURATION duration] , [TIME time] )

REAL real(
   [STRING s],
   [REAL fallback],
   [INT integer],
   [BOOL bool],
   [BYTES bytes],
   [DURATION duration],
   [TIME time]
)

从字符串、BOOL或其他数量返回实数。

如果转换为 s 论证失败, fallback 如果提供,将返回,否则将触发VCL失败。

A bool 参数将以0.0的形式返回 false 和1.0版本 true

为. bytes 参数,则将返回字节数。

为. duration 参数,则将返回秒数。

一个 integer 参数将作为实数返回。

为. time 参数,则将返回自Unix纪元(1970-01-01 00:00:00 UTC)以来的秒数。

这些转换都不是 s 都会失败。

只有一位 sintegerboolbytesdurationtime 可能会给出参数或触发VCL故障。

示例::

if (std.real(req.http.foo, 0.0) > 5.5) {
        ...
}

时间时间( [STRING s] , [TIME fallback] , [REAL real] , [INT integer] )

TIME time([STRING s], [TIME fallback], [REAL real], [INT integer])

从字符串、实数或整型参数返回时间。

对于字符串 s 参数,则支持以下格式:

"Sun, 06 Nov 1994 08:49:37 GMT"
"Sunday, 06-Nov-94 08:49:37 GMT"
"Sun Nov  6 08:49:37 1994"
"1994-11-06T08:49:37"
"784111777.00"
"784111777"

realinteger 参数以自纪元起的秒数为单位。

如果转换为 s 参数失败或否定 realinteger 给出了论据, fallback 如果提供,将返回,否则将触发VCL失败。

示例:

if (std.time(resp.http.last-modified, now) < now - 1w) {
        ...
}

if (std.time(int=2147483647) < now - 1w) {
        ...
}

字符串strftime(时间时间,字符串格式)

设置格式 timeformat 参数使用 strftime(3) 并返回UTC(历史上为GMT)时区的结果。

如果格式化失败,则返回空字符串,但也可以将其作为有效结果返回。

示例::

set req.http.iso = std.strftime(now, "%Y%m%dT%H%M%SZ");
# e.g. 20210521T175241Z

日志记录功能

无效原木(字符串S)

记录字符串 s 添加到共享内存日志,使用 VSL 标牌 SLT_VCL_Log

示例::

std.log("Something fishy is going on with the vhost " + req.http.host);

VOID syslog(int优先级,字符串S)

记录字符串 s 到Syslog,标记为 prioritypriority 是通过对设施值和级别值进行或运算而形成的。查看您的系统的 syslog.h 文件以获取可能的值。

注意:与std vmod中的VCL和其他函数不同,该函数不会因工作空间溢出而使VCL处理失败:对于工作空间不足的情况, std.syslog() 功能不起作用。

示例::

std.syslog(9, "Something is wrong");

这将使用以下命令向系统日志发送一条消息 LOG_USER | LOG_ALERT

空时间戳(字符串S)

使用以下字符串在日志中引入带有当前时间的时间戳 s 作为标签。这对于计算冗长的VCL子例程的执行时间很有用,并使Varnish自动插入的时间戳更准确。

示例::

std.timestamp("curl-request");

控制和信息功能

布尔语法(实数)

退货 true 如果VCL版本至少为 REAL

字符串getenv(字符串名称)

返回环境变量 name 或空字符串。看见 getenv(3)

示例::

set req.http.My-Env = std.getenv("MY_ENV");

布尔CACHE_REQ_BODY(字节大小)

如果请求正文小于 size 。退货 true 如果身体被缓存了, false 否则的话。

正常情况下,请求正文只能发送一次。缓存它可以使用请求正文重试后端请求,这通常是使用 POSTPUT

示例::

if (std.cache_req_body(1KB)) {
        ...
}

仅限于: vcl_recv

VOID LATE_100_CONTINUE(BOOL延迟)

控制Varnish何时对 Expect: 100-continue 客户端请求标头。

Varnish总是会生成一个 100 Continue 如果客户请求,则通过 Expect: 100-continue 等待请求正文数据时的标头。

但是,默认情况下, 100 Continue 响应已在以下时间之后立即生成 vcl_recv 在假定最终将读取请求正文的情况下,返回以减少延迟。

叫唤 std.late_100_continue(true) 在……里面 vcl_recv 将导致 100 Continue 只有在需要时才发送响应。这可能会导致处理请求正文的额外延迟,但严格解释RFC7231是正确的行为。

此功能在外部不起作用 vcl_recv 并且在呼叫之后 std.cache_req_body() 或使用请求正文的任何其他函数。

示例::

vcl_recv {
        std.late_100_continue(true);

        if (req.method == "POST") {
                std.late_100_continue(false);
                return (pass);
        }
        ...
 }

仅限于: vcl_recv

无效set_ip_tos(Int Tos)

将当前会话的区分服务代码点(DSCP)/IPv4服务类型(TOS)/IPv6流量类别(TCLASS)字节设置为 tos 。如果侦听地址是Unix域套接字,则自动忽略。

请注意,设置流量类别会影响同一HTTP1.1/HTTP2 TCP连接上的所有请求,尤其是不会在请求结束时删除。

示例::

if (req.url ~ "^/slow/") {
        std.set_ip_tos(0);
}

仅限于: client

无效回滚(HTTP H)

恢复 h 将HTTP标头恢复为其原始状态。

示例::

std.rollback(bereq);

仅限于: backendvcl_recvvcl_passvcl_hashvcl_purgevcl_missvcl_hitvcl_delivervcl_synth

Bool BAN(字符串)

使缓存中与给定表达式与BAN机制匹配的所有对象无效。退货 true 如果禁令成功, false 否则的话。有关错误详细信息,请访问 std.ban_error()

的格式 STRING 是::

<field> <operator> <arg> [&& <field> <oper> <arg> ...]
  • <field>

    • 字符串字段:

      • req.url :请求URL

      • req.http.* :任何请求标头

      • obj.status :缓存对象状态

      • obj.http.* :任何缓存对象标头

      obj.status 被视为字符串,尽管它实际上是一个整数。

    • 持续时间字段:

      • obj.ttl :禁令发布时剩余的ttl

      • obj.age :发布禁令时的对象年龄

      • obj.grace :对象的宽限时间

      • obj.keep :对象的保持时间

  • <operator>

    • 对于所有字段:

      • ==<field><arg> 是平等的

      • !=<field><arg> 是不平等的

      字符串比较时区分大小写

    • 对于字符串字段:

      • ~<field> 匹配正则表达式 <arg>

      • !~<field> 与正则表达式不匹配 <arg>

    • 对于持续时间字段:

      • ><field> 大于 <arg>

      • >=<field> 大于或等于 <arg>

      • <<field> 小于 <arg>

      • <=<field> 小于或等于 <arg>

  • <arg>

    • 对于字符串字段:

      Either a literal string or a regular expression. Note that <arg> does not use any of the string delimiters like " or {"..."} or """...""" used elsewhere in varnish. To match against strings containing whitespace, regular expressions containing \s can be used.

    • 对于持续时间字段:

      VCL持续时间,如 10s5m1h ,见 持续时间

可以使用 and 运算符 && 。为 or 语义学上,使用几个禁令。

《未定情》 <field> 不等于任何字符串,因此对于不存在的标头,运算符 ==~ 始终计算为FALSE,而运算符 !=!~ 的任何值分别求值为真。 <arg>

字符串BAN_ERROR()

返回上一个事件的文本错误说明 std.ban() 从同一任务调用,如果没有错误或没有错误,则返回空字符串 std.ban() 打电话。

现在时间()

返回当前时间。与之相对的是 now 内置变量,每次调用都会返回一个新值。

持续时间Timed_Call(SUB)

调用给定的Sub并返回执行时间的高精度度量值。

不推荐使用的函数

Int real2teger(实数r,int回退)

DEPRECATED :此函数将在Varnish的未来版本中删除,请使用 std.integer() 使用一个 real 论据和 std.round() 函数,例如::

std.integer(real=std.round(...), fallback=...)

四舍五入实数 r 设置为最接近的整数,但从零开始四舍五入(请参见 round(3) )。如果转换失败, fallback 将会被退还。

示例:

set req.http.integer = std.real2integer(1140618699.00, 0);
set req.http.posone = real2integer( 0.5, 0);    # =  1.0
set req.http.negone = real2integer(-0.5, 0);    # = -1.0

Time real2time(Real r,时间回退)

DEPRECATED :此函数将在Varnish的未来版本中删除,请使用 std.time() 使用一个 real 论据和 std.round() 函数,例如::

std.time(real=std.round(...), fallback=...)

四舍五入实数 r 设置为最接近的整数(请参见 std.real2integer() ),并在解释为Unix纪元时返回相应的时间。如果转换失败, fallback 将会被退还。

示例::

set req.http.time = std.real2time(1140618699.00, now);

Int time2teger(时间t,int回退)

DEPRECATED :此函数将在Varnish的未来版本中删除,请使用 std.integer() 使用一个 time 参数,例如::

std.integer(time=..., fallback=...)

转换时间 t 转换为一个整数。如果转换失败, fallback 将会被退还。

示例::

set req.http.int = std.time2integer(now, 0);

实时2Real(时间t,实际回退)

DEPRECATED :此函数将在Varnish的未来版本中删除,请使用 std.real() 使用一个 time 参数,例如::

std.real(time=..., fallback=...)

转换时间 t 为了一个真正的。如果转换失败, fallback 将会被退还。

示例::

set req.http.real = std.time2real(now, 1.0);

另请参阅