line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include "ClientParser.h" |
2
|
|
|
|
|
|
|
#include |
3
|
|
|
|
|
|
|
#include |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
namespace panda { namespace protocol { namespace websocket { |
7
|
|
|
|
|
|
|
|
8
|
18
|
|
|
|
|
|
static bool _init () { |
9
|
18
|
|
|
|
|
|
std::srand(std::time(NULL)); |
10
|
18
|
|
|
|
|
|
return true; |
11
|
|
|
|
|
|
|
} |
12
|
|
|
|
|
|
|
|
13
|
18
|
|
|
|
|
|
static const bool _inited = _init(); |
14
|
|
|
|
|
|
|
|
15
|
106
|
|
|
|
|
|
string ClientParser::connect_request (const ConnectRequestSP& req) { |
16
|
106
|
100
|
|
|
|
|
if (_flags[CONNECTION_REQUESTED]) throw Error("already requested connection"); |
17
|
105
|
|
|
|
|
|
_flags.set(CONNECTION_REQUESTED); |
18
|
105
|
|
|
|
|
|
_connect_request = req; |
19
|
105
|
50
|
|
|
|
|
_connect_response_parser.set_context_request(req); |
20
|
105
|
100
|
|
|
|
|
if (_deflate_cfg) req->add_deflate(*_deflate_cfg); |
21
|
105
|
|
|
|
|
|
return req->to_string(); |
22
|
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
|
24
|
170
|
|
|
|
|
|
ConnectResponseSP ClientParser::connect (string& buf) { |
25
|
170
|
50
|
|
|
|
|
if (!_flags[CONNECTION_REQUESTED]) throw Error("has not requested connection"); |
26
|
170
|
50
|
|
|
|
|
if (_flags[CONNECTION_RESPONSE_PARSED]) throw Error("already parsed connect response"); |
27
|
|
|
|
|
|
|
|
28
|
170
|
|
|
|
|
|
_connect_response_parser.max_headers_size = _max_handshake_size; |
29
|
340
|
50
|
|
|
|
|
http::ResponseParser::Result res = _connect_response_parser.parse(buf); |
30
|
170
|
50
|
|
|
|
|
_connect_response = dynamic_pointer_cast(res.response); |
31
|
|
|
|
|
|
|
|
32
|
170
|
50
|
|
|
|
|
if (res.error) { |
33
|
0
|
0
|
|
|
|
|
_connect_response->error = res.error; |
34
|
0
|
0
|
|
|
|
|
_flags.set(CONNECTION_RESPONSE_PARSED); |
35
|
|
|
|
|
|
|
|
36
|
0
|
|
|
|
|
|
ConnectResponseSP ret(_connect_response); |
37
|
0
|
|
|
|
|
|
_connect_request = NULL; |
38
|
0
|
|
|
|
|
|
_connect_response = NULL; |
39
|
0
|
|
|
|
|
|
return ret; |
40
|
|
|
|
|
|
|
} |
41
|
170
|
100
|
|
|
|
|
else if (res.state != http::State::done) { |
42
|
80
|
|
|
|
|
|
return nullptr; |
43
|
|
|
|
|
|
|
} |
44
|
90
|
50
|
|
|
|
|
_connect_response->_ws_key = _connect_request->ws_key; |
45
|
90
|
50
|
|
|
|
|
_connect_response->process_headers(); |
46
|
|
|
|
|
|
|
|
47
|
90
|
50
|
|
|
|
|
_flags.set(CONNECTION_RESPONSE_PARSED); |
48
|
|
|
|
|
|
|
|
49
|
90
|
100
|
|
|
|
|
if (!_connect_response->error && _deflate_cfg) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
50
|
|
|
|
|
|
|
using result_t = DeflateExt::EffectiveConfig::NegotiationsResult; |
51
|
70
|
|
|
|
|
|
auto& exts = _connect_response->ws_extensions(); |
52
|
140
|
|
|
|
|
|
HeaderValues used_extensions; |
53
|
70
|
|
|
|
|
|
auto role = DeflateExt::Role::CLIENT; |
54
|
70
|
50
|
|
|
|
|
auto deflate_matches = DeflateExt::select(exts, *_deflate_cfg, role); |
55
|
70
|
|
|
|
|
|
switch (deflate_matches.result) { |
56
|
|
|
|
|
|
|
case result_t::SUCCESS: |
57
|
61
|
50
|
|
|
|
|
_deflate_ext.reset(DeflateExt::uplift(deflate_matches, used_extensions, role)); |
58
|
61
|
50
|
|
|
|
|
_connect_response->ws_extensions(used_extensions); |
59
|
61
|
|
|
|
|
|
break; |
60
|
|
|
|
|
|
|
case result_t::NOT_FOUND: |
61
|
|
|
|
|
|
|
/* NOOP */ |
62
|
5
|
|
|
|
|
|
break; |
63
|
|
|
|
|
|
|
case result_t::ERROR: |
64
|
4
|
|
|
|
|
|
_connect_response->error = errc::deflate_negotiation_failed; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
90
|
100
|
|
|
|
|
if (!_connect_response->error) { |
69
|
80
|
50
|
|
|
|
|
_buffer = buf.substr(res.position);// if something remains in buf, user can get it via get_frames() or get_messages() without buf param. |
|
|
50
|
|
|
|
|
|
70
|
80
|
50
|
|
|
|
|
_flags.set(ESTABLISHED); |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
180
|
|
|
|
|
|
ConnectResponseSP ret(_connect_response); |
74
|
90
|
|
|
|
|
|
_connect_request = NULL; |
75
|
90
|
|
|
|
|
|
_connect_response = NULL; |
76
|
90
|
|
|
|
|
|
return ret; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
1
|
|
|
|
|
|
void ClientParser::reset () { |
80
|
1
|
|
|
|
|
|
_connect_request = NULL; |
81
|
1
|
|
|
|
|
|
_connect_response_parser.reset(); |
82
|
1
|
|
|
|
|
|
Parser::reset(); |
83
|
1
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
72
|
50
|
|
|
|
|
}}} |
|
|
50
|
|
|
|
|
|