-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathrequestparser.cpp
118 lines (101 loc) · 2.71 KB
/
requestparser.cpp
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "requestparser.h"
RequestParser::RequestParser() {
reset();
}
void RequestParser::reset() {
half_end_of_line = false;
end_of_line = false;
first_line = true;
beginning = true;
method = "";
path = "";
proto_ver = "";
tmp_header_name = "";
tmp_header_value = "";
previous_char = '\0';
headers.clear();
headers_available = false;
}
void RequestParser::processChunk(const char *buf, size_t size) {
char c;
size_t i = 0;
c = buf[i];
for(; i < size; ++i, c = buf[i]) {
if(c == '\r') {
half_end_of_line = true;
goto next_iter;
} else if(half_end_of_line && c == '\n') {
if(end_of_line) {
headers_available = true;
} else {
if(!first_line) {
headers[tmp_header_name] = tmp_header_value;
tmp_header_name = "";
tmp_header_value = "";
}
end_of_line = true;
first_line = false;
goto next_iter;
}
}
if(first_line) {
static int field = 0;
if(beginning || end_of_line) {
field = 0;
}
if(c == ' ') {
field++;
} else {
switch(field) {
case 0:
method += c;
break;
case 1:
path += c;
break;
case 2:
proto_ver += c;
break;
}
}
} else {
static int field = 0;
if(end_of_line) {
field = 0;
}
switch(field) {
case 0:
if(c == ' ' && previous_char == ':') {
tmp_header_name.pop_back();
field++;
} else {
tmp_header_name += c;
}
break;
case 1:
tmp_header_value += c;
break;
}
}
half_end_of_line = false;
end_of_line = false;
next_iter:
previous_char = c;
beginning = false;
}
}
bool RequestParser::allHeadersAvailable() {
return headers_available;
}
std::map<std::string, std::string> RequestParser::getHeaders() {
return headers;
}
std::string RequestParser::getMethod() {
return method;
}
std::string RequestParser::getPath() {
return path;
}
std::string RequestParser::getProtocol() {
return proto_ver;
}