diff options
Diffstat (limited to 'pkg/http/http.go')
| -rw-r--r-- | pkg/http/http.go | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/pkg/http/http.go b/pkg/http/http.go index eefe348..4180c81 100644 --- a/pkg/http/http.go +++ b/pkg/http/http.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "net/textproto" "regexp" "strconv" "strings" @@ -27,6 +28,8 @@ type Response struct { Header Header } +type handler func(string) error + var version = "HTTP/[0-9]+\\.[0-9]+" var requestLine = regexp.MustCompile("^([A-Z]+) +([^ ]+) +(" + version + ")$") var statusLine = regexp.MustCompile("^(" + version + ") +([0-9]+) +(.*)$") @@ -52,31 +55,34 @@ func addHeader(m Header, k, v string) Header { return m } -func parse(r io.Reader, init func(string) error, f func(string) error) error { - scanner := bufio.NewScanner(r) - ok := false +func parse(r *bufio.Reader, init handler, f handler) error { + proto := textproto.NewReader(r) + first := true - if scanner.Scan() { - if err := init(scanner.Text()); err != nil { + for { + line, err := proto.ReadLine() + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return err } - } - for scanner.Scan() { - if scanner.Text() == "" { - ok = true - break + if first { + if err := init(line); err != nil { + return err + } + first = false + continue } - if err := f(scanner.Text()); err != nil { - return err + if line == "" { + return nil } - } - if err := scanner.Err(); err != nil { - return err - } else if !ok { - return io.ErrUnexpectedEOF + if err := f(line); err != nil { + return err + } } return nil @@ -108,7 +114,7 @@ func (r *Request) parseHeader(s string) error { } } -func ParseRequest(r io.Reader) (*Request, error) { +func ParseRequest(r *bufio.Reader) (*Request, error) { req := new(Request) if err := parse(r, req.parseRequestLine, req.parseHeader); err != nil { @@ -146,7 +152,7 @@ func (r *Response) parseHeader(s string) error { } } -func ParseResponse(r io.Reader) (*Response, error) { +func ParseResponse(r *bufio.Reader) (*Response, error) { resp := new(Response) if err := parse(r, resp.parseStatusLine, resp.parseHeader); err != nil { |
