Echo视频时长校验需三层协同:Nginx/Apache设client_max_body_size或LimitRequestBody限制请求体大小,Echo配置e.MaxMultipartMemory控制解析内存,业务层用FFmpeg异步检测真实时长。

Echo 框架本身不提供视频时长校验能力,文件大小限制需分层实现:HTTP 层拦截超大请求体、Go 代码层校验上传文件元信息、业务逻辑层调用 FFmpeg 检查时长——三者缺一不可。
HTTP 层必须设 client_max_body_size(Nginx)或 equivalent(Apache)
如果前端直接 POST 一个 500MB 的 MP4,请求根本到不了 Echo,Nginx 会返回 413 Request Entity Too Large。Echo 在这之前就“失联”了。
- Nginx 配置中必须在
server块内加:client_max_body_size 512m;(别写在http全局块) - Apache 对应配置是:
LimitRequestBody 536870912(单位字节,512MB) - 该值要略大于你允许的最大单文件体积(比如用户最多传 500MB 视频,这里设 512MB 留余量)
- 改完后必须执行
nginx -t && nginx -s reload或重启 Apache,php-fpm重启无效
PHP 配置不相关,但 Go 的 c.FormFile() 要配合 MaxMemory 控制内存占用
Echo 是 Go 写的,和 PHP.ini 完全无关。但很多人误以为要改 upload_max_filesize —— 这个配置只对 PHP SAPI 有效,对 Echo 无意义。
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
- Echo 接收文件靠
c.FormFile("video"),它底层调用ParseMultipartForm - 默认
MaxMemory是 32MB:超过此大小的文件部分会写入磁盘临时文件,但整个解析过程仍可能因超时或 OOM 失败 - 应在启动 Echo 前显式设置:
e.MaxMultipartMemory = 512 - 否则即使 Nginx 放行了,
c.FormFile()也会在解析 multipart boundary 时 panic 或返回http.ErrMissingFile
上传后立刻校验文件大小和扩展名,再决定是否保存
c.FormFile() 返回的是 *multipart.FileHeader,它有 Size 和 Filename 字段,可立即用于基础过滤。
- 检查
file.Size > 500 * 1024 * 1024(500MB)就直接return c.String(http.StatusBadRequest, "file too large") - 用
filepath.Ext(file.Filename)提取后缀,只允许.mp4、.mov、.webm等白名单 - 禁止
file.Filename含..或以.开头,防止路径遍历(如../etc/passwd) - 不要等
file.Open()再校验——此时文件已进临时目录,浪费 I/O 且可能被恶意填充
视频时长只能靠 FFmpeg CLI 异步检测,不能依赖前端传参
前端 JavaScript 读不出真实时长(video.duration 可伪造),HTTP header 更不可信。唯一可靠方式是服务端调用 FFmpeg。
- 先
move_uploaded_file类操作把文件暂存(如/tmp/upload_abc123.mp4) - 执行命令:
ffprobe -v quiet -show_entries format=duration -of default=nw=1 /tmp/upload_abc123.mp4 - 解析 stdout 得到浮点秒数,判断是否 ≤ 600(10 分钟)
- 检测完立即
os.Remove()临时文件;合法视频再移到正式存储路径 - 注意:FFmpeg 调用要加超时(如
exec.CommandContext(ctx, ...).Run()),避免恶意构造的坏文件卡死进程
真正容易被忽略的是:Nginx 的 client_max_body_size 和 Echo 的 MaxMultipartMemory 必须协同——前者管“能不能发进来”,后者管“能不能解析出来”。差一个数量级,上传就会静默失败,日志里还找不到对应错误。

















