Rust in Everything
基于 tower-http 0.7.1

拦请求

这一部分的三个模块都在 call 时动手,而且都可能不调内层、直接交出一个响应。它们的失败不走 Err:CORS 的预检是 200,跨站写请求是 403,Content-Length 超限是 413。短路的通用写法(ResponseFuture 里一个两变体的枚举)在 四件套 里讲过,这里讲每个模块各自的判断。

  1. CORS 的内部:七个配置字段各是一个小枚举;AllowOrigin 的常量、列表、同步谓词、异步谓词四种来源统一成 AllowOriginFuture;Vary 按配置推出;非法组合在 layer() 和 poll_ready 两处检查,谓词形式的凭据能绕过去;tag 之后的 validate()。
  2. CSRF:移植 Go 1.25 的跨源保护:五步判定顺序;为什么不用 Method::is_safe;Origin 与请求 authority 按字节比、不看 scheme 的 fail open;反向代理改写 Host 时的 403;ProtectionError 与自定义拒绝响应。
  3. body 大小限制:Content-Length 的三种情况;请求 body 变成 Limited、响应 body 自带 413;和请求解压谁在外层决定限的是哪种字节。
flowchart TB
  req[请求] --> cors{"Cors:OPTIONS?"}
  cors -->|是| pre["预检 200,不调内层"]
  cors -->|否| csrf{"Csrf:跨站写请求?"}
  csrf -->|是| r403["403"]
  csrf -->|否| lim{"RequestBodyLimit:Content-Length 超限?"}
  lim -->|是| r413["413"]
  lim -->|否| inner["内层:body 已套上 Limited"]

图里的顺序只是一种常见的叠法。三个模块互不依赖,CORS 不知道 CSRF 的结论,CSRF 不读 body,限额不看来源;放在一起时,外层的短路会让里面的层根本看不到这个请求。

💬 关联讨论

发起讨论
加载中...