Files
MyAiDesk/GovAI/server/internal/handler/file.go
T
freedak f7a720204a Update: 将子项目从 submodule 转为完整内容
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用
- 添加所有子项目的完整源代码
- 保留原始 .git 为 .git.bak 备份
2026-07-04 19:20:46 +08:00

80 lines
2.1 KiB
Go

package handler
import (
"fmt"
"io"
"mime"
"mime/multipart"
"path/filepath"
"strings"
"github.com/enterprise-ai-platform/server/internal/config"
)
// ValidateFile checks file size, extension, and MIME type.
// Returns nil if valid, or an error message if invalid.
func ValidateFile(header *multipart.FileHeader, allowedExtensions []string, maxSize int64) string {
if header.Size > maxSize {
return fmt.Sprintf("文件大小超出限制,最大支持 %dMB", maxSize/(1024*1024))
}
ext := strings.ToLower(filepath.Ext(header.Filename))
if ext != "" {
ext = ext[1:] // strip leading "."
}
extAllowed := false
for _, e := range allowedExtensions {
if strings.EqualFold(e, ext) {
extAllowed = true
break
}
}
if !extAllowed {
return fmt.Sprintf("不支持的文件类型:.%s,仅支持:%s", ext, strings.Join(allowedExtensions, "、"))
}
// Verify MIME type matches extension
mimeType := header.Header.Get("Content-Type")
if mimeType != "" {
extMime, err := mime.ExtensionsByType(mimeType)
if err == nil && len(extMime) > 0 {
mimeAllowed := false
for _, e := range extMime {
if strings.EqualFold(strings.TrimPrefix(e, "."), ext) {
mimeAllowed = true
break
}
}
if !mimeAllowed && !strings.HasPrefix(mimeType, "text/") && !strings.HasPrefix(mimeType, "application/") {
return "文件类型与实际内容不匹配"
}
}
}
return "" // valid
}
// AllowedDocumentExtensions returns the list of allowed document file extensions.
func AllowedDocumentExtensions() []string {
return []string{"pdf", "docx", "txt", "md", "csv", "xlsx"}
}
// AllowedDocumentMaxSize returns the max file size for document uploads.
func AllowedDocumentMaxSize() int64 {
return config.MaxFileSize
}
// ReadAllWithLimit reads all content from r up to maxSize bytes.
// Returns error if content exceeds maxSize.
func ReadAllWithLimit(r io.Reader, maxSize int64) ([]byte, error) {
limited := &io.LimitedReader{R: r, N: maxSize + 1}
data, err := io.ReadAll(limited)
if err != nil {
return nil, err
}
if limited.N == 0 {
return nil, fmt.Errorf("文件内容超出 %dMB 限制", maxSize/(1024*1024))
}
return data, nil
}