From d82fe9fc555a912c9b143a9cd5c6fa2be3de85ed Mon Sep 17 00:00:00 2001 From: Wen Kai Yiang Date: Fri, 22 May 2026 18:05:53 -0700 Subject: [PATCH 1/4] main: remove OPTIONS handling from corsMiddleware The corsMiddleware was incorrectly returning an empty body for OPTIONS. This breaks WebDAV which uses OPTIONS. Fix by removing OPTIONS handling from corsMiddleware. Endpoints should instead check their methods to determine the request type. --- main.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/main.go b/main.go index a01d371..0212369 100644 --- a/main.go +++ b/main.go @@ -55,10 +55,6 @@ func corsMiddleware(handler http.Handler) http.Handler { return } } - if r.Method == http.MethodOptions { - w.WriteHeader(http.StatusOK) - return - } handler.ServeHTTP(w, r) }) } From 8325694ecff16bc2b7f9648472ce111e01f6b464 Mon Sep 17 00:00:00 2001 From: Wen Kai Yiang Date: Fri, 22 May 2026 18:13:42 -0700 Subject: [PATCH 2/4] dashboard: enforce request method --- microservices/dashboard/dashboard.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/microservices/dashboard/dashboard.go b/microservices/dashboard/dashboard.go index 385e258..264cfe6 100644 --- a/microservices/dashboard/dashboard.go +++ b/microservices/dashboard/dashboard.go @@ -17,6 +17,18 @@ func NewDashboard(tracker *tracker.Tracker) *Dashboard { } func (d *Dashboard) HandleDashboard(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + + if r.Method == http.MethodOptions { + w.Header().Del("Access-Control-Allow-Methods") + w.Header().Set("Access-Control-Allow-Methods", "GET") + w.WriteHeader(http.StatusOK) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Refresh", "5") clients := d.tracker.GetServers() From f8b1042ec412b18591b0679ce6efec040571272d Mon Sep 17 00:00:00 2001 From: Wen Kai Yiang Date: Fri, 22 May 2026 18:13:47 -0700 Subject: [PATCH 3/4] homepage: enforce request method --- microservices/homepage/homepage.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/microservices/homepage/homepage.go b/microservices/homepage/homepage.go index 5e1b61d..e677a79 100644 --- a/microservices/homepage/homepage.go +++ b/microservices/homepage/homepage.go @@ -17,6 +17,18 @@ func NewHomepage() *Homepage { } func (h *Homepage) HandleHomepage(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + + if r.Method == http.MethodOptions { + w.Header().Del("Access-Control-Allow-Methods") + w.Header().Set("Access-Control-Allow-Methods", "GET") + w.WriteHeader(http.StatusOK) + return + } + homepageTempl().Render(r.Context(), w) } From 142c2db4b590bf5de7fefe8a21b3b6bffc2ac698 Mon Sep 17 00:00:00 2001 From: Wen Kai Yiang Date: Fri, 22 May 2026 18:23:25 -0700 Subject: [PATCH 4/4] webdav: ensure correct CORS methods --- microservices/webdavservice/webdav.go | 35 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/microservices/webdavservice/webdav.go b/microservices/webdavservice/webdav.go index cd4c756..fbb055f 100644 --- a/microservices/webdavservice/webdav.go +++ b/microservices/webdavservice/webdav.go @@ -19,16 +19,18 @@ type WebDavService struct { } func (s *WebDavService) RegisterGinHandlers(router *gin.Engine) { - h := &webdav.Handler{ - Prefix: "/dav", - FileSystem: s.fs, - LockSystem: webdav.NewMemLS(), - Logger: func(r *http.Request, err error) { - if err != nil { - log.Printf("webdav: %s %s: %v", r.Method, r.URL.Path, err) - } else { - log.Printf("webdav: %s %s", r.Method, r.URL.Path) - } + h := corsWebdavMethodFixerWrapper{ + W: &webdav.Handler{ + Prefix: "/dav", + FileSystem: s.fs, + LockSystem: webdav.NewMemLS(), + Logger: func(r *http.Request, err error) { + if err != nil { + log.Printf("webdav: %s %s: %v", r.Method, r.URL.Path, err) + } else { + log.Printf("webdav: %s %s", r.Method, r.URL.Path) + } + }, }, } @@ -40,3 +42,16 @@ func (s *WebDavService) RegisterGinHandlers(router *gin.Engine) { router.Handle(method, "/dav/*filepath", gin.WrapH(h)) } } + +type corsWebdavMethodFixerWrapper struct { + W *webdav.Handler +} + +// ServeHTTP implements [http.Handler]. +func (c corsWebdavMethodFixerWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Del("Access-Control-Allow-Methods") + w.Header().Set("Access-Control-Allow-Methods", "COPY, DELETE, GET, HEAD, LOCK, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, TRACE, UNLOCK") + c.W.ServeHTTP(w, r) +} + +var _ http.Handler = corsWebdavMethodFixerWrapper{}