diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55a85aa7..ae233471 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+Version 52:
+
+API Changes:
+
+* auto_fragment is a member of stream
+
+Actions Required:
+
+* Change call sites which use auto_fragment with set_option
+ to call stream::auto_fragment instead.
+
+--------------------------------------------------------------------------------
+
Version 51
* Fix operator<< for header
diff --git a/doc/quickref.xml b/doc/quickref.xml
index 45362956..2622cbb4 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -123,7 +123,6 @@
Options
- auto_fragment
message_type
permessage_deflate
ping_callback
diff --git a/examples/websocket_async_echo_server.hpp b/examples/websocket_async_echo_server.hpp
index 75d7ddad..4b4f1369 100644
--- a/examples/websocket_async_echo_server.hpp
+++ b/examples/websocket_async_echo_server.hpp
@@ -20,8 +20,6 @@
#include
#include
#include
-#include
-#include
#include
namespace websocket {
@@ -37,81 +35,6 @@ public:
using endpoint_type = boost::asio::ip::tcp::endpoint;
private:
- /** A container of type-erased option setters.
- */
- template
- class options_set
- {
- // workaround for std::function bug in msvc
- struct callable
- {
- virtual ~callable() = default;
- virtual void operator()(
- beast::websocket::stream&) = 0;
- };
-
- template
- class callable_impl : public callable
- {
- T t_;
-
- public:
- template
- callable_impl(U&& u)
- : t_(std::forward(u))
- {
- }
-
- void
- operator()(beast::websocket::stream& ws)
- {
- t_(ws);
- }
- };
-
- template
- class lambda
- {
- Opt opt_;
-
- public:
- lambda(lambda&&) = default;
- lambda(lambda const&) = default;
-
- lambda(Opt const& opt)
- : opt_(opt)
- {
- }
-
- void
- operator()(beast::websocket::stream& ws) const
- {
- ws.set_option(opt_);
- }
- };
-
- std::unordered_map> list_;
-
- public:
- template
- void
- set_option(Opt const& opt)
- {
- std::unique_ptr p;
- p.reset(new callable_impl>{opt});
- list_[std::type_index{
- typeid(Opt)}] = std::move(p);
- }
-
- void
- set_options(beast::websocket::stream& ws)
- {
- for(auto const& op : list_)
- (*op.second)(ws);
- }
- };
-
std::ostream* log_;
boost::asio::io_service ios_;
socket_type sock_;
@@ -119,7 +42,7 @@ private:
boost::asio::ip::tcp::acceptor acceptor_;
std::vector thread_;
boost::optional work_;
- options_set opts_;
+ std::function&)> mod_;
public:
async_echo_server(async_echo_server const&) = delete;
@@ -150,9 +73,12 @@ public:
~async_echo_server()
{
work_ = boost::none;
- error_code ec;
ios_.dispatch(
- [&]{ acceptor_.close(ec); });
+ [&]
+ {
+ error_code ec;
+ acceptor_.close(ec);
+ });
for(auto& t : thread_)
t.join();
}
@@ -165,17 +91,16 @@ public:
return acceptor_.local_endpoint();
}
- /** Set a websocket option.
+ /** Set a handler called for new streams.
- The option will be applied to all new connections.
-
- @param opt The option to apply.
+ This function is called for each new stream.
+ It is used to set options for every connection.
*/
- template
+ template
void
- set_option(Opt const& opt)
+ on_new_stream(F const& f)
{
- opts_.set_option(opt);
+ mod_ = f;
}
/** Open a listening port.
@@ -253,7 +178,7 @@ private:
std::forward(args)...))
{
auto& d = *d_;
- d.server.opts_.set_options(d.ws);
+ d.server.mod_(d.ws);
run();
}
diff --git a/examples/websocket_echo.cpp b/examples/websocket_echo.cpp
index e8171526..524d83d3 100644
--- a/examples/websocket_echo.cpp
+++ b/examples/websocket_echo.cpp
@@ -25,6 +25,29 @@ sig_wait()
ios.run();
}
+class set_stream_options
+{
+ beast::websocket::permessage_deflate pmd_;
+
+public:
+ set_stream_options(set_stream_options const&) = default;
+
+ set_stream_options(
+ beast::websocket::permessage_deflate const& pmd)
+ : pmd_(pmd)
+ {
+ }
+
+ template
+ void
+ operator()(beast::websocket::stream& ws) const
+ {
+ ws.auto_fragment(false);
+ ws.set_option(pmd_);
+ ws.set_option(beast::websocket::read_message_max{64 * 1024 * 1024});
+ }
+};
+
int main()
{
using namespace beast::websocket;
@@ -39,16 +62,12 @@ int main()
pmd.compLevel = 3;
websocket::async_echo_server s1{&std::cout, 1};
- s1.set_option(read_message_max{64 * 1024 * 1024});
- s1.set_option(auto_fragment{false});
- s1.set_option(pmd);
+ s1.on_new_stream(set_stream_options{pmd});
s1.open(endpoint_type{
address_type::from_string("127.0.0.1"), 6000 }, ec);
websocket::sync_echo_server s2{&std::cout};
- s2.set_option(read_message_max{64 * 1024 * 1024});
- s2.set_option(auto_fragment{false});
- s2.set_option(pmd);
+ s2.on_new_stream(set_stream_options{pmd});
s2.open(endpoint_type{
address_type::from_string("127.0.0.1"), 6001 }, ec);
diff --git a/examples/websocket_sync_echo_server.hpp b/examples/websocket_sync_echo_server.hpp
index 3df6ddb5..a4fd09e8 100644
--- a/examples/websocket_sync_echo_server.hpp
+++ b/examples/websocket_sync_echo_server.hpp
@@ -20,8 +20,6 @@
#include
#include
#include
-#include
-#include
#include
namespace websocket {
@@ -37,88 +35,13 @@ public:
using socket_type = boost::asio::ip::tcp::socket;
private:
- /** A container of type-erased option setters.
- */
- template
- class options_set
- {
- // workaround for std::function bug in msvc
- struct callable
- {
- virtual ~callable() = default;
- virtual void operator()(
- beast::websocket::stream&) = 0;
- };
-
- template
- class callable_impl : public callable
- {
- T t_;
-
- public:
- template
- callable_impl(U&& u)
- : t_(std::forward(u))
- {
- }
-
- void
- operator()(beast::websocket::stream& ws)
- {
- t_(ws);
- }
- };
-
- template
- class lambda
- {
- Opt opt_;
-
- public:
- lambda(lambda&&) = default;
- lambda(lambda const&) = default;
-
- lambda(Opt const& opt)
- : opt_(opt)
- {
- }
-
- void
- operator()(beast::websocket::stream& ws) const
- {
- ws.set_option(opt_);
- }
- };
-
- std::unordered_map> list_;
-
- public:
- template
- void
- set_option(Opt const& opt)
- {
- std::unique_ptr p;
- p.reset(new callable_impl>{opt});
- list_[std::type_index{
- typeid(Opt)}] = std::move(p);
- }
-
- void
- set_options(beast::websocket::stream& ws)
- {
- for(auto const& op : list_)
- (*op.second)(ws);
- }
- };
-
std::ostream* log_;
boost::asio::io_service ios_;
socket_type sock_;
endpoint_type ep_;
boost::asio::ip::tcp::acceptor acceptor_;
std::thread thread_;
- options_set opts_;
+ std::function&)> mod_;
public:
/** Constructor.
@@ -154,17 +77,16 @@ public:
return acceptor_.local_endpoint();
}
- /** Set a websocket option.
+ /** Set a handler called for new streams.
- The option will be applied to all new connections.
-
- @param opt The option to apply.
+ This function is called for each new stream.
+ It is used to set options for every connection.
*/
- template
+ template
void
- set_option(Opt const& opt)
+ on_new_stream(F const& f)
{
- opts_.set_option(opt);
+ mod_ = f;
}
/** Open a listening port.
@@ -269,7 +191,7 @@ private:
using boost::asio::buffer_copy;
beast::websocket::stream<
socket_type> ws{std::move(sock)};
- opts_.set_options(ws);
+ mod_(ws);
error_code ec;
ws.accept_ex(
[](beast::websocket::response_type& res)
diff --git a/include/beast/websocket/option.hpp b/include/beast/websocket/option.hpp
index ef6608e1..c5a0b7cc 100644
--- a/include/beast/websocket/option.hpp
+++ b/include/beast/websocket/option.hpp
@@ -22,43 +22,6 @@
namespace beast {
namespace websocket {
-/** Automatic fragmentation option.
-
- Determines if outgoing message payloads are broken up into
- multiple pieces.
-
- When the automatic fragmentation size is turned on, outgoing
- message payloads are broken up into multiple frames no larger
- than the write buffer size.
-
- The default setting is to fragment messages.
-
- @note Objects of this type are used with
- @ref beast::websocket::stream::set_option.
-
- @par Example
- Setting the automatic fragmentation option:
- @code
- ...
- websocket::stream stream(ios);
- stream.set_option(auto_fragment{true});
- @endcode
-*/
-#if BEAST_DOXYGEN
-using auto_fragment = implementation_defined;
-#else
-struct auto_fragment
-{
- bool value;
-
- explicit
- auto_fragment(bool v)
- : value(v)
- {
- }
-};
-#endif
-
/** Message type option.
This controls the opcode set for outgoing messages. Valid
diff --git a/include/beast/websocket/stream.hpp b/include/beast/websocket/stream.hpp
index dd0f20aa..c114cda1 100644
--- a/include/beast/websocket/stream.hpp
+++ b/include/beast/websocket/stream.hpp
@@ -151,6 +151,41 @@ public:
*/
~stream() = default;
+ /** Set the automatic fragmentation option.
+
+ Determines if outgoing message payloads are broken up into
+ multiple pieces.
+
+ When the automatic fragmentation size is turned on, outgoing
+ message payloads are broken up into multiple frames no larger
+ than the write buffer size.
+
+ The default setting is to fragment messages.
+
+ @note Objects of this type are used with
+ @ref beast::websocket::stream::set_option.
+
+ @par Example
+ Setting the automatic fragmentation option:
+ @code
+ ...
+ websocket::stream stream{ios};
+ stream.auto_fragment(true);
+ @endcode
+ */
+ void
+ auto_fragment(bool v)
+ {
+ wr_autofrag_ = v;
+ }
+
+ /// Returns `true` if the automatic fragmentation option is set.
+ bool
+ auto_fragment() const
+ {
+ return wr_autofrag_;
+ }
+
/** Set options on the stream.
The application must ensure that calls to set options
@@ -173,13 +208,6 @@ public:
std::forward(an)...);
}
- /// Set the automatic fragment size option
- void
- set_option(auto_fragment const& o)
- {
- wr_autofrag_ = o.value;
- }
-
/// Set the outgoing message type
void
set_option(message_type const& o)
diff --git a/test/websocket/doc_snippets.cpp b/test/websocket/doc_snippets.cpp
index 4e7a7a30..55a6d66f 100644
--- a/test/websocket/doc_snippets.cpp
+++ b/test/websocket/doc_snippets.cpp
@@ -205,7 +205,7 @@ boost::asio::ip::tcp::socket sock{ios};
//]
//[ws_snippet_19
- ws.set_option(auto_fragment{true});
+ ws.auto_fragment(true);
ws.set_option(write_buffer_size{16384});
//]
diff --git a/test/websocket/stream.cpp b/test/websocket/stream.cpp
index 69f7cde3..a2c23598 100644
--- a/test/websocket/stream.cpp
+++ b/test/websocket/stream.cpp
@@ -553,7 +553,7 @@ public:
testOptions()
{
stream ws(ios_);
- ws.set_option(auto_fragment{true});
+ ws.auto_fragment(true);
ws.set_option(write_buffer_size{2048});
ws.set_option(message_type{opcode::text});
ws.set_option(read_buffer_size{8192});
@@ -1655,7 +1655,7 @@ public:
c.handshake(ws, "localhost", "/");
// send message
- ws.set_option(auto_fragment{false});
+ ws.auto_fragment(false);
ws.set_option(message_type(opcode::text));
c.write(ws, sbuf("Hello"));
{
@@ -1728,7 +1728,7 @@ public:
c.pong(ws, "");
// send auto fragmented message
- ws.set_option(auto_fragment{true});
+ ws.auto_fragment(true);
ws.set_option(write_buffer_size{8});
c.write(ws, sbuf("Now is the time for all good men"));
{
@@ -1738,7 +1738,7 @@ public:
c.read(ws, op, b);
BEAST_EXPECT(to_string(b.data()) == "Now is the time for all good men");
}
- ws.set_option(auto_fragment{false});
+ ws.auto_fragment(false);
ws.set_option(write_buffer_size{4096});
// send message with write buffer limit