2017-08-24 06:21:30 -07:00
|
|
|
//
|
|
|
|
|
// Copyright (w) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
|
|
|
//
|
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
//
|
|
|
|
|
// Official repository: https://github.com/boostorg/beast
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Test that header file is self-contained.
|
|
|
|
|
#include <boost/beast/websocket/stream.hpp>
|
|
|
|
|
|
|
|
|
|
#include "test.hpp"
|
|
|
|
|
|
2018-11-22 20:49:30 -08:00
|
|
|
#include <boost/asio/io_context.hpp>
|
2018-03-01 06:36:18 -08:00
|
|
|
#include <boost/asio/strand.hpp>
|
|
|
|
|
|
2017-08-24 06:21:30 -07:00
|
|
|
namespace boost {
|
|
|
|
|
namespace beast {
|
|
|
|
|
namespace websocket {
|
|
|
|
|
|
2017-08-26 06:13:11 -07:00
|
|
|
class accept_test : public websocket_test_suite
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
template<class Wrap>
|
|
|
|
|
void
|
|
|
|
|
doTestAccept(Wrap const& w)
|
|
|
|
|
{
|
|
|
|
|
class res_decorator
|
|
|
|
|
{
|
|
|
|
|
bool& b_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
res_decorator(res_decorator const&) = default;
|
|
|
|
|
|
|
|
|
|
explicit
|
|
|
|
|
res_decorator(bool& b)
|
|
|
|
|
: b_(b)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
operator()(response_type&) const
|
|
|
|
|
{
|
2017-10-21 17:39:24 -07:00
|
|
|
this->b_ = true;
|
2017-08-24 06:21:30 -07:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
auto const big = []
|
|
|
|
|
{
|
|
|
|
|
std::string s;
|
|
|
|
|
s += "X1: " + std::string(2000, '*') + "\r\n";
|
|
|
|
|
return s;
|
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
|
// request in stream
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
ts.append(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n");
|
|
|
|
|
ts.read_size(20);
|
|
|
|
|
w.accept(ws);
|
|
|
|
|
// VFALCO validate contents of ws.next_layer().str?
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in stream, oversized
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
+ big +
|
|
|
|
|
"\r\n"};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
w.accept(ws);
|
|
|
|
|
fail("", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
// VFALCO Its the http error category...
|
|
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
se.code() == http::error::buffer_overflow,
|
|
|
|
|
se.code().message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// request in stream, decorator
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
ts.append(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n");
|
|
|
|
|
ts.read_size(20);
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in stream, decorator, oversized
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
+ big +
|
|
|
|
|
"\r\n"};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, res_decorator{called});
|
|
|
|
|
fail("", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
// VFALCO Its the http error category...
|
|
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
se.code() == http::error::buffer_overflow,
|
|
|
|
|
se.code().message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// request in buffers
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
w.accept(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in buffers, oversize
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_};
|
2017-08-24 06:21:30 -07:00
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
w.accept(ws, boost::asio::buffer(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
+ big +
|
|
|
|
|
"\r\n"
|
|
|
|
|
));
|
|
|
|
|
fail("", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
se.code() == error::buffer_overflow,
|
|
|
|
|
se.code().message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// request in buffers, decorator
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"),
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in buffers, decorator, oversized
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_};
|
2017-08-24 06:21:30 -07:00
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, boost::asio::buffer(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
+ big +
|
|
|
|
|
"\r\n"),
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
fail("", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
se.code() == error::buffer_overflow,
|
|
|
|
|
se.code().message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// request in buffers and stream
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
ts.append(
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n");
|
|
|
|
|
ts.read_size(16);
|
|
|
|
|
w.accept(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
));
|
|
|
|
|
// VFALCO validate contents of ws.next_layer().str?
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in buffers and stream, oversized
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_,
|
2017-08-24 06:21:30 -07:00
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
+ big +
|
|
|
|
|
"\r\n"};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
w.accept(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
));
|
|
|
|
|
fail("", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
se.code() == http::error::buffer_overflow,
|
|
|
|
|
se.code().message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// request in buffers and stream, decorator
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
ts.append(
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n");
|
|
|
|
|
ts.read_size(16);
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"),
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in buffers and stream, decorator, oversize
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_,
|
2017-08-24 06:21:30 -07:00
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
+ big +
|
|
|
|
|
"\r\n"};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"),
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
fail("", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
se.code() == http::error::buffer_overflow,
|
|
|
|
|
se.code().message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// request in message
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
request_type req;
|
|
|
|
|
req.method(http::verb::get);
|
|
|
|
|
req.target("/");
|
2017-09-12 13:49:45 -07:00
|
|
|
req.version(11);
|
2017-08-24 06:21:30 -07:00
|
|
|
req.insert(http::field::host, "localhost");
|
|
|
|
|
req.insert(http::field::upgrade, "websocket");
|
|
|
|
|
req.insert(http::field::connection, "upgrade");
|
|
|
|
|
req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert(http::field::sec_websocket_version, "13");
|
|
|
|
|
w.accept(ws, req);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in message, decorator
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
request_type req;
|
|
|
|
|
req.method(http::verb::get);
|
|
|
|
|
req.target("/");
|
2017-09-12 13:49:45 -07:00
|
|
|
req.version(11);
|
2017-08-24 06:21:30 -07:00
|
|
|
req.insert(http::field::host, "localhost");
|
|
|
|
|
req.insert(http::field::upgrade, "websocket");
|
|
|
|
|
req.insert(http::field::connection, "upgrade");
|
|
|
|
|
req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert(http::field::sec_websocket_version, "13");
|
|
|
|
|
bool called = false;
|
|
|
|
|
w.accept_ex(ws, req,
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request in message, close frame in stream
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
request_type req;
|
|
|
|
|
req.method(http::verb::get);
|
|
|
|
|
req.target("/");
|
2017-09-12 13:49:45 -07:00
|
|
|
req.version(11);
|
2017-08-24 06:21:30 -07:00
|
|
|
req.insert(http::field::host, "localhost");
|
|
|
|
|
req.insert(http::field::upgrade, "websocket");
|
|
|
|
|
req.insert(http::field::connection, "upgrade");
|
|
|
|
|
req.insert(http::field::sec_websocket_key, "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert(http::field::sec_websocket_version, "13");
|
|
|
|
|
ts.append("\x88\x82\xff\xff\xff\xff\xfc\x17");
|
|
|
|
|
w.accept(ws, req);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
static_buffer<1> b;
|
|
|
|
|
w.read(ws, b);
|
|
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if(e.code() != websocket::error::closed)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// failed handshake (missing Sec-WebSocket-Key)
|
2017-08-26 20:10:04 -07:00
|
|
|
doStreamLoop([&](test::stream& ts)
|
2017-08-24 06:21:30 -07:00
|
|
|
{
|
|
|
|
|
stream<test::stream&> ws{ts};
|
|
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
ts.append(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n");
|
|
|
|
|
ts.read_size(20);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
w.accept(ws);
|
|
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if( e.code() !=
|
2018-01-01 17:49:19 -08:00
|
|
|
websocket::error::no_sec_key &&
|
2017-08-24 06:21:30 -07:00
|
|
|
e.code() !=
|
|
|
|
|
boost::asio::error::eof)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Closed by client
|
|
|
|
|
{
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_};
|
2017-08-24 06:21:30 -07:00
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
tr.close();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
w.accept(ws);
|
|
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if(! BEAST_EXPECTS(
|
|
|
|
|
e.code() == error::closed,
|
|
|
|
|
e.code().message()))
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
testAccept()
|
|
|
|
|
{
|
|
|
|
|
doTestAccept(SyncClient{});
|
|
|
|
|
|
|
|
|
|
yield_to([&](yield_context yield)
|
|
|
|
|
{
|
|
|
|
|
doTestAccept(AsyncClient{yield});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Bad requests
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
auto const check =
|
|
|
|
|
[&](error_code const& ev, std::string const& s)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < 3; ++i)
|
|
|
|
|
{
|
|
|
|
|
std::size_t n;
|
|
|
|
|
switch(i)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case 0:
|
|
|
|
|
n = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
n = s.size() / 2;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
n = s.size() - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-09-07 07:39:52 -07:00
|
|
|
stream<test::stream> ws{ioc_};
|
2017-08-24 06:21:30 -07:00
|
|
|
auto tr = connect(ws.next_layer());
|
|
|
|
|
ws.next_layer().append(
|
|
|
|
|
s.substr(n, s.size() - n));
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ws.accept(
|
|
|
|
|
boost::asio::buffer(s.data(), n));
|
|
|
|
|
BEAST_EXPECTS(! ev, ev.message());
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
|
|
|
|
BEAST_EXPECTS(se.code() == ev, se.what());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-01-01 17:49:19 -08:00
|
|
|
// bad version
|
|
|
|
|
check(error::bad_http_version,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.0\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// bad method
|
|
|
|
|
check(error::bad_method,
|
2017-08-24 06:21:30 -07:00
|
|
|
"POST / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Host
|
|
|
|
|
check(error::no_host,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Connection
|
|
|
|
|
check(error::no_connection,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
2017-08-24 06:21:30 -07:00
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Connection upgrade
|
|
|
|
|
check(error::no_connection_upgrade,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Connection: keep-alive\r\n"
|
2017-08-24 06:21:30 -07:00
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
2017-08-24 06:21:30 -07:00
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Upgrade
|
|
|
|
|
check(error::no_upgrade,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Connection: upgrade\r\n"
|
2017-08-24 06:21:30 -07:00
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
2017-08-24 06:21:30 -07:00
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Upgrade websocket
|
|
|
|
|
check(error::no_upgrade_websocket,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: HTTP/2\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Sec-WebSocket-Key
|
|
|
|
|
check(error::no_sec_key,
|
2017-08-24 06:21:30 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
2017-08-24 06:21:30 -07:00
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// bad Sec-WebSocket-Key
|
|
|
|
|
check(error::bad_sec_key,
|
2017-08-31 17:52:09 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQdGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// no Sec-WebSocket-Version
|
|
|
|
|
check(error::no_sec_version,
|
2017-08-31 17:52:09 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
2017-08-31 17:52:09 -07:00
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2018-01-01 17:49:19 -08:00
|
|
|
// bad Sec-WebSocket-Version
|
|
|
|
|
check(error::bad_sec_version,
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 1\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// bad Sec-WebSocket-Version
|
|
|
|
|
check(error::bad_sec_version,
|
2017-08-31 17:52:09 -07:00
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
2018-01-01 17:49:19 -08:00
|
|
|
"Sec-WebSocket-Version: 12\r\n"
|
2017-08-31 17:52:09 -07:00
|
|
|
"\r\n"
|
|
|
|
|
);
|
2017-08-24 06:21:30 -07:00
|
|
|
// valid request
|
|
|
|
|
check({},
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-28 13:36:47 -08:00
|
|
|
void
|
|
|
|
|
testMoveOnly()
|
|
|
|
|
{
|
|
|
|
|
boost::asio::io_context ioc;
|
|
|
|
|
stream<test::stream> ws{ioc};
|
|
|
|
|
ws.async_accept(move_only_handler{});
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-01 06:36:18 -08:00
|
|
|
struct copyable_handler
|
|
|
|
|
{
|
|
|
|
|
template<class... Args>
|
|
|
|
|
void
|
|
|
|
|
operator()(Args&&...) const
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
testAsioHandlerInvoke()
|
|
|
|
|
{
|
|
|
|
|
// make sure things compile, also can set a
|
|
|
|
|
// breakpoint in asio_handler_invoke to make sure
|
|
|
|
|
// it is instantiated.
|
|
|
|
|
boost::asio::io_context ioc;
|
2018-11-22 20:49:30 -08:00
|
|
|
boost::asio::strand<
|
|
|
|
|
boost::asio::io_context::executor_type> s(
|
|
|
|
|
ioc.get_executor());
|
2018-03-01 06:36:18 -08:00
|
|
|
stream<test::stream> ws{ioc};
|
2018-11-22 20:49:30 -08:00
|
|
|
ws.async_accept(boost::asio::bind_executor(
|
|
|
|
|
s, copyable_handler{}));
|
2018-03-01 06:36:18 -08:00
|
|
|
}
|
|
|
|
|
|
2017-08-24 06:21:30 -07:00
|
|
|
void
|
|
|
|
|
run() override
|
|
|
|
|
{
|
|
|
|
|
testAccept();
|
2018-02-28 13:36:47 -08:00
|
|
|
testMoveOnly();
|
2018-03-01 06:36:18 -08:00
|
|
|
testAsioHandlerInvoke();
|
2017-08-24 06:21:30 -07:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-08-26 06:13:11 -07:00
|
|
|
BEAST_DEFINE_TESTSUITE(beast,websocket,accept);
|
2017-08-24 06:21:30 -07:00
|
|
|
|
|
|
|
|
} // websocket
|
|
|
|
|
} // beast
|
|
|
|
|
} // boost
|