-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhttp.py
57 lines (42 loc) · 1.38 KB
/
http.py
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
from expr import *
do([
re := require('re'),
bisect := lambda iterable, predicate: do([
front := [],
back := [],
has_flipped := Box(False),
for_each(iterable, lambda item: do([
if_then(
not has_flipped.get(),
lambda: has_flipped.set(lambda _: predicate(item)),
),
(back if has_flipped.get() else front).append(item),
])),
(front, back),
]),
Header := t('Header', ['name', 'value']),
parse_header := lambda header: do([
split_header := re.split(': ', header),
Header(split_header[0], split_header[1])
]),
Request := t('Request', [
'method',
'path',
'headers',
'body',
]),
export(__name__, Request),
parse := lambda message: do([
lines := re.split('\r?\n', message),
split_message := bisect(lines, lambda line: line == ""),
message_header := split_message[0],
message_body := "\n".join(split_message[1]),
request_line := message_header[0].split(' '),
method := request_line[0],
path := request_line[1],
headers := [] if len(message_header) == 1 else \
[parse_header(header) for header in message_header[1:] if len(header)],
Request(method, path, headers, message_body),
]),
export(__name__, parse)
])