update: chunk upload

This commit is contained in:
tao.chen
2026-09-11 20:02:47 +08:00
parent 51f1fe96bf
commit d225b6e182
7 changed files with 584 additions and 13 deletions
+14 -8
View File
@@ -24,6 +24,12 @@ type fileResponse struct {
ExpiresAt time.Time `json:"expires_at"`
}
// checkFilenameSafe 校验文件名: 不含 NUL 字节, 且不超过 200 字节 (Linux NAME_MAX=255 的余量).
// 供 uploadHandler 与 uploadChunkHandler 复用 (NUL/200 校验只写这一份).
func checkFilenameSafe(name string) bool {
return !strings.ContainsRune(name, 0) && len(name) <= 200
}
// validateFilename 从 URL/JSON 参数提取并校验 filename.
// 返回 (sanitized, true) 表示安全可访问, 否则返回 ("", false).
// 规则与 downloadHandler 原内联逻辑一致: filepath.Base + 拒绝 "" / "." / ".."
@@ -44,14 +50,14 @@ func uploadHandler(c *gin.Context) {
audit(c, "upload", gin.H{"file": "", "result": "missing_form_field"})
return
}
// 早 reject: 防止 NUL 字节 + 超长文件名打爆 Stat/Save
if strings.ContainsRune(f.Filename, 0) {
c.JSON(http.StatusBadRequest, gin.H{"error": "filename contains null byte"})
audit(c, "upload", gin.H{"file": f.Filename, "result": "null_byte"})
return
}
// Linux/macOS 路径分量 NAME_MAX = 255 字节
if len(f.Filename) > 200 {
// 早 reject: 防止 NUL 字节 + 超长文件名打爆 Stat/Save (规则与分片上传共用)
if !checkFilenameSafe(f.Filename) {
if strings.ContainsRune(f.Filename, 0) {
c.JSON(http.StatusBadRequest, gin.H{"error": "filename contains null byte"})
audit(c, "upload", gin.H{"file": f.Filename, "result": "null_byte"})
return
}
// Linux/macOS 路径分量 NAME_MAX = 255 字节
c.JSON(http.StatusBadRequest, gin.H{"error": "filename too long (max 200 bytes)"})
audit(c, "upload", gin.H{"file": f.Filename, "result": "filename_too_long"})
return