// 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) }