| 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
|
|
|
|
|
|