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,真实的嗨)¶
返回介于 lo 和 hi 。
此函数使用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),除了!
用于字符类求反,而不是^
。
如果 pathname 是 true
, 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
.
如果 period 是 true
, 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 `` /.``)。默认情况下, period 是 false
。
std.fnmatch() 调用VCL失败并返回 false
如果其中任何一个 pattern 或 subject 是 NULL
--例如,如果指定了未设置的标头。
示例:
# 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
(年)单位。
real 和 integer 参数以秒为单位。
如果转换为 s 论证失败, fallback 如果提供,将返回,否则将触发VCL失败。
转换自 real 和 integer 争论从来不会失败。
只有一位 s , real 或 integer 可能会给出参数或触发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
(善待动物组织))。
real 和 integer 参数以字节为单位。
如果转换为 s 论证失败, fallback 如果提供,将返回,否则将触发VCL失败。
如果参数为负值、太小或太大而无法表示,则其他转换可能会失败。再说一遍, fallback 如果提供,将返回,否则将触发VCL失败。
real 论据将向下舍入。
只有一位 s , real 或 integer 可能会给出参数或触发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)以来的秒数。
duration , real 和 time 如果参数因太小或太大而无法表示,则转换可能会失败。如果是的话, fallback 如果提供,将返回,否则将触发VCL失败。
只有一位 s , bool , bytes , duration , real 或 time 可能会给出参数或触发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:port
或 address port
。如果地址是数字IPv6地址,则必须用方括号括起来,例如 [::1] 80
或 [::1]:http
。这个 fallback 也可以同时包含地址和端口,但其默认端口始终为80。
如果 resolve 是假的, getaddrinfo(3) 被调用时使用 AI_NUMERICHOST
和 AI_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 都会失败。
只有一位 s , integer , bool , bytes , duration 或 time 可能会给出参数或触发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"
real 和 integer 参数以自纪元起的秒数为单位。
如果转换为 s 参数失败或否定 real 或 integer 给出了论据, fallback 如果提供,将返回,否则将触发VCL失败。
示例:
if (std.time(resp.http.last-modified, now) < now - 1w) {
...
}
if (std.time(int=2147483647) < now - 1w) {
...
}
字符串strftime(时间时间,字符串格式)¶
设置格式 time 与 format 参数使用 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,标记为 priority 。 priority 是通过对设施值和级别值进行或运算而形成的。查看您的系统的 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
否则的话。
正常情况下,请求正文只能发送一次。缓存它可以使用请求正文重试后端请求,这通常是使用 POST
和 PUT
。
示例::
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);
仅限于: backend
, vcl_recv
, vcl_pass
, vcl_hash
, vcl_purge
, vcl_miss
, vcl_hit
, vcl_deliver
, vcl_synth
。
Bool BAN(字符串)¶
使缓存中与给定表达式与BAN机制匹配的所有对象无效。退货 true
如果禁令成功, false
否则的话。有关错误详细信息,请访问 std.ban_error() 。
的格式 STRING 是::
<field> <operator> <arg> [&& <field> <oper> <arg> ...]
<field> :
字符串字段:
req.url
:请求URLreq.http.*
:任何请求标头obj.status
:缓存对象状态obj.http.*
:任何缓存对象标头
obj.status
被视为字符串,尽管它实际上是一个整数。持续时间字段:
obj.ttl
:禁令发布时剩余的ttlobj.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持续时间,如
10s
,5m
或1h
,见 持续时间
可以使用 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);
另请参阅¶
COPYRIGHT¶
Copyright (c) 2010-2017 Varnish Software AS
All rights reserved.
Author: Poul-Henning Kamp <phk@FreeBSD.org>
SPDX-License-Identifier: BSD-2-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.