From fe6d129ae2fbe822d43cd95a7aa9f338e5f90e2e Mon Sep 17 00:00:00 2001 From: xfy Date: Mon, 20 Apr 2026 18:07:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(mimeutil):=20=E6=B7=BB=E5=8A=A0=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=AE=89=E5=85=A8=E7=9A=84=20MIME=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 AddTypes、SetDefaultType、GetDefaultType 函数, 支持运行时动态配置 MIME 类型映射。 Co-Authored-By: Claude Opus 4.7 --- internal/mimeutil/detect.go | 60 +++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/internal/mimeutil/detect.go b/internal/mimeutil/detect.go index ccc9a0e..a25953c 100644 --- a/internal/mimeutil/detect.go +++ b/internal/mimeutil/detect.go @@ -19,6 +19,7 @@ import ( "mime" "path/filepath" "strings" + "sync" ) // mimeOverrides 补充 Go 标准库缺失或错误的 MIME 类型映射。 @@ -27,13 +28,51 @@ import ( // 注意: 部分扩展名 Go 返回错误类型而非缺失: // - .otf: Go 映射到 OpenDocument 公式模板,应为字体格式 // - .webm: Go 返回 audio/webm,但 webm 可包含视频 -var mimeOverrides = map[string]string{ - ".eot": "application/vnd.ms-fontobject", // 缺失 - ".otf": "font/otf", // Go 返回错误类型 - ".webmanifest": "application/manifest+json", // 缺失 - ".map": "application/json", // 缺失 - ".webm": "video/webm", // Go 返回 audio/webm - // 注意: Go 1.26.2+ 已正确支持 .mjs, .avif, .woff, .woff2 +var ( + mimeOverrides = map[string]string{ + ".eot": "application/vnd.ms-fontobject", // 缺失 + ".otf": "font/otf", // Go 返回错误类型 + ".webmanifest": "application/manifest+json", // 缺失 + ".map": "application/json", // 缺失 + ".webm": "video/webm", // Go 返回 audio/webm + // 注意: Go 1.26.2+ 已正确支持 .mjs, .avif, .woff, .woff2 + } + mimeMutex sync.RWMutex + + defaultMIME = "application/octet-stream" + defaultMutex sync.RWMutex +) + +// AddTypes 添加自定义 MIME 类型映射(线程安全)。 +// +// 参数: +// - types: 扩展名到 MIME 类型的映射,扩展名会自动转为小写 +func AddTypes(types map[string]string) { + mimeMutex.Lock() + defer mimeMutex.Unlock() + for ext, mime := range types { + mimeOverrides[strings.ToLower(ext)] = mime + } +} + +// SetDefaultType 设置默认 MIME 类型(线程安全)。 +// +// 参数: +// - defaultType: 默认 MIME 类型 +func SetDefaultType(defaultType string) { + defaultMutex.Lock() + defer defaultMutex.Unlock() + defaultMIME = defaultType +} + +// GetDefaultType 获取默认 MIME 类型(线程安全)。 +// +// 返回值: +// - string: 当前默认 MIME 类型 +func GetDefaultType() string { + defaultMutex.RLock() + defer defaultMutex.RUnlock() + return defaultMIME } // DetectContentType 检测文件的 MIME 类型。 @@ -48,8 +87,11 @@ var mimeOverrides = map[string]string{ // - string: MIME 类型,未知类型返回空字符串 func DetectContentType(filePath string) string { ext := strings.ToLower(filepath.Ext(filePath)) - if mime, ok := mimeOverrides[ext]; ok { - return mime + mimeMutex.RLock() + mimeType, ok := mimeOverrides[ext] + mimeMutex.RUnlock() + if ok { + return mimeType } return mime.TypeByExtension(ext) }