diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-09-30 20:08:33 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-09-30 20:08:53 -0600 |
commit | 775c0c1040e6a6622fec39d49b354bfa194a6998 (patch) | |
tree | f46edde7ee0392ae714f4facfd4e64244814c040 /contrib/fs/spartan.go | |
parent | 09c482d5016cfc7b628058893a1644fdf5fa699f (diff) |
file serving refactor
* do away with fs.FS usage in gemini, like the previous refactor in gopher
* remove spartan code in contrib
* standardize fsroot/urlroot string arguments to file serving handlers
Diffstat (limited to 'contrib/fs/spartan.go')
-rw-r--r-- | contrib/fs/spartan.go | 124 |
1 files changed, 0 insertions, 124 deletions
diff --git a/contrib/fs/spartan.go b/contrib/fs/spartan.go deleted file mode 100644 index 70943ee..0000000 --- a/contrib/fs/spartan.go +++ /dev/null @@ -1,124 +0,0 @@ -package fs - -import ( - "context" - "io/fs" - "strings" - "text/template" - - sr "tildegit.org/tjp/sliderule" - "tildegit.org/tjp/sliderule/spartan" -) - -// SpartanFileHandler builds a handler which serves up files from a filesystem. -// -// It only serves responses for paths which do not correspond to directories on disk. -func SpartanFileHandler(fileSystem fs.FS) sr.Handler { - return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { - filepath, file, err := ResolveFile(request, fileSystem) - if err != nil { - return spartan.ClientError(err) - } - - if file == nil { - return nil - } - - return spartan.Success(mediaType(filepath), file) - }) -} - -// SpartanDirectoryDefault serves up default files for directory path requests. -// -// If any of the supported filenames are found, the contents of the file is returned -// as the spartan response. -// -// It returns nil for any paths which don't correspond to a directory. -// -// When it encounters a directory path which doesn't end in a trailing slash (/) it -// redirects to the same URL with the slash appended. This is necessary for relative -// links not in the directory's contents to function properly. -// -// It requires that files from the provided fs.FS implement fs.ReadDirFile. If they -// don't, it will produce nil responses for any directory paths. -func SpartanDirectoryDefault(fileSystem fs.FS, filenames ...string) sr.Handler { - return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { - dirpath, dir, response := handleDirSpartan(request, fileSystem) - if response != nil { - return response - } - if dir == nil { - return nil - } - defer func() { _ = dir.Close() }() - - filepath, file, err := ResolveDirectoryDefault(fileSystem, dirpath, dir, filenames) - if err != nil { - return spartan.ServerError(err) - } - if file == nil { - return nil - } - - return spartan.Success(mediaType(filepath), file) - }) -} - -// SpartanDirectoryListing produces a listing of the contents of any requested directories. -// -// It returns "4 Resource not found" for any paths which don't correspond to a filesystem directory. -// -// When it encounters a directory path which doesn't end in a trailing slash (/) it redirects to a -// URL with the trailing slash appended. This is necessary for relative links not in the directory's -// contents to function properly. -// -// It requires that files provided by the fs.FS implement fs.ReadDirFile. If they don't, it will -// produce "4 Resource not found" responses for any directory paths. -// -// The tmeplate may be nil, in which cause DefaultSpartanDirectoryList is used instead. The -// template is then processed with RenderDirectoryListing. -func SpartanDirectoryListing(filesystem fs.FS, template *template.Template) sr.Handler { - return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { - dirpath, dir, response := handleDirSpartan(request, filesystem) - if response != nil { - return response - } - if dir == nil { - return nil - } - defer func() { _ = dir.Close() }() - - if template == nil { - template = DefaultSpartanDirectoryList - } - body, err := RenderDirectoryListing(dirpath, dir, template, request.Server) - if err != nil { - return spartan.ServerError(err) - } - - return spartan.Success("text/gemini", body) - }) -} - -// DefaultSpartanDirectoryList is a template which renders a reasonable gemtext dir listing. -var DefaultSpartanDirectoryList = DefaultGeminiDirectoryList - -func handleDirSpartan(request *sr.Request, filesystem fs.FS) (string, fs.ReadDirFile, *sr.Response) { - path, dir, err := ResolveDirectory(request, filesystem) - if err != nil { - return "", nil, spartan.ServerError(err) - } - - if dir == nil { - return "", nil, nil - } - - if !strings.HasSuffix(request.Path, "/") { - _ = dir.Close() - url := *request.URL - url.Path += "/" - return "", nil, spartan.Redirect(url.String()) - } - - return path, dir, nil -} |