From e36c39e3f0b752e6ab47f11a2c878525d20280aa Mon Sep 17 00:00:00 2001 From: woikos Date: Tue, 3 Feb 2026 20:06:40 +0100 Subject: [PATCH] Fix blossom blob list URLs missing file extensions and add MIME sniffing - handleListBlobs now derives file extension from stored MIME type when building blob URLs, so browsers can identify file types correctly - Added http.DetectContentType fallback in upload, mirror, and media handlers for when Content-Type header is missing or unhelpful Files modified: - pkg/blossom/handlers.go: Fix list URLs, add content sniffing fallback - pkg/version/version: Bump to v0.58.8 - CLAUDE.md: Update git remotes documentation Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 6 +++--- pkg/blossom/handlers.go | 28 +++++++++++++++++++++++----- pkg/version/version | 2 +- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 134cf8a..5040f40 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -322,10 +322,10 @@ ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes root@69.164.249.71 \ ## Git Remotes -Only one remote exists: -- **origin**: `ssh://git@git.nostrdev.com:29418/mleku/next.orly.dev.git` +- **origin**: `ssh://git@git.nostrdev.com:29418/mleku/next.orly.dev.git` (contract work) +- **gitea**: `ssh://mleku@git.mleku.dev:2222/mleku/next.orly.dev.git` (primary, mleku's own host) -There is no `gitea` or `git.mleku.dev` remote configured for this repo. Do not attempt to push to `gitea`. +Push to both remotes. Use `GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519"` for gitea. ## Dependencies diff --git a/pkg/blossom/handlers.go b/pkg/blossom/handlers.go index 77c0709..649f212 100644 --- a/pkg/blossom/handlers.go +++ b/pkg/blossom/handlers.go @@ -223,11 +223,16 @@ func (s *Server) handleUpload(w http.ResponseWriter, r *http.Request) { // Note: pubkey may be nil for anonymous uploads if ACL allows it // The storage layer will handle anonymous uploads appropriately - // Detect MIME type + // Detect MIME type from header, extension, or content sniffing mimeType := DetectMimeType( r.Header.Get("Content-Type"), GetFileExtensionFromPath(r.URL.Path), ) + if mimeType == "application/octet-stream" && len(body) > 0 { + if sniffed := http.DetectContentType(body); sniffed != "application/octet-stream" { + mimeType = sniffed + } + } // Extract extension from path or infer from MIME type ext := GetFileExtensionFromPath(r.URL.Path) @@ -469,9 +474,10 @@ func (s *Server) handleListBlobs(w http.ResponseWriter, r *http.Request) { return } - // Set URLs for descriptors + // Set URLs for descriptors (include file extension for proper MIME handling) for _, desc := range descriptors { - desc.URL = BuildBlobURL(s.getBaseURL(r), desc.SHA256, "") + ext := GetExtensionFromMimeType(desc.Type) + desc.URL = BuildBlobURL(s.getBaseURL(r), desc.SHA256, ext) } // Return JSON array @@ -663,11 +669,16 @@ func (s *Server) handleMirror(w http.ResponseWriter, r *http.Request) { // Note: pubkey may be nil for anonymous uploads if ACL allows it - // Detect MIME type from remote response + // Detect MIME type from remote response, extension, or content sniffing mimeType := DetectMimeType( resp.Header.Get("Content-Type"), GetFileExtensionFromPath(mirrorURL.Path), ) + if mimeType == "application/octet-stream" && len(body) > 0 { + if sniffed := http.DetectContentType(body); sniffed != "application/octet-stream" { + mimeType = sniffed + } + } // Extract extension from path or infer from MIME type ext := GetFileExtensionFromPath(mirrorURL.Path) @@ -748,11 +759,18 @@ func (s *Server) handleMediaUpload(w http.ResponseWriter, r *http.Request) { // Note: pubkey may be nil for anonymous uploads if ACL allows it - // Optimize media (placeholder - actual optimization would be implemented here) + // Detect MIME type from header, extension, or content sniffing originalMimeType := DetectMimeType( r.Header.Get("Content-Type"), GetFileExtensionFromPath(r.URL.Path), ) + if originalMimeType == "application/octet-stream" && len(body) > 0 { + if sniffed := http.DetectContentType(body); sniffed != "application/octet-stream" { + originalMimeType = sniffed + } + } + + // Optimize media (placeholder - actual optimization would be implemented here) optimizedData, mimeType := OptimizeMedia(body, originalMimeType) // Extract extension from path or infer from MIME type diff --git a/pkg/version/version b/pkg/version/version index 354eacf..07f2919 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.58.7 +v0.58.8