func dirListHtml(w http.ResponseWriter, r *http.Request, f fsi.File) { w.Header().Set("Content-Type", "text/html; charset=utf-8") for { dirs, err := f.Readdir(100) if err != nil || len(dirs) == 0 { break } for _, d := range dirs { name := d.Name() suffix := "" if d.IsDir() { suffix = "/" } linktitle := htmlReplacer.Replace(name) linktitle = stringspb.Ellipsoider(linktitle, 40) if d.IsDir() { linktitle = common.Directorify(linktitle) } surl := path.Join(r.URL.Path, name) + suffix + "?fmt=html" oneLine := spf("<a style='display:inline-block;min-width:600px;' href=\"%s\">%s</a>", surl, linktitle) // wpf(w, " %v", d.ModTime().Format("2006-01-02 15:04:05 MST")) oneLine += spf(" %v<br>", d.ModTime().Format(time.RFC1123Z)) wpf(w, oneLine) } } }
// GetDirContents fetches from fileserver - via http // Parsing the received JSON into string slices func GetDirContents(hostWithPrefix, dir string) ([]string, []string, *bytes.Buffer, error) { lg, lge := loghttp.Logger(nil, nil) _ = lg var b = new(bytes.Buffer) dirs := []string{} fils := []string{} // build url urlSubDirs, err := url.Parse(path.Join(hostWithPrefix, dir)) lge(err) if err != nil { return dirs, fils, b, err } sd := urlSubDirs.String() sd = common.Directorify(sd) wpf(b, "requ subdirs from %v", sd) // make req bsubdirs, effU, err := fetch.UrlGetter(nil, fetch.Options{URL: sd}) lge(err) if err != nil { return dirs, fils, b, err } wpf(b, "got %s - %v", bsubdirs, effU) // parse json mpSubDir := []map[string]string{} err = json.Unmarshal(bsubdirs, &mpSubDir) lge(err) if err != nil { // lg("%s", bsubdirs) return dirs, fils, b, err } wpf(b, "json of subdir is %s", stringspb.IndentedDump(mpSubDir)) for _, v := range mpSubDir { if dir, ok := v["path"]; ok { if strings.HasSuffix(dir, "/") { dirs = append(dirs, dir) } else { fils = append(fils, dir) } } if smod, ok := v["mod"]; ok { t, err := time.Parse(time.RFC1123Z, smod) lge(err) wpf(b, "age %-6.2v", time.Now().Sub(t).Hours()) } } return dirs, fils, b, nil }
func (m *memMapFs) Open(name string) (fsi.File, error) { origName := name dir, bname := m.SplitX(name) name = dir + bname // not join, since it removes trailing slash name1 := name name2 := name if strings.HasSuffix(name, "/") { // explicitly asked for dir name2 = common.Filify(name) } else { // try file first, then try the directory name2 = common.Directorify(name) } m.rlock() f, ok := m.fos[name1] if !ok { f, ok = m.fos[name2] } if ok { ff, okConv := f.(*InMemoryFile) if okConv { ff.Open() } else { return nil, fmt.Errorf("could not convert opened file into InMemoryFile 1") } } m.runlock() // // // Fallback to underlying fs if !ok { var err error f, err = m.lookupUnderlyingFS(name, origName) if err != nil { // log.Printf("underlying says %q => %v\n", name, err) return nil, err return nil, fsi.ErrFileNotFound } // log.Printf("underlying succ %q\n", name) // m.Dump() return f, nil } // // Regular return if ok { return f, nil } else { return nil, fsi.ErrFileNotFound } }
// remove f from it's parent's directory func (m *memMapFs) unRegisterWithParent(name string) error { parent, bname := m.SplitX(name) name = parent + bname pDir, err := m.findParent(name) if err != nil { return err } pDirC := pDir.(*InMemoryFile) // log.Printf("trying to unregister %-22q in %q - \n\t%+v\n", name, pDirC.name, pDirC.memDir) delete(pDirC.memDir, common.Directorify(name)) delete(pDirC.memDir, common.Filify(name)) return nil }
func (m *memMapFs) Mkdir(name string, perm os.FileMode) error { dir, bname := m.SplitX(name) name = dir + common.Directorify(bname) // not join, since it removes trailing slash m.rlock() _, ok := m.fos[name] m.runlock() if ok { return fsi.ErrFileExists } else { fo := m.createHelper(name) fo.dir = true m.lock() m.fos[name] = fo m.unlock() m.registerDirs(name) } return nil }
func dirListJson(w http.ResponseWriter, r *http.Request, f fsi.File) { r.Header.Set("Content-Type", "application/json") mp := []map[string]string{} for { dirs, err := f.Readdir(100) if err != nil || len(dirs) == 0 { break } for _, d := range dirs { name := d.Name() if d.IsDir() { name = common.Directorify(name) } name = htmlReplacer.Replace(name) url := url.URL{Path: name} mpl := map[string]string{ "path": url.String(), "mod": d.ModTime().Format(time.RFC1123Z), } mp = append(mp, mpl) } } bdirListHtml, err := json.MarshalIndent(mp, "", "\t") if err != nil { wpf(w, "marshalling to []byte failed - mp was %v", mp) return } w.Write(bdirListHtml) }
func (m *memMapFs) lookupUnderlyingFS( nameMemFS string, origName string, // orig name has no mountname prefix รก la mnt02 ) (fsi.File, error) { // log.Printf("check shadowFS %q %q\n", nameMemFS, origName) if m.shadow == nil { // no underlying filesystem return nil, fsi.ErrFileNotFound } fshad, err := m.shadow.Open(origName) if err != nil { return nil, fsi.ErrFileNotFound } defer fshad.Close() // log.Printf("found in shadoFS %q %q\n", nameMemFS, origName) inf, err := fshad.Stat() if err != nil { return nil, fmt.Errorf("fileinfo from shadow failed: %v", err) } // // special case // resource is a directory if inf.IsDir() { // return nil, fmt.Errorf("is dir") err = m.MkdirAll(origName, 0755) if err != nil && err != fsi.ErrFileExists { return nil, err } m.rlock() dir, ok := m.fos[common.Directorify(path.Dir(nameMemFS))] m.runlock() if !ok { return nil, fmt.Errorf("dir created with MkDir, but not in fos map %q %q", nameMemFS, origName) } // Now we try to cache the index-file. // Yes. I tried to keep it simple! idx, err := m.shadow.Open(path.Join(origName, "index.html")) if err != fsi.ErrFileNotFound { return dir, nil } if err != nil { return dir, nil } defer idx.Close() fshad = idx } // // nameMemFS = origName var dst fsi.File // regular file err = m.MkdirAll(path.Dir(nameMemFS), 0755) if err != nil && err != fsi.ErrFileExists { return nil, err } log.Printf(" from underlying: created front dir %q \n", path.Dir(nameMemFS)) dst, err = m.Create(nameMemFS) if err != nil { return nil, err } log.Printf(" from underlying: created front file %q \n", nameMemFS) n, err := io.Copy(dst, fshad) _ = n if err != nil { return nil, err } // log.Printf("copied %v for %v\n", n, name) err = dst.Close() if err != nil { return nil, err } // // reopen ff, okConv := dst.(*InMemoryFile) if okConv { ff.Open() } else { return nil, fmt.Errorf("could not convert opened file into InMemoryFile 2") } return dst, nil }