跳到正文

匹配器

匹配器定义了「哪些请求走这段配置」。写成一个 @名字 开头的前缀指令。

@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
}

一个文件管多个域名:

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"
}
@internal remote_ip 192.168.1.0/24 10.0.0.1
handle @internal {
respond "Welcome home" 200
}
handle {
respond "403" 403
}

CEL 表达式:最后的兜底

章节「CEL 表达式:最后的兜底」

expression 匹配器用 CEL 语法,能做任何事。功能强大,也最容易写出没人看得懂的表达式,所以留到最后。

@weird expression (
header('X-Custom') == 'yes' &&
query.page != null
)