-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHttpProtocolParser.cpp
118 lines (111 loc) · 3.67 KB
/
HttpProtocolParser.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
//
// Created by Administrator on 2019/9/23 0023.
//
#include "HttpProtocolParser.h"
void HttpProtocolParser::Parse() {
ReadFromSocket();//read from socket
if (socket_closed) {
event_loop->CloseSocket(socket);
return;
}
while (true) {
if (!is_parse_finished) {
int pos = internal_buffer.find_first_of('\r', next_search_pos);
if (pos == string::npos) {
//can not find '\r'
return;
} else if (pos == next_search_pos) {
//header matched finished
is_parse_finished = true;
} else {
if (!is_parse_finished) {
if (!is_request_line_parse_finished) {
ParseRequestLine(pos);
next_search_pos = pos + 2;
} else {
int colon_pos = internal_buffer.find_first_of(':', next_search_pos);//look colon position
string header_name = internal_buffer.substr(next_search_pos,
(colon_pos - next_search_pos));
string header_value = internal_buffer.substr(
colon_pos + 1,
(pos - colon_pos - 1));
headers[header_name] = header_value;
next_search_pos = pos + 2;//exclude '\r\n'
ProcessHttpHeader(header_name, header_value);
}
} else {
//ignore request content
}
}
} else {
//PrintHeaders();
return;
}
}
}
void HttpProtocolParser::PrintHeaders() {
auto ab = headers.begin();
auto ae = headers.end();
while (ab != ae) {
cout << (*ab).first << endl;
cout << (*ab).second << endl;
++ab;
}
}
void HttpProtocolParser::ParseRequestLine(int pos) {
bool method_parsed = false;
bool url_parsed = false;
bool match_start = false;
bool is_last;
int start = 0;
char c;
for (int i = 0; i < pos; i++) {
c = internal_buffer[i];
is_last = (i == (pos - 1));
if (!match_start && !CharIsSpace(c)) {
match_start = true;
start = i;
} else if ((match_start && CharIsSpace(c)) || (is_last && match_start)) {
if ((match_start && CharIsSpace(c))) {
//reset status
match_start = false;
}
//part matched finished
if (!method_parsed) {
method_parsed = true;
method = internal_buffer.substr(start, (i - start));
} else if (!url_parsed) {
url_parsed = true;
uri = internal_buffer.substr(start, (i - start));
} else {
http_version = internal_buffer.substr(start, (i - start) + (is_last ? 1 : 0));
}
}
}
is_request_line_parse_finished = true;
}
size_t HttpProtocolParser::ReadFromSocket() {
char temp[1024] = {0};
int ret;
size_t has_read = 0;
while (true) {
try_again:
ret = read(socket, temp, 1024);
if (ret < 0) {
if (errno == EINTR) {
goto try_again;
} else {
throw SystemCallException((char *) "Read from Socket failed");
}
} else if (ret == 0) {
socket_closed = true;
return has_read;
} else {
has_read += ret;
internal_buffer.append(temp, ret);
if (ret < 1024) {
return has_read;
}
}
}
}