line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include "ConnectRequest.h" |
2
|
|
|
|
|
|
|
#include "Error.h" |
3
|
|
|
|
|
|
|
#include "ConnectResponse.h" |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
#include |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
namespace panda { namespace protocol { namespace websocket { |
8
|
|
|
|
|
|
|
|
9
|
241
|
|
|
|
|
|
void ConnectRequest::process_headers () { |
10
|
|
|
|
|
|
|
bool ok; |
11
|
|
|
|
|
|
|
|
12
|
241
|
100
|
|
|
|
|
if (_method != Method::GET) { |
13
|
1
|
|
|
|
|
|
error = errc::method_mustbe_get; |
14
|
241
|
|
|
|
|
|
return; |
15
|
|
|
|
|
|
|
} |
16
|
|
|
|
|
|
|
|
17
|
240
|
50
|
|
|
|
|
if (http_version != 11) { |
18
|
0
|
|
|
|
|
|
error = errc::http_1_1_required; |
19
|
0
|
|
|
|
|
|
return; |
20
|
|
|
|
|
|
|
} |
21
|
|
|
|
|
|
|
|
22
|
240
|
50
|
|
|
|
|
if (!body.empty()) { |
|
|
50
|
|
|
|
|
|
23
|
0
|
|
|
|
|
|
error = errc::body_prohibited; |
24
|
0
|
|
|
|
|
|
return; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
240
|
50
|
|
|
|
|
auto it = headers.find("Connection"); |
28
|
720
|
50
|
|
|
|
|
if (it == headers.end() || !string_contains_ci(it->value, "upgrade")) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
29
|
0
|
|
|
|
|
|
error = errc::connection_mustbe_upgrade; |
30
|
0
|
|
|
|
|
|
return; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
240
|
50
|
|
|
|
|
it = headers.find("Upgrade"); |
34
|
720
|
50
|
|
|
|
|
if (it == headers.end() || !string_contains_ci(it->value, "websocket")) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
35
|
2
|
|
|
|
|
|
error = errc::upgrade_mustbe_websocket; |
36
|
2
|
|
|
|
|
|
return; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
238
|
|
|
|
|
|
ok = false; |
40
|
238
|
50
|
|
|
|
|
it = headers.find("Sec-WebSocket-Key"); |
41
|
476
|
50
|
|
|
|
|
if (it != headers.end()) { |
42
|
238
|
50
|
|
|
|
|
ws_key = it->value; |
43
|
476
|
50
|
|
|
|
|
auto decoded = panda::encode::decode_base64(ws_key); |
44
|
238
|
50
|
|
|
|
|
if (decoded.length() == 16) ok = true; |
45
|
|
|
|
|
|
|
} |
46
|
238
|
50
|
|
|
|
|
if (!ok) { |
47
|
0
|
|
|
|
|
|
error = errc::sec_accept_missing; |
48
|
0
|
|
|
|
|
|
return; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
238
|
|
|
|
|
|
_ws_version_supported = false; |
52
|
238
|
50
|
|
|
|
|
it = headers.find("Sec-WebSocket-Version"); |
53
|
476
|
50
|
|
|
|
|
if (it != headers.end()) { |
54
|
238
|
50
|
|
|
|
|
it->value.to_number(ws_version); |
55
|
476
|
100
|
|
|
|
|
for (int v : supported_ws_versions) { |
56
|
238
|
100
|
|
|
|
|
if (ws_version != v) continue; |
57
|
235
|
|
|
|
|
|
_ws_version_supported = true; |
58
|
235
|
|
|
|
|
|
break; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
} |
61
|
238
|
100
|
|
|
|
|
if (!_ws_version_supported) { |
62
|
3
|
|
|
|
|
|
error = errc::unsupported_version; |
63
|
3
|
|
|
|
|
|
return; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
235
|
50
|
|
|
|
|
auto ext_range = headers.get_multi("Sec-WebSocket-Extensions"); |
67
|
324
|
50
|
|
|
|
|
for (auto& val : ext_range) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
68
|
89
|
50
|
|
|
|
|
parse_header_value(val, _ws_extensions); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
235
|
50
|
|
|
|
|
ws_protocol = headers.get("Sec-WebSocket-Protocol"); |
|
|
50
|
|
|
|
|
|
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
88
|
|
|
|
|
|
void ConnectRequest::add_deflate(const DeflateExt::Config& cfg) { |
75
|
88
|
|
|
|
|
|
DeflateExt::request(_ws_extensions, cfg); |
76
|
88
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
105
|
|
|
|
|
|
string ConnectRequest::to_string() { |
79
|
105
|
50
|
|
|
|
|
if (!uri || !uri->host()) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
80
|
1
|
|
|
|
|
|
throw Error("HTTPRequest[to_string] uri with net location must be defined"); |
81
|
|
|
|
|
|
|
} |
82
|
104
|
50
|
|
|
|
|
if (uri && uri->scheme() && uri->scheme() != "ws" && uri->scheme() != "wss") { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
83
|
1
|
|
|
|
|
|
throw Error("ConnectRequest[to_string] uri scheme must be 'ws' or 'wss'"); |
84
|
|
|
|
|
|
|
} |
85
|
103
|
100
|
|
|
|
|
if (body.length()) { |
86
|
1
|
|
|
|
|
|
throw Error("ConnectRequest[to_string] http body is not allowed for websocket handshake request"); |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
102
|
|
|
|
|
|
_method = Request::Method::GET; |
90
|
|
|
|
|
|
|
|
91
|
102
|
100
|
|
|
|
|
if (!ws_key) { |
92
|
23
|
|
|
|
|
|
int32_t keybuf[] = {std::rand(), std::rand(), std::rand(), std::rand()}; |
93
|
23
|
50
|
|
|
|
|
ws_key = panda::encode::encode_base64(string_view((const char*)keybuf, sizeof(keybuf)), false, true); |
|
|
50
|
|
|
|
|
|
94
|
|
|
|
|
|
|
} |
95
|
102
|
50
|
|
|
|
|
headers.set("Sec-WebSocket-Key", ws_key); |
96
|
|
|
|
|
|
|
|
97
|
102
|
100
|
|
|
|
|
if (ws_protocol) headers.set("Sec-WebSocket-Protocol", ws_protocol); |
|
|
50
|
|
|
|
|
|
98
|
|
|
|
|
|
|
|
99
|
102
|
100
|
|
|
|
|
if (!ws_version) ws_version = 13; |
100
|
102
|
50
|
|
|
|
|
headers.set("Sec-WebSocket-Version", string::from_number(ws_version)); |
101
|
|
|
|
|
|
|
|
102
|
102
|
100
|
|
|
|
|
if (_ws_extensions.size()) headers.set("Sec-WebSocket-Extensions", compile_header_value(_ws_extensions)); |
|
|
50
|
|
|
|
|
|
103
|
|
|
|
|
|
|
|
104
|
102
|
50
|
|
|
|
|
headers.set("Connection", "Upgrade"); |
105
|
102
|
50
|
|
|
|
|
headers.set("Upgrade", "websocket"); |
106
|
|
|
|
|
|
|
|
107
|
102
|
50
|
|
|
|
|
if (!headers.has("User-Agent")) headers.add("User-Agent", "Panda-WebSocket"); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
108
|
102
|
50
|
|
|
|
|
if (!headers.has("Host")) headers.add("Host", uri->host()); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
109
|
|
|
|
|
|
|
|
110
|
102
|
|
|
|
|
|
return http::Request::to_string(); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
90
|
|
|
|
|
|
http::ResponseSP ConnectRequest::new_response() const{ |
114
|
90
|
50
|
|
|
|
|
return new ConnectResponse(); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
}}} |