Skip to content

Commit

Permalink
Provides a way of passing a custom ssl context to the connection.
Browse files Browse the repository at this point in the history
  • Loading branch information
mzimbres committed Jan 21, 2024
1 parent 8bb0004 commit 234f961
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 38 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -686,12 +686,12 @@ https://lists.boost.org/Archives/boost/2023/01/253944.php.
not.

* ([Issue 168](https://github.com/boostorg/redis/issues/168)).
Provides SSL context getters. The user wants to be able to pass the
`ssl::context` in the connection constructor as is done in Boost.Beast
and Boost.MySql. However, doing so would penalize users on plain
connections, which would have to start passing a dummy context on
every instantiation. If there is more convincing argument I will
change this in the future.
Provides a way of passing a custom SSL context to the connection.
The design here differs from that of Boost.Beast and Boost.MySql
since in Boost.Redis the connection owns the context instead of only
storing a reference to a user provided one. This is ok so because
apps need only one connection for their entire application, which
makes the overhead of one ssl-context per connection negligible.

### Boost 1.84 (First release in Boost)

Expand Down
28 changes: 13 additions & 15 deletions include/boost/redis/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,23 +86,29 @@ class basic_connection {
using other = basic_connection<Executor1>;
};

/// Contructs from an executor.
/** @brief Constructor
*
* @param ex Executor on which connection operation will run.
* @param ctx SSL context.
* @param max_read_size Maximum read size that is passed to
* the internal `asio::dynamic_buffer` constructor.
*/
explicit
basic_connection(
executor_type ex,
asio::ssl::context::method method = asio::ssl::context::tls_client,
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)())
: impl_{ex, method, max_read_size}
: impl_{ex, std::move(ctx), max_read_size}
, timer_{ex}
{ }

/// Contructs from a context.
explicit
basic_connection(
asio::io_context& ioc,
asio::ssl::context::method method = asio::ssl::context::tls_client,
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)())
: basic_connection(ioc.get_executor(), method, max_read_size)
: basic_connection(ioc.get_executor(), std::move(ctx), max_read_size)
{ }

/** @brief Starts underlying connection operations.
Expand Down Expand Up @@ -286,10 +292,6 @@ class basic_connection {
auto const& get_ssl_context() const noexcept
{ return impl_.get_ssl_context();}

/// Returns the ssl context.
auto& get_ssl_context() noexcept
{ return impl_.get_ssl_context();}

/// Resets the underlying stream.
void reset_stream()
{ impl_.reset_stream(); }
Expand Down Expand Up @@ -343,14 +345,14 @@ class connection {
explicit
connection(
executor_type ex,
asio::ssl::context::method method = asio::ssl::context::tls_client,
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)());

/// Contructs from a context.
explicit
connection(
asio::io_context& ioc,
asio::ssl::context::method method = asio::ssl::context::tls_client,
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)());

/// Returns the underlying executor.
Expand Down Expand Up @@ -427,10 +429,6 @@ class connection {
auto const& get_ssl_context() const noexcept
{ return impl_.get_ssl_context();}

/// Returns the ssl context.
auto& get_ssl_context() noexcept
{ return impl_.get_ssl_context();}

private:
void
async_run_impl(
Expand Down
8 changes: 2 additions & 6 deletions include/boost/redis/detail/connection_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,9 @@ class connection_base {
/// Constructs from an executor.
connection_base(
executor_type ex,
asio::ssl::context::method method,
asio::ssl::context ctx,
std::size_t max_read_size)
: ctx_{method}
: ctx_{std::move(ctx)}
, stream_{std::make_unique<next_layer_type>(ex, ctx_)}
, writer_timer_{ex}
, receive_channel_{ex, 256}
Expand All @@ -411,10 +411,6 @@ class connection_base {
auto const& get_ssl_context() const noexcept
{ return ctx_;}

/// Returns the ssl context.
auto& get_ssl_context() noexcept
{ return ctx_;}

/// Resets the underlying stream.
void reset_stream()
{
Expand Down
8 changes: 4 additions & 4 deletions include/boost/redis/impl/connection.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ namespace boost::redis {

connection::connection(
executor_type ex,
asio::ssl::context::method method,
asio::ssl::context ctx,
std::size_t max_read_size)
: impl_{ex, method, max_read_size}
: impl_{ex, std::move(ctx), max_read_size}
{ }

connection::connection(
asio::io_context& ioc,
asio::ssl::context::method method,
asio::ssl::context ctx,
std::size_t max_read_size)
: impl_{ioc.get_executor(), method, max_read_size}
: impl_{ioc.get_executor(), std::move(ctx), max_read_size}
{ }

void
Expand Down
42 changes: 35 additions & 7 deletions test/test_conn_tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ bool verify_certificate(bool, net::ssl::verify_context&)
return true;
}

BOOST_AUTO_TEST_CASE(ping)
config make_tls_config()
{
config cfg;
cfg.use_ssl = true;
Expand All @@ -34,7 +34,12 @@ BOOST_AUTO_TEST_CASE(ping)
cfg.addr.host = "db.occase.de";
cfg.addr.port = "6380";
//cfg.health_check_interval = std::chrono::seconds{0};
return cfg;
}

BOOST_AUTO_TEST_CASE(ping_internal_ssl_context)
{
auto const cfg = make_tls_config();
std::string const in = "Kabuf";

request req;
Expand All @@ -59,14 +64,37 @@ BOOST_AUTO_TEST_CASE(ping)
BOOST_CHECK_EQUAL(in, std::get<0>(resp).value());
}

BOOST_AUTO_TEST_CASE(ping_custom_ssl_context)
{
auto const cfg = make_tls_config();
std::string const in = "Kabuf";

request req;
req.push("PING", in);

response<std::string> resp;

net::io_context ioc;
net::ssl::context ctx{boost::asio::ssl::context::tls_client};
connection conn{ioc, std::move(ctx)};
conn.next_layer().set_verify_mode(net::ssl::verify_peer);
conn.next_layer().set_verify_callback(verify_certificate);

conn.async_exec(req, resp, [&](auto ec, auto) {
BOOST_TEST(!ec);
conn.cancel();
});

conn.async_run(cfg, {}, [](auto) { });

ioc.run();

BOOST_CHECK_EQUAL(in, std::get<0>(resp).value());
}

BOOST_AUTO_TEST_CASE(acl_does_not_allow_select)
{
config cfg;
cfg.use_ssl = true;
cfg.username = "aedis";
cfg.password = "aedis";
cfg.addr.host = "db.occase.de";
cfg.addr.port = "6380";
auto cfg = make_tls_config();
cfg.database_index = 22;
cfg.reconnect_wait_interval = std::chrono::seconds::zero();

Expand Down

0 comments on commit 234f961

Please sign in to comment.