export const MIME_CLASSES = ["image", "video", "audio", "document", "archive", "other"] as const; export type MimeClass = (typeof MIME_CLASSES)[number]; export interface SniffedMime { mime: string; mimeClass: MimeClass; extension: string | null; } /** Bytes needed to recognise every supported signature. */ export const SNIFF_BYTES = 16; const UNKNOWN: SniffedMime = { mime: "application/octet-stream", mimeClass: "other", extension: null }; function startsWith(head: Uint8Array, signature: readonly number[], offset = 0): boolean { if (head.length < offset + signature.length) return false; return signature.every((byte, i) => head[offset + i] === byte); } function ascii(text: string): number[] { return [...text].map((c) => c.charCodeAt(0)); } /** * MIME is decided by magic bytes only; the sender's declared `info.mimetype` * is never trusted. Unrecognised payloads are stored as octet-stream/other. */ export function sniffMime(head: Uint8Array): SniffedMime { if (startsWith(head, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) { return { mime: "image/png", mimeClass: "image", extension: "png" }; } if (startsWith(head, [0xff, 0xd8, 0xff])) return { mime: "image/jpeg", mimeClass: "image", extension: "jpg" }; if (startsWith(head, ascii("GIF87a")) || startsWith(head, ascii("GIF89a"))) { return { mime: "image/gif", mimeClass: "image", extension: "gif" }; } if (startsWith(head, ascii("%PDF-"))) return { mime: "application/pdf", mimeClass: "document", extension: "pdf" }; if (startsWith(head, [0x50, 0x4b, 0x03, 0x04])) { return { mime: "application/zip", mimeClass: "archive", extension: "zip" }; } if (startsWith(head, ascii("ftyp"), 4)) return { mime: "video/mp4", mimeClass: "video", extension: "mp4" }; if (startsWith(head, [0x1a, 0x45, 0xdf, 0xa3])) return { mime: "video/webm", mimeClass: "video", extension: "webm" }; if (startsWith(head, ascii("OggS"))) return { mime: "audio/ogg", mimeClass: "audio", extension: "ogg" }; return UNKNOWN; }