summaryrefslogtreecommitdiff
path: root/gopher
diff options
context:
space:
mode:
Diffstat (limited to 'gopher')
-rw-r--r--gopher/gophermap/extended.go32
-rw-r--r--gopher/protocol.go27
-rw-r--r--gopher/response.go30
3 files changed, 61 insertions, 28 deletions
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
-}