summaryrefslogtreecommitdiff
path: root/gemini
diff options
context:
space:
mode:
Diffstat (limited to 'gemini')
-rw-r--r--gemini/request.go32
-rw-r--r--gemini/serve.go28
2 files changed, 31 insertions, 29 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")
+}
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.