diff options
Diffstat (limited to 'gopher')
| -rw-r--r-- | gopher/gophermap/extended.go | 32 | ||||
| -rw-r--r-- | gopher/protocol.go | 27 | ||||
| -rw-r--r-- | gopher/response.go | 30 | 
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 -} | 
