diff options
| author | jet2tlf <jet2tlf@gmail.com> | 2024-06-03 16:48:36 +0000 |
|---|---|---|
| committer | jet2tlf <jet2tlf@gmail.com> | 2024-06-03 16:48:36 +0000 |
| commit | b3dd001bc8cc282c75105ba229e0c55e5a4b3252 (patch) | |
| tree | 1351303952ba7ee16a494db4c069d38747bf3528 /app/request.go | |
| parent | 8a94110728cca144388958d4bd322045f8bfb9e4 (diff) | |
| download | http-server-go-b3dd001bc8cc282c75105ba229e0c55e5a4b3252.tar.gz http-server-go-b3dd001bc8cc282c75105ba229e0c55e5a4b3252.zip | |
codecrafters submit [skip ci]
Diffstat (limited to 'app/request.go')
| -rw-r--r-- | app/request.go | 83 |
1 files changed, 67 insertions, 16 deletions
diff --git a/app/request.go b/app/request.go index a859154..8dd161b 100644 --- a/app/request.go +++ b/app/request.go @@ -4,34 +4,85 @@ import ( "bufio" "bytes" "fmt" - "io" ) +type requestHeaders struct { + headers map[string]string +} + +type requestLine struct { + method string + target string + version string +} + type Request struct { - Method string - Target string - Version string + line requestLine + headers requestHeaders } -func NewRequest(reader io.Reader) (*Request, error) { - scanner := bufio.NewScanner(reader) +func newRequestHeaders(reader *bufio.Reader) (requestHeaders, error) { + request := requestHeaders{make(map[string]string)} - ok := scanner.Scan() - if !ok { - err := scanner.Err() - if err == nil { - err = io.EOF + for { + buf, err := reader.ReadBytes('\n') + if err != nil { + return request, err } - return nil, err + if bytes.Equal(buf, []byte{'\r', '\n'}) { + return request, nil + } + + buf = bytes.TrimSuffix(buf, []byte{'\r', '\n'}) + header := bytes.Split(buf, []byte{':', ' '}) + + if len(header) != 2 { + return request, fmt.Errorf("invalid header line") + } + + request.headers[string(header[0])] = string(header[1]) } +} - line := scanner.Bytes() - elements := bytes.Split(line, []byte(" ")) +func newRequestLine(reader *bufio.Reader) (requestLine, error) { + buf, err := reader.ReadBytes('\n') + if err != nil { + return requestLine{}, err + } + + buf = bytes.TrimSuffix(buf, []byte{'\r', '\n'}) + elements := bytes.Split(buf, []byte{' '}) if len(elements) != 3 { - return nil, fmt.Errorf("invalid request, excepted 3 elements, got %d", len(elements)) + return requestLine{}, fmt.Errorf("invalid request, expected 3 elements, got %d", len(elements)) } - return &Request{Method: string(elements[0]), Target: string(elements[1]), Version: string(elements[2])}, nil + return requestLine{string(elements[0]), string(elements[1]), string(elements[2])}, nil +} + +func NewRequest(reader *bufio.Reader) (*Request, error) { + line, err := newRequestLine(reader) + if err != nil { + return nil, err + } + + headers, err := newRequestHeaders(reader) + if err != nil { + return nil, err + } + + return &Request{line, headers}, nil +} + +func (r *Request) Method() string { + return r.line.method +} + +func (r *Request) Target() string { + return r.line.target +} + +func (r *Request) Header(name string) string { + return r.headers.headers[name] } |