From 96f3a7607ffbdb349a4c2eff35efdf11b8d35a4e Mon Sep 17 00:00:00 2001 From: tjpcc Date: Tue, 10 Jan 2023 13:46:35 -0700 Subject: Add a CGI contrib --- gemini/response.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'gemini/response.go') 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() -- cgit v1.2.3