From 1e0f8e0aaeaf1bd2ee39c02e922238b641bcf88b Mon Sep 17 00:00:00 2001 From: tjp Date: Mon, 13 Nov 2023 07:25:39 -0700 Subject: refactor contribs to work with a Protocol interface --- gopher/gophermap/extended.go | 32 ++++++++++++++++++++++++++++++++ gopher/protocol.go | 27 +++++++++++++++++++++++++++ gopher/response.go | 30 ++---------------------------- 3 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 gopher/protocol.go (limited to 'gopher') diff --git a/gopher/gophermap/extended.go b/gopher/gophermap/extended.go index 8e48e99..7d64fe0 100644 --- a/gopher/gophermap/extended.go +++ b/gopher/gophermap/extended.go @@ -3,6 +3,7 @@ package gophermap import ( "bufio" "bytes" + "context" "errors" "fmt" "io" @@ -14,6 +15,7 @@ import ( "strconv" "strings" + sr "tildegit.org/tjp/sliderule" "tildegit.org/tjp/sliderule/gopher" "tildegit.org/tjp/sliderule/internal" "tildegit.org/tjp/sliderule/internal/types" @@ -298,3 +300,33 @@ func openExtended(path string, location *url.URL, settings FileSystemSettings) ( return ParseExtended(file, location) } + +func ExtendMiddleware(fsroot, urlroot string, settings *FileSystemSettings) sr.Middleware { + return sr.Middleware(func(handler sr.Handler) sr.Handler { + return sr.HandlerFunc(func(ctx context.Context, request *sr.Request) *sr.Response { + response := handler.Handle(ctx, request) + + if !settings.ParseExtended || response.Status != gopher.MenuType { + return response + } + + defer func() { _ = response.Close() }() + + edoc, err := ParseExtended(response.Body, request.URL) + if err != nil { + return gopher.Error(err).Response() + } + + fpath := strings.TrimPrefix(request.Path, urlroot) + fpath = strings.Trim(fpath, "/") + fpath = filepath.Join(fsroot, fpath) + + doc, _, err := edoc.Compatible(filepath.Dir(fpath), *settings) + if err != nil { + return gopher.Error(err).Response() + } + + return doc.Response() + }) + }) +} diff --git a/gopher/protocol.go b/gopher/protocol.go new file mode 100644 index 0000000..22ccd56 --- /dev/null +++ b/gopher/protocol.go @@ -0,0 +1,27 @@ +package gopher + +import ( + "io" + "net/url" + + "tildegit.org/tjp/sliderule/internal/types" +) + +type proto struct{} + +func (p proto) TemporaryRedirect(u *url.URL) *types.Response { return nil } +func (p proto) PermanentRedirect(u *url.URL) *types.Response { return nil } + +func (p proto) TemporaryServerError(err error) *types.Response { return Error(err).Response() } +func (p proto) PermanentServerError(err error) *types.Response { return Error(err).Response() } +func (p proto) CGIFailure(err error) *types.Response { return Error(err).Response() } + +func (p proto) Success(filename string, body io.Reader) *types.Response { + return File(GuessItemType(filename), body) +} + +func (p proto) ParseResponse(input io.Reader) (*types.Response, error) { + return &types.Response{Body: input, Status: MenuType}, nil +} + +var ServerProtocol types.ServerProtocol = proto{} diff --git a/gopher/response.go b/gopher/response.go index 269176f..3651e07 100644 --- a/gopher/response.go +++ b/gopher/response.go @@ -5,12 +5,11 @@ import ( "fmt" "io" "mime" - "os" "path" "strings" "sync" - "unicode/utf8" + "tildegit.org/tjp/sliderule/internal" "tildegit.org/tjp/sliderule/internal/types" ) @@ -207,34 +206,9 @@ func GuessItemType(filepath string) types.Status { return TextFileType } - if contentsAreText(filepath) { + if internal.ContentsAreText(filepath) { return TextFileType } return BinaryFileType } - -func contentsAreText(filepath string) bool { - f, err := os.Open(filepath) - if err != nil { - return false - } - defer func() { _ = f.Close() }() - - var buf [1024]byte - n, err := f.Read(buf[:]) - if err != nil { - return false - } - - for i, c := range string(buf[:n]) { - if i+utf8.UTFMax > n { - // incomplete last char - break - } - if c == 0xFFFD || c < ' ' && c != '\n' && c != '\t' && c != '\f' { - return false - } - } - return true -} -- cgit v1.2.3