aboutsummaryrefslogtreecommitdiff
path: root/app/request.go
diff options
context:
space:
mode:
authorjet2tlf <jet2tlf@gmail.com>2024-06-03 16:48:36 +0000
committerjet2tlf <jet2tlf@gmail.com>2024-06-03 16:48:36 +0000
commitb3dd001bc8cc282c75105ba229e0c55e5a4b3252 (patch)
tree1351303952ba7ee16a494db4c069d38747bf3528 /app/request.go
parent8a94110728cca144388958d4bd322045f8bfb9e4 (diff)
downloadhttp-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.go83
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]
}