line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include "HeaderValueParamsParser.h" |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
namespace panda { namespace protocol { namespace websocket { |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
static const int MAX_HEADER_VALUE = 8*1024; |
6
|
|
|
|
|
|
|
using uchar = unsigned char; |
7
|
|
|
|
|
|
|
static bool header_value_special[256]; |
8
|
|
|
|
|
|
|
|
9
|
18
|
|
|
|
|
|
static int init () { |
10
|
18
|
|
|
|
|
|
header_value_special[(uchar)';'] = true; |
11
|
18
|
|
|
|
|
|
header_value_special[(uchar)','] = true; |
12
|
18
|
|
|
|
|
|
header_value_special[(uchar)'='] = true; |
13
|
18
|
|
|
|
|
|
header_value_special[(uchar)' '] = true; |
14
|
18
|
|
|
|
|
|
return 0; |
15
|
|
|
|
|
|
|
} |
16
|
18
|
|
|
|
|
|
static const auto __init = init(); |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
154
|
|
|
|
|
|
void parse_header_value(const string& strval, HeaderValues& values) { |
20
|
154
|
50
|
|
|
|
|
auto cur = strval.begin(); |
21
|
154
|
50
|
|
|
|
|
auto end = strval.end(); |
22
|
|
|
|
|
|
|
|
23
|
154
|
|
|
|
|
|
enum { PARSE_MODE_NAME, PARSE_MODE_KEY, PARSE_MODE_VAL } mode = PARSE_MODE_NAME; |
24
|
|
|
|
|
|
|
char accstr[MAX_HEADER_VALUE]; |
25
|
308
|
|
|
|
|
|
string key; |
26
|
154
|
|
|
|
|
|
char* acc = accstr; |
27
|
154
|
|
|
|
|
|
HeaderValue* elem = NULL; |
28
|
|
|
|
|
|
|
|
29
|
10662
|
100
|
|
|
|
|
for (; cur != end; ++cur) { |
30
|
10508
|
|
|
|
|
|
char c = *cur; |
31
|
10508
|
100
|
|
|
|
|
if (!header_value_special[(uchar)c]) { |
32
|
9656
|
|
|
|
|
|
*acc++ = c; |
33
|
9656
|
|
|
|
|
|
continue; |
34
|
|
|
|
|
|
|
} |
35
|
852
|
100
|
|
|
|
|
if (c == ' ') continue; |
36
|
|
|
|
|
|
|
|
37
|
561
|
100
|
|
|
|
|
if (mode == PARSE_MODE_NAME) { |
38
|
142
|
50
|
|
|
|
|
if (c == ';' || c == ',') { |
|
|
0
|
|
|
|
|
|
39
|
142
|
|
|
|
|
|
auto sz = values.size(); |
40
|
142
|
50
|
|
|
|
|
values.resize(sz+1); |
41
|
142
|
|
|
|
|
|
elem = &values[sz]; |
42
|
142
|
50
|
|
|
|
|
elem->name.assign(accstr, acc-accstr); |
43
|
142
|
|
|
|
|
|
acc = accstr; |
44
|
142
|
50
|
|
|
|
|
if (c == ';') mode = PARSE_MODE_KEY; |
45
|
|
|
|
|
|
|
} |
46
|
142
|
|
|
|
|
|
else *acc++ = c; |
47
|
|
|
|
|
|
|
} |
48
|
419
|
100
|
|
|
|
|
else if (mode == PARSE_MODE_KEY) { |
49
|
280
|
100
|
|
|
|
|
if (c == ';' || c == ',') { |
|
|
50
|
|
|
|
|
|
50
|
7
|
50
|
|
|
|
|
elem->params.emplace(string(accstr, acc-accstr), string()); |
|
|
50
|
|
|
|
|
|
51
|
7
|
|
|
|
|
|
acc = accstr; |
52
|
7
|
50
|
|
|
|
|
if (c == ',') mode = PARSE_MODE_NAME; |
53
|
|
|
|
|
|
|
} |
54
|
273
|
50
|
|
|
|
|
else if (c == '=') { |
55
|
273
|
50
|
|
|
|
|
key.assign(accstr, acc-accstr); |
56
|
273
|
|
|
|
|
|
acc = accstr; |
57
|
273
|
|
|
|
|
|
mode = PARSE_MODE_VAL; |
58
|
|
|
|
|
|
|
} |
59
|
280
|
|
|
|
|
|
else *acc++ = c; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
else { // PARSE_MODE_VAL |
62
|
139
|
100
|
|
|
|
|
if (c == ';' || c == ',') { |
|
|
50
|
|
|
|
|
|
63
|
139
|
50
|
|
|
|
|
elem->params.emplace(key, string(accstr, acc-accstr)); |
|
|
50
|
|
|
|
|
|
64
|
139
|
|
|
|
|
|
acc = accstr; |
65
|
277
|
100
|
|
|
|
|
if (c == ',') mode = PARSE_MODE_NAME; |
66
|
138
|
|
|
|
|
|
else mode = PARSE_MODE_KEY; |
67
|
|
|
|
|
|
|
} |
68
|
0
|
|
|
|
|
|
else *acc++ = c; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
// finish |
73
|
154
|
100
|
|
|
|
|
if (mode == PARSE_MODE_NAME) values.push_back(HeaderValue{string(accstr, acc-accstr), HeaderValueParams()}); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
74
|
141
|
100
|
|
|
|
|
else if (mode == PARSE_MODE_KEY) elem->params.emplace(string(accstr, acc-accstr), string()); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
75
|
134
|
50
|
|
|
|
|
else /* PARSE_MODE_VAL */ elem->params.emplace(key, string(accstr, acc-accstr)); |
|
|
50
|
|
|
|
|
|
76
|
154
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
168
|
|
|
|
|
|
string compile_header_value(const HeaderValues& values) { |
79
|
168
|
|
|
|
|
|
string str; |
80
|
|
|
|
|
|
|
|
81
|
336
|
100
|
|
|
|
|
for (const auto& elem : values) { |
82
|
168
|
50
|
|
|
|
|
str += elem.name; |
83
|
483
|
100
|
|
|
|
|
for (const auto& param : elem.params) { |
84
|
315
|
50
|
|
|
|
|
str += "; "; |
85
|
315
|
50
|
|
|
|
|
str += param.first; |
86
|
315
|
100
|
|
|
|
|
if (param.second) { |
87
|
300
|
50
|
|
|
|
|
str += '='; |
88
|
300
|
50
|
|
|
|
|
str += param.second; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
} |
91
|
168
|
50
|
|
|
|
|
str += ", "; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
168
|
50
|
|
|
|
|
if (str) str.length(str.length() - 2); |
95
|
|
|
|
|
|
|
|
96
|
168
|
|
|
|
|
|
return str; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
72
|
50
|
|
|
|
|
}}} |
|
|
50
|
|
|
|
|
|