projects > from_scratch > http.go
1
An HTTP/1.1 server, from scratch, in Go[github]
1
2
An HTTP/1.1 server built from scratch in Go directly on raw TCP,
3
without using net/http for the server itself — it carves the
4
request line, header block, and body out of the byte stream by
5
hand, validates field names against the RFC tchar set, and reads
6
bodies strictly against Content-Length.
7
8
Serializes responses by hand and supports chunked transfer
9
encoding with trailer fields (X-Content-SHA256, X-Content-Length)
10
computed once the body is fully sent, plus streamed file
11
responses, reverse proxying, goroutine-per-connection concurrency
12
and graceful shutdown. Built end-to-end as the Boot.dev 'Learn
13
HTTP Protocol' course, starting from raw UDP datagrams.
14
15
[Go][GitHub]
16
18
19
func ParseHeaders(lines []string) (Headers, error) {
20
res := make(map[string]string)
21
for _, line := range lines {
22
name, value, err := parseHeader(line)
23
if err != nil {
24
return res, fmt.Errorf("cannot parse header '%s': %w", line, err)
25
}
26
27
// 1. field name is case insensitive
28
// so we just make all lowercase for simplicity
29
lowerCasedName := strings.ToLower(name)
30
31
// 2. if there are repetitive field names - their values are joined with ' ,'
32
if _, hasValue := res[lowerCasedName]; hasValue {
33
res[lowerCasedName] = fmt.Sprintf("%s,%s", res[lowerCasedName], value)
34
} else {
35
res[lowerCasedName] = value
36
}
37
}
38
39
return res, nil
40
}
41
42
43
44
45
46
47
48
49
50
51
NORMAL~/oleksandr/projects/from_scratch/http.go.../from_scratch/http.gomainutf-8
Enter to open · :q to quit
keys
j / kmove the cursor line, or the tree cursor
hfocus the tree; in the tree, fold or go to the parent
l / Enterin the tree, unfold or open the file
gg / Gfirst / last line
clickput the cursor on a line; on README.sh, run the session again
:qquit to the shell
:help ?this table
q / Escclose this