匹配器
匹配器定义了「哪些请求走这段配置」。写成一个 @名字 开头的前缀指令。
常用匹配器
章节「常用匹配器」@static path /static/*@api path /api/* /v1/* # 多个值 = 或关系@post method POST PUT DELETE@api { path /api/* method GET POST}# 大括号 = 且关系| 匹配器 | 说明 | 示例 |
|---|---|---|
path |
URL 路径,支持 * 通配和 /foo* 前缀 |
@a path /api/* |
method |
HTTP 方法 | @m method GET HEAD |
host |
Host 头 | @h host example.com |
header |
请求头匹配 | @ua header User-Agent *bot* |
remote_ip |
来源 IP / CIDR | @lan remote_ip 192.168.0.0/16 |
query |
查询参数 | @q query page=1 debug=true |
expression |
CEL 表达式(万能兜底) | @e expression query.len('x') > 0 |
大小写与子目录
章节「大小写与子目录」path 是不区分大小写的,而且 /api 不会自动匹配 /apixxx——它匹配的是精确路径或 /api/ 开头。
想在反代时剥掉前缀:
@api path /api/*handle @api { uri strip_prefix /api reverse_proxy localhost:8080}按 Host 分流
章节「按 Host 分流」一个文件管多个域名:
example.com { root * /var/www/marketing file_server}
api.example.com { reverse_proxy localhost:8080}
admin.example.com { basic_auth { ops $2a$14$abc... # 必须是 bcrypt hash } reverse_proxy localhost:9000}正则匹配器
章节「正则匹配器」@images { path_regexp image `\.(png|jpe?g|gif|webp|svg)$`}handle @images { header Cache-Control "public, max-age=31536000, immutable"}IP 白名单
章节「IP 白名单」@internal remote_ip 192.168.1.0/24 10.0.0.1handle @internal { respond "Welcome home" 200}handle { respond "403" 403}CEL 表达式:最后的兜底
章节「CEL 表达式:最后的兜底」expression 匹配器用 CEL 语法,能做任何事。功能强大,也最容易写出没人看得懂的表达式,所以留到最后。
@weird expression ( header('X-Custom') == 'yes' && query.page != null)