Fix issues with rclone mounting
Some checks failed
GoReleaser / goreleaser (push) Has been cancelled
Release Docker Build / docker (push) Has been cancelled

This commit is contained in:
Mukhtar Akere
2025-08-18 22:12:26 +01:00
parent 8696db42d2
commit e3a249a9cc
4 changed files with 41 additions and 52 deletions

View File

@@ -45,7 +45,7 @@ func (m *Manager) checkMountHealth(provider string) bool {
Command: "operations/list", Command: "operations/list",
Args: map[string]interface{}{ Args: map[string]interface{}{
"fs": fmt.Sprintf("%s:", provider), "fs": fmt.Sprintf("%s:", provider),
"remote": "/", "remote": "",
}, },
} }

View File

@@ -55,39 +55,29 @@ type entry struct {
} }
func filesToXML(urlPath string, fi os.FileInfo, children []os.FileInfo) stringbuf.StringBuf { func filesToXML(urlPath string, fi os.FileInfo, children []os.FileInfo) stringbuf.StringBuf {
now := time.Now().UTC().Format(time.RFC3339) now := time.Now().UTC().Format(time.RFC3339)
entries := make([]entry, 0, len(children)+1) entries := make([]entry, 0, len(children)+1)
// Current directory - use relative paths // Add the current file itself
var currentHref, currentName string
if urlPath == "/webdav" {
currentHref = "" // Root has empty href
currentName = "" // Root has empty displayname
} else {
// For other paths, this shouldn't be called, but handle gracefully
currentName = path.Base(urlPath)
currentHref = currentName + "/"
}
// Add the current directory
entries = append(entries, entry{ entries = append(entries, entry{
escHref: xmlEscape(fastEscapePath(currentHref)), escHref: xmlEscape(fastEscapePath(urlPath)),
escName: xmlEscape(currentName), escName: xmlEscape(fi.Name()),
isDir: fi.IsDir(), isDir: fi.IsDir(),
size: fi.Size(), size: fi.Size(),
modTime: fi.ModTime().Format(time.RFC3339), modTime: fi.ModTime().Format(time.RFC3339),
}) })
// Add children - just use the name
for _, info := range children { for _, info := range children {
nm := info.Name() nm := info.Name()
childHref := nm // build raw href
href := path.Join("/", urlPath, nm)
if info.IsDir() { if info.IsDir() {
childHref += "/" href += "/"
} }
entries = append(entries, entry{ entries = append(entries, entry{
escHref: xmlEscape(fastEscapePath(childHref)), escHref: xmlEscape(fastEscapePath(href)),
escName: xmlEscape(nm), escName: xmlEscape(nm),
isDir: info.IsDir(), isDir: info.IsDir(),
size: info.Size(), size: info.Size(),
@@ -95,11 +85,13 @@ func filesToXML(urlPath string, fi os.FileInfo, children []os.FileInfo) stringbu
}) })
} }
// ... rest of XML generation stays the same ...
sb := stringbuf.New("") sb := stringbuf.New("")
// XML header and main element
_, _ = sb.WriteString(`<?xml version="1.0" encoding="UTF-8"?>`) _, _ = sb.WriteString(`<?xml version="1.0" encoding="UTF-8"?>`)
_, _ = sb.WriteString(`<d:multistatus xmlns:d="DAV:">`) _, _ = sb.WriteString(`<d:multistatus xmlns:d="DAV:">`)
// Add responses for each entry
for _, e := range entries { for _, e := range entries {
_, _ = sb.WriteString(`<d:response>`) _, _ = sb.WriteString(`<d:response>`)
_, _ = sb.WriteString(`<d:href>`) _, _ = sb.WriteString(`<d:href>`)
@@ -120,15 +112,18 @@ func filesToXML(urlPath string, fi os.FileInfo, children []os.FileInfo) stringbu
_, _ = sb.WriteString(`<d:getlastmodified>`) _, _ = sb.WriteString(`<d:getlastmodified>`)
_, _ = sb.WriteString(now) _, _ = sb.WriteString(now)
_, _ = sb.WriteString(`</d:getlastmodified>`) _, _ = sb.WriteString(`</d:getlastmodified>`)
_, _ = sb.WriteString(`<d:displayname>`) _, _ = sb.WriteString(`<d:displayname>`)
_, _ = sb.WriteString(e.escName) _, _ = sb.WriteString(e.escName)
_, _ = sb.WriteString(`</d:displayname>`) _, _ = sb.WriteString(`</d:displayname>`)
_, _ = sb.WriteString(`</d:prop>`) _, _ = sb.WriteString(`</d:prop>`)
_, _ = sb.WriteString(`<d:status>HTTP/1.1 200 OK</d:status>`) _, _ = sb.WriteString(`<d:status>HTTP/1.1 200 OK</d:status>`)
_, _ = sb.WriteString(`</d:propstat>`) _, _ = sb.WriteString(`</d:propstat>`)
_, _ = sb.WriteString(`</d:response>`) _, _ = sb.WriteString(`</d:response>`)
} }
// Close root element
_, _ = sb.WriteString(`</d:multistatus>`) _, _ = sb.WriteString(`</d:multistatus>`)
return sb return sb
} }

View File

@@ -27,7 +27,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
// Build the list of entries // Build the list of entries
type entry struct { type entry struct {
escHref string escHref string // already XML-safe + percent-escaped
escName string escName string
size int64 size int64
isDir bool isDir bool
@@ -56,42 +56,25 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
} }
entries := make([]entry, 0, len(rawEntries)+1) entries := make([]entry, 0, len(rawEntries)+1)
// Add the current file itself
// Current directory name
var currentDirName string
if cleanPath == "/" {
currentDirName = h.Name
} else {
currentDirName = path.Base(cleanPath)
}
// Current directory href - simple logic
var currentHref string
if cleanPath == "/" {
currentHref = "" // Root is empty
} else {
currentHref = currentDirName + "/" // Subdirs are just "dirname/"
}
// Add current directory
entries = append(entries, entry{ entries = append(entries, entry{
escHref: xmlEscape(fastEscapePath(currentHref)), escHref: xmlEscape(fastEscapePath(cleanPath)),
escName: xmlEscape(currentDirName), escName: xmlEscape(fi.Name()),
isDir: fi.IsDir(), isDir: fi.IsDir(),
size: fi.Size(), size: fi.Size(),
modTime: fi.ModTime().Format(time.RFC3339), modTime: fi.ModTime().Format(time.RFC3339),
}) })
// Add children - always just the name
for _, info := range rawEntries { for _, info := range rawEntries {
nm := info.Name() nm := info.Name()
childHref := nm // build raw href
href := path.Join("/", cleanPath, nm)
if info.IsDir() { if info.IsDir() {
childHref += "/" href += "/"
} }
entries = append(entries, entry{ entries = append(entries, entry{
escHref: xmlEscape(fastEscapePath(childHref)), escHref: xmlEscape(fastEscapePath(href)),
escName: xmlEscape(nm), escName: xmlEscape(nm),
isDir: info.IsDir(), isDir: info.IsDir(),
size: info.Size(), size: info.Size(),
@@ -99,17 +82,20 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
}) })
} }
// Generate XML
sb := stringbuf.New("") sb := stringbuf.New("")
// XML header and main element
_, _ = sb.WriteString(`<?xml version="1.0" encoding="UTF-8"?>`) _, _ = sb.WriteString(`<?xml version="1.0" encoding="UTF-8"?>`)
_, _ = sb.WriteString(`<d:multistatus xmlns:d="DAV:">`) _, _ = sb.WriteString(`<d:multistatus xmlns:d="DAV:">`)
// Add responses for each entry
for _, e := range entries { for _, e := range entries {
_, _ = sb.WriteString(`<d:response>`) _, _ = sb.WriteString(`<d:response>`)
_, _ = sb.WriteString(`<d:href>`) _, _ = sb.WriteString(`<d:href>`)
_, _ = sb.WriteString(e.escHref) _, _ = sb.WriteString(e.escHref)
_, _ = sb.WriteString(`</d:href>`) _, _ = sb.WriteString(`</d:href>`)
_, _ = sb.WriteString(`<d:propstat><d:prop>`) _, _ = sb.WriteString(`<d:propstat>`)
_, _ = sb.WriteString(`<d:prop>`)
if e.isDir { if e.isDir {
_, _ = sb.WriteString(`<d:resourcetype><d:collection/></d:resourcetype>`) _, _ = sb.WriteString(`<d:resourcetype><d:collection/></d:resourcetype>`)
@@ -123,22 +109,30 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
_, _ = sb.WriteString(`<d:getlastmodified>`) _, _ = sb.WriteString(`<d:getlastmodified>`)
_, _ = sb.WriteString(e.modTime) _, _ = sb.WriteString(e.modTime)
_, _ = sb.WriteString(`</d:getlastmodified>`) _, _ = sb.WriteString(`</d:getlastmodified>`)
_, _ = sb.WriteString(`<d:displayname>`) _, _ = sb.WriteString(`<d:displayname>`)
_, _ = sb.WriteString(e.escName) _, _ = sb.WriteString(e.escName)
_, _ = sb.WriteString(`</d:displayname>`) _, _ = sb.WriteString(`</d:displayname>`)
_, _ = sb.WriteString(`</d:prop>`) _, _ = sb.WriteString(`</d:prop>`)
_, _ = sb.WriteString(`<d:status>HTTP/1.1 200 OK</d:status>`) _, _ = sb.WriteString(`<d:status>HTTP/1.1 200 OK</d:status>`)
_, _ = sb.WriteString(`</d:propstat></d:response>`) _, _ = sb.WriteString(`</d:propstat>`)
_, _ = sb.WriteString(`</d:response>`)
} }
// Close root element
_, _ = sb.WriteString(`</d:multistatus>`) _, _ = sb.WriteString(`</d:multistatus>`)
// Set headers
w.Header().Set("Content-Type", "application/xml; charset=utf-8") w.Header().Set("Content-Type", "application/xml; charset=utf-8")
w.Header().Set("Vary", "Accept-Encoding") w.Header().Set("Vary", "Accept-Encoding")
w.WriteHeader(http.StatusMultiStatus)
// Set status code and write response
w.WriteHeader(http.StatusMultiStatus) // 207 MultiStatus
_, _ = w.Write(sb.Bytes()) _, _ = w.Write(sb.Bytes())
} }
// Basic XML escaping function
func xmlEscape(s string) string { func xmlEscape(s string) string {
var b strings.Builder var b strings.Builder
b.Grow(len(s)) b.Grow(len(s))

View File

@@ -198,7 +198,7 @@ func (wd *WebDav) handleGetRoot() http.HandlerFunc {
func (wd *WebDav) handleWebdavRoot() http.HandlerFunc { func (wd *WebDav) handleWebdavRoot() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
fi := &FileInfo{ fi := &FileInfo{
name: "", name: "/",
size: 0, size: 0,
mode: 0755 | os.ModeDir, mode: 0755 | os.ModeDir,
modTime: time.Now(), modTime: time.Now(),