diff --git a/khatru/blossom/handlers.go b/khatru/blossom/handlers.go index e6fbf82..daf4284 100644 --- a/khatru/blossom/handlers.go +++ b/khatru/blossom/handlers.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "io" - "mime" "net/http" "regexp" "strconv" @@ -129,7 +128,7 @@ func (bs BlossomServer) handleUpload(w http.ResponseWriter, r *http.Request) { hash := sha256.Sum256(b) hhash := nostr.HexEncodeToString(hash[:]) - mimeType := mime.TypeByExtension(ext) + mimeType := blossom.GetMIMEType(ext) if mimeType == "" { mimeType = "application/octet-stream" } diff --git a/nipb0/blossom/utils.go b/nipb0/blossom/utils.go index 97ac3bf..49fb43a 100644 --- a/nipb0/blossom/utils.go +++ b/nipb0/blossom/utils.go @@ -2,37 +2,109 @@ package blossom import ( "mime" + "strings" ) -func GetExtension(mimetype string) string { +var commonMimeExtensions = map[string]string{ + "application/json": ".json", + "application/pdf": ".pdf", + "application/vnd.android.package-archive": ".apk", + "application/vnd.sqlite3": ".sqlite3", + "application/xml": ".xml", + "audio/aac": ".aac", + "audio/flac": ".flac", + "audio/midi": ".midi", + "audio/mp3": ".mp3", + "audio/mpeg": ".mp3", + "audio/mp4": ".m4a", + "audio/ogg": ".ogg", + "audio/wav": ".wav", + "audio/webm": ".weba", + "audio/x-aiff": ".aiff", + "audio/x-m4a": ".m4a", + "image/avif": ".avif", + "image/gif": ".gif", + "image/jpeg": ".jpg", + "image/png": ".png", + "image/svg+xml": ".svg", + "image/webp": ".webp", + "text/css": ".css", + "text/csv": ".csv", + "text/html": ".html", + "text/javascript": ".js", + "text/markdown": ".md", + "text/plain": ".txt", + "text/xml": ".xml", + "video/mp2t": ".ts", + "video/mp4": ".mp4", + "video/ogg": ".ogv", + "video/quicktime": ".mov", + "video/webm": ".webm", + "video/x-matroska": ".mkv", +} + +var commonExtensionMimes = map[string]string{ + ".aac": "audio/aac", + ".aiff": "audio/x-aiff", + ".apk": "application/vnd.android.package-archive", + ".avif": "image/avif", + ".css": "text/css; charset=utf-8", + ".csv": "text/csv; charset=utf-8", + ".flac": "audio/flac", + ".gif": "image/gif", + ".html": "text/html; charset=utf-8", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", + ".js": "text/javascript; charset=utf-8", + ".json": "application/json", + ".m4a": "audio/mp4", + ".md": "text/markdown; charset=utf-8", + ".midi": "audio/midi", + ".mkv": "video/x-matroska", + ".mov": "video/quicktime", + ".mp3": "audio/mpeg", + ".mp4": "video/mp4", + ".oga": "audio/ogg", + ".ogg": "audio/ogg", + ".ogv": "video/ogg", + ".pdf": "application/pdf", + ".png": "image/png", + ".sqlite3": "application/vnd.sqlite3", + ".svg": "image/svg+xml", + ".ts": "video/mp2t", + ".txt": "text/plain; charset=utf-8", + ".wav": "audio/wav", + ".weba": "audio/webm", + ".webm": "video/webm", + ".webp": "image/webp", + ".xml": "application/xml", +} + +func normalizeMIMEType(mimetype string) string { if mimetype == "" { return "" } - // hardcode some common cases (abd jbiwb oribkenatuc cases kuje ,ogg/.oga or .mov/.moov) - switch mimetype { - case "image/jpeg": - return ".jpg" - case "image/gif": - return ".gif" - case "image/png": - return ".png" - case "image/webp": - return ".webp" - case "video/mp4": - return ".mp4" - case "application/vnd.android.package-archive": - return ".apk" - case "video/quicktime": - return ".mov" - case "application/vnd.sqlite3": - return "sqlite3" - case "text/markdown": - return "md" - case "audio/midi": - return "midi" - case "audio/x-aiff": - return "aiff" + base, _, err := mime.ParseMediaType(mimetype) + if err == nil { + return strings.ToLower(base) + } + + if idx := strings.IndexByte(mimetype, ';'); idx >= 0 { + mimetype = mimetype[:idx] + } + + return strings.ToLower(strings.TrimSpace(mimetype)) +} + +func GetExtension(mimetype string) string { + mimetype = normalizeMIMEType(mimetype) + if mimetype == "" { + return "" + } + + if ext, ok := commonMimeExtensions[mimetype]; ok { + return ext } exts, _ := mime.ExtensionsByType(mimetype) @@ -42,3 +114,20 @@ func GetExtension(mimetype string) string { return "" } + +func GetMIMEType(ext string) string { + if ext == "" { + return "" + } + + ext = strings.ToLower(strings.TrimSpace(ext)) + if ext != "" && ext[0] != '.' { + ext = "." + ext + } + + if mimetype, ok := commonExtensionMimes[ext]; ok { + return mimetype + } + + return mime.TypeByExtension(ext) +}