summaryrefslogtreecommitdiff
path: root/contrib/fs/gopher.go
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fs/gopher.go')
-rw-r--r--contrib/fs/gopher.go150
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))
-}