diff --git a/pkg/rclone/health.go b/pkg/rclone/health.go
index bc6a95f..5c6cd81 100644
--- a/pkg/rclone/health.go
+++ b/pkg/rclone/health.go
@@ -45,7 +45,7 @@ func (m *Manager) checkMountHealth(provider string) bool {
Command: "operations/list",
Args: map[string]interface{}{
"fs": fmt.Sprintf("%s:", provider),
- "remote": "/",
+ "remote": "",
},
}
diff --git a/pkg/webdav/misc.go b/pkg/webdav/misc.go
index ecc01d2..18699e4 100644
--- a/pkg/webdav/misc.go
+++ b/pkg/webdav/misc.go
@@ -55,39 +55,29 @@ type entry struct {
}
func filesToXML(urlPath string, fi os.FileInfo, children []os.FileInfo) stringbuf.StringBuf {
+
now := time.Now().UTC().Format(time.RFC3339)
entries := make([]entry, 0, len(children)+1)
- // Current directory - use relative paths
- 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
+ // Add the current file itself
entries = append(entries, entry{
- escHref: xmlEscape(fastEscapePath(currentHref)),
- escName: xmlEscape(currentName),
+ escHref: xmlEscape(fastEscapePath(urlPath)),
+ escName: xmlEscape(fi.Name()),
isDir: fi.IsDir(),
size: fi.Size(),
modTime: fi.ModTime().Format(time.RFC3339),
})
-
- // Add children - just use the name
for _, info := range children {
+
nm := info.Name()
- childHref := nm
+ // build raw href
+ href := path.Join("/", urlPath, nm)
if info.IsDir() {
- childHref += "/"
+ href += "/"
}
entries = append(entries, entry{
- escHref: xmlEscape(fastEscapePath(childHref)),
+ escHref: xmlEscape(fastEscapePath(href)),
escName: xmlEscape(nm),
isDir: info.IsDir(),
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("")
+
+ // XML header and main element
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(``)
+ // Add responses for each entry
for _, e := range entries {
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(``)
@@ -120,15 +112,18 @@ func filesToXML(urlPath string, fi os.FileInfo, children []os.FileInfo) stringbu
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(now)
_, _ = sb.WriteString(``)
+
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(e.escName)
_, _ = sb.WriteString(``)
+
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(`HTTP/1.1 200 OK`)
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(``)
}
+ // Close root element
_, _ = sb.WriteString(``)
return sb
}
diff --git a/pkg/webdav/propfind.go b/pkg/webdav/propfind.go
index ffb9266..f6a22ae 100644
--- a/pkg/webdav/propfind.go
+++ b/pkg/webdav/propfind.go
@@ -27,7 +27,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
// Build the list of entries
type entry struct {
- escHref string
+ escHref string // already XML-safe + percent-escaped
escName string
size int64
isDir bool
@@ -56,42 +56,25 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
}
entries := make([]entry, 0, len(rawEntries)+1)
-
- // 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
+ // Add the current file itself
entries = append(entries, entry{
- escHref: xmlEscape(fastEscapePath(currentHref)),
- escName: xmlEscape(currentDirName),
+ escHref: xmlEscape(fastEscapePath(cleanPath)),
+ escName: xmlEscape(fi.Name()),
isDir: fi.IsDir(),
size: fi.Size(),
modTime: fi.ModTime().Format(time.RFC3339),
})
-
- // Add children - always just the name
for _, info := range rawEntries {
+
nm := info.Name()
- childHref := nm
+ // build raw href
+ href := path.Join("/", cleanPath, nm)
if info.IsDir() {
- childHref += "/"
+ href += "/"
}
entries = append(entries, entry{
- escHref: xmlEscape(fastEscapePath(childHref)),
+ escHref: xmlEscape(fastEscapePath(href)),
escName: xmlEscape(nm),
isDir: info.IsDir(),
size: info.Size(),
@@ -99,17 +82,20 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
})
}
- // Generate XML
sb := stringbuf.New("")
+
+ // XML header and main element
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(``)
+ // Add responses for each entry
for _, e := range entries {
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(e.escHref)
_, _ = sb.WriteString(``)
- _, _ = sb.WriteString(``)
+ _, _ = sb.WriteString(``)
+ _, _ = sb.WriteString(``)
if e.isDir {
_, _ = sb.WriteString(``)
@@ -123,22 +109,30 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) {
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(e.modTime)
_, _ = sb.WriteString(``)
+
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(e.escName)
_, _ = sb.WriteString(``)
+
_, _ = sb.WriteString(``)
_, _ = sb.WriteString(`HTTP/1.1 200 OK`)
- _, _ = sb.WriteString(``)
+ _, _ = sb.WriteString(``)
+ _, _ = sb.WriteString(``)
}
+ // Close root element
_, _ = sb.WriteString(``)
+ // Set headers
w.Header().Set("Content-Type", "application/xml; charset=utf-8")
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())
}
+// Basic XML escaping function
func xmlEscape(s string) string {
var b strings.Builder
b.Grow(len(s))
diff --git a/pkg/webdav/webdav.go b/pkg/webdav/webdav.go
index 77118b5..1b6e387 100644
--- a/pkg/webdav/webdav.go
+++ b/pkg/webdav/webdav.go
@@ -198,7 +198,7 @@ func (wd *WebDav) handleGetRoot() http.HandlerFunc {
func (wd *WebDav) handleWebdavRoot() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
fi := &FileInfo{
- name: "",
+ name: "/",
size: 0,
mode: 0755 | os.ModeDir,
modTime: time.Now(),