Fix issues with rclone mounting
This commit is contained in:
@@ -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": "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
Reference in New Issue
Block a user