From f73f5da752fbfdb927240bc3da1d4b6ee93859a8 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 6 Mar 2026 11:57:27 -0600 Subject: [PATCH] Append file extension to Blossom URLs when missing Blossom servers return content-addressed URLs (/) that may omit the file extension. After upload, extract the extension from the source filename and append it to the URL if not already present. This helps clients infer the media type from the URL alone. --- src/hooks/useUploadFile.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/hooks/useUploadFile.ts b/src/hooks/useUploadFile.ts index a0a01733..1f3dae91 100644 --- a/src/hooks/useUploadFile.ts +++ b/src/hooks/useUploadFile.ts @@ -23,6 +23,15 @@ export function useUploadFile() { }); const tags = await uploader.upload(file); + + // If the returned URL is missing a file extension, append one from the + // source file name. Blossom URLs are content-addressed (`/`) and + // may omit the extension. Adding it helps clients infer the media type. + const ext = getFileExtension(file.name); + if (ext) { + tags[0][1] = appendExtensionIfMissing(tags[0][1], ext); + } + const url = tags[0][1]; // Mirror to all other servers in the background (fire-and-forget). @@ -42,6 +51,23 @@ export function useUploadFile() { }); } +/** Extract the file extension (with leading dot) from a filename, or empty string if none. */ +function getFileExtension(filename: string): string { + const dotIndex = filename.lastIndexOf('.'); + if (dotIndex <= 0) return ''; + return filename.slice(dotIndex).toLowerCase(); +} + +/** Append a file extension to a URL if its path doesn't already have one. */ +function appendExtensionIfMissing(urlString: string, ext: string): string { + const url = new URL(urlString); + const lastSegment = url.pathname.split('/').pop() ?? ''; + // Check if the last path segment already contains a dot (has an extension) + if (lastSegment.includes('.')) return urlString; + url.pathname = url.pathname + ext; + return url.toString(); +} + /** Mirror a blob to additional Blossom servers (BUD-04). */ async function mirrorToServers( sourceUrl: string,