From 40ded4d4db61c7cba3f69fdd5df59862b06d346b Mon Sep 17 00:00:00 2001 From: jbergner Date: Tue, 30 Sep 2025 00:09:57 +0200 Subject: [PATCH] Bugfix: cache failed --- cmd/unified/main.go | 55 ++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/cmd/unified/main.go b/cmd/unified/main.go index bee9101..3dc206a 100644 --- a/cmd/unified/main.go +++ b/cmd/unified/main.go @@ -639,36 +639,28 @@ func registerPublicDownloads(mux *http.ServeMux, store filesvc.MeshStore, blobs base = "/" + base } mux.HandleFunc(base+"/", func(w http.ResponseWriter, r *http.Request) { - idStr := strings.TrimPrefix(r.URL.Path, base+"/") - if idStr == "" { - http.NotFound(w, r) - return - } - id := idStr - if strings.TrimSpace(id) == "" { + id := strings.TrimSpace(strings.TrimPrefix(r.URL.Path, base+"/")) + if id == "" { http.NotFound(w, r) return } - // 1) Metadaten prüfen (nicht vorhanden oder gelöscht → 404) + // 1) Metadaten prüfen it, err := store.Get(r.Context(), filesvc.ID(id)) if err != nil || it.Deleted { http.NotFound(w, r) return } - // 2) lokal versuchen - if rc, meta, err := blobs.Open(r.Context(), id); err == nil { + // 2) Lokal versuchen + if rc, meta, err := blobs.Open(context.Background(), id); err == nil { defer rc.Close() - serveBlob(w, r, rc, meta, it.Name) // Download-Name aus Store! + serveBlob(w, r, rc, meta, it.Name) return - } else { // ########## HIER EVENTUELL PROBLEM!!! ########### - // Lokal nicht vorhanden → nur aus Mesh ziehen, wenn Owner aktiv ist - it, err := store.Get(r.Context(), filesvc.ID(id)) - if err != nil || it.Deleted { - http.NotFound(w, r) - return - } + } + + // (Optional) Owner-Online-Check — wenn du auch bei offline Ownern liefern willst, block auskommentieren + { peers := meshNode.PeerList() ttl := 2 * time.Minute if !isOwnerActive(it.Owner, peers, ttl) { @@ -677,26 +669,37 @@ func registerPublicDownloads(mux *http.ServeMux, store filesvc.MeshStore, blobs } } - // 3) aus Mesh holen (signiert) und cachen - rrc, _, _, _, err := meshNode.FetchBlobAny(r.Context(), id) + // 3) Aus Mesh holen — EIGENER Timeout-Kontext, NICHT r.Context() + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + rrc, remoteName, _, _, err := meshNode.FetchBlobAny(ctx, id) if err != nil { http.NotFound(w, r) return } defer rrc.Close() - if _, err := blobs.Save(r.Context(), id, it.Name, rrc); err != nil { - http.Error(w, "cache failed", http.StatusInternalServerError) + + // Dateiname bevorzugt vom Remote, sonst Metadaten-Name + filename := strings.TrimSpace(remoteName) + if filename == "" { + filename = it.Name + } + + // 4) Lokal cachen — KEIN Request-Kontext, damit Save nicht abbricht + if _, err := blobs.Save(context.Background(), id, filename, rrc); err != nil { + log.Printf("[public] cache save failed id=%s name=%q: %v", id, filename, err) + http.Error(w, "cache failed: "+err.Error(), http.StatusInternalServerError) return } - // 4) erneut lokal öffnen und streamen - lrc, meta, err := blobs.Open(r.Context(), id) + // 5) Erneut lokal öffnen und streamen + lrc, meta, err := blobs.Open(context.Background(), id) if err != nil { - http.Error(w, "open failed", http.StatusInternalServerError) + http.Error(w, "open failed: "+err.Error(), http.StatusInternalServerError) return } defer lrc.Close() - serveBlob(w, r, lrc, meta, it.Name) + serveBlob(w, r, lrc, meta, filename) }) }