From 264b8d9f59be03dd68ce2c491bbf8a4d425441ac Mon Sep 17 00:00:00 2001 From: tjpcc Date: Mon, 30 Oct 2023 10:24:49 -0600 Subject: move gemini titan request handling from server to request parser --- gemini/request.go | 32 ++++++++++++++++++++++++++++++-- gemini/serve.go | 28 +--------------------------- 2 files changed, 31 insertions(+), 29 deletions(-) (limited to 'gemini') 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") +} diff --git a/gemini/serve.go b/gemini/serve.go index 0303c13..c76353c 100644 --- a/gemini/serve.go +++ b/gemini/serve.go @@ -4,15 +4,12 @@ import ( "bufio" "context" "crypto/tls" - "errors" "fmt" "io" "net" - "strconv" - "strings" - "tildegit.org/tjp/sliderule/internal/types" "tildegit.org/tjp/sliderule/internal" + "tildegit.org/tjp/sliderule/internal/types" "tildegit.org/tjp/sliderule/logging" ) @@ -66,13 +63,6 @@ func (s *server) handleConn(conn net.Conn) { request.TLSState = &state } - if request.Scheme == "titan" { - len, err := sizeParam(request.Path) - if err == nil { - request.Meta = io.LimitReader(buf, int64(len)) - } - } - defer func() { if r := recover(); r != nil { err := fmt.Errorf("%s", r) @@ -90,22 +80,6 @@ func (s *server) handleConn(conn net.Conn) { _, _ = io.Copy(conn, NewResponseReader(response)) } -func sizeParam(path string) (int, error) { - _, rest, found := strings.Cut(path, ";") - if !found { - return 0, errors.New("no params in 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") -} - // GeminiOnly filters requests down to just those on the gemini:// protocol. // // Optionally, it will also allow through titan:// requests. -- cgit v1.2.3