]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // Copyright (w) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) | |
3 | // | |
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) | |
6 | // | |
7 | // Official repository: https://github.com/boostorg/beast | |
8 | // | |
9 | ||
10 | // Test that header file is self-contained. | |
11 | #include <boost/beast/websocket/stream.hpp> | |
12 | ||
13 | #include "test.hpp" | |
14 | ||
11fdf7f2 TL |
15 | #include <boost/asio/io_service.hpp> |
16 | #include <boost/asio/strand.hpp> | |
17 | ||
b32b8144 FG |
18 | namespace boost { |
19 | namespace beast { | |
20 | namespace websocket { | |
21 | ||
22 | class accept_test : public websocket_test_suite | |
23 | { | |
24 | public: | |
25 | template<class Wrap> | |
26 | void | |
27 | doTestAccept(Wrap const& w) | |
28 | { | |
29 | class res_decorator | |
30 | { | |
31 | bool& b_; | |
32 | ||
33 | public: | |
34 | res_decorator(res_decorator const&) = default; | |
35 | ||
36 | explicit | |
37 | res_decorator(bool& b) | |
38 | : b_(b) | |
39 | { | |
40 | } | |
41 | ||
42 | void | |
43 | operator()(response_type&) const | |
44 | { | |
45 | this->b_ = true; | |
46 | } | |
47 | }; | |
48 | ||
49 | auto const big = [] | |
50 | { | |
51 | std::string s; | |
52 | s += "X1: " + std::string(2000, '*') + "\r\n"; | |
53 | return s; | |
54 | }(); | |
55 | ||
56 | // request in stream | |
57 | doStreamLoop([&](test::stream& ts) | |
58 | { | |
59 | stream<test::stream&> ws{ts}; | |
60 | auto tr = connect(ws.next_layer()); | |
61 | ts.append( | |
62 | "GET / HTTP/1.1\r\n" | |
63 | "Host: localhost\r\n" | |
64 | "Upgrade: websocket\r\n" | |
65 | "Connection: upgrade\r\n" | |
66 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
67 | "Sec-WebSocket-Version: 13\r\n" | |
68 | "\r\n"); | |
69 | ts.read_size(20); | |
70 | w.accept(ws); | |
71 | // VFALCO validate contents of ws.next_layer().str? | |
72 | }); | |
73 | ||
74 | // request in stream, oversized | |
75 | { | |
76 | stream<test::stream> ws{ioc_, | |
77 | "GET / HTTP/1.1\r\n" | |
78 | "Host: localhost\r\n" | |
79 | "Upgrade: websocket\r\n" | |
80 | "Connection: upgrade\r\n" | |
81 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
82 | "Sec-WebSocket-Version: 13\r\n" | |
83 | + big + | |
84 | "\r\n"}; | |
85 | auto tr = connect(ws.next_layer()); | |
86 | try | |
87 | { | |
88 | w.accept(ws); | |
89 | fail("", __FILE__, __LINE__); | |
90 | } | |
91 | catch(system_error const& se) | |
92 | { | |
93 | // VFALCO Its the http error category... | |
94 | BEAST_EXPECTS( | |
95 | se.code() == http::error::buffer_overflow, | |
96 | se.code().message()); | |
97 | } | |
98 | } | |
99 | ||
100 | // request in stream, decorator | |
101 | doStreamLoop([&](test::stream& ts) | |
102 | { | |
103 | stream<test::stream&> ws{ts}; | |
104 | auto tr = connect(ws.next_layer()); | |
105 | ts.append( | |
106 | "GET / HTTP/1.1\r\n" | |
107 | "Host: localhost\r\n" | |
108 | "Upgrade: websocket\r\n" | |
109 | "Connection: upgrade\r\n" | |
110 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
111 | "Sec-WebSocket-Version: 13\r\n" | |
112 | "\r\n"); | |
113 | ts.read_size(20); | |
114 | bool called = false; | |
115 | w.accept_ex(ws, res_decorator{called}); | |
116 | BEAST_EXPECT(called); | |
117 | }); | |
118 | ||
119 | // request in stream, decorator, oversized | |
120 | { | |
121 | stream<test::stream> ws{ioc_, | |
122 | "GET / HTTP/1.1\r\n" | |
123 | "Host: localhost\r\n" | |
124 | "Upgrade: websocket\r\n" | |
125 | "Connection: upgrade\r\n" | |
126 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
127 | "Sec-WebSocket-Version: 13\r\n" | |
128 | + big + | |
129 | "\r\n"}; | |
130 | auto tr = connect(ws.next_layer()); | |
131 | try | |
132 | { | |
133 | bool called = false; | |
134 | w.accept_ex(ws, res_decorator{called}); | |
135 | fail("", __FILE__, __LINE__); | |
136 | } | |
137 | catch(system_error const& se) | |
138 | { | |
139 | // VFALCO Its the http error category... | |
140 | BEAST_EXPECTS( | |
141 | se.code() == http::error::buffer_overflow, | |
142 | se.code().message()); | |
143 | } | |
144 | } | |
145 | ||
146 | // request in buffers | |
147 | doStreamLoop([&](test::stream& ts) | |
148 | { | |
149 | stream<test::stream&> ws{ts}; | |
150 | auto tr = connect(ws.next_layer()); | |
151 | w.accept(ws, sbuf( | |
152 | "GET / HTTP/1.1\r\n" | |
153 | "Host: localhost\r\n" | |
154 | "Upgrade: websocket\r\n" | |
155 | "Connection: upgrade\r\n" | |
156 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
157 | "Sec-WebSocket-Version: 13\r\n" | |
158 | "\r\n" | |
159 | )); | |
160 | }); | |
161 | ||
162 | // request in buffers, oversize | |
163 | { | |
164 | stream<test::stream> ws{ioc_}; | |
165 | auto tr = connect(ws.next_layer()); | |
166 | try | |
167 | { | |
168 | w.accept(ws, boost::asio::buffer( | |
169 | "GET / HTTP/1.1\r\n" | |
170 | "Host: localhost\r\n" | |
171 | "Upgrade: websocket\r\n" | |
172 | "Connection: upgrade\r\n" | |
173 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
174 | "Sec-WebSocket-Version: 13\r\n" | |
175 | + big + | |
176 | "\r\n" | |
177 | )); | |
178 | fail("", __FILE__, __LINE__); | |
179 | } | |
180 | catch(system_error const& se) | |
181 | { | |
182 | BEAST_EXPECTS( | |
183 | se.code() == error::buffer_overflow, | |
184 | se.code().message()); | |
185 | } | |
186 | } | |
187 | ||
188 | // request in buffers, decorator | |
189 | doStreamLoop([&](test::stream& ts) | |
190 | { | |
191 | stream<test::stream&> ws{ts}; | |
192 | auto tr = connect(ws.next_layer()); | |
193 | bool called = false; | |
194 | w.accept_ex(ws, sbuf( | |
195 | "GET / HTTP/1.1\r\n" | |
196 | "Host: localhost\r\n" | |
197 | "Upgrade: websocket\r\n" | |
198 | "Connection: upgrade\r\n" | |
199 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
200 | "Sec-WebSocket-Version: 13\r\n" | |
201 | "\r\n"), | |
202 | res_decorator{called}); | |
203 | BEAST_EXPECT(called); | |
204 | }); | |
205 | ||
206 | // request in buffers, decorator, oversized | |
207 | { | |
208 | stream<test::stream> ws{ioc_}; | |
209 | auto tr = connect(ws.next_layer()); | |
210 | try | |
211 | { | |
212 | bool called = false; | |
213 | w.accept_ex(ws, boost::asio::buffer( | |
214 | "GET / HTTP/1.1\r\n" | |
215 | "Host: localhost\r\n" | |
216 | "Upgrade: websocket\r\n" | |
217 | "Connection: upgrade\r\n" | |
218 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
219 | "Sec-WebSocket-Version: 13\r\n" | |
220 | + big + | |
221 | "\r\n"), | |
222 | res_decorator{called}); | |
223 | fail("", __FILE__, __LINE__); | |
224 | } | |
225 | catch(system_error const& se) | |
226 | { | |
227 | BEAST_EXPECTS( | |
228 | se.code() == error::buffer_overflow, | |
229 | se.code().message()); | |
230 | } | |
231 | } | |
232 | ||
233 | // request in buffers and stream | |
234 | doStreamLoop([&](test::stream& ts) | |
235 | { | |
236 | stream<test::stream&> ws{ts}; | |
237 | auto tr = connect(ws.next_layer()); | |
238 | ts.append( | |
239 | "Connection: upgrade\r\n" | |
240 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
241 | "Sec-WebSocket-Version: 13\r\n" | |
242 | "\r\n"); | |
243 | ts.read_size(16); | |
244 | w.accept(ws, sbuf( | |
245 | "GET / HTTP/1.1\r\n" | |
246 | "Host: localhost\r\n" | |
247 | "Upgrade: websocket\r\n" | |
248 | )); | |
249 | // VFALCO validate contents of ws.next_layer().str? | |
250 | }); | |
251 | ||
252 | // request in buffers and stream, oversized | |
253 | { | |
254 | stream<test::stream> ws{ioc_, | |
255 | "Connection: upgrade\r\n" | |
256 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
257 | "Sec-WebSocket-Version: 13\r\n" | |
258 | + big + | |
259 | "\r\n"}; | |
260 | auto tr = connect(ws.next_layer()); | |
261 | try | |
262 | { | |
263 | w.accept(ws, sbuf( | |
264 | "GET / HTTP/1.1\r\n" | |
265 | "Host: localhost\r\n" | |
266 | "Upgrade: websocket\r\n" | |
267 | )); | |
268 | fail("", __FILE__, __LINE__); | |
269 | } | |
270 | catch(system_error const& se) | |
271 | { | |
272 | BEAST_EXPECTS( | |
273 | se.code() == http::error::buffer_overflow, | |
274 | se.code().message()); | |
275 | } | |
276 | } | |
277 | ||
278 | // request in buffers and stream, decorator | |
279 | doStreamLoop([&](test::stream& ts) | |
280 | { | |
281 | stream<test::stream&> ws{ts}; | |
282 | auto tr = connect(ws.next_layer()); | |
283 | ts.append( | |
284 | "Connection: upgrade\r\n" | |
285 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
286 | "Sec-WebSocket-Version: 13\r\n" | |
287 | "\r\n"); | |
288 | ts.read_size(16); | |
289 | bool called = false; | |
290 | w.accept_ex(ws, sbuf( | |
291 | "GET / HTTP/1.1\r\n" | |
292 | "Host: localhost\r\n" | |
293 | "Upgrade: websocket\r\n"), | |
294 | res_decorator{called}); | |
295 | BEAST_EXPECT(called); | |
296 | }); | |
297 | ||
298 | // request in buffers and stream, decorator, oversize | |
299 | { | |
300 | stream<test::stream> ws{ioc_, | |
301 | "Connection: upgrade\r\n" | |
302 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
303 | "Sec-WebSocket-Version: 13\r\n" | |
304 | + big + | |
305 | "\r\n"}; | |
306 | auto tr = connect(ws.next_layer()); | |
307 | try | |
308 | { | |
309 | bool called = false; | |
310 | w.accept_ex(ws, sbuf( | |
311 | "GET / HTTP/1.1\r\n" | |
312 | "Host: localhost\r\n" | |
313 | "Upgrade: websocket\r\n"), | |
314 | res_decorator{called}); | |
315 | fail("", __FILE__, __LINE__); | |
316 | } | |
317 | catch(system_error const& se) | |
318 | { | |
319 | BEAST_EXPECTS( | |
320 | se.code() == http::error::buffer_overflow, | |
321 | se.code().message()); | |
322 | } | |
323 | } | |
324 | ||
325 | // request in message | |
326 | doStreamLoop([&](test::stream& ts) | |
327 | { | |
328 | stream<test::stream&> ws{ts}; | |
329 | auto tr = connect(ws.next_layer()); | |
330 | request_type req; | |
331 | req.method(http::verb::get); | |
332 | req.target("/"); | |
333 | req.version(11); | |
334 | req.insert(http::field::host, "localhost"); | |
335 | req.insert(http::field::upgrade, "websocket"); | |
336 | req.insert(http::field::connection, "upgrade"); | |
337 | req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ=="); | |
338 | req.insert(http::field::sec_websocket_version, "13"); | |
339 | w.accept(ws, req); | |
340 | }); | |
341 | ||
342 | // request in message, decorator | |
343 | doStreamLoop([&](test::stream& ts) | |
344 | { | |
345 | stream<test::stream&> ws{ts}; | |
346 | auto tr = connect(ws.next_layer()); | |
347 | request_type req; | |
348 | req.method(http::verb::get); | |
349 | req.target("/"); | |
350 | req.version(11); | |
351 | req.insert(http::field::host, "localhost"); | |
352 | req.insert(http::field::upgrade, "websocket"); | |
353 | req.insert(http::field::connection, "upgrade"); | |
354 | req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ=="); | |
355 | req.insert(http::field::sec_websocket_version, "13"); | |
356 | bool called = false; | |
357 | w.accept_ex(ws, req, | |
358 | res_decorator{called}); | |
359 | BEAST_EXPECT(called); | |
360 | }); | |
361 | ||
362 | // request in message, close frame in stream | |
363 | doStreamLoop([&](test::stream& ts) | |
364 | { | |
365 | stream<test::stream&> ws{ts}; | |
366 | auto tr = connect(ws.next_layer()); | |
367 | request_type req; | |
368 | req.method(http::verb::get); | |
369 | req.target("/"); | |
370 | req.version(11); | |
371 | req.insert(http::field::host, "localhost"); | |
372 | req.insert(http::field::upgrade, "websocket"); | |
373 | req.insert(http::field::connection, "upgrade"); | |
374 | req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ=="); | |
375 | req.insert(http::field::sec_websocket_version, "13"); | |
376 | ts.append("\x88\x82\xff\xff\xff\xff\xfc\x17"); | |
377 | w.accept(ws, req); | |
378 | try | |
379 | { | |
380 | static_buffer<1> b; | |
381 | w.read(ws, b); | |
382 | fail("success", __FILE__, __LINE__); | |
383 | } | |
384 | catch(system_error const& e) | |
385 | { | |
386 | if(e.code() != websocket::error::closed) | |
387 | throw; | |
388 | } | |
389 | }); | |
390 | ||
391 | // failed handshake (missing Sec-WebSocket-Key) | |
392 | doStreamLoop([&](test::stream& ts) | |
393 | { | |
394 | stream<test::stream&> ws{ts}; | |
395 | auto tr = connect(ws.next_layer()); | |
396 | ts.append( | |
397 | "GET / HTTP/1.1\r\n" | |
398 | "Host: localhost\r\n" | |
399 | "Upgrade: websocket\r\n" | |
400 | "Connection: upgrade\r\n" | |
401 | "Sec-WebSocket-Version: 13\r\n" | |
402 | "\r\n"); | |
403 | ts.read_size(20); | |
404 | try | |
405 | { | |
406 | w.accept(ws); | |
407 | fail("success", __FILE__, __LINE__); | |
408 | } | |
409 | catch(system_error const& e) | |
410 | { | |
411 | if( e.code() != | |
11fdf7f2 | 412 | websocket::error::no_sec_key && |
b32b8144 FG |
413 | e.code() != |
414 | boost::asio::error::eof) | |
415 | throw; | |
416 | } | |
417 | }); | |
418 | ||
419 | // Closed by client | |
420 | { | |
421 | stream<test::stream> ws{ioc_}; | |
422 | auto tr = connect(ws.next_layer()); | |
423 | tr.close(); | |
424 | try | |
425 | { | |
426 | w.accept(ws); | |
427 | fail("success", __FILE__, __LINE__); | |
428 | } | |
429 | catch(system_error const& e) | |
430 | { | |
431 | if(! BEAST_EXPECTS( | |
432 | e.code() == error::closed, | |
433 | e.code().message())) | |
434 | throw; | |
435 | } | |
436 | } | |
437 | } | |
438 | ||
439 | void | |
440 | testAccept() | |
441 | { | |
442 | doTestAccept(SyncClient{}); | |
443 | ||
444 | yield_to([&](yield_context yield) | |
445 | { | |
446 | doTestAccept(AsyncClient{yield}); | |
447 | }); | |
448 | ||
449 | // | |
450 | // Bad requests | |
451 | // | |
452 | ||
453 | auto const check = | |
454 | [&](error_code const& ev, std::string const& s) | |
455 | { | |
456 | for(int i = 0; i < 3; ++i) | |
457 | { | |
458 | std::size_t n; | |
459 | switch(i) | |
460 | { | |
461 | default: | |
462 | case 0: | |
463 | n = 1; | |
464 | break; | |
465 | case 1: | |
466 | n = s.size() / 2; | |
467 | break; | |
468 | case 2: | |
469 | n = s.size() - 1; | |
470 | break; | |
471 | } | |
472 | stream<test::stream> ws{ioc_}; | |
473 | auto tr = connect(ws.next_layer()); | |
474 | ws.next_layer().append( | |
475 | s.substr(n, s.size() - n)); | |
476 | try | |
477 | { | |
478 | ws.accept( | |
479 | boost::asio::buffer(s.data(), n)); | |
480 | BEAST_EXPECTS(! ev, ev.message()); | |
481 | } | |
482 | catch(system_error const& se) | |
483 | { | |
484 | BEAST_EXPECTS(se.code() == ev, se.what()); | |
485 | } | |
486 | } | |
487 | }; | |
488 | ||
11fdf7f2 TL |
489 | // bad version |
490 | check(error::bad_http_version, | |
b32b8144 FG |
491 | "GET / HTTP/1.0\r\n" |
492 | "Host: localhost:80\r\n" | |
493 | "Upgrade: WebSocket\r\n" | |
494 | "Connection: keep-alive,upgrade\r\n" | |
495 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
496 | "Sec-WebSocket-Version: 13\r\n" | |
497 | "\r\n" | |
498 | ); | |
11fdf7f2 TL |
499 | // bad method |
500 | check(error::bad_method, | |
b32b8144 FG |
501 | "POST / HTTP/1.1\r\n" |
502 | "Host: localhost:80\r\n" | |
503 | "Upgrade: WebSocket\r\n" | |
504 | "Connection: keep-alive,upgrade\r\n" | |
505 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
506 | "Sec-WebSocket-Version: 13\r\n" | |
507 | "\r\n" | |
508 | ); | |
11fdf7f2 TL |
509 | // no Host |
510 | check(error::no_host, | |
b32b8144 FG |
511 | "GET / HTTP/1.1\r\n" |
512 | "Upgrade: WebSocket\r\n" | |
513 | "Connection: keep-alive,upgrade\r\n" | |
514 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
515 | "Sec-WebSocket-Version: 13\r\n" | |
516 | "\r\n" | |
517 | ); | |
11fdf7f2 TL |
518 | // no Connection |
519 | check(error::no_connection, | |
b32b8144 FG |
520 | "GET / HTTP/1.1\r\n" |
521 | "Host: localhost:80\r\n" | |
522 | "Upgrade: WebSocket\r\n" | |
11fdf7f2 | 523 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
b32b8144 FG |
524 | "Sec-WebSocket-Version: 13\r\n" |
525 | "\r\n" | |
526 | ); | |
11fdf7f2 TL |
527 | // no Connection upgrade |
528 | check(error::no_connection_upgrade, | |
b32b8144 FG |
529 | "GET / HTTP/1.1\r\n" |
530 | "Host: localhost:80\r\n" | |
531 | "Upgrade: WebSocket\r\n" | |
11fdf7f2 | 532 | "Connection: keep-alive\r\n" |
b32b8144 | 533 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
11fdf7f2 | 534 | "Sec-WebSocket-Version: 13\r\n" |
b32b8144 FG |
535 | "\r\n" |
536 | ); | |
11fdf7f2 TL |
537 | // no Upgrade |
538 | check(error::no_upgrade, | |
b32b8144 FG |
539 | "GET / HTTP/1.1\r\n" |
540 | "Host: localhost:80\r\n" | |
11fdf7f2 | 541 | "Connection: upgrade\r\n" |
b32b8144 | 542 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
11fdf7f2 | 543 | "Sec-WebSocket-Version: 13\r\n" |
b32b8144 FG |
544 | "\r\n" |
545 | ); | |
11fdf7f2 TL |
546 | // no Upgrade websocket |
547 | check(error::no_upgrade_websocket, | |
b32b8144 FG |
548 | "GET / HTTP/1.1\r\n" |
549 | "Host: localhost:80\r\n" | |
550 | "Upgrade: HTTP/2\r\n" | |
551 | "Connection: upgrade\r\n" | |
552 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
553 | "Sec-WebSocket-Version: 13\r\n" | |
554 | "\r\n" | |
555 | ); | |
11fdf7f2 TL |
556 | // no Sec-WebSocket-Key |
557 | check(error::no_sec_key, | |
b32b8144 FG |
558 | "GET / HTTP/1.1\r\n" |
559 | "Host: localhost:80\r\n" | |
560 | "Upgrade: WebSocket\r\n" | |
11fdf7f2 | 561 | "Connection: keep-alive,upgrade\r\n" |
b32b8144 FG |
562 | "Sec-WebSocket-Version: 13\r\n" |
563 | "\r\n" | |
564 | ); | |
11fdf7f2 TL |
565 | // bad Sec-WebSocket-Key |
566 | check(error::bad_sec_key, | |
b32b8144 FG |
567 | "GET / HTTP/1.1\r\n" |
568 | "Host: localhost:80\r\n" | |
569 | "Upgrade: WebSocket\r\n" | |
570 | "Connection: upgrade\r\n" | |
571 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQdGhlIHNhbXBsZSBub25jZQ==\r\n" | |
572 | "Sec-WebSocket-Version: 13\r\n" | |
573 | "\r\n" | |
574 | ); | |
11fdf7f2 TL |
575 | // no Sec-WebSocket-Version |
576 | check(error::no_sec_version, | |
b32b8144 FG |
577 | "GET / HTTP/1.1\r\n" |
578 | "Host: localhost:80\r\n" | |
579 | "Upgrade: WebSocket\r\n" | |
11fdf7f2 | 580 | "Connection: keep-alive,upgrade\r\n" |
b32b8144 | 581 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" |
b32b8144 FG |
582 | "\r\n" |
583 | ); | |
11fdf7f2 TL |
584 | // bad Sec-WebSocket-Version |
585 | check(error::bad_sec_version, | |
586 | "GET / HTTP/1.1\r\n" | |
587 | "Host: localhost:80\r\n" | |
588 | "Upgrade: WebSocket\r\n" | |
589 | "Connection: keep-alive,upgrade\r\n" | |
590 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
591 | "Sec-WebSocket-Version: 1\r\n" | |
592 | "\r\n" | |
593 | ); | |
594 | // bad Sec-WebSocket-Version | |
595 | check(error::bad_sec_version, | |
b32b8144 FG |
596 | "GET / HTTP/1.1\r\n" |
597 | "Host: localhost:80\r\n" | |
598 | "Upgrade: WebSocket\r\n" | |
599 | "Connection: upgrade\r\n" | |
600 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
11fdf7f2 | 601 | "Sec-WebSocket-Version: 12\r\n" |
b32b8144 FG |
602 | "\r\n" |
603 | ); | |
604 | // valid request | |
605 | check({}, | |
606 | "GET / HTTP/1.1\r\n" | |
607 | "Host: localhost:80\r\n" | |
608 | "Upgrade: WebSocket\r\n" | |
609 | "Connection: upgrade\r\n" | |
610 | "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" | |
611 | "Sec-WebSocket-Version: 13\r\n" | |
612 | "\r\n" | |
613 | ); | |
614 | } | |
615 | ||
11fdf7f2 TL |
616 | void |
617 | testMoveOnly() | |
618 | { | |
619 | boost::asio::io_context ioc; | |
620 | stream<test::stream> ws{ioc}; | |
621 | ws.async_accept(move_only_handler{}); | |
622 | } | |
623 | ||
624 | struct copyable_handler | |
625 | { | |
626 | template<class... Args> | |
627 | void | |
628 | operator()(Args&&...) const | |
629 | { | |
630 | } | |
631 | }; | |
632 | ||
633 | void | |
634 | testAsioHandlerInvoke() | |
635 | { | |
636 | // make sure things compile, also can set a | |
637 | // breakpoint in asio_handler_invoke to make sure | |
638 | // it is instantiated. | |
639 | boost::asio::io_context ioc; | |
640 | boost::asio::io_service::strand s{ioc}; | |
641 | stream<test::stream> ws{ioc}; | |
642 | ws.async_accept(s.wrap(copyable_handler{})); | |
643 | } | |
644 | ||
b32b8144 FG |
645 | void |
646 | run() override | |
647 | { | |
648 | testAccept(); | |
11fdf7f2 TL |
649 | testMoveOnly(); |
650 | testAsioHandlerInvoke(); | |
b32b8144 FG |
651 | } |
652 | }; | |
653 | ||
654 | BEAST_DEFINE_TESTSUITE(beast,websocket,accept); | |
655 | ||
656 | } // websocket | |
657 | } // beast | |
658 | } // boost |