diff options
Diffstat (limited to 'contrib/fs/gemini.go')
-rw-r--r-- | contrib/fs/gemini.go | 109 |
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. |