2 // Copyright (w) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 // Test that header file is self-contained.
11 #include <boost/beast/websocket/stream.hpp>
19 class handshake_test
: public websocket_test_suite
24 doTestHandshake(Wrap
const& w
)
31 req_decorator(req_decorator
const&) = default;
34 req_decorator(bool& b
)
40 operator()(request_type
&) const
47 doStreamLoop([&](test::stream
& ts
)
51 ws
.next_layer().connect(es
.stream());
54 w
.handshake(ws
, "localhost", "/");
64 // handshake, response
65 doStreamLoop([&](test::stream
& ts
)
69 ws
.next_layer().connect(es
.stream());
73 w
.handshake(ws
, res
, "localhost", "/");
74 // VFALCO validate res?
84 // handshake, decorator
85 doStreamLoop([&](test::stream
& ts
)
89 ws
.next_layer().connect(es
.stream());
93 w
.handshake_ex(ws
, "localhost", "/",
94 req_decorator
{called
});
105 // handshake, response, decorator
106 doStreamLoop([&](test::stream
& ts
)
110 ws
.next_layer().connect(es
.stream());
115 w
.handshake_ex(ws
, res
, "localhost", "/",
116 req_decorator
{called
});
117 // VFALCO validate res?
118 BEAST_EXPECT(called
);
132 doTestHandshake(SyncClient
{});
134 yield_to([&](yield_context yield
)
136 doTestHandshake(AsyncClient
{yield
});
140 [&](std::string
const& s
)
142 stream
<test::stream
> ws
{ioc_
};
143 auto tr
= connect(ws
.next_layer());
144 ws
.next_layer().append(s
);
148 ws
.handshake("localhost:80", "/");
151 catch(system_error
const& se
)
153 BEAST_EXPECT(se
.code() == error::handshake_failed
);
156 // wrong HTTP version
158 "HTTP/1.0 101 Switching Protocols\r\n"
160 "Upgrade: WebSocket\r\n"
161 "Connection: upgrade\r\n"
162 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
163 "Sec-WebSocket-Version: 13\r\n"
168 "HTTP/1.1 200 OK\r\n"
170 "Upgrade: WebSocket\r\n"
171 "Connection: upgrade\r\n"
172 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
173 "Sec-WebSocket-Version: 13\r\n"
176 // missing upgrade token
178 "HTTP/1.1 101 Switching Protocols\r\n"
180 "Upgrade: HTTP/2\r\n"
181 "Connection: upgrade\r\n"
182 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
183 "Sec-WebSocket-Version: 13\r\n"
186 // missing connection token
188 "HTTP/1.1 101 Switching Protocols\r\n"
190 "Upgrade: WebSocket\r\n"
191 "Connection: keep-alive\r\n"
192 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
193 "Sec-WebSocket-Version: 13\r\n"
196 // missing accept key
198 "HTTP/1.1 101 Switching Protocols\r\n"
200 "Upgrade: WebSocket\r\n"
201 "Connection: upgrade\r\n"
202 "Sec-WebSocket-Version: 13\r\n"
207 "HTTP/1.1 101 Switching Protocols\r\n"
209 "Upgrade: WebSocket\r\n"
210 "Connection: upgrade\r\n"
211 "Sec-WebSocket-Accept: *\r\n"
212 "Sec-WebSocket-Version: 13\r\n"
217 // Compression Extensions for WebSocket
219 // https://tools.ietf.org/html/rfc7692
224 detail::pmd_offer po
;
230 f
.set(http::field::sec_websocket_extensions
, s
);
231 po
= detail::pmd_offer();
232 detail::pmd_read(po
, f
);
233 BEAST_EXPECT(po
.accept
);
240 f
.set(http::field::sec_websocket_extensions
, s
);
241 po
= detail::pmd_offer();
242 detail::pmd_read(po
, f
);
243 BEAST_EXPECT(! po
.accept
);
246 // duplicate parameters
247 reject("permessage-deflate; server_max_window_bits=8; server_max_window_bits=8");
250 reject("permessage-deflate; server_max_window_bits");
251 reject("permessage-deflate; server_max_window_bits=");
254 reject("permessage-deflate; server_max_window_bits=-1");
255 reject("permessage-deflate; server_max_window_bits=7");
256 reject("permessage-deflate; server_max_window_bits=16");
257 reject("permessage-deflate; server_max_window_bits=999999999999999999999999");
258 reject("permessage-deflate; server_max_window_bits=9a");
260 // duplicate parameters
261 reject("permessage-deflate; client_max_window_bits=8; client_max_window_bits=8");
263 // optional value excluded
264 accept("permessage-deflate; client_max_window_bits");
265 BEAST_EXPECT(po
.client_max_window_bits
== -1);
266 accept("permessage-deflate; client_max_window_bits=");
267 BEAST_EXPECT(po
.client_max_window_bits
== -1);
270 reject("permessage-deflate; client_max_window_bits=-1");
271 reject("permessage-deflate; client_max_window_bits=7");
272 reject("permessage-deflate; client_max_window_bits=16");
273 reject("permessage-deflate; client_max_window_bits=999999999999999999999999");
275 // duplicate parameters
276 reject("permessage-deflate; server_no_context_takeover; server_no_context_takeover");
278 // valueless parameter
279 accept("permessage-deflate; server_no_context_takeover");
280 BEAST_EXPECT(po
.server_no_context_takeover
);
281 accept("permessage-deflate; server_no_context_takeover=");
282 BEAST_EXPECT(po
.server_no_context_takeover
);
285 reject("permessage-deflate; server_no_context_takeover=-1");
286 reject("permessage-deflate; server_no_context_takeover=x");
287 reject("permessage-deflate; server_no_context_takeover=\"yz\"");
288 reject("permessage-deflate; server_no_context_takeover=999999999999999999999999");
290 // duplicate parameters
291 reject("permessage-deflate; client_no_context_takeover; client_no_context_takeover");
293 // valueless parameter
294 accept("permessage-deflate; client_no_context_takeover");
295 BEAST_EXPECT(po
.client_no_context_takeover
);
296 accept("permessage-deflate; client_no_context_takeover=");
297 BEAST_EXPECT(po
.client_no_context_takeover
);
300 reject("permessage-deflate; client_no_context_takeover=-1");
301 reject("permessage-deflate; client_no_context_takeover=x");
302 reject("permessage-deflate; client_no_context_takeover=\"yz\"");
303 reject("permessage-deflate; client_no_context_takeover=999999999999999999999999");
305 // unknown extension parameter
306 reject("permessage-deflate; unknown");
307 reject("permessage-deflate; unknown=");
308 reject("permessage-deflate; unknown=1");
309 reject("permessage-deflate; unknown=x");
310 reject("permessage-deflate; unknown=\"xy\"");
316 detail::pmd_offer po
;
319 [&](string_view match
)
322 detail::pmd_write(f
, po
);
324 f
[http::field::sec_websocket_extensions
]
329 po
.server_max_window_bits
= 0;
330 po
.client_max_window_bits
= 0;
331 po
.server_no_context_takeover
= false;
332 po
.client_no_context_takeover
= false;
334 check("permessage-deflate");
336 po
.server_max_window_bits
= 10;
337 check("permessage-deflate; server_max_window_bits=10");
339 po
.server_max_window_bits
= -1;
340 check("permessage-deflate; server_max_window_bits");
342 po
.server_max_window_bits
= 0;
343 po
.client_max_window_bits
= 10;
344 check("permessage-deflate; client_max_window_bits=10");
346 po
.client_max_window_bits
= -1;
347 check("permessage-deflate; client_max_window_bits");
349 po
.client_max_window_bits
= 0;
350 po
.server_no_context_takeover
= true;
351 check("permessage-deflate; server_no_context_takeover");
353 po
.server_no_context_takeover
= false;
354 po
.client_no_context_takeover
= true;
355 check("permessage-deflate; client_no_context_takeover");
361 permessage_deflate pmd
;
367 detail::pmd_offer po
;
370 f
.set(http::field::sec_websocket_extensions
, offer
);
371 detail::pmd_read(po
, f
);
374 detail::pmd_offer config
;
375 detail::pmd_negotiate(f
, config
, po
, pmd
);
376 BEAST_EXPECT(! config
.accept
);
384 detail::pmd_offer po
;
387 f
.set(http::field::sec_websocket_extensions
, offer
);
388 detail::pmd_read(po
, f
);
391 detail::pmd_offer config
;
392 detail::pmd_negotiate(f
, config
, po
, pmd
);
394 f
[http::field::sec_websocket_extensions
];
395 BEAST_EXPECTS(got
== result
, got
);
397 detail::pmd_offer poc
;
398 detail::pmd_read(poc
, f
);
399 detail::pmd_normalize(poc
);
400 BEAST_EXPECT(poc
.accept
);
402 BEAST_EXPECT(config
.server_max_window_bits
!= 0);
403 BEAST_EXPECT(config
.client_max_window_bits
!= 0);
406 pmd
.server_enable
= true;
407 pmd
.server_max_window_bits
= 15;
408 pmd
.client_max_window_bits
= 15;
409 pmd
.server_no_context_takeover
= false;
410 pmd
.client_no_context_takeover
= false;
414 "permessage-deflate",
415 "permessage-deflate");
417 // non-default server_max_window_bits
419 "permessage-deflate; server_max_window_bits=14",
420 "permessage-deflate; server_max_window_bits=14");
422 // explicit default server_max_window_bits
424 "permessage-deflate; server_max_window_bits=15",
425 "permessage-deflate");
427 // minimum window size of 8 bits (a zlib bug)
429 "permessage-deflate; server_max_window_bits=8",
430 "permessage-deflate; server_max_window_bits=9");
432 // non-default server_max_window_bits setting
433 pmd
.server_max_window_bits
= 10;
435 "permessage-deflate",
436 "permessage-deflate; server_max_window_bits=10");
438 // clamped server_max_window_bits setting #1
439 pmd
.server_max_window_bits
= 10;
441 "permessage-deflate; server_max_window_bits=14",
442 "permessage-deflate; server_max_window_bits=10");
444 // clamped server_max_window_bits setting #2
445 pmd
.server_max_window_bits
=8;
447 "permessage-deflate; server_max_window_bits=14",
448 "permessage-deflate; server_max_window_bits=9");
450 pmd
.server_max_window_bits
= 15;
452 // present with no value
454 "permessage-deflate; client_max_window_bits",
455 "permessage-deflate");
457 // present with no value, non-default setting
458 pmd
.client_max_window_bits
= 10;
460 "permessage-deflate; client_max_window_bits",
461 "permessage-deflate; client_max_window_bits=10");
463 // absent, non-default setting
464 pmd
.client_max_window_bits
= 10;
466 "permessage-deflate");
479 BEAST_DEFINE_TESTSUITE(beast
,websocket
,handshake
);