diff options
Diffstat (limited to 'gemini/request.go')
-rw-r--r-- | gemini/request.go | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/gemini/request.go b/gemini/request.go index 4eb7cf0..8fa1e40 100644 --- a/gemini/request.go +++ b/gemini/request.go @@ -5,6 +5,8 @@ import ( "errors" "io" "net/url" + "strconv" + "strings" "tildegit.org/tjp/sliderule/internal/types" ) @@ -12,7 +14,7 @@ import ( // InvalidRequestLineEnding indicates that a gemini request didn't end with "\r\n". var InvalidRequestLineEnding = errors.New("invalid request line ending") -// ParseRequest parses a single gemini request from a reader. +// ParseRequest parses a single gemini/titan request from a reader. // // If the reader argument is a *bufio.Reader, it will only read a single line from it. func ParseRequest(rdr io.Reader) (*types.Request, error) { @@ -39,7 +41,17 @@ func ParseRequest(rdr io.Reader) (*types.Request, error) { u.Scheme = "gemini" } - return &types.Request{URL: u}, nil + req := &types.Request{URL: u} + + if u.Scheme == "titan" { + length, err := sizeParam(u.Path) + if err != nil { + return nil, err + } + req.Meta = io.LimitReader(bufrdr, int64(length)) + } + + return req, nil } // GetTitanRequestBody fetches the request body from a titan request. @@ -55,3 +67,19 @@ func GetTitanRequestBody(request *types.Request) io.Reader { } return nil } + +func sizeParam(path string) (int, error) { + _, rest, found := strings.Cut(path, ";") + if !found { + return 0, errors.New("no params in titan request path") + } + + for _, piece := range strings.Split(rest, ";") { + key, val, _ := strings.Cut(piece, "=") + if key == "size" { + return strconv.Atoi(val) + } + } + + return 0, errors.New("no size param found in titan request") +} |