Fiber框架本身不内置文件上传大小限制,需手动通过中间件校验Content-Length或包装multipart.Reader实现;其底层依赖net/http的ParseMultipartForm,默认32MB仅控内存缓冲,不拒绝超大请求。

直接说结论:Fiber 框架本身不内置文件上传大小限制逻辑,限制必须由底层 HTTP 服务器(如 Go 的 http.Server)或中间件手动控制;你不能靠配置项一键设置,得自己写校验逻辑或包装 multipart.Reader。
为什么 Fiber 没有像 Spring Boot 那样的 max-file-size 配置
Fiber 是轻量级 Web 框架,它把请求解析交给标准库 net/http,而 Go 标准库的 request.ParseMultipartForm() 默认限制是 32MB(由 MaxMemory 决定),但这个值不是“硬拦截”——它只控制内存缓冲上限,超出部分自动落盘,不拒绝请求。真正能拦截超大请求的,只有在读取请求体前就做字节流检查。
常见误区是以为调用 c.MultipartForm() 就会触发限制,其实不会;它只是懒解析,等你真正访问 form.File 或 form.Value 时才开始读,此时攻击者早已把几百 MB 数据发过来了。
在 ctx.FormFile() 前拦截:用中间件限请求体总长
最可靠的方式是在路由处理前,用中间件读取并校验 Content-Length 头(仅适用于非分块传输的请求)。注意:该头可被客户端伪造,仅作快速过滤,不能替代业务层校验。
-
Content-Length存在且 > 允许的最大值(比如 50MB →52428800)→ 直接c.Status(413).SendString("request too large") - 若
Content-Length缺失(如 chunked encoding),则需用io.LimitReader(c.Request().Body, max)包装 body,并在后续解析中捕获http.ErrBodyReadAfterClose或io.EOF等异常 - 别在中间件里调用
c.Body()或c.FormValue(),这会提前消费 body,导致后续FormFile()失败
解析时限制单个文件大小:包装 multipart.FileHeader 的 Open()
即使请求体没超限,恶意用户仍可上传一个 2GB 的文件字段。正确做法是在调用 file, err := header.Open() 后,立刻用 io.LimitReader(file, maxSize) 封装返回的 io.ReadCloser,再传给存储逻辑:
file, err := header.Open()
if err != nil {
return c.Status(400).SendString("invalid file field")
}
defer file.Close()
limited := io.LimitReader(file, 50*1024*1024) // 50MB
_, err = io.Copy(dst, limited)
if err == io.EOF {
// 正常结束
} else if errors.Is(err, io.ErrUnexpectedEOF) {
return c.Status(400).SendString("file exceeds size limit")
}
注意:header.Size 可被伪造(来自表单头),不可信;必须以实际读取字节数为准。
容易被忽略的点:分块上传和代理层干扰
如果你的应用前面挂了 Nginx、Cloudflare 或 ALB,它们自身也有上传限制(如 Nginx 的 client_max_body_size),且优先于 Fiber 生效。一旦被它们拦截,请求根本到不了 Fiber,也就不会触发任何中间件或 handler。务必同步检查反向代理配置,否则你会看到 413 错误但日志里完全没 Fiber 记录。
另外,multipart/form-data 请求的 boundary 和字段名也会占用字节数,Content-Length 是整个请求体长度,不是文件原始大小。设限时建议留出 1–2% 余量。


















