diff options
Diffstat (limited to 'contrib/fs/gopher.go')
-rw-r--r-- | contrib/fs/gopher.go | 150 |
1 files changed, 12 insertions, 138 deletions
diff --git a/contrib/fs/gopher.go b/contrib/fs/gopher.go index 0a0b482..209a4ec 100644 --- a/contrib/fs/gopher.go +++ b/contrib/fs/gopher.go @@ -2,9 +2,6 @@ package fs import ( "context" - "os" - "path/filepath" - "slices" "strings" sr "tildegit.org/tjp/sliderule" @@ -16,50 +13,8 @@ import ( // // It only serves responses for paths which correspond to files, not directories. func GopherFileHandler(fsroot, urlroot string, settings *gophermap.FileSystemSettings) sr.Handler { - fsroot = strings.TrimRight(fsroot, "/") - - return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { - if !strings.HasPrefix(request.Path, urlroot) { - return nil - } - requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/") - - path := filepath.Join(fsroot, requestpath) - if isPrivate(path) { - return nil - } - if isf, err := isFile(path); err != nil { - return gopher.Error(err).Response() - } else if !isf { - return nil - } - - if settings == nil { - settings = &gophermap.FileSystemSettings{} - } - - file, err := os.Open(path) - if err != nil { - return gopher.Error(err).Response() - } - - if !(settings.ParseExtended && isMap(path, *settings)) { - return gopher.File(gopher.GuessItemType(path), file) - } - - defer func() { _ = file.Close() }() - - edoc, err := gophermap.ParseExtended(file, request.URL) - if err != nil { - return gopher.Error(err).Response() - } - - doc, _, err := edoc.Compatible(filepath.Dir(path), *settings) - if err != nil { - return gopher.Error(err).Response() - } - return doc.Response() - }) + handler := fileHandler(gopher.ServerProtocol, fsroot, urlroot) + return gophermap.ExtendMiddleware(fsroot, urlroot, settings)(handler) } // GopherDirectoryDefault serves up default files for directory path requests. @@ -69,61 +24,12 @@ func GopherFileHandler(fsroot, urlroot string, settings *gophermap.FileSystemSet // // It returns nil for any paths which don't correspond to a directory. func GopherDirectoryDefault(fsroot, urlroot string, settings *gophermap.FileSystemSettings) sr.Handler { - fsroot = strings.TrimRight(fsroot, "/") - - return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { - if !strings.HasPrefix(request.Path, urlroot) { - return nil - } - requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/") - - path := filepath.Join(fsroot, requestpath) - if isPrivate(path) { - return nil - } - if isd, err := isDir(path); err != nil { - return gopher.Error(err).Response() - } else if !isd { - return nil - } - - if settings == nil { - settings = &gophermap.FileSystemSettings{} - } - - for _, fname := range settings.DirMaps { - fpath := filepath.Join(path, fname) - if isf, err := isFile(fpath); err != nil { - return gopher.Error(err).Response() - } else if !isf { - continue - } - - file, err := os.Open(fpath) - if err != nil { - return gopher.Error(err).Response() - } - - if settings.ParseExtended { - defer func() { _ = file.Close() }() - - edoc, err := gophermap.ParseExtended(file, request.URL) - if err != nil { - return gopher.Error(err).Response() - } - - doc, _, err := edoc.Compatible(path, *settings) - if err != nil { - return gopher.Error(err).Response() - } - return doc.Response() - } else { - return gopher.File(gopher.MenuType, file) - } - } + if settings == nil { + return sr.HandlerFunc(func(_ context.Context, _ *sr.Request) *sr.Response { return nil }) + } - return nil - }) + handler := directoryDefault(gopher.ServerProtocol, fsroot, urlroot, false, settings.DirMaps...) + return gophermap.ExtendMiddleware(fsroot, urlroot, settings)(handler) } // GopherDirectoryListing produces a listing of the contents of any requested directories. @@ -136,13 +42,13 @@ func GopherDirectoryListing(fsroot, urlroot string, settings *gophermap.FileSyst if !strings.HasPrefix(request.Path, urlroot) { return nil } - requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/") - path := filepath.Join(fsroot, requestpath) - if isPrivate(path) { + dpath, _ := rebasePath(fsroot, urlroot, request) + + if isPrivate(dpath) { return nil } - if isd, err := isDir(path); err != nil { + if isd, err := isDir(dpath); err != nil { return gopher.Error(err).Response() } else if !isd { return nil @@ -151,7 +57,7 @@ func GopherDirectoryListing(fsroot, urlroot string, settings *gophermap.FileSyst if settings == nil { settings = &gophermap.FileSystemSettings{} } - doc, err := gophermap.ListDir(path, request.URL, *settings) + doc, err := gophermap.ListDir(dpath, request.URL, *settings) if err != nil { return gopher.Error(err).Response() } @@ -159,35 +65,3 @@ func GopherDirectoryListing(fsroot, urlroot string, settings *gophermap.FileSyst return doc.Response() }) } - -func isDir(path string) (bool, error) { - info, err := os.Stat(path) - if err != nil { - if isNotFound(err) { - err = nil - } - return false, err - } - return info.IsDir() && info.Mode()&4 == 4, nil -} - -func isFile(path string) (bool, error) { - info, err := os.Stat(path) - if err != nil { - if isNotFound(err) { - err = nil - } - return false, err - } - m := info.Mode() - - return m.IsRegular() && m&4 == 4, nil -} - -func isMap(path string, settings gophermap.FileSystemSettings) bool { - base := filepath.Base(path) - if base == "gophermap" || strings.HasSuffix(base, ".gph") || strings.HasSuffix(base, ".gophermap") { - return true - } - return slices.Contains(settings.DirMaps, filepath.Base(path)) -} |