File Coverage

t/deflate/deflate-frames.cc
Criterion Covered Total %
statement 356 356 100.0
branch 897 2088 42.9
condition n/a
subroutine n/a
pod n/a
total 1253 2444 51.2


line stmt bran cond sub pod time code
1             #include
2             #include
3             #include
4             #include
5             #include
6              
7             using namespace panda;
8             using namespace panda::protocol::websocket;
9              
10             template
11 16           string to_string(T range) {
12 16           string r;
13 56 100         for (const string& s : range) r += s;
    50          
    100          
    50          
    100          
    50          
14 16           return r;
15             }
16              
17 38           TEST_CASE("FrameSender & Message builder", "[deflate-extension]") {
18 40           Parser::Config cfg;
19 20           cfg.deflate->compression_threshold = 0;
20              
21 40 50         ServerParser server;
22 20 50         server.configure(cfg);
23 40 50         ClientParser client;
24              
25 40 50         ConnectRequestSP connect_request(new ConnectRequest());
    50          
26 20 50         connect_request->uri = new URI("ws://crazypanda.ru");
    50          
27 20 50         connect_request->ws_key = "dGhlIHNhbXBsZSBub25jZQ==";
28 20           connect_request->ws_version = 13;
29 20 50         connect_request->ws_protocol = "ws";
30 40 50         auto client_request = client.connect_request(connect_request);
31              
32 20 50         REQUIRE((bool)server.accept(client_request));
    50          
    50          
    50          
    50          
    0          
    0          
33 40 50         auto server_reply = server.accept_response();
34 20 50         client.connect(server_reply);
35              
36 20 50         REQUIRE(server.established());
    50          
    50          
    50          
    0          
    0          
37 20 50         REQUIRE(client.established());
    50          
    50          
    50          
    0          
    0          
38 20 50         REQUIRE(server.is_deflate_active());
    50          
    50          
    50          
    0          
    0          
39 20 50         REQUIRE(client.is_deflate_active());
    50          
    50          
    50          
    0          
    0          
40              
41 24 50         SECTION("FrameBuffer") {
    50          
    50          
    50          
    100          
42              
43 5 50         SECTION("send (iterator)") {
    50          
    50          
    50          
    100          
44 2           std::vector fragments;
45 1 50         fragments.push_back("hello");
46 1 50         fragments.push_back(" world");
47 2 50         auto data = server.start_message(DeflateFlag::YES).send(fragments.begin(), fragments.end(), true);
    50          
48 2 50         auto data_string = to_string(data);
    50          
49 2 50         auto messages_it = client.get_messages(data_string);
50 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
51 1 50         REQUIRE(messages_it.begin()->payload[0] == "hello world");
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
52             }
53              
54 5 50         SECTION("send (iterator, empty)") {
    50          
    50          
    50          
    100          
55 2           std::vector fragments;
56 2 50         auto data = server.start_message(DeflateFlag::YES).send(fragments.begin(), fragments.end(), true);
    50          
57 2 50         auto data_string = to_string(data);
    50          
58 2 50         auto messages_it = client.get_messages(data_string);
59 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
60 1 50         REQUIRE(messages_it.begin()->payload.empty());
    50          
    50          
    50          
    50          
    50          
    0          
    0          
61             }
62              
63 5 50         SECTION("send (iterator with holes)") {
    50          
    50          
    50          
    100          
64 2           std::vector fragments;
65 1 50         fragments.push_back("");
66 1 50         fragments.push_back("hello");
67 1 50         fragments.push_back("");
68 1 50         fragments.push_back(" world");
69 1 50         fragments.push_back("");
70 2 50         auto data = server.start_message(DeflateFlag::YES).send(fragments.begin(), fragments.end(), true);
    50          
71 2 50         auto data_string = to_string(data);
    50          
72 2 50         auto messages_it = client.get_messages(data_string);
73 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
74 2 50         auto it = messages_it.begin();
75 1 50         REQUIRE(it->payload.size() == 1);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
76 1 50         REQUIRE(it->payload[0] == "hello world");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
77             }
78              
79 5 50         SECTION("send with zero shared-capacity last buff") {
    50          
    50          
    50          
    100          
80             // some png piece
81             unsigned const char buff[] = {
82             0x03, 0x6c, 0x01, 0x8b, 0xfe, 0xd6, 0xd7, 0x16,
83             0xb0, 0xe8, 0x7f, 0x1d, 0x6d, 0x01, 0x8b, 0x3e,
84             0xea, 0x65, 0x0b, 0x58, 0xf4, 0x5d, 0x17, 0x5b,
85             0xc0, 0xa2, 0x8d, 0xae, 0xdb, 0x02, 0x16, 0x6d,
86             0x77, 0xd1, 0x16, 0xb0, 0x68, 0xb7, 0x2b, 0xb6,
87             0x80, 0x45, 0x47, 0x35, 0xdb, 0x02, 0x16, 0x9d,
88             0xd4, 0x66, 0x0b, 0x58, 0x74, 0x5e, 0x83, 0x2d,
89             0x60, 0x51, 0x51, 0xb5, 0xb6, 0x80, 0x45, 0xa5,
90             0x55, 0xd9, 0x02, 0x16, 0x55, 0x54, 0x6e, 0x0b,
91             0x58, 0x54, 0x57, 0xa1, 0x2d, 0x60, 0x51, 0x75,
92             0x25, 0xb6, 0x80, 0x45, 0x2d, 0x9d, 0xda, 0x02,
93             0x16, 0x35, 0x76, 0x6c, 0x0b, 0x58, 0xd4, 0xde,
94             0x81, 0x2d, 0x60, 0xd1, 0xa5, 0xf6, 0x6c, 0x01,
95             0x8b, 0xae, 0xb6, 0x69, 0x0b, 0x58, 0xd4, 0xa1,
96             0x5f, 0x5b, 0xc0, 0xa2, 0x3e, 0x7d, 0xd9, 0x02,
97             0x16, 0x75, 0xeb, 0xdd, 0x16, 0xb0, 0xa8, 0x67,
98             0x2f, 0x5b, 0xc0, 0xa2, 0xce, 0x3d, 0x6d, 0xdd,
99             0x1e, 0xab, 0x5f, 0x07, 0x85, 0x8c, 0xdf, 0x58,
100             0x34, 0xa4, 0x3f, 0x0d, 0x82, 0x2c, 0x9c, 0x00,
101             0x25, 0xe0, 0x67, 0x00, 0x00, 0x00, 0x00, 0x49,
102             0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00
103 1           };
104 2           std::vector fragments;
105 1 50         fragments.emplace_back(reinterpret_cast(buff), sizeof(buff));
106 1           const char* buff_23 = "12345678901234567890123";
107 2           string sso_23(buff_23);
108 1 50         fragments.emplace_back(sso_23.substr(23, 0));
    50          
109 1 50         REQUIRE(bool(fragments.back().shared_buf())); // bool to prevent Catch printing data
    50          
    50          
    50          
    50          
    0          
    0          
110 1 50         REQUIRE(fragments.back().shared_capacity() == 0);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
111 2 50         auto data = server.start_message(DeflateFlag::YES).send(fragments.begin(), fragments.end(), true);
    50          
112 2 50         auto data_string = to_string(data);
    50          
113 2 50         auto messages_it = client.get_messages(data_string);
114 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
115 2 50         auto it = messages_it.begin();
116 1 50         REQUIRE(it->payload.size() == 1);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
117 1 50         REQUIRE(it->payload[0].size() >= sizeof(buff));
    50          
    50          
    50          
    50          
    50          
    0          
    0          
118             }
119             }
120              
121              
122 29 50         SECTION("MessageBuilder") {
    50          
    50          
    50          
    100          
123 10 50         SECTION("MessageBuilder::send (fragmented message iterator)") {
    50          
    50          
    50          
    100          
124 2           std::vector fragments;
125 1 50         fragments.push_back("hello");
126 1 50         fragments.push_back(" world");
127 2 50         auto data = server.message().send(fragments.begin(), fragments.end());
128 2 50         auto data_string = to_string(data);
    50          
129 2 50         auto messages_it = client.get_messages(data_string);
130 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
131 1 50         REQUIRE(messages_it.begin()->payload[0] == "hello world");
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
132             }
133              
134 10 50         SECTION("MessageBuilder::send (fragmented message iterator, hole in the middle)") {
    50          
    50          
    50          
    100          
135 2           std::vector fragments;
136 1 50         fragments.push_back("hello");
137 1 50         fragments.push_back("");
138 1 50         fragments.push_back("");
139 1 50         fragments.push_back(" world");
140 2 50         auto data = server.message().send(fragments.begin(), fragments.end());
141 2 50         auto data_string = to_string(data);
    50          
142 2 50         auto messages_it = client.get_messages(data_string);
143 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
144 1 50         REQUIRE(messages_it.begin()->payload[0] == "hello world");
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
145             }
146              
147 10 50         SECTION("MessageBuilder::send (empty string)") {
    50          
    50          
    50          
    100          
148 2           panda::string item = "";
149 2 50         auto data = server.message().send(item);
150 2 50         auto data_string = to_string(data);
    50          
151 2 50         auto messages_it = client.get_messages(data_string);
152 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
153 1 50         REQUIRE(messages_it.begin()->payload.size() == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
154             }
155              
156 10 50         SECTION("MessageBuilder::send (fragmented message iterator, empty)") {
    50          
    50          
    50          
    100          
157 2           std::vector fragments;
158 1 50         fragments.push_back("");
159 2 50         auto data = server.message().send(fragments.begin(), fragments.end());
160 2 50         auto data_string = to_string(data);
    50          
161 2 50         auto messages_it = client.get_messages(data_string);
162 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
163 1 50         REQUIRE(messages_it.begin()->payload.size() == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
164             }
165              
166 10 50         SECTION("MessageBuilder::send (fragmented multi-frame iterator, 1 fragment)") {
    50          
    50          
    50          
    100          
167 2           std::vector> pieces;
168              
169 2           std::vector fragments1;
170 1 50         fragments1.push_back("hello");
171 1 50         fragments1.push_back(" world!");
172 1 50         pieces.push_back(fragments1);
173              
174              
175 1           auto builder = server.message();
176 2 50         auto data = builder.deflate(true).send(pieces.begin(), pieces.end());
177 2 50         auto data_string = to_string(data);
    50          
178 1 50         REQUIRE(data_string != "hello world!");
    50          
    50          
    50          
    50          
    0          
    0          
179 2 50         auto messages_it = client.get_messages(data_string);
180 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
181              
182 2 50         auto it = messages_it.begin();
183 1 50         REQUIRE(it->payload[0] == "hello world!");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
184             }
185              
186 10 50         SECTION("MessageBuilder::send (fragmented multi-frame iterator, 2 fragments)") {
    50          
    50          
    50          
    100          
187 2           std::vector> pieces;
188              
189 2           std::vector fragments1;
190 1 50         fragments1.push_back("hello");
191 1 50         fragments1.push_back(" world!");
192 1 50         pieces.push_back(fragments1);
193              
194 2           std::vector fragments2;
195 1 50         fragments2.push_back(" Let's do ");
196 1 50         fragments2.push_back("some testing");
197 1 50         pieces.push_back(fragments2);
198              
199 1           auto builder = server.message();
200 2 50         auto data = builder.deflate(true).send(pieces.begin(), pieces.end());
201 2 50         auto data_string = to_string(data);
    50          
202 1 50         REQUIRE(data_string.find("hello") == std::string::npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
203 2 50         auto messages_it = client.get_messages(data_string);
204 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
205              
206 2 50         auto it = messages_it.begin();
207 1 50         REQUIRE(it->payload.size() == 2);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
208 1 50         REQUIRE(it->payload[0] == "hello world!");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
209 1 50         REQUIRE(it->payload[1] == " Let's do some testing");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
210             }
211              
212 10 50         SECTION("MessageBuilder::send (fragmented multi-frame iterator, 2 fragments, last empty)") {
    50          
    50          
    50          
    100          
213 2           std::vector> pieces;
214              
215 2           std::vector fragments1;
216 1 50         fragments1.push_back("hello");
217 1 50         fragments1.push_back(" world!");
218 1 50         pieces.push_back(fragments1);
219              
220 2           std::vector fragments2;
221 1 50         pieces.push_back(fragments2);
222              
223 1           auto builder = server.message();
224 2 50         auto data = builder.deflate(true).send(pieces.begin(), pieces.end());
225 2 50         auto data_string = to_string(data);
    50          
226 1 50         REQUIRE(data_string.find("hello") == std::string::npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
227 2 50         auto messages_it = client.get_messages(data_string);
228 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
229              
230 2 50         auto it = messages_it.begin();
231 1 50         REQUIRE(it->payload.size() == 1);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
232 1 50         REQUIRE(it->payload[0] == "hello world!");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
233             }
234              
235 10 50         SECTION("MessageBuilder::send (fragmented multi-frame iterator, 4 fragments, empty middle)") {
    50          
    50          
    50          
    100          
236 2           std::vector> pieces;
237              
238 2           std::vector fragments1;
239 1 50         fragments1.push_back("hello");
240 1 50         fragments1.push_back(" world");
241 1 50         pieces.push_back(fragments1);
242              
243 2           std::vector fragments2;
244 1 50         pieces.push_back(fragments2);
245              
246 2           std::vector fragments3;
247 1 50         fragments3.push_back("");
248 1 50         pieces.push_back(fragments3);
249              
250 2           std::vector fragments4;
251 1 50         fragments4.push_back("!");
252 1 50         pieces.push_back(fragments4);
253              
254 1           auto builder = server.message();
255 2 50         auto data = builder.deflate(true).send(pieces.begin(), pieces.end());
256 2 50         auto data_string = to_string(data);
    50          
257 1 50         REQUIRE(data_string.find("hello") == std::string::npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
258 2 50         auto messages_it = client.get_messages(data_string);
259 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
260              
261 2 50         auto it = messages_it.begin();
262 1 50         REQUIRE(it->payload.size() == 2);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
263 1 50         REQUIRE(it->payload[0] == "hello world");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
264 1 50         REQUIRE(it->payload[1] == "!");
    50          
    50          
    50          
    50          
    50          
    0          
    0          
265             }
266              
267 10 50         SECTION("MessageBuilder::send (fragmented multi-frame iterator, 2 fragments, both empty)") {
    50          
    50          
    50          
    100          
268 2           std::vector> pieces;
269              
270 2           std::vector fragments1;
271 1 50         pieces.push_back(fragments1);
272              
273 2           std::vector fragments2;
274 1 50         pieces.push_back(fragments2);
275              
276 1           auto builder = server.message();
277 2 50         auto data = builder.deflate(true).send(pieces.begin(), pieces.end());
278 2 50         auto data_string = to_string(data);
    50          
279 1 50         REQUIRE(data_string.find("hello") == std::string::npos);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
280 2 50         auto messages_it = client.get_messages(data_string);
281 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
282              
283 2 50         auto it = messages_it.begin();
284 1 50         REQUIRE(it->payload.empty());
    50          
    50          
    50          
    50          
    0          
    0          
285             }
286             }
287              
288 22 50         SECTION("empty compressed frame with zero payload") {
    50          
    50          
    50          
    100          
289 4           string payload;
290 2 50         REQUIRE(payload.length() == 0);
    50          
    50          
    50          
    50          
    0          
    0          
291             //auto builder =
292 4 50         auto data = server.start_message(DeflateFlag::YES).send(payload, true);
    50          
293 2 50         auto it = std::begin(data) + 1;
294 2 50         REQUIRE((*it).length() == 1);
    50          
    50          
    50          
    50          
    0          
    0          
295 2 50         REQUIRE((*it).capacity() >= ((*it).length()));
    50          
    50          
    50          
    50          
    50          
    0          
    0          
296 4 50         auto data_string = to_string(data);
    50          
297 2 50         REQUIRE(data_string.length() == 3);
    50          
    50          
    50          
    50          
    0          
    0          
298              
299 3 50         SECTION("zero uncompressed payload") {
    50          
    50          
    50          
    100          
300 2 50         auto messages_it = client.get_messages(data_string);
301 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
302 1 50         REQUIRE(messages_it.begin()->payload_length() == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
303             }
304              
305 3 50         SECTION("non-zero network payload") {
    50          
    50          
    50          
    100          
306 2 50         auto frames_it = client.get_frames(data_string);
307 1 50         REQUIRE(std::distance(frames_it.begin(), frames_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
308 1 50         REQUIRE(frames_it.begin()->payload_length() == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
309             }
310             }
311              
312              
313 21 50         SECTION("compressed frame with zero payload") {
    50          
    50          
    50          
    100          
314 2           string payload;
315 1 50         REQUIRE(payload.length() == 0);
    50          
    50          
    50          
    50          
    0          
    0          
316 1           FrameHeader fh(Opcode::TEXT, true, true, false, false, true, (uint32_t)std::rand());
317 2 50         auto data_string = Frame::compile(fh, payload);
318 2 50         auto messages_it = client.get_messages(data_string);
319 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
320 1 50         REQUIRE(messages_it.begin()->payload_length() == 0);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
321             }
322              
323 21 50         SECTION("Control compressed frame") {
    50          
    50          
    50          
    100          
324 2           string payload;
325 1           FrameHeader fh(Opcode::PING, true, true, false, false, true, (uint32_t)std::rand());
326 2 50         auto data_string = Frame::compile(fh, payload);
327 2 50         auto frames_it = client.get_frames(data_string);
328 1 50         REQUIRE(frames_it.begin()->error & errc::control_frame_compression);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
329             }
330              
331 21 50         SECTION("send compressed frame bigger then original") {
    50          
    50          
    50          
    100          
332 2 50         string payload = encode::decode_base16("8e008f8f8f0090909000919191009292");
333 2 50         string payload_copy = payload;
334              
335 2 50         auto data = server.start_message(DeflateFlag::YES).send(payload, true);
    50          
336 1 50         auto it = std::begin(data) + 1;
337 1 50         REQUIRE((*it).length() == 24);
    50          
    50          
    50          
    50          
    0          
    0          
338 2 50         auto data_string = to_string(data);
    50          
339 2 50         auto messages_it = client.get_messages(data_string);
340 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
341 1 50         REQUIRE_FALSE(messages_it.begin()->error);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
342 1 50         REQUIRE(messages_it.begin()->payload[0] == payload_copy);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
343             }
344              
345 21 50         SECTION("SRV-1236") {
    50          
    50          
    50          
    100          
346 2 50         SECTION("buggy sample (does work)") {
    50          
    50          
    50          
    50          
347 2           string data_sample = "UlBQUDLWM1eyUqjmUoABpaTUjMSyzPwioLCSv7eSDhYp55z84lQs8imlRYklmfl5QCkjZPGi1Nz8klSwLuf8FJBOQwMDNBUF+UUlaZk5YGMTS0vykxIz8goqSzLy8+IN4s2AODmxODXeON5cL6sYaANUby3MECUTPUM9Q9K8AgAAAP//";
348 2 50         string payload = encode::decode_base64(data_sample);
349 1           FrameHeader fh(Opcode::TEXT, true, true, false, false, true, (uint32_t)std::rand());
350 2 50         auto data_string = Frame::compile(fh, payload).append(payload);
    50          
    50          
351 2 50         auto messages_it = server.get_messages(data_string);
352 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
353 1 50         REQUIRE(!messages_it.begin()->error);
    50          
    50          
    50          
    50          
    50          
    0          
    0          
354             }
355             }
356              
357 21 50         SECTION("zlib test") {
    50          
    50          
    50          
    100          
358 2 50         string payload = encode::decode_base16("8e008f8f8f0090909000919191009292");
359             char buff1[50];
360             char buff2[50];
361             char buff1_out[50];
362             char buff2_out[50];
363              
364 1           memset(buff1, 0, 50);
365 1           memset(buff2, 0, 50);
366 1           memset(buff1_out, 0, 50);
367 1           memset(buff2_out, 0, 50);
368              
369             z_stream tx_stream1;
370 1           tx_stream1.avail_in = 0;
371 1           tx_stream1.zalloc = Z_NULL;
372 1           tx_stream1.zfree = Z_NULL;
373 1           tx_stream1.opaque = Z_NULL;
374 1 50         auto r = deflateInit2(&tx_stream1, -1, Z_DEFLATED, -1 * 15, 8, Z_DEFAULT_STRATEGY);
375 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
376              
377 1 50         tx_stream1.next_in = reinterpret_cast(payload.buf());
378 1           tx_stream1.avail_in = static_cast(payload.length());
379 1           tx_stream1.avail_out = 50;
380 1           tx_stream1.next_out = reinterpret_cast(buff1);
381 1 50         r = deflate(&tx_stream1, Z_SYNC_FLUSH);
382 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
383 1 50         REQUIRE(tx_stream1.total_out == 23);
    50          
    50          
    50          
    50          
    0          
    0          
384              
385              
386             z_stream tx_stream2;
387 1           tx_stream2.avail_in = 0;
388 1           tx_stream2.zalloc = Z_NULL;
389 1           tx_stream2.zfree = Z_NULL;
390 1           tx_stream2.opaque = Z_NULL;
391 1 50         r = deflateInit2(&tx_stream2, -1, Z_DEFLATED, -1 * 15, 8, Z_DEFAULT_STRATEGY);
392 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
393 1 50         REQUIRE(tx_stream1.avail_out !=0);
    50          
    50          
    50          
    50          
    0          
    0          
394              
395 1 50         tx_stream2.next_in = reinterpret_cast(payload.buf());
396 1           tx_stream2.avail_in = static_cast(payload.length());
397 1           tx_stream2.avail_out = 23;
398 1           tx_stream2.next_out = reinterpret_cast(buff2);
399 1 50         r = deflate(&tx_stream2, Z_SYNC_FLUSH);
400 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
401 1 50         REQUIRE(tx_stream2.total_out == 23);
    50          
    50          
    50          
    50          
    0          
    0          
402 1 50         REQUIRE(tx_stream2.avail_out == 0); // !!! ???
    50          
    50          
    50          
    50          
    0          
    0          
403              
404 1           tx_stream2.avail_out = 50 - 23;
405 1 50         r = deflate(&tx_stream2, Z_SYNC_FLUSH);
406 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
407             //REQUIRE(tx_stream2.total_out == tx_stream1.total_out); /// !!! ???
408              
409             z_stream rx_stream1;
410 1           rx_stream1.avail_in = 0;
411 1           rx_stream1.next_in = Z_NULL;
412 1           rx_stream1.zalloc = Z_NULL;
413 1           rx_stream1.zfree = Z_NULL;
414 1           rx_stream1.opaque = Z_NULL;
415              
416 1 50         r = inflateInit2(&rx_stream1, -1 * 15);
417 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
418              
419 1           rx_stream1.next_in = reinterpret_cast(buff1);
420 1           rx_stream1.avail_in = static_cast(tx_stream1.avail_out);
421 1           rx_stream1.next_out = reinterpret_cast(buff1_out);
422 1           rx_stream1.avail_out = 50;
423 1 50         r = inflate(&rx_stream1, Z_SYNC_FLUSH);
424 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
425              
426             z_stream rx_stream2;
427 1           rx_stream2.avail_in = 0;
428 1           rx_stream2.zalloc = Z_NULL;
429 1           rx_stream2.zfree = Z_NULL;
430 1           rx_stream2.opaque = Z_NULL;
431              
432 1 50         r = inflateInit2(&rx_stream2, -1 * 15);
433 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
434              
435 1           rx_stream2.next_in = reinterpret_cast(buff2);
436 1           rx_stream2.avail_in = static_cast(tx_stream2.avail_out);
437 1           rx_stream2.next_out = reinterpret_cast(buff2_out);
438 1           rx_stream2.avail_out = 50;
439 1 50         r = inflate(&rx_stream2, Z_SYNC_FLUSH);
440 1 50         REQUIRE(r == Z_OK);
    50          
    50          
    50          
    50          
    0          
    0          
441              
442 1 50         deflateEnd(&tx_stream1);
443 1 50         deflateEnd(&tx_stream2);
444 1 50         inflateEnd(&rx_stream1);
445 1 50         inflateEnd(&rx_stream2);
446             }
447 20           }
448              
449              
450 20           TEST_CASE("SRV-1236", "[deflate-extension]") {
451 4           Parser::Config cfg;
452 2           cfg.deflate->client_no_context_takeover = true;
453              
454 4 50         ServerParser server;
455 2 50         server.configure(cfg);
456 4 50         ClientParser client;
457              
458 4 50         ConnectRequestSP connect_request(new ConnectRequest());
    50          
459 2 50         connect_request->uri = new URI("ws://crazypanda.ru");
    50          
460 2 50         connect_request->ws_key = "dGhlIHNhbXBsZSBub25jZQ==";
461 2           connect_request->ws_version = 13;
462 2 50         connect_request->ws_protocol = "ws";
463 4 50         auto client_request = client.connect_request(connect_request);
464              
465 2 50         REQUIRE((bool)server.accept(client_request));
    50          
    50          
    50          
    50          
    0          
    0          
466 4 50         auto server_reply = server.accept_response();
467 2 50         client.connect(server_reply);
468              
469 2 50         REQUIRE(server.established());
    50          
    50          
    50          
    0          
    0          
470 2 50         REQUIRE(client.established());
    50          
    50          
    50          
    0          
    0          
471 2 50         REQUIRE(server.is_deflate_active());
    50          
    50          
    50          
    0          
    0          
472 2 50         REQUIRE(client.is_deflate_active());
    50          
    50          
    50          
    0          
    0          
473              
474 3 50         SECTION("12.1.3 :: false inflate error caused by incorrectly handling Z_BUF_ERROR") {
    50          
    50          
    50          
    100          
475             string data_samples[] = {
476             "0uFSgAGlpNSMxLLM/CLnnPziVCUrBSV/byUdJPmU0qLEksz8PKCUCbJ4UWpufkkqWJdzfgpIp6GBgRGqioL8opK0zBywsYmlJflJiRl5BZUlGfl58QbxZkCcnFicGm8cb6yXVQy0Aaq3FmaIkrGeCVBrNRbXYnEoCR4BAAAA//8",
477             "MjTX4VKAAaWi1Nz8klTnnPziVOf8lFQlKwVDAwMjVBUF+UUlaZk5IEmlxNKS/KTEjLyCypKM/Lx4g3gzIE5OLE6NN4430csqzs9TguqthRmiZKxnCtRajWRmUmpGYllmfhHIRH9vJR0sUmAnYZFPKS1KLMkEWmOlYESWRwAAAAD//w",
478             "ysxJVbJSUEosLclPSszIK6gsycjPizeINwPi5MTi1HjjeFO9rOL8PCUuBTCo1YEylIz1zIBaq6FckEhSakZiWWZ+EchEf28lHSxSzjn5xalY5FNKixJLMoHWWCkYIYsXpebml6SCdTnnp4B0GhoYoKkoyC8qScsk7BEzLB4BAAAA//8",
479             "UlBQUDLWM1eyUqjmUoABpaTUjMSyzPwioLCSv7eSDhYp55z84lQs8imlRYklmfl5QCkjZPGi1Nz8klSwLuf8FJBOQwMDNBUF+UUlaZk5YGMTS0vykxIz8goqSzLy8+IN4s2AODmxODXeON5cL6sYaANUby3MECUTPUM9Q9K8AgAAAP//",
480 6 100         };
    0          
481 5 100         for(auto it = std::begin(data_samples); it != std::end(data_samples); ++it){
482 8 50         string payload = encode::decode_base64(*it);
483 4           FrameHeader fh(Opcode::TEXT, true, true, false, false, true, (uint32_t)std::rand());
484 8 50         auto data_string = Frame::compile(fh, payload).append(payload);
    50          
    50          
485 8 50         auto messages_it = server.get_messages(data_string);
486 4 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
487 4 50         REQUIRE_FALSE(messages_it.begin()->error);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
488             }
489             }
490              
491 3 50         SECTION("12.1.11 (no rsv1 flag on 2nd frame == that's correct)") {
    50          
    50          
    50          
    100          
492 2 50         string payload1 = encode::decode_base64("MjAgFQAAAAD//w");
493 2 50         string payload2 = encode::decode_base64("Ih0AAAAA//8");
494              
495 1           FrameHeader fh1(Opcode::TEXT, false, true, false, false, true, (uint32_t)std::rand());
496 2 50         auto data_string1 = Frame::compile(fh1, payload1).append(payload1);
    50          
    50          
497              
498 1           FrameHeader fh2(Opcode::CONTINUE, true, false, false, false, true, (uint32_t)std::rand());
499 2 50         auto data_string2 = Frame::compile(fh2, payload2).append(payload2);
    50          
    50          
500 2 50         auto data_string = data_string1 + data_string2;
501              
502 2 50         auto messages_it = server.get_messages(data_string);
503 1 50         REQUIRE(std::distance(messages_it.begin(), messages_it.end()) == 1);
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
504 1 50         REQUIRE_FALSE(messages_it.begin()->error);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
505 1 50         REQUIRE(messages_it.begin()->payload.size() == 2);
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
506 1 50         REQUIRE(messages_it.begin()->payload[0] == "00000000000000000000000000000000000000000000000000");
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
507 1 50         REQUIRE(messages_it.begin()->payload[1] == "00000000000000000000000000000000000000000000000000");
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
508             }
509              
510 74 50         }
    50