c.file() 和 e.file() 不触发上传大小限制错误,真正需捕获该错误的是 post /upload 中调用 c.formfile() 时;go 标准库无 upload_err_ini_size 类错误码,须手动设 maxmultipartmemory 并校验文件大小与 content-length。

echo.File() 不会触发上传大小限制错误
你不会在 c.File() 或 e.File() 调用中捕获到“上传超出限制”错误——因为它们是服务端文件输出行为,不涉及上传过程。真正需要捕获上传限制错误的场景,是用户通过 POST /upload 提交表单上传文件时,且后端用 c.FormFile("file") 获取文件。
上传阶段的 error 值来自 Go 标准库,不是 Echo 自定义的
Go 的 http.Request.ParseMultipartForm() 在解析 multipart 表单时,若请求体超过 MaxMemory(默认 32MB)或 ParseMultipartForm 设置的上限,会直接返回 http.ErrMissingFile 或更常见的 http.ErrNotMultipart;但关键点在于:**超出 MaxMemory 并不会让 c.FormFile() 返回明确的“超限”错误码,而是导致 err != nil 且文件为空**。
-
c.FormFile("file")成功返回时,err == nil,且file.Size是真实字节数 - 若上传文件 >32MB(默认),且未调大
MaxMemory,ParseMultipartForm会把超出部分写入临时磁盘,但c.FormFile()仍可能成功返回——只是后续file.Open()可能因临时文件路径不可读而失败 - 真正“被截断”的典型表现是:
file.Size明显小于客户端声称的大小,或file.Header.Get("Content-Length")与实际读取长度不符
必须手动设置 MaxMemory 并检查 Size + Header
Go HTTP 默认对 multipart 解析有隐式内存限制,Echo 没有封装这层校验。你要主动做两件事:
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
- 在 Echo 启动前,为底层
http.Server设置MaxMultipartMemory,例如:e := echo.New() e.Server.MaxMultipartMemory = 100
- 在 handler 中,用
c.FormFile()获取后,立刻比对原始 header 和实际 size:file, err := c.FormFile("video") if err != nil { return echo.NewHTTPError(http.StatusBadRequest, "no file received") } if file.Size > 100>20)) } // 还可额外检查 Content-Length header 是否匹配(需注意代理可能改写) if cl := c.Request().Header.Get("Content-Length"); cl != "" { if expected, _ := strconv.ParseInt(cl, 10, 64); expected > 0 && file.Size != expected { return echo.NewHTTPError(http.StatusBadRequest, "inconsistent upload size") } }
别依赖 $_FILES 风格的 error 码 —— Go 没有 UPLOAD_ERR_INI_SIZE
PHP 的 $_FILES["x"]["error"] === UPLOAD_ERR_INI_SIZE 是 PHP 运行时在解析阶段注入的语义化错误码;Go 标准库没有等价机制。你在 Echo 中永远拿不到类似 1 这样的上传限制错误数字。所有边界控制都得自己加:预设最大值、提前拒绝、检查 Size、监控 ParseMultipartForm 错误类型(如 multipart: message too large)。
最容易被忽略的是:即使设置了 MaxMultipartMemory,Nginx 或 Cloudflare 等前置代理仍可能在连接层就切断大请求,此时 Echo 根本收不到完整 body —— 所以超时和代理配置也得同步调大。










