tower-http
axum 的中间件就是 tower 的 Layer,所以它没有自己的一套静态文件、压缩或 CORS 实现,中间件文档开头就说「the ecosystem of tower and tower-http middleware all work with axum」。tower-http 不依赖 axum,操作的是 http::Request / http::Response 和 http_body::Body,同一个 CompressionLayer 也能套在纯 hyper 或其他基于 tower 的服务上。这一部分对着 tower-http 0.7.1 的源码,只讲 Web 应用最常用的几样,重点是每一样在请求的哪个点上起作用、自己会返回什么、和 axum 自己的机制怎么叠在一起。
- ServeDir 与 ServeFile:URI 先百分号解码再按段检查,
..一律 404;目录无尾斜杠时 307 重定向(0.7.1 可关,挂在前缀下要配redirect_path_prefix);按Accept-Encoding挑预压缩文件;单段 Range 与 ETag 条件请求;0.7.1 起try_call把 IO 错误交给调用方。 - 压缩:按 q 值和 zstd > br > gzip > deflate 的优先级选编码,拒绝一切时回 406;已编码、有
Content-Range、小于 32 字节、图片、gRPC、SSE 不压;压缩时去掉Content-Length和Accept-Ranges、加Vary;流式 body 边读边压。 - 其余常用中间件:
TimeoutLayer超时回一个空响应,包括读请求 body;RequestBodyLimitLayer与 axum 的DefaultBodyLimit谁先触发;CorsLayer拦下所有 OPTIONS;TraceLayer的回调与分类器;CatchPanicLayer只管到响应头为止。
flowchart TB client["客户端"] --> outer["Router::layer 的中间件"] outer --> cors["CorsLayer"] outer --> lim["RequestBodyLimitLayer"] outer --> tmo["TimeoutLayer"] outer --> cmp["CompressionLayer"] outer --> trace["TraceLayer、CatchPanicLayer"] outer --> router["路由"] router --> handler["handler"] router --> sd["nest_service:ServeDir"]
本卷锁定的是 tower-http 0.7.1;本站自己的代码目前锁在 0.6.11,两者对本站有影响的差异放在「在本站中」一章。
这一部分只讲「怎么用、在 axum 里会怎样」。tower-http 内部怎么组织、模块之间怎么复用、客户端方向的用法,以及这里没讲到的模块,见 tower-http 源码解析。
💬 关联讨论
发起讨论加载中...