111 lines
2.1 KiB
Go
111 lines
2.1 KiB
Go
// Copyright (C) 2022 Marius Schellenberger
|
|
|
|
package srv
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/xml"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
|
|
"cachefs/pkg/fs"
|
|
)
|
|
|
|
type statusInterceptor struct {
|
|
w http.ResponseWriter
|
|
status int
|
|
}
|
|
|
|
func (s *statusInterceptor) Header() http.Header {
|
|
return s.w.Header()
|
|
}
|
|
|
|
func (s *statusInterceptor) Write(p []byte) (int, error) {
|
|
return s.w.Write(p)
|
|
}
|
|
|
|
func (s *statusInterceptor) WriteHeader(statusCode int) {
|
|
s.w.WriteHeader(statusCode)
|
|
s.status = statusCode
|
|
}
|
|
|
|
func (s *statusInterceptor) Status() int {
|
|
if s.status == 0 {
|
|
return http.StatusOK
|
|
}
|
|
return s.status
|
|
}
|
|
|
|
type dirContents struct {
|
|
AllPaths []string `xml:"a"`
|
|
Dirs []string `xml:"-"`
|
|
Files files `xml:"-"`
|
|
}
|
|
|
|
type file struct {
|
|
Name string
|
|
Anchor string
|
|
Status int
|
|
}
|
|
|
|
type files []file
|
|
|
|
func (f files) Len() int { return len(f) }
|
|
func (f files) Less(i, j int) bool { return f[i].Name < f[j].Name }
|
|
func (f files) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
|
|
|
|
type responseInterceptor struct {
|
|
buf bytes.Buffer
|
|
w http.ResponseWriter
|
|
status int
|
|
}
|
|
|
|
func (r *responseInterceptor) Header() http.Header {
|
|
return r.w.Header()
|
|
}
|
|
|
|
func (r *responseInterceptor) Write(p []byte) (int, error) {
|
|
return r.buf.Write(p)
|
|
}
|
|
|
|
func (r *responseInterceptor) WriteHeader(statusCode int) {
|
|
r.status = statusCode
|
|
}
|
|
|
|
func (r *responseInterceptor) Status() int {
|
|
if r.status == 0 {
|
|
return http.StatusOK
|
|
}
|
|
return r.status
|
|
}
|
|
|
|
func (r *responseInterceptor) GetPaths(path string, fs *fs.FS) (dir dirContents, err error) {
|
|
err = xml.Unmarshal(r.buf.Bytes(), &dir)
|
|
if err != nil {
|
|
return
|
|
}
|
|
path = strings.TrimSuffix(path, "/")
|
|
for _, p := range dir.AllPaths {
|
|
if p[len(p)-1] == '/' {
|
|
dir.Dirs = append(dir.Dirs, p)
|
|
} else {
|
|
dir.Files = append(dir.Files, file{
|
|
Name: p,
|
|
Anchor: anchor(p),
|
|
Status: fs.CacheStatus(path + "/" + p),
|
|
})
|
|
}
|
|
}
|
|
sort.Strings(dir.Dirs)
|
|
sort.Sort(dir.Files)
|
|
return
|
|
}
|
|
|
|
func anchor(s string) string {
|
|
if i := strings.LastIndex(s, "/"); i > 0 && i+1 < len(s) {
|
|
s = s[i+1:]
|
|
}
|
|
s = strings.ReplaceAll(s, " ", "_")
|
|
return strings.ToLower(s)
|
|
}
|