package utils import ( "fmt" "github.com/h2non/filetype" "github.com/h2non/filetype/types" "strings" "sync" ) type SourceType string const ( Image SourceType = "image" Video SourceType = "video" Archive SourceType = "archive" Audio SourceType = "audio" Document SourceType = "document" ) func CheckFileType(buf []byte, sourceType SourceType, exactFileType []string, fileExt string) bool { switch sourceType { case Document: kind, err := filetype.Document(buf) if err != nil { return false } return exactFile(exactFileType, kind, fileExt) case Image: kind, err := filetype.Image(buf) if err != nil { return false } return exactFile(exactFileType, kind, fileExt) case Video: kind, err := filetype.Video(buf) if err != nil { return false } return exactFile(exactFileType, kind, fileExt) case Audio: kind, err := filetype.Audio(buf) if err != nil { return false } return exactFile(exactFileType, kind, fileExt) case Archive: kind, err := filetype.Archive(buf) if err != nil { return false } return exactFile(exactFileType, kind, fileExt) default: return false } } func exactFile(exactFileType []string, fileKind types.Type, fileExt string) bool { lowCase := strings.ToLower(fileExt) for _, fileType := range exactFileType { if fileKind.Extension == fileType { if lowCase != "" && (lowCase == fmt.Sprintf(".%s", fileKind.Extension) || (lowCase == ".jpeg" && fileKind.Extension == "jpg")) { return true } return false } } return false } func IsValidType(buf []byte, sourceTypes []SourceType, exactFileType []string, fileExt string) bool { if len(sourceTypes) == 0 { return false } var wg sync.WaitGroup resultChan := make(chan bool, len(sourceTypes)) for _, sourceType := range sourceTypes { wg.Add(1) go func(st SourceType) { defer wg.Done() resultChan <- CheckFileType(buf, st, exactFileType, fileExt) }(sourceType) } wg.Wait() close(resultChan) for result := range resultChan { if result { return true } } return false }