From 8d9ef6bd2e51a3aad121ef8610634c6897199b8b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Apr 2026 06:34:14 +0000 Subject: [PATCH] fix(webdav): suppress superfluous WriteHeader and log underlying PROPFIND error When HandlePropfind writes 207 headers mid-walk and then encounters an error, the caller's unconditional w.WriteHeader(status) triggers Go's "superfluous response.WriteHeader" warning. Add a headerTracker wrapper to detect whether headers were already committed; if so, skip the redundant WriteHeader and log the underlying error instead. https://claude.ai/code/session_01Wu4GcWKTyMySdMH3wbnikR --- internal/webdav/adapter.go | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/webdav/adapter.go b/internal/webdav/adapter.go index 695f0993..99fc6724 100644 --- a/internal/webdav/adapter.go +++ b/internal/webdav/adapter.go @@ -49,6 +49,22 @@ type webdavMethods struct { prefix string } +// headerTracker wraps http.ResponseWriter to track whether headers have been committed. +type headerTracker struct { + http.ResponseWriter + written bool +} + +func (h *headerTracker) WriteHeader(status int) { + h.written = true + h.ResponseWriter.WriteHeader(status) +} + +func (h *headerTracker) Write(b []byte) (int, error) { + h.written = true + return h.ResponseWriter.Write(b) +} + func (h *webdavMethods) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.Method { case "OPTIONS": @@ -56,8 +72,14 @@ func (h *webdavMethods) ServeHTTP(w http.ResponseWriter, r *http.Request) { case http.MethodHead, http.MethodGet: h.handleGet(w, r) case "PROPFIND": - status, err := propfind.HandlePropfind(propfindFS{h.fs}, w, r, h.prefix) + tracker := &headerTracker{ResponseWriter: w} + status, err := propfind.HandlePropfind(propfindFS{h.fs}, tracker, r, h.prefix) if status != 0 { + if tracker.written { + // Headers already committed (207 sent); log the underlying error. + slog.ErrorContext(r.Context(), "PROPFIND error after headers sent", "status", status, "err", err) + return + } w.WriteHeader(status) if status != http.StatusNoContent { _, _ = w.Write([]byte(http.StatusText(status)))