Skip to content

Commit

Permalink
Remove Beast dependency from connect_op.hpp
Browse files Browse the repository at this point in the history
Summary: resolves T15243

Reviewers: ivica

Reviewed By: ivica

Subscribers: iljazovic, miljen

Maniphest Tasks: T15243

Differential Revision: https://repo.mireo.local/D32561
  • Loading branch information
ksimicevic committed Dec 2, 2024
1 parent 8d45025 commit d19f466
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Getting Started
---------
Async.MQTT5 is a header-only library. To use Async.MQTT5 it requires the following:
- **C++17 capable compiler**
- **Boost 1.82 or later**. In addition to Asio, we use other header-only libraries such as Beast, Spirit, and more.
- **Boost 1.82 or later**. In addition to Asio, we use other header-only libraries.
- **OpenSSL**. If you require an SSL connection by using [boost::asio::ssl::stream](https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/reference/ssl__stream.html).

Async.MQTT5 has been tested with the following compilers:
Expand Down
2 changes: 1 addition & 1 deletion doc/qbk/01_intro.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ __Self__ is a header-only library.
To use __Self__ it requires the following:

* [*C++17 capable compiler]
* [*Boost 1.82 or later]. In addition to Asio, we use other header-only libraries such as Beast, Spirit, and more.
* [*Boost 1.82 or later]. In addition to Asio, we use other header-only libraries.
* [*OpenSSL]. If you require an SSL connection by using [asioreflink ssl__stream ssl::stream].

__Self__ has been tested with the following compilers:
Expand Down
1 change: 1 addition & 0 deletions example/hello_world_over_websocket_tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <boost/beast/websocket.hpp>

#include <async_mqtt5.hpp>
#include <async_mqtt5/websocket.hpp> // WebSocket traits

int main() {
boost::asio::io_context ioc;
Expand Down
1 change: 1 addition & 0 deletions example/hello_world_over_websocket_tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <boost/beast/ssl/ssl_stream.hpp> // async_teardown specialization for websocket ssl stream

#include <async_mqtt5.hpp>
#include <async_mqtt5/websocket.hpp> // WebSocket traits

// External customization point.
namespace async_mqtt5 {
Expand Down
7 changes: 7 additions & 0 deletions include/async_mqtt5/detail/async_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ namespace async_mqtt5 {

namespace asio = boost::asio;

// TLS

template <typename StreamType>
struct tls_handshake_type {};

template <typename TlsContext, typename TlsStream>
void assign_tls_sni(const authority_path& ap, TlsContext& ctx, TlsStream& s);

// WebSocket

template <typename Stream>
struct ws_handshake_traits {};

namespace detail {

// tracking executor
Expand Down
36 changes: 6 additions & 30 deletions include/async_mqtt5/impl/connect_op.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
#include <boost/asio/write.hpp>
#include <boost/asio/ip/tcp.hpp>

#include <boost/beast/http/field.hpp>
#include <boost/beast/websocket/rfc6455.hpp>
#include <boost/beast/websocket/stream_base.hpp>

#include <async_mqtt5/error.hpp>
#include <async_mqtt5/reason_codes.hpp>

Expand Down Expand Up @@ -171,35 +167,15 @@ class connect_op {
}

void do_ws_handshake(endpoint ep, authority_path ap) {
if constexpr (has_ws_handshake<Stream>) {
using namespace boost::beast;

// We'll need to turn off read timeouts on the underlying stream
// because the websocket stream has its own timeout system.

// Set suggested timeout settings for the websocket
_stream.set_option(
websocket::stream_base::timeout::suggested(role_type::client)
);

_stream.binary(true);

// Set a decorator to change the User-Agent of the handshake
_stream.set_option(websocket::stream_base::decorator(
[](websocket::request_type& req) {
req.set(http::field::sec_websocket_protocol, "mqtt");
req.set(http::field::user_agent, "boost.mqtt");
})
);

_stream.async_handshake(
ap.host + ':' + ap.port, ap.path,
if constexpr (has_ws_handshake<Stream>)
// If you get a compilation error here,
// it might be because of a missing <async_mqtt5/websocket.hpp> include
ws_handshake_traits<Stream>::async_handshake(
_stream, std::move(ap),
asio::append(
asio::prepend(std::move(*this), on_ws_handshake {}),
ep
asio::prepend(std::move(*this), on_ws_handshake {}), ep
)
);
}
else
(*this)(on_ws_handshake {}, error_code {}, ep);
}
Expand Down
54 changes: 54 additions & 0 deletions include/async_mqtt5/websocket.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// Copyright (c) 2023-2024 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef ASYNC_MQTT5_WEBSOCKET_HPP
#define ASYNC_MQTT5_WEBSOCKET_HPP

#include <boost/beast/http/field.hpp>
#include <boost/beast/websocket/rfc6455.hpp>
#include <boost/beast/websocket/stream.hpp>

#include <async_mqtt5/types.hpp>

namespace async_mqtt5 {

// Trait definition for Beast
template <typename Stream>
struct ws_handshake_traits<boost::beast::websocket::stream<Stream>> {

template <typename CompletionToken>
static decltype(auto) async_handshake(
boost::beast::websocket::stream<Stream>& stream,
authority_path ap, CompletionToken&& token
) {
using namespace boost::beast;

// Set suggested timeout settings for the websocket
stream.set_option(
websocket::stream_base::timeout::suggested(role_type::client)
);

stream.binary(true);

// Set a decorator to change the User-Agent of the handshake
stream.set_option(websocket::stream_base::decorator(
[](websocket::request_type& req) {
req.set(http::field::sec_websocket_protocol, "mqtt");
req.set(http::field::user_agent, "boost.mqtt");
})
);

stream.async_handshake(
ap.host + ':' + ap.port, ap.path,
std::forward<CompletionToken>(token)
);
}
};

} // end namespace async_mqtt5

#endif // !ASYNC_MQTT5_WEBSOCKET_HPP
1 change: 1 addition & 0 deletions test/integration/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <boost/system/error_code.hpp>

#include <async_mqtt5.hpp>
#include <async_mqtt5/websocket.hpp>

namespace async_mqtt5 {

Expand Down
1 change: 1 addition & 0 deletions test/integration/mqtt_features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <boost/beast/websocket/stream.hpp>

#include <async_mqtt5.hpp>
#include <async_mqtt5/websocket.hpp>

BOOST_AUTO_TEST_SUITE(mqtt_features/*, *boost::unit_test::disabled()*/)

Expand Down
1 change: 1 addition & 0 deletions test/unit/default_completion_tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <boost/beast/websocket/ssl.hpp> // async_teardown for asio::ssl::socket

#include <async_mqtt5.hpp>
#include <async_mqtt5/websocket.hpp>

namespace async_mqtt5 {

Expand Down
1 change: 1 addition & 0 deletions test/unit/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <async_mqtt5/mqtt_client.hpp>
#include <async_mqtt5/logger.hpp>
#include <async_mqtt5/logger_traits.hpp>
#include <async_mqtt5/websocket.hpp>

#include "test_common/message_exchange.hpp"
#include "test_common/test_service.hpp"
Expand Down

0 comments on commit d19f466

Please sign in to comment.