1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
package main
import (
"bufio"
"bytes"
"fmt"
)
type requestHeaders struct {
headers map[string]string
}
type requestLine struct {
method string
target string
version string
}
type Request struct {
line requestLine
headers requestHeaders
body *bufio.Reader
}
func newRequestHeaders(reader *bufio.Reader) (requestHeaders, error) {
request := requestHeaders{make(map[string]string)}
for {
buf, err := reader.ReadBytes('\n')
if err != nil {
return request, 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])
}
}
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 requestLine{}, fmt.Errorf("invalid request, expected 3 elements, got %d", len(elements))
}
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: line, headers: headers, body: reader}, nil
}
func (r *Request) Body() *bufio.Reader {
return r.body
}
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]
}
|