边缘规则语法介绍

语法规则

当您希望通过编程模式来自行编写边缘规则时,你需要对又拍云边缘规则的语法规则进行详细了解,方可自行编写规则。本文将围绕函数、变量、字符串常量、break 进行详细介绍。

函数

函数调用以 $ 开头,后跟一组大写字母,字母之间可以包含下划线 _,函数需要的参数放在()中,以 , 分隔。如果没有特别说明,边缘规则 中的函数参数个数不能少于要求的参数个数,否则视为语法错误,然后终止规则执行过程,多余的参数会被求值,但不影响调用。函数调用是有上下文的,譬如 $WHEN 这个函数,参数是 bool 类 型,参数中有不成立的条件 false 时,会终止本次规则执行过程。支持的函数有:

条件选择和判断

函数 含义
$WHEN(E1, E2, ...) 所有条件都成立时才会执行规则,并返回空字符串
$NOT(E) E 不成立时返回 true, 否则返回 false
$ALL(E1, E2, ...) 所有条件都成立时返回 true,否则返回 false,参数个数不限
$ANY(E1, E2, ...) 其中一个条件成立时返回 true,否则返回 false,参数个数不限
$OR(E1, E2, ...) 值为第一个为真的表达式
$SELECT(E1, E2, E3) E1 为真时值为 E2,否则为 E3
$PCALL(E) 保护模式下解析 E,失败时返回空字符串

字符匹配和捕获

函数 含义
$MATCH(E1, E2) PCRE 匹配,E2 为要匹配的 pattern,返回 true 或者 false
$CAPTURE(E1, E2, E3) E2 pattern 对 E1 进行捕获,E3 表示是否忽略大小写,捕获后生成 $n.m 形式的变量,n 为当前 CAPTURE 出现的次序,m 表示匹配分组;E2 为空时,表示对 E1 进行捕获,此时 E1 对应 $n.0

请求/响应修改

函数 含义
$ADD_REQ_HEADER(E1, E2) 添加请求头 E1E2
$DEL_REQ_HEADER(E) 删除请求头 E
$ADD_RSP_HEADER(E1, E2) 添加响应头 E1E2
$DEL_RSP_HEADER(E) 删除响应头 E
$DEL_ARG(E) 删除请求参数项 E
$SET_METHOD(E) 修改当前 HTTP 请求方法为 EE 可选值有:GET, HEAD, PUT, POST, DELETE, OPTIONS, PATCH; 注 1
$SET_BODY(E) 修改当前 HTTP 请求体的内容为 E,仅在 PUTPOST 请求下有效
$REDIRECT(E1, E2) 重定向地址到 E1,状态码为 E2(301, 302)
$EXIT(E1, E2) 以状态码 E1 退出,响应体为 E2

注: 删除响应头函数不能删除 CDN 自带的一些字段,比如 via、age、server、connection、x-cache、x-request-id、x-source、content-length、transfer-encoding等字段是有保护的。

数值计算

函数 含义
$ADD(E1, E2) 数字相加,返回 E1 + E2 结果数值
$MOD(E1, E2) 数字取余,返回 E1 % E2 结果数值,其中 E2 不能为 0
$MSUB(E1, E2) 数字相减,返回 E1 - E2 结果数值
$MULTIPLY(E1, E2) 数字相乘,返回 E1 * E2 结果数值
$DIVIDE(E1, E2) 数字相除,返回 E1 / E2 结果数值,其中 E2 不能为 0
$BYTE(E) 返回字符 E 的 ASCII 编码值
$FLOOR(E) 返回小于或等于数字 E 的最大整数
$CEIL(E) 返回大于或等于数字 E 的最小整数
$GT(E1, E2) 数字比较,是否大于,返回 true 或者 false
$GE(E1, E2) 数字比较,是否大于等于,返回 true 或者 false

字符串操作

函数 含义
$SUB(E1, from, to) 字符串截取,从 fromto
$GSUB(E1,E2,E3,N) E1为要处理的字符串,E2为要替换的字符串,E3为替换成的字符串(可以为空,表示删除E1),N为从字符串开始的替换E1的个数,空或小于零表示所有,函数返回处理后的字符串
$EQ(E1, E2) 字符串是否相等,返回 true 或者 false
$UPPER(E) E 转换为大写
$LOWER(E) E 转换为小写
$LEN(E) 返回字符串 E 的长度

通用功能类函数

函数 含义
$ENCODE_BASE64(E) 将字符串 E 按 base64 编码压缩
$DECODE_BASE64(E) 将字符串 E 按 base64 编码解压
$ESCAPE(E) 将字符串 E 按 URL 编码处理,具体实现和 Chrome JS 实现的 encodeURIComponent() 一致
$UNESCAPE(E) 将字符串 E 按 URL 解码处理,具体实现和 Chrome JS 实现的 decodeURIComponent() 一致
$MD5(E) 计算 E 的 md5 值
$MD5_BIN(E) 计算 E 的 md5 值,并以二进制数据输出
$RANDI(E1, E2) 返回大于 E1 并小于 E2 的随机数值
$UNIXT(y, m, d, h, min, sec) 指定年,月,日,小时,分钟,秒,返回相应的 UNIX TIME
$INT(E1, E2, E3) 进制转换,将 E2 进制的数字(字符串形式) E1 转换成 E3 进制并返回,E2, E3 可选,E2 默认为 10
$STRF_TIME(E1,E2 )         时间格式转换,表示把时间进行格式化成年月日时分,E1 代表 UNIX 时间戳,可以使用变量 $_TIME来获取当前时间;E2 为间隔符,为可选项,不填时格式为 201802230955;间隔符为 -时,格式为2018-02-23-09-55

限速相关

函数 含义
$LIMIT_RATE_AFTER(E1, E2) 限速策略设置,发送 E1 大小单位为 E2 字节数据后,进行限速,E2 可选值有:k(KB),m(MB)
$LIMIT_RATE(E1, E2) 限速策略设置,按 E1 大小每秒进行限速,单位为 E2E2 可选值有:k(KB),m(MB)

注 1:若当前请求带有请求体的情况下,$SET_METHOD(E) 不允许设置为除 PUTPOST 以外的方法。

其中 E[n] 代表合法的表达式,也就是说函数可以相互嵌套,例如规则可以为:

/$SUB($DECODE_BASE64($_HEADER_foo), $_GET_from, $_GET_to)/;布尔函数包括 WHEN
, ALL, ANY
都是短路的,譬如 $WHEN($ALL(), $EXIT(403)) 不会返回 403,因为 $ALL() 的值为 false

使用 '' 能对变量进行转义,使其不被解释,例如以下规则:

/foo/'$_HOST'

会被转换为:

/foo/$_HOST

对于含有请求参数的规则,原先的请求参数会附加到后面,如果不希望这样,可以放置一个 ‘?’ 在规则的最后面,例如这样:

/foo?bar=$1?

特别地,如果重写后的 URL 没有参数,那么此时需要在最后加两个 ?,例如这样:

/foo??

变量

变量以 $_ 开头,这些变量都是对此次请求上下文中一些参数的映射,譬如 $_HOST 对应此次请求头中的 Host 字段,$_GET_foo 对应此次请求 URL 参数 foo 的值,等等。若将变量内插到重写后的 URL 中,譬如 URL 改写 /$_GET_foo/bar,如果请求参数中没有 foo则视为此次改写 失败;

若将变量放在函数中,则由该函数确定返回的值,例如 $NOT($_GET_foo),如果参数中包含 foo,则返回 false,否则返回true。目前支持的变量有:

变量 含义
$_IP 客户端 IP
$_HOST 请求头中的 Host 字段
$_HOST_n $_HOST_n 指 Host 中的第 n 个子域,例如对于 foo.bar.baz.com:$_HOST_1 = foo,$_HOST_2 = bar,$_HOST_3 = baz
$_GET_name 使用 Query String 中的变量(无需 urldecode)
$_POST_name 使用 POST 表单中的变量(只支持 www form )
$_HEADER_name 使用 Header 中的值,注意 name 全为小写
$_COOKIE_name 使用 Cookie 中的字段值
$_RANDOM 随机字符串,字符集为 [a-zA-Z0-9],默认 8 位
$_RANDOM_n n 位随机字符串,其中 1 <= n <= 32
$_URI 请求的 URI,不包含参数
$_QUERY Query String,不带前缀 ‘?’
$_METHOD GET/PUT/POST/DELETE/OPTIONS/PATCH
$_SCHEME http/https,注意此处全为小写
$_TIME 获取当前服务器时间,格式为 UNIX TIME
$_BODY 获取当前请求的 BODY(请求体)内容,大小限制为 16KB
$_GEOIP_COUNTRY_CODE 国家代码,可参照维基百科: https://en.wikipedia.org/wiki/ISO_3166-2

字符串常量

字符串常量有两种形式,第一种就是普通的字符串例如/foo/bar,但是如果字符串中包含了一些特殊字符,例如空白字符将被省略,例如 $(),' 这些字符有特殊的用途,不能被直接使用,要使用这些特殊的字符,要加 \ 前缀对其转义,例如 /foo/bar\,;第二种是加单引号的字符串 '',单引号中的字符只有 \ 是特殊转义字符前缀,其他的都视为普通字符,例如这样一条改写规则 /foo/'$\\,\'',改写过后对应 /foo/$\,'

break

除了能勾选 break 选项 指定是否 break,也可以直接在边缘规则最后加上 $$ 表示 break

这篇文章有帮助吗?

相关文章