2016-04-30 13:00:33 -04:00
|
|
|
//
|
2017-02-06 20:07:03 -05:00
|
|
|
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
2016-04-30 13:00:33 -04:00
|
|
|
//
|
|
|
|
|
// 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)
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
// Test that header file is self-contained.
|
|
|
|
|
#include <beast/websocket/stream.hpp>
|
|
|
|
|
|
2016-08-26 09:11:06 -04:00
|
|
|
#include "websocket_async_echo_server.hpp"
|
|
|
|
|
#include "websocket_sync_echo_server.hpp"
|
2016-04-30 13:00:33 -04:00
|
|
|
|
2017-05-04 05:01:50 -07:00
|
|
|
#include <beast/core/ostream.hpp>
|
2017-05-04 15:40:07 -07:00
|
|
|
#include <beast/core/multi_buffer.hpp>
|
2016-05-07 07:08:21 -04:00
|
|
|
#include <beast/test/fail_stream.hpp>
|
2017-01-09 11:13:19 -05:00
|
|
|
#include <beast/test/string_istream.hpp>
|
2017-04-25 10:12:43 -07:00
|
|
|
#include <beast/test/string_iostream.hpp>
|
|
|
|
|
#include <beast/test/string_ostream.hpp>
|
2016-05-07 07:08:21 -04:00
|
|
|
#include <beast/test/yield_to.hpp>
|
2016-05-06 19:14:17 -04:00
|
|
|
#include <beast/unit_test/suite.hpp>
|
2016-04-30 13:00:33 -04:00
|
|
|
#include <boost/asio.hpp>
|
|
|
|
|
#include <boost/asio/spawn.hpp>
|
|
|
|
|
#include <boost/optional.hpp>
|
2016-05-15 16:22:25 -04:00
|
|
|
#include <mutex>
|
|
|
|
|
#include <condition_variable>
|
2016-04-30 13:00:33 -04:00
|
|
|
|
|
|
|
|
namespace beast {
|
|
|
|
|
namespace websocket {
|
|
|
|
|
|
2016-05-04 17:27:50 -04:00
|
|
|
class stream_test
|
2016-05-06 19:14:17 -04:00
|
|
|
: public beast::unit_test::suite
|
2016-05-04 17:27:50 -04:00
|
|
|
, public test::enable_yield_to
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
|
|
|
|
public:
|
2016-05-15 16:22:25 -04:00
|
|
|
using self = stream_test;
|
2016-04-30 13:00:33 -04:00
|
|
|
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
|
|
|
|
using address_type = boost::asio::ip::address;
|
|
|
|
|
using socket_type = boost::asio::ip::tcp::socket;
|
|
|
|
|
|
2017-05-04 05:01:50 -07:00
|
|
|
template<class ConstBufferSequence>
|
|
|
|
|
static
|
|
|
|
|
std::string
|
|
|
|
|
to_string(ConstBufferSequence const& bs)
|
|
|
|
|
{
|
|
|
|
|
return boost::lexical_cast<
|
|
|
|
|
std::string>(buffers(bs));
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
struct con
|
2016-05-07 17:06:46 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
stream<socket_type> ws;
|
2016-05-07 17:06:46 -04:00
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
con(endpoint_type const& ep, boost::asio::io_service& ios)
|
|
|
|
|
: ws(ios)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.next_layer().connect(ep);
|
|
|
|
|
ws.handshake("localhost", "/");
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<std::size_t N>
|
|
|
|
|
class cbuf_helper
|
|
|
|
|
{
|
|
|
|
|
std::array<std::uint8_t, N> v_;
|
|
|
|
|
boost::asio::const_buffer cb_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
using value_type = decltype(cb_);
|
|
|
|
|
using const_iterator = value_type const*;
|
|
|
|
|
|
|
|
|
|
template<class... Vn>
|
|
|
|
|
explicit
|
|
|
|
|
cbuf_helper(Vn... vn)
|
|
|
|
|
: v_({{ static_cast<std::uint8_t>(vn)... }})
|
|
|
|
|
, cb_(v_.data(), v_.size())
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
const_iterator
|
|
|
|
|
begin() const
|
2016-05-04 17:27:50 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
return &cb_;
|
2016-05-04 17:27:50 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
const_iterator
|
|
|
|
|
end() const
|
2016-05-04 17:27:50 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
return begin()+1;
|
2016-05-04 17:27:50 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class... Vn>
|
|
|
|
|
cbuf_helper<sizeof...(Vn)>
|
|
|
|
|
cbuf(Vn... vn)
|
|
|
|
|
{
|
|
|
|
|
return cbuf_helper<sizeof...(Vn)>(vn...);
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<std::size_t N>
|
|
|
|
|
static
|
|
|
|
|
boost::asio::const_buffers_1
|
2016-05-15 16:22:25 -04:00
|
|
|
sbuf(const char (&s)[N])
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
|
|
|
|
return boost::asio::const_buffers_1(&s[0], N-1);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
template<class Pred>
|
|
|
|
|
static
|
|
|
|
|
bool
|
|
|
|
|
run_until(boost::asio::io_service& ios,
|
|
|
|
|
std::size_t limit, Pred&& pred)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
for(std::size_t i = 0; i < limit; ++i)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
if(pred())
|
|
|
|
|
return true;
|
|
|
|
|
ios.run_one();
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-25 10:12:43 -07:00
|
|
|
struct SyncClient
|
|
|
|
|
{
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
accept(stream<NextLayer>& ws) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Buffers>
|
2017-05-08 12:41:45 -07:00
|
|
|
typename std::enable_if<
|
|
|
|
|
! http::detail::is_header<Buffers>::value>::type
|
2017-04-25 10:12:43 -07:00
|
|
|
accept(stream<NextLayer>& ws,
|
|
|
|
|
Buffers const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept(buffers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Fields>
|
|
|
|
|
void
|
|
|
|
|
accept(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept(req);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Fields, class Buffers>
|
|
|
|
|
void
|
|
|
|
|
accept(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req,
|
|
|
|
|
Buffers const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept(req, buffers);
|
|
|
|
|
}
|
|
|
|
|
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
template<class NextLayer, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept_ex(d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Buffers, class Decorator>
|
2017-05-08 12:41:45 -07:00
|
|
|
typename std::enable_if<
|
|
|
|
|
! http::detail::is_header<Buffers>::value>::type
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
Buffers const& buffers,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept_ex(buffers, d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Fields, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept_ex(req, d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Fields, class Buffers,
|
|
|
|
|
class Decorator>
|
|
|
|
|
void
|
|
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req,
|
|
|
|
|
Buffers const& buffers,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
ws.accept_ex(req, buffers, d);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-25 10:12:43 -07:00
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
handshake(stream<NextLayer>& ws,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path) const
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
|
|
|
|
ws.handshake(uri, path);
|
|
|
|
|
}
|
|
|
|
|
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
handshake(stream<NextLayer>& ws,
|
|
|
|
|
response_type& res,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path) const
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
ws.handshake(res, uri, path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
handshake_ex(stream<NextLayer>& ws,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
ws.handshake_ex(uri, path, d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
handshake_ex(stream<NextLayer>& ws,
|
|
|
|
|
response_type& res,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
ws.handshake_ex(res, uri, path, d);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-25 10:12:43 -07:00
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
ping(stream<NextLayer>& ws,
|
|
|
|
|
ping_data const& payload) const
|
|
|
|
|
{
|
|
|
|
|
ws.ping(payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
pong(stream<NextLayer>& ws,
|
|
|
|
|
ping_data const& payload) const
|
|
|
|
|
{
|
|
|
|
|
ws.pong(payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
close(stream<NextLayer>& ws,
|
|
|
|
|
close_reason const& cr) const
|
|
|
|
|
{
|
|
|
|
|
ws.close(cr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class DynamicBuffer>
|
|
|
|
|
void
|
|
|
|
|
read(stream<NextLayer>& ws,
|
2017-06-08 19:55:42 -07:00
|
|
|
DynamicBuffer& buffer) const
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.read(buffer);
|
2017-04-25 10:12:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
write(stream<NextLayer>& ws,
|
|
|
|
|
ConstBufferSequence const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
ws.write(buffers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
write_frame(stream<NextLayer>& ws, bool fin,
|
|
|
|
|
ConstBufferSequence const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
ws.write_frame(fin, buffers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
write_raw(stream<NextLayer>& ws,
|
|
|
|
|
ConstBufferSequence const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
boost::asio::write(
|
|
|
|
|
ws.next_layer(), buffers);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class AsyncClient
|
|
|
|
|
{
|
|
|
|
|
yield_context& yield_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit
|
|
|
|
|
AsyncClient(yield_context& yield)
|
|
|
|
|
: yield_(yield)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
accept(stream<NextLayer>& ws) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept(yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Buffers>
|
2017-05-08 12:41:45 -07:00
|
|
|
typename std::enable_if<
|
|
|
|
|
! http::detail::is_header<Buffers>::value>::type
|
2017-04-25 10:12:43 -07:00
|
|
|
accept(stream<NextLayer>& ws,
|
|
|
|
|
Buffers const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept(buffers, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Fields>
|
|
|
|
|
void
|
|
|
|
|
accept(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept(req, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Fields, class Buffers>
|
|
|
|
|
void
|
|
|
|
|
accept(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req,
|
|
|
|
|
Buffers const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept(req, buffers, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
class Decorator>
|
2017-04-25 10:12:43 -07:00
|
|
|
void
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept_ex(d, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Buffers, class Decorator>
|
2017-05-08 12:41:45 -07:00
|
|
|
typename std::enable_if<
|
|
|
|
|
! http::detail::is_header<Buffers>::value>::type
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
Buffers const& buffers,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept_ex(buffers, d, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer,
|
|
|
|
|
class Fields, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
accept_ex(stream<NextLayer>& ws,
|
|
|
|
|
http::header<true, Fields> const& req,
|
|
|
|
|
Decorator const& d) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept_ex(req, d, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Fields,
|
|
|
|
|
class Buffers, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
accept_ex(stream<NextLayer>& ws,
|
2017-04-25 10:12:43 -07:00
|
|
|
http::header<true, Fields> const& req,
|
|
|
|
|
Buffers const& buffers,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
Decorator const& d) const
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
error_code ec;
|
|
|
|
|
ws.async_accept_ex(
|
|
|
|
|
req, buffers, d, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
2017-04-25 10:12:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
handshake(stream<NextLayer>& ws,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path) const
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
|
|
|
|
error_code ec;
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
ws.async_handshake(
|
|
|
|
|
uri, path, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
handshake(stream<NextLayer>& ws,
|
|
|
|
|
response_type& res,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path) const
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_handshake(
|
|
|
|
|
res, uri, path, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
handshake_ex(stream<NextLayer>& ws,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
Decorator const &d) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_handshake_ex(
|
|
|
|
|
uri, path, d, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer, class Decorator>
|
|
|
|
|
void
|
|
|
|
|
handshake_ex(stream<NextLayer>& ws,
|
|
|
|
|
response_type& res,
|
2017-06-04 10:52:28 -07:00
|
|
|
string_view uri,
|
|
|
|
|
string_view path,
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
Decorator const &d) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_handshake_ex(
|
|
|
|
|
res, uri, path, d, yield_[ec]);
|
2017-04-25 10:12:43 -07:00
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
ping(stream<NextLayer>& ws,
|
|
|
|
|
ping_data const& payload) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_ping(payload, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
pong(stream<NextLayer>& ws,
|
|
|
|
|
ping_data const& payload) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_pong(payload, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class NextLayer>
|
|
|
|
|
void
|
|
|
|
|
close(stream<NextLayer>& ws,
|
|
|
|
|
close_reason const& cr) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_close(cr, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class DynamicBuffer>
|
|
|
|
|
void
|
|
|
|
|
read(stream<NextLayer>& ws,
|
2017-06-08 19:55:42 -07:00
|
|
|
DynamicBuffer& buffer) const
|
2017-04-25 10:12:43 -07:00
|
|
|
{
|
|
|
|
|
error_code ec;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(buffer, yield_[ec]);
|
2017-04-25 10:12:43 -07:00
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
write(stream<NextLayer>& ws,
|
|
|
|
|
ConstBufferSequence const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_write(buffers, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
write_frame(stream<NextLayer>& ws, bool fin,
|
|
|
|
|
ConstBufferSequence const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.async_write_frame(fin, buffers, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<
|
|
|
|
|
class NextLayer, class ConstBufferSequence>
|
|
|
|
|
void
|
|
|
|
|
write_raw(stream<NextLayer>& ws,
|
|
|
|
|
ConstBufferSequence const& buffers) const
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
boost::asio::async_write(
|
|
|
|
|
ws.next_layer(), buffers, yield_[ec]);
|
|
|
|
|
if(ec)
|
|
|
|
|
throw system_error{ec};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-12 18:49:18 -07:00
|
|
|
void
|
|
|
|
|
testOptions()
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
stream<socket_type> ws(ios_);
|
2017-06-08 17:36:31 -07:00
|
|
|
ws.auto_fragment(true);
|
2017-06-08 18:27:32 -07:00
|
|
|
ws.write_buffer_size(2048);
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(false);
|
2017-06-08 18:12:27 -07:00
|
|
|
ws.read_buffer_size(8192);
|
2017-06-08 18:22:25 -07:00
|
|
|
ws.read_message_max(1 * 1024 * 1024);
|
2016-05-15 16:22:25 -04:00
|
|
|
try
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2017-06-08 18:27:32 -07:00
|
|
|
ws.write_buffer_size(7);
|
2016-05-15 16:22:25 -04:00
|
|
|
fail();
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
catch(std::exception const&)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
pass();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
class res_decorator
|
|
|
|
|
{
|
|
|
|
|
bool& b_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
res_decorator(res_decorator const&) = default;
|
|
|
|
|
|
|
|
|
|
explicit
|
|
|
|
|
res_decorator(bool& b)
|
|
|
|
|
: b_(b)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
operator()(response_type&) const
|
|
|
|
|
{
|
|
|
|
|
b_ = true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-04-25 10:12:43 -07:00
|
|
|
template<class Client>
|
|
|
|
|
void
|
|
|
|
|
testAccept(Client const& c)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
static std::size_t constexpr limit = 200;
|
|
|
|
|
std::size_t n;
|
|
|
|
|
for(n = 0; n < limit; ++n)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
test::fail_counter fc{n};
|
|
|
|
|
try
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
// request in stream
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"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"
|
|
|
|
|
, 20};
|
|
|
|
|
c.accept(ws);
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
// VFALCO validate contents of ws.next_layer().str?
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"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"
|
|
|
|
|
, 20};
|
|
|
|
|
bool called = false;
|
|
|
|
|
c.accept_ex(ws, res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
// request in buffers
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_ostream>> ws{fc, ios_};
|
|
|
|
|
c.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"
|
|
|
|
|
));
|
|
|
|
|
}
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_ostream>> ws{fc, ios_};
|
|
|
|
|
bool called = false;
|
|
|
|
|
c.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);
|
|
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
// request in buffers and stream
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
, 16};
|
|
|
|
|
c.accept(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"
|
|
|
|
|
));
|
|
|
|
|
}
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
, 16};
|
|
|
|
|
bool called = false;
|
|
|
|
|
c.accept_ex(ws, sbuf(
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost\r\n"
|
|
|
|
|
"Upgrade: websocket\r\n"),
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
// request in message
|
|
|
|
|
{
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
request_type req;
|
2017-05-30 06:58:40 -07:00
|
|
|
req.method(http::verb::get);
|
2017-05-02 15:49:22 -07:00
|
|
|
req.target("/");
|
2017-04-25 10:12:43 -07:00
|
|
|
req.version = 11;
|
2017-06-05 19:28:17 -07:00
|
|
|
req.insert("Host", "localhost");
|
|
|
|
|
req.insert("Upgrade", "websocket");
|
|
|
|
|
req.insert("Connection", "upgrade");
|
|
|
|
|
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert("Sec-WebSocket-Version", "13");
|
2017-04-25 10:12:43 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_ostream>> ws{fc, ios_};
|
|
|
|
|
c.accept(ws, req);
|
|
|
|
|
}
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
request_type req;
|
2017-05-30 06:58:40 -07:00
|
|
|
req.method(http::verb::get);
|
2017-05-02 15:49:22 -07:00
|
|
|
req.target("/");
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
req.version = 11;
|
2017-06-05 19:28:17 -07:00
|
|
|
req.insert("Host", "localhost");
|
|
|
|
|
req.insert("Upgrade", "websocket");
|
|
|
|
|
req.insert("Connection", "upgrade");
|
|
|
|
|
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert("Sec-WebSocket-Version", "13");
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_ostream>> ws{fc, ios_};
|
|
|
|
|
bool called = false;
|
|
|
|
|
c.accept_ex(ws, req,
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
// request in message, close frame in buffers
|
|
|
|
|
{
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
request_type req;
|
2017-05-30 06:58:40 -07:00
|
|
|
req.method(http::verb::get);
|
2017-05-02 15:49:22 -07:00
|
|
|
req.target("/");
|
2017-04-25 10:12:43 -07:00
|
|
|
req.version = 11;
|
2017-06-05 19:28:17 -07:00
|
|
|
req.insert("Host", "localhost");
|
|
|
|
|
req.insert("Upgrade", "websocket");
|
|
|
|
|
req.insert("Connection", "upgrade");
|
|
|
|
|
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert("Sec-WebSocket-Version", "13");
|
2017-04-25 10:12:43 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_ostream>> ws{fc, ios_};
|
|
|
|
|
c.accept(ws, req,
|
|
|
|
|
cbuf(0x88, 0x82, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x17));
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer b;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, b);
|
2017-04-25 10:12:43 -07:00
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if(e.code() != websocket::error::closed)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
request_type req;
|
2017-05-30 06:58:40 -07:00
|
|
|
req.method(http::verb::get);
|
2017-05-02 15:49:22 -07:00
|
|
|
req.target("/");
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
req.version = 11;
|
2017-06-05 19:28:17 -07:00
|
|
|
req.insert("Host", "localhost");
|
|
|
|
|
req.insert("Upgrade", "websocket");
|
|
|
|
|
req.insert("Connection", "upgrade");
|
|
|
|
|
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert("Sec-WebSocket-Version", "13");
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_ostream>> ws{fc, ios_};
|
|
|
|
|
bool called = false;
|
|
|
|
|
c.accept_ex(ws, req,
|
|
|
|
|
cbuf(0x88, 0x82, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x17),
|
|
|
|
|
res_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer b;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, b);
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if(e.code() != websocket::error::closed)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
// request in message, close frame in stream
|
|
|
|
|
{
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
request_type req;
|
2017-05-30 06:58:40 -07:00
|
|
|
req.method(http::verb::get);
|
2017-05-02 15:49:22 -07:00
|
|
|
req.target("/");
|
2017-04-25 10:12:43 -07:00
|
|
|
req.version = 11;
|
2017-06-05 19:28:17 -07:00
|
|
|
req.insert("Host", "localhost");
|
|
|
|
|
req.insert("Upgrade", "websocket");
|
|
|
|
|
req.insert("Connection", "upgrade");
|
|
|
|
|
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert("Sec-WebSocket-Version", "13");
|
2017-04-25 10:12:43 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"\x88\x82\xff\xff\xff\xff\xfc\x17"};
|
|
|
|
|
c.accept(ws, req);
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer b;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, b);
|
2017-04-25 10:12:43 -07:00
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if(e.code() != websocket::error::closed)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// request in message, close frame in stream and buffers
|
|
|
|
|
{
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
request_type req;
|
2017-05-30 06:58:40 -07:00
|
|
|
req.method(http::verb::get);
|
2017-05-02 15:49:22 -07:00
|
|
|
req.target("/");
|
2017-04-25 10:12:43 -07:00
|
|
|
req.version = 11;
|
2017-06-05 19:28:17 -07:00
|
|
|
req.insert("Host", "localhost");
|
|
|
|
|
req.insert("Upgrade", "websocket");
|
|
|
|
|
req.insert("Connection", "upgrade");
|
|
|
|
|
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
|
|
|
|
|
req.insert("Sec-WebSocket-Version", "13");
|
2017-04-25 10:12:43 -07:00
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"xff\xff\xfc\x17"};
|
|
|
|
|
c.accept(ws, req,
|
|
|
|
|
cbuf(0x88, 0x82, 0xff, 0xff));
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer b;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, b);
|
2017-04-25 10:12:43 -07:00
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
|
|
|
|
if(e.code() != websocket::error::closed)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// failed handshake (missing Sec-WebSocket-Key)
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
test::string_iostream>> ws{fc, ios_,
|
|
|
|
|
"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"
|
|
|
|
|
, 20};
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
c.accept(ws);
|
|
|
|
|
fail("success", __FILE__, __LINE__);
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const& e)
|
|
|
|
|
{
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
if( e.code() !=
|
|
|
|
|
websocket::error::handshake_failed &&
|
|
|
|
|
e.code() !=
|
|
|
|
|
boost::asio::error::eof)
|
2017-04-25 10:12:43 -07:00
|
|
|
throw;
|
|
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
catch(system_error const&)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
continue;
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
break;
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2017-04-25 10:12:43 -07:00
|
|
|
BEAST_EXPECT(n < limit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
testAccept()
|
|
|
|
|
{
|
|
|
|
|
testAccept(SyncClient{});
|
|
|
|
|
yield_to(
|
|
|
|
|
[&](yield_context yield)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2017-04-25 10:12:43 -07:00
|
|
|
testAccept(AsyncClient{yield});
|
|
|
|
|
});
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
|
|
|
|
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
class req_decorator
|
|
|
|
|
{
|
|
|
|
|
bool& b_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
req_decorator(req_decorator const&) = default;
|
|
|
|
|
|
|
|
|
|
explicit
|
|
|
|
|
req_decorator(bool& b)
|
|
|
|
|
: b_(b)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
operator()(request_type&) const
|
|
|
|
|
{
|
|
|
|
|
b_ = true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class Client>
|
|
|
|
|
void
|
|
|
|
|
testHandshake(endpoint_type const& ep, Client const& c)
|
|
|
|
|
{
|
|
|
|
|
static std::size_t constexpr limit = 200;
|
|
|
|
|
std::size_t n;
|
2017-05-30 06:58:40 -07:00
|
|
|
for(n = 199; n < limit; ++n)
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
{
|
|
|
|
|
test::fail_counter fc{n};
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// handshake
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
boost::asio::ip::tcp::socket>> ws{fc, ios_};
|
|
|
|
|
ws.next_layer().next_layer().connect(ep);
|
|
|
|
|
c.handshake(ws, "localhost", "/");
|
|
|
|
|
}
|
|
|
|
|
// handshake, response
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
boost::asio::ip::tcp::socket>> ws{fc, ios_};
|
|
|
|
|
ws.next_layer().next_layer().connect(ep);
|
|
|
|
|
response_type res;
|
|
|
|
|
c.handshake(ws, res, "localhost", "/");
|
|
|
|
|
// VFALCO validate res?
|
|
|
|
|
}
|
|
|
|
|
// handshake_ex
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
boost::asio::ip::tcp::socket>> ws{fc, ios_};
|
|
|
|
|
ws.next_layer().next_layer().connect(ep);
|
|
|
|
|
bool called = false;
|
|
|
|
|
c.handshake_ex(ws, "localhost", "/",
|
|
|
|
|
req_decorator{called});
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
}
|
|
|
|
|
// handshake_ex, response
|
|
|
|
|
{
|
|
|
|
|
stream<test::fail_stream<
|
|
|
|
|
boost::asio::ip::tcp::socket>> ws{fc, ios_};
|
|
|
|
|
ws.next_layer().next_layer().connect(ep);
|
|
|
|
|
bool called = false;
|
|
|
|
|
response_type res;
|
|
|
|
|
c.handshake_ex(ws, res, "localhost", "/",
|
|
|
|
|
req_decorator{called});
|
|
|
|
|
// VFALCO validate res?
|
|
|
|
|
BEAST_EXPECT(called);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const&)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
BEAST_EXPECT(n < limit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
testHandshake()
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
::websocket::async_echo_server server{nullptr, 1};
|
|
|
|
|
auto const any = endpoint_type{
|
|
|
|
|
address_type::from_string("127.0.0.1"), 0};
|
|
|
|
|
server.open(any, ec);
|
|
|
|
|
BEAST_EXPECTS(! ec, ec.message());
|
|
|
|
|
auto const ep = server.local_endpoint();
|
|
|
|
|
testHandshake(ep, SyncClient{});
|
|
|
|
|
yield_to(
|
|
|
|
|
[&](yield_context yield)
|
|
|
|
|
{
|
|
|
|
|
testHandshake(ep, AsyncClient{yield});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
void testBadHandshakes()
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
auto const check =
|
|
|
|
|
[&](error_code const& ev, std::string const& s)
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
for(std::size_t i = 0; i < s.size(); ++i)
|
|
|
|
|
{
|
2017-01-09 11:13:19 -05:00
|
|
|
stream<test::string_istream> ws(ios_,
|
2016-05-15 16:22:25 -04:00
|
|
|
s.substr(i, s.size() - i));
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
ws.accept(boost::asio::buffer(
|
|
|
|
|
s.substr(0, i), i));
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(! ev, ev.message());
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
catch(system_error const& se)
|
|
|
|
|
{
|
2016-10-05 23:17:17 +02:00
|
|
|
BEAST_EXPECTS(se.code() == ev, se.what());
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
// wrong version
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"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"
|
|
|
|
|
);
|
|
|
|
|
// wrong method
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"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"
|
|
|
|
|
);
|
|
|
|
|
// missing Host
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"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"
|
|
|
|
|
);
|
|
|
|
|
// missing Sec-WebSocket-Key
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive,upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// missing Sec-WebSocket-Version
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"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"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// wrong Sec-WebSocket-Version
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"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"
|
|
|
|
|
);
|
|
|
|
|
// missing upgrade token
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"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"
|
|
|
|
|
);
|
|
|
|
|
// missing connection token
|
|
|
|
|
check(error::handshake_failed,
|
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
|
"Host: localhost:80\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive\r\n"
|
|
|
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// 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"
|
|
|
|
|
);
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
void testBadResponses()
|
2016-05-04 11:06:17 -04:00
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
auto const check =
|
|
|
|
|
[&](std::string const& s)
|
2016-05-04 11:06:17 -04:00
|
|
|
{
|
2017-01-09 11:13:19 -05:00
|
|
|
stream<test::string_istream> ws(ios_, s);
|
2016-05-04 11:06:17 -04:00
|
|
|
try
|
|
|
|
|
{
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.handshake("localhost:80", "/");
|
|
|
|
|
fail();
|
2016-05-04 11:06:17 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
catch(system_error const& se)
|
2016-05-04 11:06:17 -04:00
|
|
|
{
|
2017-05-01 20:49:51 -07:00
|
|
|
BEAST_EXPECT(se.code() == error::handshake_failed);
|
2016-05-04 11:06:17 -04:00
|
|
|
}
|
2016-05-15 16:22:25 -04:00
|
|
|
};
|
|
|
|
|
// wrong HTTP version
|
|
|
|
|
check(
|
|
|
|
|
"HTTP/1.0 101 Switching Protocols\r\n"
|
|
|
|
|
"Server: beast\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// wrong status
|
|
|
|
|
check(
|
|
|
|
|
"HTTP/1.1 200 OK\r\n"
|
|
|
|
|
"Server: beast\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// missing upgrade token
|
|
|
|
|
check(
|
|
|
|
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
|
|
|
|
"Server: beast\r\n"
|
|
|
|
|
"Upgrade: HTTP/2\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// missing connection token
|
|
|
|
|
check(
|
|
|
|
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
|
|
|
|
"Server: beast\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: keep-alive\r\n"
|
|
|
|
|
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// missing accept key
|
|
|
|
|
check(
|
|
|
|
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
|
|
|
|
"Server: beast\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
|
|
|
|
// wrong accept key
|
|
|
|
|
check(
|
|
|
|
|
"HTTP/1.1 101 Switching Protocols\r\n"
|
|
|
|
|
"Server: beast\r\n"
|
|
|
|
|
"Upgrade: WebSocket\r\n"
|
|
|
|
|
"Connection: upgrade\r\n"
|
|
|
|
|
"Sec-WebSocket-Accept: *\r\n"
|
|
|
|
|
"Sec-WebSocket-Version: 13\r\n"
|
|
|
|
|
"\r\n"
|
|
|
|
|
);
|
2016-05-04 11:06:17 -04:00
|
|
|
}
|
|
|
|
|
|
2017-05-04 05:01:50 -07:00
|
|
|
void
|
|
|
|
|
testMask(endpoint_type const& ep,
|
2016-05-04 17:27:50 -04:00
|
|
|
yield_context do_yield)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
std::vector<char> v;
|
|
|
|
|
for(char n = 0; n < 20; ++n)
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
socket_type sock(ios_);
|
|
|
|
|
sock.connect(ep, ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
|
|
|
|
stream<socket_type&> ws(sock);
|
|
|
|
|
ws.handshake("localhost", "/", ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
|
|
|
|
ws.write(boost::asio::buffer(v), ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.read(db, ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(to_string(db.data()) ==
|
|
|
|
|
std::string(v.data(), v.size()));
|
2016-05-04 17:27:50 -04:00
|
|
|
v.push_back(n+1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
std::vector<char> v;
|
|
|
|
|
for(char n = 0; n < 20; ++n)
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
socket_type sock(ios_);
|
|
|
|
|
sock.connect(ep, ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
|
|
|
|
stream<socket_type&> ws(sock);
|
|
|
|
|
ws.handshake("localhost", "/", ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
|
|
|
|
ws.async_write(boost::asio::buffer(v), do_yield[ec]);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db, do_yield[ec]);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-04 17:27:50 -04:00
|
|
|
break;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(to_string(db.data()) ==
|
|
|
|
|
std::string(v.data(), v.size()));
|
2016-05-04 17:27:50 -04:00
|
|
|
v.push_back(n+1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-13 12:32:01 +10:00
|
|
|
void testClose(endpoint_type const& ep, yield_context)
|
2016-04-30 10:29:39 -04:00
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
// payload length 1
|
|
|
|
|
con c(ep, ios_);
|
|
|
|
|
boost::asio::write(c.ws.next_layer(),
|
|
|
|
|
cbuf(0x88, 0x81, 0xff, 0xff, 0xff, 0xff, 0x00));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// invalid close code 1005
|
|
|
|
|
con c(ep, ios_);
|
|
|
|
|
boost::asio::write(c.ws.next_layer(),
|
|
|
|
|
cbuf(0x88, 0x82, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x12));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// invalid utf8
|
|
|
|
|
con c(ep, ios_);
|
|
|
|
|
boost::asio::write(c.ws.next_layer(),
|
|
|
|
|
cbuf(0x88, 0x86, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x15,
|
|
|
|
|
0x0f, 0xd7, 0x73, 0x43));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// good utf8
|
|
|
|
|
con c(ep, ios_);
|
|
|
|
|
boost::asio::write(c.ws.next_layer(),
|
|
|
|
|
cbuf(0x88, 0x86, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x15,
|
|
|
|
|
'u', 't', 'f', '8'));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
#if 0
|
2017-04-27 17:29:25 -07:00
|
|
|
void testPausation1(endpoint_type const& ep)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
|
stream<socket_type> ws(ios);
|
|
|
|
|
ws.next_layer().connect(ep);
|
|
|
|
|
ws.handshake("localhost", "/");
|
|
|
|
|
|
|
|
|
|
// Make remote send a ping frame
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(false);
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.write(buffer_cat(sbuf("PING"), sbuf("ping")));
|
|
|
|
|
|
|
|
|
|
std::size_t count = 0;
|
|
|
|
|
|
|
|
|
|
// Write a text message
|
|
|
|
|
++count;
|
|
|
|
|
ws.async_write(sbuf("Hello"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
--count;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Read
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2016-05-15 16:22:25 -04:00
|
|
|
++count;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
--count;
|
|
|
|
|
});
|
|
|
|
|
// Run until the read_op writes a close frame.
|
|
|
|
|
while(! ws.wr_block_)
|
|
|
|
|
ios.run_one();
|
|
|
|
|
// Write a text message, leaving
|
2017-04-27 17:29:25 -07:00
|
|
|
// the write_op suspended as pausation.
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.async_write(sbuf("Hello"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
|
|
|
|
// Send is canceled because close received.
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
// Writes after close are aborted.
|
|
|
|
|
ws.async_write(sbuf("World"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
// Run until all completions are delivered.
|
|
|
|
|
static std::size_t constexpr limit = 100;
|
|
|
|
|
std::size_t n;
|
|
|
|
|
for(n = 0; n < limit; ++n)
|
|
|
|
|
{
|
|
|
|
|
if(count >= 4)
|
|
|
|
|
break;
|
|
|
|
|
ios.run_one();
|
|
|
|
|
}
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(n < limit);
|
2016-05-15 16:22:25 -04:00
|
|
|
ios.run();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-04-27 17:29:25 -07:00
|
|
|
void testPausation2(endpoint_type const& ep)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
|
stream<socket_type> ws(ios);
|
|
|
|
|
ws.next_layer().connect(ep);
|
|
|
|
|
ws.handshake("localhost", "/");
|
|
|
|
|
|
|
|
|
|
// Make remote send a text message with bad utf8.
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.write(buffer_cat(sbuf("TEXT"),
|
|
|
|
|
cbuf(0x03, 0xea, 0xf0, 0x28, 0x8c, 0xbc)));
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2016-05-15 16:22:25 -04:00
|
|
|
std::size_t count = 0;
|
|
|
|
|
// Read text message with bad utf8.
|
|
|
|
|
// Causes a close to be sent, blocking writes.
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
// Read should fail with protocol error
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(
|
|
|
|
|
ec == error::failed, ec.message());
|
2016-05-15 16:22:25 -04:00
|
|
|
// Reads after failure are aborted
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
// Run until the read_op writes a close frame.
|
|
|
|
|
while(! ws.wr_block_)
|
|
|
|
|
ios.run_one();
|
|
|
|
|
// Write a text message, leaving
|
2017-04-27 17:29:25 -07:00
|
|
|
// the write_op suspended as a pausation.
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.async_write(sbuf("Hello"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
|
|
|
|
// Send is canceled because close received.
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
// Writes after close are aborted.
|
|
|
|
|
ws.async_write(sbuf("World"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
// Run until all completions are delivered.
|
|
|
|
|
static std::size_t constexpr limit = 100;
|
|
|
|
|
std::size_t n;
|
|
|
|
|
for(n = 0; n < limit; ++n)
|
|
|
|
|
{
|
|
|
|
|
if(count >= 4)
|
|
|
|
|
break;
|
|
|
|
|
ios.run_one();
|
|
|
|
|
}
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(n < limit);
|
2016-05-15 16:22:25 -04:00
|
|
|
ios.run();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-27 17:29:25 -07:00
|
|
|
void testPausation3(endpoint_type const& ep)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
|
stream<socket_type> ws(ios);
|
|
|
|
|
ws.next_layer().connect(ep);
|
|
|
|
|
ws.handshake("localhost", "/");
|
|
|
|
|
|
|
|
|
|
// Cause close to be received
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.write(sbuf("CLOSE"));
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2016-05-15 16:22:25 -04:00
|
|
|
std::size_t count = 0;
|
|
|
|
|
// Read a close frame.
|
|
|
|
|
// Sends a close frame, blocking writes.
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
// Read should complete with error::closed
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == error::closed,
|
2016-05-15 16:22:25 -04:00
|
|
|
ec.message());
|
|
|
|
|
// Pings after a close are aborted
|
|
|
|
|
ws.async_ping("",
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
});
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECT(run_until(ios, 100,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&]{ return ws.wr_close_; })))
|
|
|
|
|
return;
|
|
|
|
|
// Try to ping
|
|
|
|
|
ws.async_ping("payload",
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
// Pings after a close are aborted
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
// Subsequent calls to close are aborted
|
|
|
|
|
ws.async_close({},
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
static std::size_t constexpr limit = 100;
|
|
|
|
|
std::size_t n;
|
|
|
|
|
for(n = 0; n < limit; ++n)
|
|
|
|
|
{
|
|
|
|
|
if(count >= 4)
|
|
|
|
|
break;
|
|
|
|
|
ios.run_one();
|
|
|
|
|
}
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(n < limit);
|
2016-05-15 16:22:25 -04:00
|
|
|
ios.run();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-27 17:29:25 -07:00
|
|
|
void testPausation4(endpoint_type const& ep)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
|
stream<socket_type> ws(ios);
|
|
|
|
|
ws.next_layer().connect(ep);
|
|
|
|
|
ws.handshake("localhost", "/");
|
|
|
|
|
|
|
|
|
|
// Cause close to be received
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.write(sbuf("CLOSE"));
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2016-05-15 16:22:25 -04:00
|
|
|
std::size_t count = 0;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == error::closed,
|
2016-05-15 16:22:25 -04:00
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
while(! ws.wr_block_)
|
|
|
|
|
ios.run_one();
|
|
|
|
|
// try to close
|
|
|
|
|
ws.async_close("payload",
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
|
|
|
|
++count;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == boost::asio::
|
2016-05-15 16:22:25 -04:00
|
|
|
error::operation_aborted,
|
|
|
|
|
ec.message());
|
|
|
|
|
});
|
|
|
|
|
static std::size_t constexpr limit = 100;
|
|
|
|
|
std::size_t n;
|
|
|
|
|
for(n = 0; n < limit; ++n)
|
|
|
|
|
{
|
|
|
|
|
if(count >= 2)
|
|
|
|
|
break;
|
|
|
|
|
ios.run_one();
|
|
|
|
|
}
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(n < limit);
|
2016-05-15 16:22:25 -04:00
|
|
|
ios.run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
2017-04-27 17:29:25 -07:00
|
|
|
void testPausation5(endpoint_type const& ep)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
|
stream<socket_type> ws(ios);
|
|
|
|
|
ws.next_layer().connect(ep);
|
|
|
|
|
ws.handshake("localhost", "/");
|
|
|
|
|
|
|
|
|
|
ws.async_write(sbuf("CLOSE"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(! ec);
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.async_write(sbuf("PING"),
|
|
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(! ec);
|
2016-05-15 16:22:25 -04:00
|
|
|
});
|
|
|
|
|
});
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.async_read(db,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&](error_code ec)
|
|
|
|
|
{
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECTS(ec == error::closed, ec.message());
|
2016-05-15 16:22:25 -04:00
|
|
|
});
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECT(run_until(ios, 100,
|
2016-05-15 16:22:25 -04:00
|
|
|
[&]{ return ios.stopped(); })))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-04-14 12:32:36 -07:00
|
|
|
/*
|
|
|
|
|
https://github.com/vinniefalco/Beast/issues/300
|
|
|
|
|
|
|
|
|
|
Write a message as two individual frames
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
testWriteFrames(endpoint_type const& ep)
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
|
|
|
|
socket_type sock{ios_};
|
|
|
|
|
sock.connect(ep, ec);
|
|
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
|
|
|
|
return;
|
|
|
|
|
stream<socket_type&> ws{sock};
|
|
|
|
|
ws.handshake("localhost", "/", ec);
|
|
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
|
|
|
|
return;
|
|
|
|
|
ws.write_frame(false, sbuf("u"));
|
|
|
|
|
ws.write_frame(true, sbuf("v"));
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer b;
|
2017-06-08 19:55:42 -07:00
|
|
|
ws.read(b, ec);
|
2017-04-14 12:32:36 -07:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-24 18:41:25 -04:00
|
|
|
void
|
|
|
|
|
testAsyncWriteFrame(endpoint_type const& ep)
|
|
|
|
|
{
|
|
|
|
|
for(;;)
|
|
|
|
|
{
|
|
|
|
|
boost::asio::io_service ios;
|
|
|
|
|
error_code ec;
|
|
|
|
|
socket_type sock(ios);
|
|
|
|
|
sock.connect(ep, ec);
|
|
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
|
|
|
|
break;
|
|
|
|
|
stream<socket_type&> ws(sock);
|
|
|
|
|
ws.handshake("localhost", "/", ec);
|
|
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
|
|
|
|
break;
|
|
|
|
|
ws.async_write_frame(false,
|
|
|
|
|
boost::asio::null_buffers{},
|
|
|
|
|
[&](error_code)
|
|
|
|
|
{
|
|
|
|
|
fail();
|
|
|
|
|
});
|
|
|
|
|
ws.next_layer().cancel(ec);
|
|
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
|
|
|
|
break;
|
|
|
|
|
//
|
|
|
|
|
// Destruction of the io_service will cause destruction
|
|
|
|
|
// of the write_frame_op without invoking the final handler.
|
|
|
|
|
//
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct abort_test
|
|
|
|
|
{
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class Client>
|
|
|
|
|
void
|
|
|
|
|
testEndpoint(Client const& c,
|
|
|
|
|
endpoint_type const& ep, permessage_deflate const& pmd)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
using boost::asio::buffer;
|
|
|
|
|
static std::size_t constexpr limit = 200;
|
|
|
|
|
std::size_t n;
|
2016-10-24 18:41:25 -04:00
|
|
|
for(n = 0; n <= limit; ++n)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2016-10-24 18:41:25 -04:00
|
|
|
stream<test::fail_stream<socket_type>> ws{n, ios_};
|
|
|
|
|
ws.set_option(pmd);
|
2016-05-15 16:22:25 -04:00
|
|
|
auto const restart =
|
|
|
|
|
[&](error_code ev)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, db);
|
2016-05-15 16:22:25 -04:00
|
|
|
fail();
|
2016-10-24 18:41:25 -04:00
|
|
|
throw abort_test{};
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
2016-10-04 18:00:11 -04:00
|
|
|
catch(system_error const& se)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
if(se.code() != ev)
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.lowest_layer().connect(ep, ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-10-24 18:41:25 -04:00
|
|
|
throw abort_test{};
|
|
|
|
|
c.handshake(ws, "localhost", "/");
|
2016-05-15 16:22:25 -04:00
|
|
|
};
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
// connect
|
|
|
|
|
error_code ec;
|
|
|
|
|
ws.lowest_layer().connect(ep, ec);
|
2016-08-29 13:28:08 -04:00
|
|
|
if(! BEAST_EXPECTS(! ec, ec.message()))
|
2016-05-15 16:22:25 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2016-10-24 18:41:25 -04:00
|
|
|
c.handshake(ws, "localhost", "/");
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// send message
|
2017-06-08 17:36:31 -07:00
|
|
|
ws.auto_fragment(false);
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(false);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("Hello"));
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
// receive echoed message
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, db);
|
|
|
|
|
BEAST_EXPECT(ws.got_text());
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(to_string(db.data()) == "Hello");
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// close, no payload
|
2016-10-24 18:41:25 -04:00
|
|
|
c.close(ws, {});
|
|
|
|
|
restart(error::closed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// close with code
|
2016-10-24 18:41:25 -04:00
|
|
|
c.close(ws, close_code::going_away);
|
|
|
|
|
restart(error::closed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// close with code and reason string
|
2016-10-24 18:41:25 -04:00
|
|
|
c.close(ws, {close_code::going_away, "Going away"});
|
|
|
|
|
restart(error::closed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// send ping and message
|
|
|
|
|
bool pong = false;
|
2017-06-08 19:28:12 -07:00
|
|
|
ws.ping_callback(
|
2017-02-03 16:22:28 -05:00
|
|
|
[&](bool is_pong, ping_data const& payload)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-02-03 16:22:28 -05:00
|
|
|
BEAST_EXPECT(is_pong);
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(! pong);
|
2016-05-15 16:22:25 -04:00
|
|
|
pong = true;
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(payload == "");
|
2017-06-08 19:28:12 -07:00
|
|
|
});
|
2016-10-24 18:41:25 -04:00
|
|
|
c.ping(ws, "");
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("Hello"));
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
// receive echoed message
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, db);
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(pong == 1);
|
2017-06-08 19:55:42 -07:00
|
|
|
BEAST_EXPECT(ws.got_binary());
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(to_string(db.data()) == "Hello");
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
2017-06-08 19:28:12 -07:00
|
|
|
ws.ping_callback({});
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// send ping and fragmented message
|
2017-06-08 19:28:12 -07:00
|
|
|
ws.ping_callback(
|
2017-02-03 16:22:28 -05:00
|
|
|
[&](bool is_pong, ping_data const& payload)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2017-02-03 16:22:28 -05:00
|
|
|
BEAST_EXPECT(is_pong);
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(payload == "payload");
|
2017-06-08 19:28:12 -07:00
|
|
|
});
|
2016-05-15 16:22:25 -04:00
|
|
|
ws.ping("payload");
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write_frame(ws, false, sbuf("Hello, "));
|
|
|
|
|
c.write_frame(ws, false, sbuf(""));
|
|
|
|
|
c.write_frame(ws, true, sbuf("World!"));
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
// receive echoed message
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, db);
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(pong == 1);
|
|
|
|
|
BEAST_EXPECT(to_string(db.data()) == "Hello, World!");
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
2017-06-08 19:28:12 -07:00
|
|
|
ws.ping_callback({});
|
2016-05-15 16:22:25 -04:00
|
|
|
|
2016-11-03 17:53:32 -04:00
|
|
|
// send pong
|
2016-10-24 18:41:25 -04:00
|
|
|
c.pong(ws, "");
|
2016-11-03 17:53:32 -04:00
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
// send auto fragmented message
|
2017-06-08 17:36:31 -07:00
|
|
|
ws.auto_fragment(true);
|
2017-06-08 18:27:32 -07:00
|
|
|
ws.write_buffer_size(8);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("Now is the time for all good men"));
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
// receive echoed message
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer b;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, b);
|
2017-05-04 15:40:07 -07:00
|
|
|
BEAST_EXPECT(to_string(b.data()) == "Now is the time for all good men");
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
2017-06-08 17:36:31 -07:00
|
|
|
ws.auto_fragment(false);
|
2017-06-08 18:27:32 -07:00
|
|
|
ws.write_buffer_size(4096);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// send message with write buffer limit
|
|
|
|
|
{
|
|
|
|
|
std::string s(2000, '*');
|
2017-06-08 18:27:32 -07:00
|
|
|
ws.write_buffer_size(1200);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, buffer(s.data(), s.size()));
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
// receive echoed message
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, db);
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(to_string(db.data()) == s);
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cause ping
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("PING"));
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(false);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("Hello"));
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
|
|
|
|
// receive echoed message
|
2017-05-04 15:40:07 -07:00
|
|
|
multi_buffer db;
|
2017-06-08 19:55:42 -07:00
|
|
|
c.read(ws, db);
|
|
|
|
|
BEAST_EXPECT(ws.got_text());
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(to_string(db.data()) == "Hello");
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cause close
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("CLOSE"));
|
|
|
|
|
restart(error::closed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// send bad utf8
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, buffer_cat(sbuf("TEXT"),
|
2016-05-15 16:22:25 -04:00
|
|
|
cbuf(0x03, 0xea, 0xf0, 0x28, 0x8c, 0xbc)));
|
2016-10-24 18:41:25 -04:00
|
|
|
restart(error::failed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// cause bad utf8
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, buffer_cat(sbuf("TEXT"),
|
2016-05-15 16:22:25 -04:00
|
|
|
cbuf(0x03, 0xea, 0xf0, 0x28, 0x8c, 0xbc)));
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, sbuf("Hello"));
|
|
|
|
|
restart(error::failed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// cause bad close
|
2017-06-08 18:03:10 -07:00
|
|
|
ws.binary(true);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, buffer_cat(sbuf("RAW"),
|
2016-05-15 16:22:25 -04:00
|
|
|
cbuf(0x88, 0x02, 0x03, 0xed)));
|
2016-10-24 18:41:25 -04:00
|
|
|
restart(error::failed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// unexpected cont
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write_raw(ws,
|
2016-05-15 16:22:25 -04:00
|
|
|
cbuf(0x80, 0x80, 0xff, 0xff, 0xff, 0xff));
|
2016-10-24 18:41:25 -04:00
|
|
|
restart(error::closed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// invalid fixed frame header
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write_raw(ws,
|
2016-05-15 16:22:25 -04:00
|
|
|
cbuf(0x8f, 0x80, 0xff, 0xff, 0xff, 0xff));
|
2016-10-24 18:41:25 -04:00
|
|
|
restart(error::closed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
|
|
|
|
// cause non-canonical extended size
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, buffer_cat(sbuf("RAW"),
|
2016-05-15 16:22:25 -04:00
|
|
|
cbuf(0x82, 0x7e, 0x00, 0x01, 0x00)));
|
2016-10-24 18:41:25 -04:00
|
|
|
restart(error::failed);
|
2016-05-15 16:22:25 -04:00
|
|
|
|
2016-10-24 18:41:25 -04:00
|
|
|
if(! pmd.client_enable)
|
2016-05-15 16:22:25 -04:00
|
|
|
{
|
2016-10-24 18:41:25 -04:00
|
|
|
// expected cont
|
|
|
|
|
c.write_frame(ws, false, boost::asio::null_buffers{});
|
|
|
|
|
c.write_raw(ws,
|
|
|
|
|
cbuf(0x81, 0x80, 0xff, 0xff, 0xff, 0xff));
|
|
|
|
|
restart(error::closed);
|
|
|
|
|
|
|
|
|
|
// message size above 2^64
|
|
|
|
|
c.write_frame(ws, false, cbuf(0x00));
|
|
|
|
|
c.write_raw(ws,
|
|
|
|
|
cbuf(0x80, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff));
|
|
|
|
|
restart(error::closed);
|
|
|
|
|
|
|
|
|
|
// message size exceeds max
|
2017-06-08 18:22:25 -07:00
|
|
|
ws.read_message_max(1);
|
2016-10-24 18:41:25 -04:00
|
|
|
c.write(ws, cbuf(0x00, 0x00));
|
|
|
|
|
restart(error::failed);
|
2017-06-08 18:22:25 -07:00
|
|
|
ws.read_message_max(16*1024*1024);
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(system_error const&)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-08-29 13:28:08 -04:00
|
|
|
BEAST_EXPECT(n < limit);
|
2016-05-15 16:22:25 -04:00
|
|
|
}
|
|
|
|
|
|
2017-06-07 17:41:27 -07:00
|
|
|
void
|
|
|
|
|
run() override
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2017-05-23 12:33:31 -07:00
|
|
|
BOOST_STATIC_ASSERT(std::is_constructible<
|
|
|
|
|
stream<socket_type>, boost::asio::io_service&>::value);
|
2016-05-07 17:06:46 -04:00
|
|
|
|
2017-05-23 12:33:31 -07:00
|
|
|
BOOST_STATIC_ASSERT(std::is_move_constructible<
|
|
|
|
|
stream<socket_type>>::value);
|
2016-04-30 13:00:33 -04:00
|
|
|
|
2017-05-23 12:33:31 -07:00
|
|
|
BOOST_STATIC_ASSERT(std::is_move_assignable<
|
|
|
|
|
stream<socket_type>>::value);
|
2016-04-30 13:00:33 -04:00
|
|
|
|
2017-05-23 12:33:31 -07:00
|
|
|
BOOST_STATIC_ASSERT(std::is_constructible<
|
|
|
|
|
stream<socket_type&>, socket_type&>::value);
|
2016-04-30 13:00:33 -04:00
|
|
|
|
2017-05-23 12:33:31 -07:00
|
|
|
BOOST_STATIC_ASSERT(std::is_move_constructible<
|
|
|
|
|
stream<socket_type&>>::value);
|
2016-05-04 11:06:17 -04:00
|
|
|
|
2017-05-23 12:33:31 -07:00
|
|
|
BOOST_STATIC_ASSERT(! std::is_move_assignable<
|
|
|
|
|
stream<socket_type&>>::value);
|
2016-05-04 17:27:50 -04:00
|
|
|
|
2016-06-10 15:48:39 -04:00
|
|
|
log << "sizeof(websocket::stream) == " <<
|
|
|
|
|
sizeof(websocket::stream<boost::asio::ip::tcp::socket&>) << std::endl;
|
|
|
|
|
|
2016-05-15 16:22:25 -04:00
|
|
|
auto const any = endpoint_type{
|
|
|
|
|
address_type::from_string("127.0.0.1"), 0};
|
2016-04-30 10:29:39 -04:00
|
|
|
|
2016-10-24 18:41:25 -04:00
|
|
|
testOptions();
|
|
|
|
|
testAccept();
|
Refactor websocket decorators (API Change):
fix #80, #212, fix #303, fix #314, fix #317
websocket::stream now provides the following families of
functions for performing handshakes:
When operating in the server role:
* stream::accept
* stream::accept_ex
* stream::async_accept
* stream::async_accept_ex
When operating in the client role:
* stream::handshake
* stream::handshake_ex
* stream::async_handshake
* stream::async_handshake_ex
Member functions ending with "_ex" allow an additional
RequestDecorator parameter (for the accept family of
functions) or ResponseDecorator parameter (for the
handshake family of functions).
The decorator is called to optionally modify the contents
of the HTTP request or HTTP response object generated by
the implementation, before the message is sent. This
permits callers to set the User-Agent or Server fields,
add or modify HTTP fields related to subprotocols, or
perform any required transformation of the HTTP message
for application-specific needs.
The handshake() family of functions now have an additional
set of overloads accepting a parameter of type response_type&,
allowing the caller to receive the HTTP Response to the
Upgrade handshake. This permits inspection of the response
to handle things like subprotocols, authentication, or
other application-specific needs.
The new implementation does not require any state to be
stored in the stream object. Therefore, websocket::stream
objects are now smaller in size.
The overload of set_option for setting a decorator on the
stream is removed. The only way to set decorators now is
with a suitable overload of accept or handshake.
2017-04-25 09:35:22 -07:00
|
|
|
testHandshake();
|
2016-10-24 18:41:25 -04:00
|
|
|
testBadHandshakes();
|
|
|
|
|
testBadResponses();
|
|
|
|
|
|
2017-04-14 12:32:36 -07:00
|
|
|
permessage_deflate pmd;
|
|
|
|
|
pmd.client_enable = false;
|
|
|
|
|
pmd.server_enable = false;
|
|
|
|
|
|
2016-04-30 13:00:33 -04:00
|
|
|
{
|
2017-01-30 09:53:10 -05:00
|
|
|
error_code ec;
|
|
|
|
|
::websocket::sync_echo_server server{nullptr};
|
2017-04-14 12:32:36 -07:00
|
|
|
server.set_option(pmd);
|
2017-01-30 09:53:10 -05:00
|
|
|
server.open(any, ec);
|
|
|
|
|
BEAST_EXPECTS(! ec, ec.message());
|
2016-10-24 18:41:25 -04:00
|
|
|
auto const ep = server.local_endpoint();
|
2017-04-27 17:29:25 -07:00
|
|
|
//testPausation1(ep);
|
|
|
|
|
testPausation2(ep);
|
|
|
|
|
testPausation3(ep);
|
|
|
|
|
testPausation4(ep);
|
|
|
|
|
//testPausation5(ep);
|
2017-04-14 12:32:36 -07:00
|
|
|
testWriteFrames(ep);
|
2016-10-24 18:41:25 -04:00
|
|
|
testAsyncWriteFrame(ep);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
2017-01-30 09:53:10 -05:00
|
|
|
::websocket::async_echo_server server{nullptr, 4};
|
2016-10-24 18:41:25 -04:00
|
|
|
server.open(any, ec);
|
|
|
|
|
BEAST_EXPECTS(! ec, ec.message());
|
|
|
|
|
auto const ep = server.local_endpoint();
|
|
|
|
|
testAsyncWriteFrame(ep);
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
2016-10-24 18:41:25 -04:00
|
|
|
|
|
|
|
|
auto const doClientTests =
|
|
|
|
|
[this, any](permessage_deflate const& pmd)
|
|
|
|
|
{
|
|
|
|
|
{
|
2017-01-30 09:53:10 -05:00
|
|
|
error_code ec;
|
|
|
|
|
::websocket::sync_echo_server server{nullptr};
|
2016-10-24 18:41:25 -04:00
|
|
|
server.set_option(pmd);
|
2017-01-30 09:53:10 -05:00
|
|
|
server.open(any, ec);
|
|
|
|
|
BEAST_EXPECTS(! ec, ec.message());
|
2016-10-24 18:41:25 -04:00
|
|
|
auto const ep = server.local_endpoint();
|
|
|
|
|
testEndpoint(SyncClient{}, ep, pmd);
|
|
|
|
|
yield_to(
|
|
|
|
|
[&](yield_context yield)
|
|
|
|
|
{
|
|
|
|
|
testEndpoint(
|
|
|
|
|
AsyncClient{yield}, ep, pmd);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
error_code ec;
|
2017-01-30 09:53:10 -05:00
|
|
|
::websocket::async_echo_server server{nullptr, 4};
|
2016-10-24 18:41:25 -04:00
|
|
|
server.set_option(pmd);
|
|
|
|
|
server.open(any, ec);
|
|
|
|
|
BEAST_EXPECTS(! ec, ec.message());
|
|
|
|
|
auto const ep = server.local_endpoint();
|
|
|
|
|
testEndpoint(SyncClient{}, ep, pmd);
|
|
|
|
|
yield_to(
|
|
|
|
|
[&](yield_context yield)
|
|
|
|
|
{
|
|
|
|
|
testEndpoint(
|
|
|
|
|
AsyncClient{yield}, ep, pmd);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pmd.client_enable = false;
|
|
|
|
|
pmd.server_enable = false;
|
|
|
|
|
doClientTests(pmd);
|
|
|
|
|
|
|
|
|
|
pmd.client_enable = true;
|
|
|
|
|
pmd.server_enable = true;
|
|
|
|
|
pmd.client_max_window_bits = 10;
|
|
|
|
|
pmd.client_no_context_takeover = false;
|
|
|
|
|
doClientTests(pmd);
|
|
|
|
|
|
|
|
|
|
pmd.client_enable = true;
|
|
|
|
|
pmd.server_enable = true;
|
|
|
|
|
pmd.client_max_window_bits = 10;
|
|
|
|
|
pmd.client_no_context_takeover = true;
|
|
|
|
|
doClientTests(pmd);
|
2016-04-30 13:00:33 -04:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
BEAST_DEFINE_TESTSUITE(stream,websocket,beast);
|
|
|
|
|
|
|
|
|
|
} // websocket
|
|
|
|
|
} // beast
|