Fiber 框架无内置全局请求体大小限制,需通过中间件校验 Content-Length 并调用 SetMaxRequestBodySize 设置底层硬限制,二者互补缺一不可。

直接说结论:Fiber 框架没有内置的「全局请求体大小限制」配置项,必须通过中间件手动拦截并校验 Content-Length,否则超大请求会直接打满内存或触发 Go runtime 的 panic(如 http: request body too large)。
为什么 Fiber 不像 Spring Boot 那样有 max-request-size 配置
Fiber 基于 Fasthttp,而 Fasthttp 默认不解析整个请求体——它只按需读取。这意味着:
- 它不会自动拒绝超大请求,也不会提前校验
Content-Length - 如果你在 handler 里调用
c.Body()或c.FormValue(),且请求体远超预期(比如 500MB),Go 进程可能因内存耗尽被 OOM kill - 错误通常表现为
http: request body too large(Fasthttp 底层抛出)或更隐蔽的read: connection reset by peer
用 c.Request().Header.ContentLength() 做前置拦截
这是最轻量、最可控的方式,在请求进入业务逻辑前就拒绝非法体积。注意:该值来自请求头,可被伪造,仅作第一道防线。
app.Use(func(c *fiber.Ctx) error {
// 允许最大 10MB
const maxBodySize = 10 * 1024 * 1024
if cl := c.Request().Header.ContentLength(); cl > maxBodySize {
return c.Status(fiber.StatusRequestEntityTooLarge).JSON(fiber.Map{
"error": "request body too large",
"limit": maxBodySize,
})
}
return c.Next()
})
- 必须放在所有路由注册之前(
app.Use(...)) - 对
GET请求无效(无 body),但 Fasthttp 仍可能读取空 body,无需额外跳过 - 不适用于流式上传(如分块上传),因为
Content-Length可能为 -1
处理流式请求或 multipart 表单时的特殊逻辑
当使用 c.MultipartForm() 或需要读取原始 body 流时,不能只依赖 Content-Length。此时应配合 io.LimitReader 控制实际读取上限:
app.Post("/upload", func(c *fiber.Ctx) error {
const maxUploadSize = 50 * 1024 * 1024 // 50MB
body := io.LimitReader(c.Request().Body, maxUploadSize)
<pre class="brush:php;toolbar:false;">form, err := c.MultipartForm()
if err != nil {
if strings.Contains(err.Error(), "request body too large") {
return c.Status(fiber.StatusRequestEntityTooLarge).SendString("file too large")
}
return err
}
// 处理 form...})
-
io.LimitReader在读取过程中强制截断,比全量加载再校验更安全 -
c.MultipartForm()内部会调用ParseMultipartForm,后者受 Go 标准库MaxMemory影响,默认仅 32MB;若需更大,需先调用c.Request().Ctx.SetMaxRequestBodySize(...) - Fiber v2.49+ 支持
c.Request().Ctx.SetMaxRequestBodySize(n),它会转发给 Fasthttp 的底层限制(推荐设为略大于业务上限,如60 * 1024 * 1024)
真正容易被忽略的是:Fiber 的 SetMaxRequestBodySize 和中间件里的 Content-Length 校验不是互斥关系,而是互补——前者是 Fasthttp 层硬限制(防 crash),后者是应用层语义限制(返回友好错误)。两者都得配,缺一不可。


















