diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-04-29 16:24:38 -0600 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-04-29 16:24:38 -0600 |
commit | 039c58c9d00a4a5886fa99d7c7d472e6d02d6a67 (patch) | |
tree | 2b19ed023e956617ee3206a4528ad62317316942 /spartan/request.go | |
parent | aa6bdb0649c2f2a63b4deae8c4984a660cd0400a (diff) |
initial spartan server support
Diffstat (limited to 'spartan/request.go')
-rw-r--r-- | spartan/request.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/spartan/request.go b/spartan/request.go new file mode 100644 index 0000000..331b68c --- /dev/null +++ b/spartan/request.go @@ -0,0 +1,62 @@ +package spartan + +import ( + "bufio" + "errors" + "io" + "net/url" + "strconv" + "strings" + + "tildegit.org/tjp/gus" +) + +var ( + // InvalidRequestLine indicates a malformed first-line of a spartan request. + InvalidRequestLine = errors.New("invalid request line") + + // InvalidRequestLineEnding says that a spartan request's first line wasn't terminated with CRLF. + InvalidRequestLineEnding = errors.New("invalid request line ending") +) + +// ParseRequest parses a single spartan request and the indicated content-length from a reader. +// +// If ther reader artument is a *bufio.Reader, it will only read a single line from it. +func ParseRequest(rdr io.Reader) (*gus.Request, int, error) { + bufrdr, ok := rdr.(*bufio.Reader) + if !ok { + bufrdr = bufio.NewReader(rdr) + } + + line, err := bufrdr.ReadString('\n') + if err != io.EOF && err != nil { + return nil, 0, err + } + + host, rest, ok := strings.Cut(line, " ") + if !ok { + return nil, 0, InvalidRequestLine + } + path, rest, ok := strings.Cut(line, " ") + if !ok { + return nil, 0, InvalidRequestLine + } + + if len(rest) < 2 || line[len(line)-2:] != "\r\n" { + return nil, 0, InvalidRequestLineEnding + } + + contentlen, err := strconv.Atoi(line[:len(line)-2]) + if err != nil { + return nil, 0, err + } + + return &gus.Request{ + URL: &url.URL{ + Scheme: "spartan", + Host: host, + Path: path, + RawPath: path, + }, + }, contentlen, nil +} |