跳转到内容

HTTP 中间件

中间件在路由处理前后对 HTTP 请求进行处理。

中间件包装 HTTP 处理器以添加处理逻辑。每个中间件接收选项映射并返回处理器包装器:

middleware:
- cors
- ratelimit
options:
cors.allow.origins: "https://example.com"
ratelimit.requests: "100"

选项使用点号表示法:middleware_name.option.name。为了向后兼容,也支持旧版下划线格式。

匹配前在路由匹配之前运行,用于 CORS 和压缩等横切关注点。 匹配后在路由匹配之后运行,用于需要路由信息的授权。
middleware: # 匹配前
- cors
- compress
options:
cors.allow.origins: "*"
post_middleware: # 匹配后
- endpoint_firewall
post_options:
endpoint_firewall.action: "access"

匹配前

浏览器请求的跨域资源共享。

middleware:
- cors
options:
cors.allow.origins: "https://app.example.com"
cors.allow.credentials: "true"
选项默认值说明
cors.allow.origins*允许的来源 (逗号分隔,支持 *.example.com)
cors.allow.methodsGET,POST,PUT,DELETE,OPTIONS,PATCH允许的方法
cors.allow.headersOrigin,Content-Type,Accept,Authorization,X-Requested-With允许的请求头
cors.expose.headers-暴露给客户端的响应头
cors.allow.credentialsfalse允许 Cookie/认证
cors.max.age86400预检缓存时间 (秒)
cors.allow.private.networkfalse私有网络访问

OPTIONS 预检请求自动处理。


匹配前

令牌桶限流,支持按 key 追踪。

middleware:
- ratelimit
options:
ratelimit.requests: "100"
ratelimit.window: "1m"
ratelimit.key: "ip"
选项默认值说明
ratelimit.requests100每个时间窗口的请求数
ratelimit.window1m时间窗口
ratelimit.burst20突发容量
ratelimit.keyipKey 策略
ratelimit.cleanup_interval5m清理频率
ratelimit.entry_ttl10m条目过期时间
ratelimit.max_entries100000最大追踪 key 数

Key 策略: ipheader:X-API-Keyquery:api_key

返回 429 Too Many Requests,包含响应头:X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset


匹配前

响应的 Gzip 压缩。

middleware:
- compress
options:
compress.level: "default"
compress.min.length: "1024"
选项默认值说明
compress.leveldefaultfastestdefaultbest
compress.min.length1024最小响应大小 (字节)

仅在客户端发送 Accept-Encoding: gzip 时压缩。


匹配前

从代理头中提取客户端 IP。

middleware:
- real_ip
options:
real_ip.trusted.subnets: "10.0.0.0/8,172.16.0.0/12"
选项默认值说明
real_ip.trusted.subnets私有网络受信任的代理 CIDR
real_ip.trust_allfalse信任所有来源 (不安全)

头部优先级: True-Client-IP > X-Real-IP > X-Forwarded-For


匹配前

基于 Token 的认证。Token 存储配置请参阅安全性

middleware:
- token_auth
options:
token_auth.store: "app:tokens"
选项默认值说明
token_auth.store必填Token 存储的 Registry ID
token_auth.header.nameAuthorization请求头名称
token_auth.header.prefixBearer 请求头前缀
token_auth.query.paramx-auth-token查询参数备选
token_auth.cookie.namex-auth-tokenCookie 备选

在上下文中设置 actor 和安全范围供下游中间件使用。不阻止请求,授权在防火墙中间件中进行。


匹配前

Prometheus 风格的 HTTP 指标。无配置选项。

middleware:
- metrics
指标类型说明
wippy_http_requests_totalCounter总请求数
wippy_http_request_duration_secondsHistogram请求延迟
wippy_http_requests_in_flightGauge并发请求数

匹配后

基于匹配端点的授权。需要 token_auth 提供的 actor。

post_middleware:
- endpoint_firewall
post_options:
endpoint_firewall.action: "access"
选项默认值说明
endpoint_firewall.actionaccess要检查的权限动作

返回 401 Unauthorized (无 actor) 或 403 Forbidden (权限拒绝)。


匹配后

按 ID 保护特定资源。适用于路由器级别。

post_middleware:
- resource_firewall
post_options:
resource_firewall.action: "admin"
resource_firewall.target: "app:admin-panel"
选项默认值说明
resource_firewall.actionaccess权限动作
resource_firewall.target必填资源的 Registry ID

匹配前

通过处理器的 X-Sendfile 头提供文件服务。

middleware:
- sendfile
options:
sendfile.fs: "app:downloads"

处理器设置头部以触发文件服务:

头部说明
X-Sendfile文件系统中的文件路径
X-File-Name下载文件名

支持范围请求以实现断点续传。


匹配后

将 WebSocket 连接中继到进程。参阅 WebSocket Relay

post_middleware:
- websocket_relay
post_options:
wsrelay.allowed.origins: "https://app.example.com"

Post-match

从进程流式传输 Server-Sent Events。参阅 Server-Sent Events

post_middleware:
- sse_relay
post_options:
sserelay.allowed.origins: "https://app.example.com"

Pre-match

记录传入请求的 OpenTelemetry spans 和指标。启用 OTel 时自动注册;否则作为 no-op 运行。

middleware:
- otel

不接受任何选项。与 metrics 中间件协同工作;当需要 Prometheus 计数器和 OTel 追踪时同时启用。


中间件按列出顺序执行。推荐顺序:

middleware:
- real_ip # 1. 首先提取真实 IP
- cors # 2. 处理 CORS 预检
- compress # 3. 设置响应压缩
- ratelimit # 4. 检查限流
- metrics # 5. 记录指标
- token_auth # 6. 认证请求
post_middleware:
- endpoint_firewall # 路由匹配后授权