diff options
author | tjpcc <tjp@ctrl-c.club> | 2023-01-10 13:46:35 -0700 |
---|---|---|
committer | tjpcc <tjp@ctrl-c.club> | 2023-01-10 13:46:35 -0700 |
commit | 96f3a7607ffbdb349a4c2eff35efdf11b8d35a4e (patch) | |
tree | 8f1755bd3f3aedf33784f66aab9feccdd36c165e /gemini/response.go | |
parent | db7b6ef07254d61dee46a863786458e15a6459f6 (diff) |
Add a CGI contrib
Diffstat (limited to 'gemini/response.go')
-rw-r--r-- | gemini/response.go | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/gemini/response.go b/gemini/response.go index 90340a5..478913b 100644 --- a/gemini/response.go +++ b/gemini/response.go @@ -1,7 +1,9 @@ package gemini import ( + "bufio" "bytes" + "errors" "io" "strconv" ) @@ -262,6 +264,39 @@ func CertInvalid(msg string) *Response { } } +// InvalidResponseLineEnding indicates that a gemini response header didn't end with "\r\n". +var InvalidResponseLineEnding = errors.New("Invalid response line ending.") + +// InvalidResponseHeaderLine indicates a malformed gemini response header line. +var InvalidResponseHeaderLine = errors.New("Invalid response header line.") + +// ParseResponse parses a complete gemini response from a reader. +// +// The reader must contain only one gemini response. +func ParseResponse(rdr io.Reader) (*Response, error) { + bufrdr := bufio.NewReader(rdr) + + hdrLine, err := bufrdr.ReadBytes('\n') + if err != nil { + return nil, InvalidResponseLineEnding + } + if hdrLine[len(hdrLine)-2] != '\r' { + return nil, InvalidResponseLineEnding + } + hdrLine = hdrLine[:len(hdrLine)-2] + + status, err := strconv.Atoi(string(hdrLine[:2])) + if err != nil { + return nil, InvalidResponseHeaderLine + } + + return &Response{ + Status: Status(status), + Meta: string(hdrLine[2:]), + Body: bufrdr, + }, nil +} + // Read implements io.Reader for Response. func (r *Response) Read(b []byte) (int, error) { r.ensureReader() |