]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/beast/test/beast/websocket/accept.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / beast / test / beast / websocket / accept.cpp
CommitLineData
b32b8144 1//
92f5a8d4 2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
b32b8144
FG
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
92f5a8d4
TL
13#include <boost/beast/_experimental/test/stream.hpp>
14#include <boost/beast/_experimental/test/tcp.hpp>
15#include <boost/beast/_experimental/unit_test/suite.hpp>
b32b8144 16#include "test.hpp"
20effc67
TL
17#if BOOST_ASIO_HAS_CO_AWAIT
18#include <boost/asio/use_awaitable.hpp>
19#endif
b32b8144
FG
20namespace boost {
21namespace beast {
22namespace websocket {
23
92f5a8d4 24class accept_test : public unit_test::suite //: public websocket_test_suite
b32b8144
FG
25{
26public:
92f5a8d4 27 class res_decorator
b32b8144 28 {
92f5a8d4
TL
29 bool& b_;
30
31 public:
32 res_decorator(res_decorator const&) = default;
33
34 explicit
35 res_decorator(bool& b)
36 : b_(b)
b32b8144 37 {
92f5a8d4 38 }
b32b8144 39
92f5a8d4
TL
40 void
41 operator()(response_type&) const
42 {
43 this->b_ = true;
44 }
45 };
46
47 template<std::size_t N>
48 static
49 net::const_buffer
50 sbuf(const char (&s)[N])
51 {
52 return net::const_buffer(&s[0], N-1);
53 }
b32b8144 54
92f5a8d4
TL
55 static
56 void
57 fail_loop(
58 std::function<void(stream<test::stream>&)> f,
59 std::chrono::steady_clock::duration amount =
60 std::chrono::seconds(5))
61 {
62 using clock_type = std::chrono::steady_clock;
63 auto const expires_at =
64 clock_type::now() + amount;
65 net::io_context ioc;
66 for(std::size_t n = 0;;++n)
67 {
68 test::fail_count fc(n);
69 try
b32b8144 70 {
92f5a8d4
TL
71 stream<test::stream> ws(ioc, fc);
72 auto tr = connect(ws.next_layer());
73 f(ws);
74 break;
b32b8144 75 }
92f5a8d4 76 catch(system_error const& se)
b32b8144 77 {
92f5a8d4
TL
78 // VFALCO Commented this out after the short
79 // read change, because it converts test_failure
80 // into http::partial_message
81 //
82 boost::ignore_unused(se);
83 #if 0
84 if(! BEAST_EXPECTS(
85 se.code() == test::error::test_failure,
86 se.code().message()))
87 throw;
88 #endif
89 if(! BEAST_EXPECTS(
90 clock_type::now() < expires_at,
91 "a test timeout occurred"))
92 break;
b32b8144 93 }
92f5a8d4
TL
94 }
95 }
b32b8144 96
92f5a8d4
TL
97 template<class Api>
98 void
99 testMatrix(Api api)
100 {
101 net::io_context ioc;
b32b8144
FG
102
103 // request in stream
92f5a8d4 104 fail_loop([&](stream<test::stream>& ws)
b32b8144 105 {
92f5a8d4 106 ws.next_layer().append(
b32b8144
FG
107 "GET / HTTP/1.1\r\n"
108 "Host: localhost\r\n"
109 "Upgrade: websocket\r\n"
110 "Connection: upgrade\r\n"
111 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
112 "Sec-WebSocket-Version: 13\r\n"
113 "\r\n");
92f5a8d4
TL
114 ws.next_layer().read_size(20);
115 api.accept(ws);
b32b8144
FG
116 });
117
92f5a8d4
TL
118 // request in stream, decorator
119 fail_loop([&](stream<test::stream>& ws)
b32b8144 120 {
92f5a8d4 121 ws.next_layer().append(
b32b8144
FG
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"
92f5a8d4
TL
128 "\r\n");
129 ws.next_layer().read_size(20);
130 bool called = false;
131 ws.set_option(stream_base::decorator(
132 res_decorator{called}));
133 api.accept(ws);
134 BEAST_EXPECT(called);
135 });
b32b8144 136
92f5a8d4
TL
137 // request in buffers
138 fail_loop([&](stream<test::stream>& ws)
b32b8144 139 {
92f5a8d4
TL
140 api.accept(ws, sbuf(
141 "GET / HTTP/1.1\r\n"
142 "Host: localhost\r\n"
143 "Upgrade: websocket\r\n"
144 "Connection: upgrade\r\n"
145 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
146 "Sec-WebSocket-Version: 13\r\n"
147 "\r\n"
148 ));
149 });
150
151 // request in buffers, decorator
152 fail_loop([&](stream<test::stream>& ws)
153 {
154 bool called = false;
155 ws.set_option(stream_base::decorator(
156 res_decorator{called}));
157 api.accept(ws, sbuf(
158 "GET / HTTP/1.1\r\n"
159 "Host: localhost\r\n"
160 "Upgrade: websocket\r\n"
161 "Connection: upgrade\r\n"
162 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
163 "Sec-WebSocket-Version: 13\r\n"
164 "\r\n"));
165 BEAST_EXPECT(called);
166 });
167
168 // request in buffers and stream
169 fail_loop([&](stream<test::stream>& ws)
170 {
171 ws.next_layer().append(
172 "Connection: upgrade\r\n"
173 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
174 "Sec-WebSocket-Version: 13\r\n"
175 "\r\n");
176 ws.next_layer().read_size(16);
177 api.accept(ws, sbuf(
b32b8144
FG
178 "GET / HTTP/1.1\r\n"
179 "Host: localhost\r\n"
180 "Upgrade: websocket\r\n"
92f5a8d4
TL
181 ));
182 // VFALCO validate contents of ws.next_layer().str?
183 });
184
185 // request in buffers and stream, decorator
186 fail_loop([&](stream<test::stream>& ws)
187 {
188 ws.next_layer().append(
b32b8144
FG
189 "Connection: upgrade\r\n"
190 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
191 "Sec-WebSocket-Version: 13\r\n"
192 "\r\n");
92f5a8d4 193 ws.next_layer().read_size(16);
b32b8144 194 bool called = false;
92f5a8d4
TL
195 ws.set_option(stream_base::decorator(
196 res_decorator{called}));
197 api.accept(ws, sbuf(
198 "GET / HTTP/1.1\r\n"
199 "Host: localhost\r\n"
200 "Upgrade: websocket\r\n"));
b32b8144
FG
201 BEAST_EXPECT(called);
202 });
203
92f5a8d4
TL
204 // request in message
205 {
206 request_type req;
207 req.method(http::verb::get);
208 req.target("/");
209 req.version(11);
210 req.insert(http::field::host, "localhost");
211 req.insert(http::field::upgrade, "websocket");
212 req.insert(http::field::connection, "upgrade");
213 req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
214 req.insert(http::field::sec_websocket_version, "13");
215
216 fail_loop([&](stream<test::stream>& ws)
217 {
218 api.accept(ws, req);
219 });
220 }
221
222 // request in message, decorator
223 {
224 request_type req;
225 req.method(http::verb::get);
226 req.target("/");
227 req.version(11);
228 req.insert(http::field::host, "localhost");
229 req.insert(http::field::upgrade, "websocket");
230 req.insert(http::field::connection, "upgrade");
231 req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
232 req.insert(http::field::sec_websocket_version, "13");
233
234 fail_loop([&](stream<test::stream>& ws)
235 {
236 bool called = false;
237 ws.set_option(stream_base::decorator(
238 res_decorator{called}));
239 api.accept(ws, req);
240 BEAST_EXPECT(called);
241 });
242 }
243
244 // request in message, close frame in stream
245 {
246 request_type req;
247 req.method(http::verb::get);
248 req.target("/");
249 req.version(11);
250 req.insert(http::field::host, "localhost");
251 req.insert(http::field::upgrade, "websocket");
252 req.insert(http::field::connection, "upgrade");
253 req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
254 req.insert(http::field::sec_websocket_version, "13");
255
256 fail_loop([&](stream<test::stream>& ws)
257 {
258 ws.next_layer().append("\x88\x82\xff\xff\xff\xff\xfc\x17");
259 api.accept(ws, req);
260 try
261 {
262 static_buffer<1> b;
263 api.read(ws, b);
264 fail("success", __FILE__, __LINE__);
265 }
266 catch(system_error const& e)
267 {
268 if(e.code() != websocket::error::closed)
269 throw;
270 }
271 });
272 }
273
274 // failed handshake (missing Sec-WebSocket-Key)
275 fail_loop([&](stream<test::stream>& ws)
276 {
277 ws.next_layer().append(
278 "GET / HTTP/1.1\r\n"
279 "Host: localhost\r\n"
280 "Upgrade: websocket\r\n"
281 "Connection: upgrade\r\n"
282 "Sec-WebSocket-Version: 13\r\n"
283 "\r\n");
284 ws.next_layer().read_size(20);
285 try
286 {
287 api.accept(ws);
288 BEAST_FAIL();
289 }
290 catch(system_error const& e)
291 {
292 if( e.code() != websocket::error::no_sec_key &&
293 e.code() != net::error::eof)
294 throw;
295 }
296 });
297 }
298
299 template<class Api>
300 void
301 testOversized(Api const& api)
302 {
303 net::io_context ioc;
304
305 auto const big = []
306 {
307 std::string s;
308 s += "X1: " + std::string(2000, '*') + "\r\n";
309 return s;
310 }();
311
312 // request in stream
b32b8144 313 {
92f5a8d4 314 stream<test::stream> ws{ioc,
b32b8144
FG
315 "GET / HTTP/1.1\r\n"
316 "Host: localhost\r\n"
317 "Upgrade: websocket\r\n"
318 "Connection: upgrade\r\n"
319 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
320 "Sec-WebSocket-Version: 13\r\n"
321 + big +
322 "\r\n"};
323 auto tr = connect(ws.next_layer());
324 try
325 {
92f5a8d4
TL
326 api.accept(ws);
327 BEAST_FAIL();
b32b8144
FG
328 }
329 catch(system_error const& se)
330 {
331 // VFALCO Its the http error category...
332 BEAST_EXPECTS(
333 se.code() == http::error::buffer_overflow,
334 se.code().message());
335 }
336 }
337
92f5a8d4 338 // request in stream, decorator
b32b8144 339 {
92f5a8d4 340 stream<test::stream> ws{ioc,
b32b8144
FG
341 "GET / HTTP/1.1\r\n"
342 "Host: localhost\r\n"
343 "Upgrade: websocket\r\n"
344 "Connection: upgrade\r\n"
345 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
346 "Sec-WebSocket-Version: 13\r\n"
92f5a8d4
TL
347 + big +
348 "\r\n"};
349 auto tr = connect(ws.next_layer());
350 try
351 {
352 bool called = false;
353 ws.set_option(stream_base::decorator(
354 res_decorator{called}));
355 api.accept(ws);
356 BEAST_FAIL();
357 }
358 catch(system_error const& se)
359 {
360 // VFALCO Its the http error category...
361 BEAST_EXPECTS(
362 se.code() == http::error::buffer_overflow,
363 se.code().message());
364 }
365 }
b32b8144 366
92f5a8d4 367 // request in buffers
b32b8144 368 {
92f5a8d4 369 stream<test::stream> ws{ioc};
b32b8144
FG
370 auto tr = connect(ws.next_layer());
371 try
372 {
92f5a8d4 373 api.accept(ws, net::buffer(
b32b8144
FG
374 "GET / HTTP/1.1\r\n"
375 "Host: localhost\r\n"
376 "Upgrade: websocket\r\n"
377 "Connection: upgrade\r\n"
378 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
379 "Sec-WebSocket-Version: 13\r\n"
380 + big +
381 "\r\n"
382 ));
92f5a8d4 383 BEAST_FAIL();
b32b8144
FG
384 }
385 catch(system_error const& se)
386 {
387 BEAST_EXPECTS(
388 se.code() == error::buffer_overflow,
389 se.code().message());
390 }
391 }
392
393 // request in buffers, decorator
b32b8144 394 {
92f5a8d4 395 stream<test::stream> ws{ioc};
b32b8144
FG
396 auto tr = connect(ws.next_layer());
397 try
398 {
399 bool called = false;
92f5a8d4
TL
400 ws.set_option(stream_base::decorator(
401 res_decorator{called}));
402 api.accept(ws, net::buffer(
b32b8144
FG
403 "GET / HTTP/1.1\r\n"
404 "Host: localhost\r\n"
405 "Upgrade: websocket\r\n"
406 "Connection: upgrade\r\n"
407 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
408 "Sec-WebSocket-Version: 13\r\n"
409 + big +
92f5a8d4
TL
410 "\r\n"));
411 BEAST_FAIL();
b32b8144
FG
412 }
413 catch(system_error const& se)
414 {
415 BEAST_EXPECTS(
416 se.code() == error::buffer_overflow,
417 se.code().message());
418 }
419 }
420
421 // request in buffers and stream
b32b8144 422 {
92f5a8d4 423 stream<test::stream> ws{ioc,
b32b8144
FG
424 "Connection: upgrade\r\n"
425 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
426 "Sec-WebSocket-Version: 13\r\n"
427 + big +
428 "\r\n"};
429 auto tr = connect(ws.next_layer());
430 try
431 {
92f5a8d4 432 api.accept(ws, websocket_test_suite::sbuf(
b32b8144
FG
433 "GET / HTTP/1.1\r\n"
434 "Host: localhost\r\n"
435 "Upgrade: websocket\r\n"
436 ));
92f5a8d4 437 BEAST_FAIL();
b32b8144
FG
438 }
439 catch(system_error const& se)
440 {
441 BEAST_EXPECTS(
442 se.code() == http::error::buffer_overflow,
443 se.code().message());
444 }
445 }
446
447 // request in buffers and stream, decorator
b32b8144 448 {
92f5a8d4 449 stream<test::stream> ws{ioc,
b32b8144
FG
450 "Connection: upgrade\r\n"
451 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
452 "Sec-WebSocket-Version: 13\r\n"
453 + big +
454 "\r\n"};
455 auto tr = connect(ws.next_layer());
456 try
457 {
458 bool called = false;
92f5a8d4
TL
459 ws.set_option(stream_base::decorator(
460 res_decorator{called}));
461 api.accept(ws, websocket_test_suite::sbuf(
b32b8144
FG
462 "GET / HTTP/1.1\r\n"
463 "Host: localhost\r\n"
92f5a8d4
TL
464 "Upgrade: websocket\r\n"));
465 BEAST_FAIL();
b32b8144
FG
466 }
467 catch(system_error const& se)
468 {
469 BEAST_EXPECTS(
470 se.code() == http::error::buffer_overflow,
471 se.code().message());
472 }
473 }
b32b8144
FG
474 }
475
476 void
92f5a8d4 477 testInvalidInputs()
b32b8144 478 {
92f5a8d4 479 net::io_context ioc;
b32b8144
FG
480
481 auto const check =
92f5a8d4 482 [&](error_code ev, string_view s)
b32b8144
FG
483 {
484 for(int i = 0; i < 3; ++i)
485 {
486 std::size_t n;
487 switch(i)
488 {
489 default:
490 case 0:
491 n = 1;
492 break;
493 case 1:
494 n = s.size() / 2;
495 break;
496 case 2:
497 n = s.size() - 1;
498 break;
499 }
92f5a8d4 500 stream<test::stream> ws(ioc);
b32b8144
FG
501 auto tr = connect(ws.next_layer());
502 ws.next_layer().append(
503 s.substr(n, s.size() - n));
92f5a8d4 504 tr.close();
b32b8144
FG
505 try
506 {
92f5a8d4 507 ws.accept(net::buffer(s.data(), n));
b32b8144
FG
508 BEAST_EXPECTS(! ev, ev.message());
509 }
510 catch(system_error const& se)
511 {
512 BEAST_EXPECTS(se.code() == ev, se.what());
513 }
514 }
515 };
516
11fdf7f2
TL
517 // bad version
518 check(error::bad_http_version,
b32b8144
FG
519 "GET / HTTP/1.0\r\n"
520 "Host: localhost:80\r\n"
521 "Upgrade: WebSocket\r\n"
522 "Connection: keep-alive,upgrade\r\n"
523 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
524 "Sec-WebSocket-Version: 13\r\n"
525 "\r\n"
526 );
92f5a8d4 527
11fdf7f2
TL
528 // bad method
529 check(error::bad_method,
b32b8144
FG
530 "POST / HTTP/1.1\r\n"
531 "Host: localhost:80\r\n"
532 "Upgrade: WebSocket\r\n"
533 "Connection: keep-alive,upgrade\r\n"
534 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
535 "Sec-WebSocket-Version: 13\r\n"
536 "\r\n"
537 );
92f5a8d4 538
11fdf7f2
TL
539 // no Host
540 check(error::no_host,
b32b8144
FG
541 "GET / HTTP/1.1\r\n"
542 "Upgrade: WebSocket\r\n"
543 "Connection: keep-alive,upgrade\r\n"
544 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
545 "Sec-WebSocket-Version: 13\r\n"
546 "\r\n"
547 );
92f5a8d4 548
11fdf7f2
TL
549 // no Connection
550 check(error::no_connection,
b32b8144
FG
551 "GET / HTTP/1.1\r\n"
552 "Host: localhost:80\r\n"
553 "Upgrade: WebSocket\r\n"
11fdf7f2 554 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
b32b8144
FG
555 "Sec-WebSocket-Version: 13\r\n"
556 "\r\n"
557 );
92f5a8d4 558
11fdf7f2
TL
559 // no Connection upgrade
560 check(error::no_connection_upgrade,
b32b8144
FG
561 "GET / HTTP/1.1\r\n"
562 "Host: localhost:80\r\n"
563 "Upgrade: WebSocket\r\n"
11fdf7f2 564 "Connection: keep-alive\r\n"
b32b8144 565 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
11fdf7f2 566 "Sec-WebSocket-Version: 13\r\n"
b32b8144
FG
567 "\r\n"
568 );
92f5a8d4 569
11fdf7f2
TL
570 // no Upgrade
571 check(error::no_upgrade,
b32b8144
FG
572 "GET / HTTP/1.1\r\n"
573 "Host: localhost:80\r\n"
11fdf7f2 574 "Connection: upgrade\r\n"
b32b8144 575 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
11fdf7f2 576 "Sec-WebSocket-Version: 13\r\n"
b32b8144
FG
577 "\r\n"
578 );
92f5a8d4 579
11fdf7f2
TL
580 // no Upgrade websocket
581 check(error::no_upgrade_websocket,
b32b8144
FG
582 "GET / HTTP/1.1\r\n"
583 "Host: localhost:80\r\n"
584 "Upgrade: HTTP/2\r\n"
585 "Connection: upgrade\r\n"
586 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
587 "Sec-WebSocket-Version: 13\r\n"
588 "\r\n"
589 );
92f5a8d4 590
11fdf7f2
TL
591 // no Sec-WebSocket-Key
592 check(error::no_sec_key,
b32b8144
FG
593 "GET / HTTP/1.1\r\n"
594 "Host: localhost:80\r\n"
595 "Upgrade: WebSocket\r\n"
11fdf7f2 596 "Connection: keep-alive,upgrade\r\n"
b32b8144
FG
597 "Sec-WebSocket-Version: 13\r\n"
598 "\r\n"
599 );
92f5a8d4 600
11fdf7f2
TL
601 // bad Sec-WebSocket-Key
602 check(error::bad_sec_key,
b32b8144
FG
603 "GET / HTTP/1.1\r\n"
604 "Host: localhost:80\r\n"
605 "Upgrade: WebSocket\r\n"
606 "Connection: upgrade\r\n"
607 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQdGhlIHNhbXBsZSBub25jZQ==\r\n"
608 "Sec-WebSocket-Version: 13\r\n"
609 "\r\n"
610 );
92f5a8d4 611
11fdf7f2
TL
612 // no Sec-WebSocket-Version
613 check(error::no_sec_version,
b32b8144
FG
614 "GET / HTTP/1.1\r\n"
615 "Host: localhost:80\r\n"
616 "Upgrade: WebSocket\r\n"
11fdf7f2 617 "Connection: keep-alive,upgrade\r\n"
b32b8144 618 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
b32b8144
FG
619 "\r\n"
620 );
92f5a8d4 621
11fdf7f2
TL
622 // bad Sec-WebSocket-Version
623 check(error::bad_sec_version,
624 "GET / HTTP/1.1\r\n"
625 "Host: localhost:80\r\n"
626 "Upgrade: WebSocket\r\n"
627 "Connection: keep-alive,upgrade\r\n"
628 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
629 "Sec-WebSocket-Version: 1\r\n"
630 "\r\n"
631 );
92f5a8d4 632
11fdf7f2
TL
633 // bad Sec-WebSocket-Version
634 check(error::bad_sec_version,
b32b8144
FG
635 "GET / HTTP/1.1\r\n"
636 "Host: localhost:80\r\n"
637 "Upgrade: WebSocket\r\n"
638 "Connection: upgrade\r\n"
639 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
11fdf7f2 640 "Sec-WebSocket-Version: 12\r\n"
b32b8144
FG
641 "\r\n"
642 );
92f5a8d4 643
b32b8144
FG
644 // valid request
645 check({},
646 "GET / HTTP/1.1\r\n"
647 "Host: localhost:80\r\n"
648 "Upgrade: WebSocket\r\n"
649 "Connection: upgrade\r\n"
650 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
651 "Sec-WebSocket-Version: 13\r\n"
652 "\r\n"
653 );
654 }
655
11fdf7f2 656 void
92f5a8d4 657 testEndOfStream()
11fdf7f2 658 {
92f5a8d4
TL
659 net::io_context ioc;
660 {
661 stream<test::stream> ws(ioc);
662 auto tr = connect(ws.next_layer());
663 tr.close();
664 try
665 {
666 test_sync_api api;
667 api.accept(ws, net::const_buffer{});
668 BEAST_FAIL();
669 }
670 catch(system_error const& se)
671 {
672 BEAST_EXPECTS(
673 se.code() == error::closed,
674 se.code().message());
675 }
676 }
677 {
678 stream<test::stream> ws(ioc);
679 auto tr = connect(ws.next_layer());
680 tr.close();
681 try
682 {
683 test_async_api api;
684 api.accept(ws, net::const_buffer{});
685 BEAST_FAIL();
686 }
687 catch(system_error const& se)
688 {
689 BEAST_EXPECTS(
690 se.code() == error::closed,
691 se.code().message());
692 }
693 }
11fdf7f2
TL
694 }
695
92f5a8d4
TL
696 void
697 testAsync()
11fdf7f2 698 {
92f5a8d4
TL
699 using tcp = net::ip::tcp;
700
701 net::io_context ioc;
702
703 // success, no timeout
704
11fdf7f2 705 {
92f5a8d4
TL
706 stream<tcp::socket> ws1(ioc);
707 stream<tcp::socket> ws2(ioc);
708 test::connect(ws1.next_layer(), ws2.next_layer());
709
710 ws1.async_handshake("test", "/", test::success_handler());
711 ws2.async_accept(test::success_handler());
712 test::run_for(ioc, std::chrono::seconds(1));
11fdf7f2 713 }
11fdf7f2 714
92f5a8d4
TL
715 {
716 stream<test::stream> ws1(ioc);
717 stream<test::stream> ws2(ioc);
718 test::connect(ws1.next_layer(), ws2.next_layer());
719
720 ws1.async_handshake("test", "/", test::success_handler());
721 ws2.async_accept(test::success_handler());
722 test::run_for(ioc, std::chrono::seconds(1));
723 }
724
725 // success, timeout enabled
726
727 {
728 stream<tcp::socket> ws1(ioc);
729 stream<tcp::socket> ws2(ioc);
730 test::connect(ws1.next_layer(), ws2.next_layer());
731
732 ws1.set_option(stream_base::timeout{
733 std::chrono::milliseconds(50),
734 stream_base::none(),
735 false});
736 ws1.async_accept(test::success_handler());
737 ws2.async_handshake("test", "/", test::success_handler());
738 test::run_for(ioc, std::chrono::seconds(1));
739 }
740
741 {
742 stream<test::stream> ws1(ioc);
743 stream<test::stream> ws2(ioc);
744 test::connect(ws1.next_layer(), ws2.next_layer());
745
746 ws1.set_option(stream_base::timeout{
747 std::chrono::milliseconds(50),
748 stream_base::none(),
749 false});
750 ws1.async_accept(test::success_handler());
751 ws2.async_handshake("test", "/", test::success_handler());
752 test::run_for(ioc, std::chrono::seconds(1));
753 }
754
755 // timeout
756
757 {
758 stream<tcp::socket> ws1(ioc);
759 stream<tcp::socket> ws2(ioc);
760 test::connect(ws1.next_layer(), ws2.next_layer());
761
762 ws1.set_option(stream_base::timeout{
763 std::chrono::milliseconds(50),
764 stream_base::none(),
765 false});
766 ws1.async_accept(test::fail_handler(beast::error::timeout));
767 test::run_for(ioc, std::chrono::seconds(1));
768 }
769
770 {
771 stream<test::stream> ws1(ioc);
772 stream<test::stream> ws2(ioc);
773 test::connect(ws1.next_layer(), ws2.next_layer());
774
775 ws1.set_option(stream_base::timeout{
776 std::chrono::milliseconds(50),
777 stream_base::none(),
778 false});
779 ws1.async_accept(test::fail_handler(beast::error::timeout));
780 test::run_for(ioc, std::chrono::seconds(1));
781 }
782
783 // abandoned operation
784
785 {
786 {
787 stream<tcp::socket> ws1(ioc);
788 ws1.async_accept(test::fail_handler(
789 net::error::operation_aborted));
790 }
791 test::run(ioc);
792 }
793
794 {
795 {
796 stream<tcp::socket> ws1(ioc);
797 string_view s =
798 "GET / HTTP/1.1\r\n"
799 "Host: localhost\r\n"
800 "Upgrade: websocket\r\n"
801 "Connection: upgrade\r\n"
802 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
803 "Sec-WebSocket-Version: 13\r\n"
804 "\r\n";
805 error_code ec;
806 http::request_parser<http::empty_body> p;
807 p.put(net::const_buffer(s.data(), s.size()), ec);
808 ws1.async_accept(p.get(), test::fail_handler(
809 net::error::operation_aborted));
810 }
811 test::run(ioc);
812 }
11fdf7f2
TL
813 }
814
20effc67
TL
815#if BOOST_ASIO_HAS_CO_AWAIT
816 void testAwaitableCompiles(
817 stream<net::ip::tcp::socket>& s,
818 http::request<http::empty_body>& req,
819 net::mutable_buffer buf
820 )
821 {
822 static_assert(std::is_same_v<
823 net::awaitable<void>, decltype(
824 s.async_accept(net::use_awaitable))>);
825
826 static_assert(std::is_same_v<
827 net::awaitable<void>, decltype(
828 s.async_accept(req, net::use_awaitable))>);
829
830 static_assert(std::is_same_v<
831 net::awaitable<void>, decltype(
832 s.async_accept(buf, net::use_awaitable))>);
833 }
834#endif
835
b32b8144
FG
836 void
837 run() override
838 {
92f5a8d4
TL
839 testMatrix(test_sync_api{});
840 testMatrix(test_async_api{});
841 testOversized(test_sync_api{});
842 testOversized(test_async_api{});
843 testInvalidInputs();
844 testEndOfStream();
845 testAsync();
20effc67
TL
846#if BOOST_ASIO_HAS_CO_AWAIT
847 boost::ignore_unused(&accept_test::testAwaitableCompiles);
848#endif
b32b8144
FG
849 }
850};
851
852BEAST_DEFINE_TESTSUITE(beast,websocket,accept);
853
854} // websocket
855} // beast
856} // boost