mirror of
https://github.com/harivansh-afk/betterNAS.git
synced 2026-04-15 03:00:44 +00:00
Fix macOS Finder WebDAV mount by handling GET on directories (#12)
Go's webdav.Handler returns 405 Method Not Allowed for GET on collections (directories). macOS Finder sends GET to the WebDAV root as part of its mount flow and refuses to connect when it gets 405. Add a finderCompatible wrapper that intercepts GET/HEAD on directories and returns a minimal 200 response, while passing all standard WebDAV methods through to the underlying handler unchanged.
This commit is contained in:
parent
b74db855c8
commit
18b6ac625f
2 changed files with 63 additions and 2 deletions
|
|
@ -155,12 +155,13 @@ func (a *app) handler() http.Handler {
|
|||
|
||||
for _, mount := range a.exportMounts {
|
||||
mountPathPrefix := strings.TrimSuffix(mount.mountPath, "/")
|
||||
fs := webdav.Dir(mount.exportPath)
|
||||
dav := &webdav.Handler{
|
||||
Prefix: mountPathPrefix,
|
||||
FileSystem: webdav.Dir(mount.exportPath),
|
||||
FileSystem: fs,
|
||||
LockSystem: webdav.NewMemLS(),
|
||||
}
|
||||
mux.Handle(mount.mountPath, a.requireDAVAuth(mount, dav))
|
||||
mux.Handle(mount.mountPath, a.requireDAVAuth(mount, finderCompatible(dav, fs, mountPathPrefix)))
|
||||
}
|
||||
|
||||
return mux
|
||||
|
|
|
|||
60
apps/node-agent/cmd/node-agent/dav_finder.go
Normal file
60
apps/node-agent/cmd/node-agent/dav_finder.go
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/webdav"
|
||||
)
|
||||
|
||||
// finderCompatible wraps a webdav.Handler to work around macOS Finder quirks.
|
||||
//
|
||||
// Finder sends GET requests to WebDAV collection (directory) URLs and expects
|
||||
// a 200 response. The standard Go webdav.Handler returns 405 Method Not Allowed
|
||||
// for GET on directories, which causes Finder to refuse the mount.
|
||||
//
|
||||
// This wrapper intercepts GET and HEAD requests on directories and returns a
|
||||
// minimal 200 response so Finder proceeds with the WebDAV protocol.
|
||||
func finderCompatible(dav *webdav.Handler, fs webdav.FileSystem, prefix string) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet && r.Method != http.MethodHead {
|
||||
dav.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Strip the prefix to get the filesystem-relative path.
|
||||
fsPath := strings.TrimPrefix(r.URL.Path, prefix)
|
||||
if fsPath == "" {
|
||||
fsPath = "/"
|
||||
}
|
||||
|
||||
f, err := fs.OpenFile(context.Background(), fsPath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
// Not found or other error: let the regular handler deal with it.
|
||||
dav.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
info, err := f.Stat()
|
||||
if err != nil {
|
||||
dav.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
// Regular file: let the standard handler serve it.
|
||||
dav.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Directory GET: return a minimal 200 so Finder is satisfied.
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if r.Method == http.MethodGet {
|
||||
_, _ = w.Write([]byte("<!DOCTYPE html><html><body><p>betterNAS WebDAV</p></body></html>\n"))
|
||||
}
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue