summaryrefslogtreecommitdiff
path: root/contrib/fs/gemini.go
diff options
context:
space:
mode:
authortjp <tjp@ctrl-c.club>2023-11-13 07:25:39 -0700
committertjp <tjp@ctrl-c.club>2023-11-13 07:27:16 -0700
commit1e0f8e0aaeaf1bd2ee39c02e922238b641bcf88b (patch)
tree020e5de91f2343119fed10dede9d2c8262a3cd83 /contrib/fs/gemini.go
parenta808b4692656c10bb43e2d54a2f5ef2746d231d5 (diff)
refactor contribs to work with a Protocol interface
Diffstat (limited to 'contrib/fs/gemini.go')
-rw-r--r--contrib/fs/gemini.go109
1 files changed, 8 insertions, 101 deletions
diff --git a/contrib/fs/gemini.go b/contrib/fs/gemini.go
index 79dcc63..6f9c75d 100644
--- a/contrib/fs/gemini.go
+++ b/contrib/fs/gemini.go
@@ -7,7 +7,6 @@ import (
"net/url"
"os"
"path"
- "path/filepath"
"strings"
"text/template"
@@ -42,7 +41,7 @@ func TitanUpload(fsroot, urlroot string, approver tlsauth.Approver) sr.Middlewar
if _, err := io.Copy(tmpf, body); err != nil {
_ = os.Remove(tmpf.Name())
- return gemini.PermanentFailure(err)
+ return gemini.Failure(err)
}
request = cloneRequest(request)
@@ -87,30 +86,7 @@ func cloneRequest(start *sr.Request) *sr.Request {
//
// It only serves responses for paths which do not correspond to directories on disk.
func GeminiFileHandler(fsroot, urlroot string) 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), "/")
-
- fpath := filepath.Join(fsroot, requestpath)
- if isPrivate(fpath) {
- return nil
- }
- if isf, err := isFile(fpath); err != nil {
- return gemini.Failure(err)
- } else if !isf {
- return nil
- }
-
- file, err := os.Open(fpath)
- if err != nil {
- return gemini.Failure(err)
- }
- return gemini.Success(mediaType(fpath), file)
- })
+ return fileHandler(gemini.ServerProtocol, fsroot, urlroot)
}
// GeminiDirectoryDefault serves up default files for directory path requests.
@@ -124,47 +100,7 @@ func GeminiFileHandler(fsroot, urlroot string) sr.Handler {
// redirects to a URL with the trailing slash appended. This is necessary for relative
// links in the directory's contents to function properly.
func GeminiDirectoryDefault(fsroot, urlroot string, filenames ...string) 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
- }
-
- if !strings.HasSuffix(request.Path, "/") {
- u := *request.URL
- u.Path += "/"
- return gemini.PermanentRedirect(u.String())
- }
-
- requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/")
- fpath := filepath.Join(fsroot, requestpath)
- if isPrivate(fpath) {
- return nil
- }
- if isd, err := isDir(fpath); err != nil {
- return gemini.Failure(err)
- } else if !isd {
- return nil
- }
-
- for _, fname := range filenames {
- candidatepath := filepath.Join(fpath, fname)
- if isf, err := isFile(candidatepath); err != nil {
- return gemini.Failure(err)
- } else if !isf {
- continue
- }
-
- file, err := os.Open(candidatepath)
- if err != nil {
- return gemini.Failure(err)
- }
- return gemini.Success(mediaType(candidatepath), file)
- }
-
- return nil
- })
+ return directoryDefault(gemini.ServerProtocol, fsroot, urlroot, true, filenames...)
}
// GeminiDirectoryListing produces a listing of the contents of any requested directories.
@@ -177,40 +113,11 @@ func GeminiDirectoryDefault(fsroot, urlroot string, filenames ...string) sr.Hand
//
// The template may be nil, in which case DefaultGeminiDirectoryList is used instead. The
// template is then processed with RenderDirectoryListing.
-func GeminiDirectoryListing(fsroot, urlroot string, template *template.Template) sr.Handler {
- fsroot = strings.TrimRight(fsroot, "/")
-
- return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response {
- if !strings.HasSuffix(request.Path, "/") {
- u := *request.URL
- u.Path += "/"
- return gemini.PermanentRedirect(u.String())
- }
- if !strings.HasPrefix(request.Path, urlroot) {
- return nil
- }
- requestpath := strings.Trim(strings.TrimPrefix(request.Path, urlroot), "/")
-
- fpath := filepath.Join(fsroot, requestpath)
- if isPrivate(fpath) {
- return nil
- }
- if isd, err := isDir(fpath); err != nil {
- return gemini.Failure(err)
- } else if !isd {
- return nil
- }
-
- if template == nil {
- template = DefaultGeminiDirectoryList
- }
- body, err := RenderDirectoryListing(fpath, requestpath, template, request.Server)
- if err != nil {
- return gemini.Failure(err)
- }
-
- return gemini.Success("text/gemini", body)
- })
+func GeminiDirectoryListing(fsroot, urlroot string, tmpl *template.Template) sr.Handler {
+ if tmpl == nil {
+ tmpl = DefaultGeminiDirectoryList
+ }
+ return directoryListing(gemini.ServerProtocol, fsroot, urlroot, "file.gmi", true, tmpl)
}
// DefaultGeminiDirectoryList is a template which renders a reasonable gemtext dir list.