mirror of https://github.com/veypi/OneAuth.git
webdav enable dir renader
parent
2766dd99bd
commit
a4bb05d60d
@ -0,0 +1,89 @@
|
||||
//
|
||||
// dir_render.go
|
||||
// Copyright (C) 2024 veypi <i@veypi.com>
|
||||
// 2024-10-18 19:35
|
||||
// Distributed under terms of the GPL license.
|
||||
//
|
||||
|
||||
package webdav
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/veypi/utils/logv"
|
||||
)
|
||||
|
||||
type anyDirs interface {
|
||||
len() int
|
||||
name(i int) string
|
||||
isDir(i int) bool
|
||||
}
|
||||
|
||||
type fileInfoDirs []fs.FileInfo
|
||||
|
||||
func (d fileInfoDirs) len() int { return len(d) }
|
||||
func (d fileInfoDirs) isDir(i int) bool { return d[i].IsDir() }
|
||||
func (d fileInfoDirs) name(i int) string { return d[i].Name() }
|
||||
|
||||
type dirEntryDirs []fs.DirEntry
|
||||
|
||||
func (d dirEntryDirs) len() int { return len(d) }
|
||||
func (d dirEntryDirs) isDir(i int) bool { return d[i].IsDir() }
|
||||
func (d dirEntryDirs) name(i int) string { return d[i].Name() }
|
||||
|
||||
func dirList(w http.ResponseWriter, r *http.Request, f File) {
|
||||
|
||||
// Prefer to use ReadDir instead of Readdir,
|
||||
// because the former doesn't require calling
|
||||
// Stat on every entry of a directory on Unix.
|
||||
var dirs anyDirs
|
||||
var err error
|
||||
if d, ok := f.(fs.ReadDirFile); ok {
|
||||
var list dirEntryDirs
|
||||
list, err = d.ReadDir(-1)
|
||||
dirs = list
|
||||
} else {
|
||||
var list fileInfoDirs
|
||||
list, err = f.Readdir(-1)
|
||||
dirs = list
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logv.Warn().Msgf("http: error reading directory: %v", err)
|
||||
http.Error(w, "Error reading directory", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
sort.Slice(dirs, func(i, j int) bool { return dirs.name(i) < dirs.name(j) })
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
fmt.Fprintf(w, "<!doctype html>\n")
|
||||
fmt.Fprintf(w, "<meta name=\"viewport\" content=\"width=device-width\">\n")
|
||||
fmt.Fprintf(w, "<pre>\n")
|
||||
for i, n := 0, dirs.len(); i < n; i++ {
|
||||
name := dirs.name(i)
|
||||
if dirs.isDir(i) {
|
||||
name += "/"
|
||||
}
|
||||
// name may contain '?' or '#', which must be escaped to remain
|
||||
// part of the URL path, and not indicate the start of a query
|
||||
// string or fragment.
|
||||
url := url.URL{Path: name}
|
||||
fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), htmlReplacer.Replace(name))
|
||||
}
|
||||
fmt.Fprintf(w, "</pre>\n")
|
||||
}
|
||||
|
||||
var htmlReplacer = strings.NewReplacer(
|
||||
"&", "&",
|
||||
"<", "<",
|
||||
">", ">",
|
||||
// """ is shorter than """.
|
||||
`"`, """,
|
||||
// "'" is shorter than "'" and apos was not in HTML until HTML5.
|
||||
"'", "'",
|
||||
)
|
Loading…
Reference in New Issue