From e2da5769f56b8ee9e48033fc44ad38db0c03d802 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 17 Jan 2020 11:41:44 +0100 Subject: [PATCH] Improve OPTIONS handling --- internal/server.go | 13 ++++++++++--- server.go | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/internal/server.go b/internal/server.go index bf5cf1d..e88aed2 100644 --- a/internal/server.go +++ b/internal/server.go @@ -1,10 +1,11 @@ package internal import ( - "net/http" + "encoding/xml" "fmt" "mime" - "encoding/xml" + "net/http" + "strings" ) type HTTPError struct { @@ -26,6 +27,7 @@ func (err *HTTPError) Error() string { } type Backend interface { + Options(r *http.Request) ([]string, error) HeadGet(w http.ResponseWriter, r *http.Request) error Propfind(r *http.Request, pf *Propfind, depth Depth) (*Multistatus, error) } @@ -61,7 +63,12 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) error { - w.Header().Add("Allow", "OPTIONS, GET, HEAD, PROPFIND") + methods, err := h.Backend.Options(r) + if err != nil { + return err + } + + w.Header().Add("Allow", strings.Join(methods, ", ")) w.Header().Add("DAV", "1, 3") w.WriteHeader(http.StatusNoContent) return nil diff --git a/server.go b/server.go index f9d84a9..f6ab544 100644 --- a/server.go +++ b/server.go @@ -37,6 +37,27 @@ type backend struct { FileSystem FileSystem } +func (b *backend) Options(r *http.Request) ([]string, error) { + f, err := b.FileSystem.Open(r.URL.Path) + if os.IsNotExist(err) { + return []string{http.MethodOptions}, nil + } else if err != nil { + return nil, err + } + defer f.Close() + + fi, err := f.Stat() + if err != nil { + return nil, err + } + + if fi.IsDir() { + return []string{http.MethodOptions, "PROPFIND"}, nil + } else { + return []string{http.MethodOptions, http.MethodHead, http.MethodGet, "PROPFIND"}, nil + } +} + func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error { f, err := b.FileSystem.Open(r.URL.Path) if err != nil {