File Coverage

src/panda/protocol/websocket/ClientParser.cc
Criterion Covered Total %
statement 47 53 88.6
branch 31 52 59.6
condition n/a
subroutine n/a
pod n/a
total 78 105 74.2


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