]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/websocket/accept.cpp
2 // Copyright (c) 2016-2019 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>
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>
22 class accept_test
: public unit_test::suite
//: public websocket_test_suite
30 res_decorator(res_decorator
const&) = default;
33 res_decorator(bool& b
)
39 operator()(response_type
&) const
45 template<std::size_t N
>
48 sbuf(const char (&s
)[N
])
50 return net::const_buffer(&s
[0], N
-1);
56 std::function
<void(stream
<test::stream
>&)> f
,
57 std::chrono::steady_clock::duration amount
=
58 std::chrono::seconds(5))
60 using clock_type
= std::chrono::steady_clock
;
61 auto const expires_at
=
62 clock_type::now() + amount
;
64 for(std::size_t n
= 0;;++n
)
66 test::fail_count
fc(n
);
69 stream
<test::stream
> ws(ioc
, fc
);
70 auto tr
= connect(ws
.next_layer());
74 catch(system_error
const& se
)
76 // VFALCO Commented this out after the short
77 // read change, because it converts test_failure
78 // into http::partial_message
80 boost::ignore_unused(se
);
83 se
.code() == test::error::test_failure
,
88 clock_type::now() < expires_at
,
89 "a test timeout occurred"))
102 fail_loop([&](stream
<test::stream
>& ws
)
104 ws
.next_layer().append(
106 "Host: localhost\r\n"
107 "Upgrade: websocket\r\n"
108 "Connection: upgrade\r\n"
109 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
110 "Sec-WebSocket-Version: 13\r\n"
112 ws
.next_layer().read_size(20);
116 // request in stream, decorator
117 fail_loop([&](stream
<test::stream
>& ws
)
119 ws
.next_layer().append(
121 "Host: localhost\r\n"
122 "Upgrade: websocket\r\n"
123 "Connection: upgrade\r\n"
124 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
125 "Sec-WebSocket-Version: 13\r\n"
127 ws
.next_layer().read_size(20);
129 ws
.set_option(stream_base::decorator(
130 res_decorator
{called
}));
132 BEAST_EXPECT(called
);
135 // request in buffers
136 fail_loop([&](stream
<test::stream
>& ws
)
140 "Host: localhost\r\n"
141 "Upgrade: websocket\r\n"
142 "Connection: upgrade\r\n"
143 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
144 "Sec-WebSocket-Version: 13\r\n"
149 // request in buffers, decorator
150 fail_loop([&](stream
<test::stream
>& ws
)
153 ws
.set_option(stream_base::decorator(
154 res_decorator
{called
}));
157 "Host: localhost\r\n"
158 "Upgrade: websocket\r\n"
159 "Connection: upgrade\r\n"
160 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
161 "Sec-WebSocket-Version: 13\r\n"
163 BEAST_EXPECT(called
);
166 // request in buffers and stream
167 fail_loop([&](stream
<test::stream
>& ws
)
169 ws
.next_layer().append(
170 "Connection: upgrade\r\n"
171 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
172 "Sec-WebSocket-Version: 13\r\n"
174 ws
.next_layer().read_size(16);
177 "Host: localhost\r\n"
178 "Upgrade: websocket\r\n"
180 // VFALCO validate contents of ws.next_layer().str?
183 // request in buffers and stream, decorator
184 fail_loop([&](stream
<test::stream
>& ws
)
186 ws
.next_layer().append(
187 "Connection: upgrade\r\n"
188 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
189 "Sec-WebSocket-Version: 13\r\n"
191 ws
.next_layer().read_size(16);
193 ws
.set_option(stream_base::decorator(
194 res_decorator
{called
}));
197 "Host: localhost\r\n"
198 "Upgrade: websocket\r\n"));
199 BEAST_EXPECT(called
);
202 // request in message
205 req
.method(http::verb::get
);
208 req
.insert(http::field::host
, "localhost");
209 req
.insert(http::field::upgrade
, "websocket");
210 req
.insert(http::field::connection
, "upgrade");
211 req
.insert(http::field::sec_websocket_key
, "dGhlIHNhbXBsZSBub25jZQ==");
212 req
.insert(http::field::sec_websocket_version
, "13");
214 fail_loop([&](stream
<test::stream
>& ws
)
220 // request in message, decorator
223 req
.method(http::verb::get
);
226 req
.insert(http::field::host
, "localhost");
227 req
.insert(http::field::upgrade
, "websocket");
228 req
.insert(http::field::connection
, "upgrade");
229 req
.insert(http::field::sec_websocket_key
, "dGhlIHNhbXBsZSBub25jZQ==");
230 req
.insert(http::field::sec_websocket_version
, "13");
232 fail_loop([&](stream
<test::stream
>& ws
)
235 ws
.set_option(stream_base::decorator(
236 res_decorator
{called
}));
238 BEAST_EXPECT(called
);
242 // request in message, close frame in stream
245 req
.method(http::verb::get
);
248 req
.insert(http::field::host
, "localhost");
249 req
.insert(http::field::upgrade
, "websocket");
250 req
.insert(http::field::connection
, "upgrade");
251 req
.insert(http::field::sec_websocket_key
, "dGhlIHNhbXBsZSBub25jZQ==");
252 req
.insert(http::field::sec_websocket_version
, "13");
254 fail_loop([&](stream
<test::stream
>& ws
)
256 ws
.next_layer().append("\x88\x82\xff\xff\xff\xff\xfc\x17");
262 fail("success", __FILE__
, __LINE__
);
264 catch(system_error
const& e
)
266 if(e
.code() != websocket::error::closed
)
272 // failed handshake (missing Sec-WebSocket-Key)
273 fail_loop([&](stream
<test::stream
>& ws
)
275 ws
.next_layer().append(
277 "Host: localhost\r\n"
278 "Upgrade: websocket\r\n"
279 "Connection: upgrade\r\n"
280 "Sec-WebSocket-Version: 13\r\n"
282 ws
.next_layer().read_size(20);
288 catch(system_error
const& e
)
290 if( e
.code() != websocket::error::no_sec_key
&&
291 e
.code() != net::error::eof
)
299 testOversized(Api
const& api
)
306 s
+= "X1: " + std::string(2000, '*') + "\r\n";
312 stream
<test::stream
> ws
{ioc
,
314 "Host: localhost\r\n"
315 "Upgrade: websocket\r\n"
316 "Connection: upgrade\r\n"
317 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
318 "Sec-WebSocket-Version: 13\r\n"
321 auto tr
= connect(ws
.next_layer());
327 catch(system_error
const& se
)
329 // VFALCO Its the http error category...
331 se
.code() == http::error::buffer_overflow
,
332 se
.code().message());
336 // request in stream, decorator
338 stream
<test::stream
> ws
{ioc
,
340 "Host: localhost\r\n"
341 "Upgrade: websocket\r\n"
342 "Connection: upgrade\r\n"
343 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
344 "Sec-WebSocket-Version: 13\r\n"
347 auto tr
= connect(ws
.next_layer());
351 ws
.set_option(stream_base::decorator(
352 res_decorator
{called
}));
356 catch(system_error
const& se
)
358 // VFALCO Its the http error category...
360 se
.code() == http::error::buffer_overflow
,
361 se
.code().message());
365 // request in buffers
367 stream
<test::stream
> ws
{ioc
};
368 auto tr
= connect(ws
.next_layer());
371 api
.accept(ws
, net::buffer(
373 "Host: localhost\r\n"
374 "Upgrade: websocket\r\n"
375 "Connection: upgrade\r\n"
376 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
377 "Sec-WebSocket-Version: 13\r\n"
383 catch(system_error
const& se
)
386 se
.code() == error::buffer_overflow
,
387 se
.code().message());
391 // request in buffers, decorator
393 stream
<test::stream
> ws
{ioc
};
394 auto tr
= connect(ws
.next_layer());
398 ws
.set_option(stream_base::decorator(
399 res_decorator
{called
}));
400 api
.accept(ws
, net::buffer(
402 "Host: localhost\r\n"
403 "Upgrade: websocket\r\n"
404 "Connection: upgrade\r\n"
405 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
406 "Sec-WebSocket-Version: 13\r\n"
411 catch(system_error
const& se
)
414 se
.code() == error::buffer_overflow
,
415 se
.code().message());
419 // request in buffers and stream
421 stream
<test::stream
> ws
{ioc
,
422 "Connection: upgrade\r\n"
423 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
424 "Sec-WebSocket-Version: 13\r\n"
427 auto tr
= connect(ws
.next_layer());
430 api
.accept(ws
, websocket_test_suite::sbuf(
432 "Host: localhost\r\n"
433 "Upgrade: websocket\r\n"
437 catch(system_error
const& se
)
440 se
.code() == http::error::buffer_overflow
,
441 se
.code().message());
445 // request in buffers and stream, decorator
447 stream
<test::stream
> ws
{ioc
,
448 "Connection: upgrade\r\n"
449 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
450 "Sec-WebSocket-Version: 13\r\n"
453 auto tr
= connect(ws
.next_layer());
457 ws
.set_option(stream_base::decorator(
458 res_decorator
{called
}));
459 api
.accept(ws
, websocket_test_suite::sbuf(
461 "Host: localhost\r\n"
462 "Upgrade: websocket\r\n"));
465 catch(system_error
const& se
)
468 se
.code() == http::error::buffer_overflow
,
469 se
.code().message());
480 [&](error_code ev
, string_view s
)
482 for(int i
= 0; i
< 3; ++i
)
498 stream
<test::stream
> ws(ioc
);
499 auto tr
= connect(ws
.next_layer());
500 ws
.next_layer().append(
501 s
.substr(n
, s
.size() - n
));
505 ws
.accept(net::buffer(s
.data(), n
));
506 BEAST_EXPECTS(! ev
, ev
.message());
508 catch(system_error
const& se
)
510 BEAST_EXPECTS(se
.code() == ev
, se
.what());
516 check(error::bad_http_version
,
518 "Host: localhost:80\r\n"
519 "Upgrade: WebSocket\r\n"
520 "Connection: keep-alive,upgrade\r\n"
521 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
522 "Sec-WebSocket-Version: 13\r\n"
527 check(error::bad_method
,
528 "POST / HTTP/1.1\r\n"
529 "Host: localhost:80\r\n"
530 "Upgrade: WebSocket\r\n"
531 "Connection: keep-alive,upgrade\r\n"
532 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
533 "Sec-WebSocket-Version: 13\r\n"
538 check(error::no_host
,
540 "Upgrade: WebSocket\r\n"
541 "Connection: keep-alive,upgrade\r\n"
542 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
543 "Sec-WebSocket-Version: 13\r\n"
548 check(error::no_connection
,
550 "Host: localhost:80\r\n"
551 "Upgrade: WebSocket\r\n"
552 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
553 "Sec-WebSocket-Version: 13\r\n"
557 // no Connection upgrade
558 check(error::no_connection_upgrade
,
560 "Host: localhost:80\r\n"
561 "Upgrade: WebSocket\r\n"
562 "Connection: keep-alive\r\n"
563 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
564 "Sec-WebSocket-Version: 13\r\n"
569 check(error::no_upgrade
,
571 "Host: localhost:80\r\n"
572 "Connection: upgrade\r\n"
573 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
574 "Sec-WebSocket-Version: 13\r\n"
578 // no Upgrade websocket
579 check(error::no_upgrade_websocket
,
581 "Host: localhost:80\r\n"
582 "Upgrade: HTTP/2\r\n"
583 "Connection: upgrade\r\n"
584 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
585 "Sec-WebSocket-Version: 13\r\n"
589 // no Sec-WebSocket-Key
590 check(error::no_sec_key
,
592 "Host: localhost:80\r\n"
593 "Upgrade: WebSocket\r\n"
594 "Connection: keep-alive,upgrade\r\n"
595 "Sec-WebSocket-Version: 13\r\n"
599 // bad Sec-WebSocket-Key
600 check(error::bad_sec_key
,
602 "Host: localhost:80\r\n"
603 "Upgrade: WebSocket\r\n"
604 "Connection: upgrade\r\n"
605 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQdGhlIHNhbXBsZSBub25jZQ==\r\n"
606 "Sec-WebSocket-Version: 13\r\n"
610 // no Sec-WebSocket-Version
611 check(error::no_sec_version
,
613 "Host: localhost:80\r\n"
614 "Upgrade: WebSocket\r\n"
615 "Connection: keep-alive,upgrade\r\n"
616 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
620 // bad Sec-WebSocket-Version
621 check(error::bad_sec_version
,
623 "Host: localhost:80\r\n"
624 "Upgrade: WebSocket\r\n"
625 "Connection: keep-alive,upgrade\r\n"
626 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
627 "Sec-WebSocket-Version: 1\r\n"
631 // bad Sec-WebSocket-Version
632 check(error::bad_sec_version
,
634 "Host: localhost:80\r\n"
635 "Upgrade: WebSocket\r\n"
636 "Connection: upgrade\r\n"
637 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
638 "Sec-WebSocket-Version: 12\r\n"
645 "Host: localhost:80\r\n"
646 "Upgrade: WebSocket\r\n"
647 "Connection: upgrade\r\n"
648 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
649 "Sec-WebSocket-Version: 13\r\n"
659 stream
<test::stream
> ws(ioc
);
660 auto tr
= connect(ws
.next_layer());
665 api
.accept(ws
, net::const_buffer
{});
668 catch(system_error
const& se
)
671 se
.code() == error::closed
,
672 se
.code().message());
676 stream
<test::stream
> ws(ioc
);
677 auto tr
= connect(ws
.next_layer());
682 api
.accept(ws
, net::const_buffer
{});
685 catch(system_error
const& se
)
688 se
.code() == error::closed
,
689 se
.code().message());
697 using tcp
= net::ip::tcp
;
701 // success, no timeout
704 stream
<tcp::socket
> ws1(ioc
);
705 stream
<tcp::socket
> ws2(ioc
);
706 test::connect(ws1
.next_layer(), ws2
.next_layer());
708 ws1
.async_handshake("test", "/", test::success_handler());
709 ws2
.async_accept(test::success_handler());
710 test::run_for(ioc
, std::chrono::seconds(1));
714 stream
<test::stream
> ws1(ioc
);
715 stream
<test::stream
> ws2(ioc
);
716 test::connect(ws1
.next_layer(), ws2
.next_layer());
718 ws1
.async_handshake("test", "/", test::success_handler());
719 ws2
.async_accept(test::success_handler());
720 test::run_for(ioc
, std::chrono::seconds(1));
723 // success, timeout enabled
726 stream
<tcp::socket
> ws1(ioc
);
727 stream
<tcp::socket
> ws2(ioc
);
728 test::connect(ws1
.next_layer(), ws2
.next_layer());
730 ws1
.set_option(stream_base::timeout
{
731 std::chrono::milliseconds(50),
734 ws1
.async_accept(test::success_handler());
735 ws2
.async_handshake("test", "/", test::success_handler());
736 test::run_for(ioc
, std::chrono::seconds(1));
740 stream
<test::stream
> ws1(ioc
);
741 stream
<test::stream
> ws2(ioc
);
742 test::connect(ws1
.next_layer(), ws2
.next_layer());
744 ws1
.set_option(stream_base::timeout
{
745 std::chrono::milliseconds(50),
748 ws1
.async_accept(test::success_handler());
749 ws2
.async_handshake("test", "/", test::success_handler());
750 test::run_for(ioc
, std::chrono::seconds(1));
756 stream
<tcp::socket
> ws1(ioc
);
757 stream
<tcp::socket
> ws2(ioc
);
758 test::connect(ws1
.next_layer(), ws2
.next_layer());
760 ws1
.set_option(stream_base::timeout
{
761 std::chrono::milliseconds(50),
764 ws1
.async_accept(test::fail_handler(beast::error::timeout
));
765 test::run_for(ioc
, std::chrono::seconds(1));
769 stream
<test::stream
> ws1(ioc
);
770 stream
<test::stream
> ws2(ioc
);
771 test::connect(ws1
.next_layer(), ws2
.next_layer());
773 ws1
.set_option(stream_base::timeout
{
774 std::chrono::milliseconds(50),
777 ws1
.async_accept(test::fail_handler(beast::error::timeout
));
778 test::run_for(ioc
, std::chrono::seconds(1));
781 // abandoned operation
785 stream
<tcp::socket
> ws1(ioc
);
786 ws1
.async_accept(test::fail_handler(
787 net::error::operation_aborted
));
794 stream
<tcp::socket
> ws1(ioc
);
797 "Host: localhost\r\n"
798 "Upgrade: websocket\r\n"
799 "Connection: upgrade\r\n"
800 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
801 "Sec-WebSocket-Version: 13\r\n"
804 http::request_parser
<http::empty_body
> p
;
805 p
.put(net::const_buffer(s
.data(), s
.size()), ec
);
806 ws1
.async_accept(p
.get(), test::fail_handler(
807 net::error::operation_aborted
));
816 testMatrix(test_sync_api
{});
817 testMatrix(test_async_api
{});
818 testOversized(test_sync_api
{});
819 testOversized(test_async_api
{});
826 BEAST_DEFINE_TESTSUITE(beast
,websocket
,accept
);