Skip to content

Commit 109248d

Browse files
committed
Removes unnecessary dynamic buffer.
1 parent f7b4ec2 commit 109248d

File tree

5 files changed

+28
-41
lines changed

5 files changed

+28
-41
lines changed

include/boost/redis/config.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <string>
1111
#include <chrono>
1212
#include <optional>
13+
#include <limits>
1314

1415
namespace boost::redis
1516
{
@@ -78,6 +79,13 @@ struct config {
7879
* To disable reconnection pass zero as duration.
7980
*/
8081
std::chrono::steady_clock::duration reconnect_wait_interval = std::chrono::seconds{1};
82+
83+
/** @brief Maximum size of a socket read.
84+
*
85+
* Sets a limit on how much data is allowed to be read into the
86+
* read buffer. It can be used to prevent DDOS.
87+
*/
88+
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)();
8189
};
8290

8391
} // boost::redis

include/boost/redis/connection.hpp

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
#include <cstddef>
5151
#include <deque>
5252
#include <functional>
53-
#include <limits>
5453
#include <memory>
5554
#include <string_view>
5655
#include <utility>
@@ -59,13 +58,6 @@ namespace boost::redis {
5958
namespace detail
6059
{
6160

62-
template <class DynamicBuffer>
63-
std::string_view buffer_view(DynamicBuffer buf) noexcept
64-
{
65-
char const* start = static_cast<char const*>(buf.data(0, buf.size()).data());
66-
return std::string_view{start, std::size(buf)};
67-
}
68-
6961
template <class AsyncReadStream, class DynamicBuffer>
7062
class append_some_op {
7163
private:
@@ -250,6 +242,8 @@ template <class Conn, class Logger>
250242
struct reader_op {
251243
using parse_result = typename Conn::parse_result;
252244
using parse_ret_type = typename Conn::parse_ret_type;
245+
using dyn_buffer_type = asio::dynamic_string_buffer<char, std::char_traits<char>, std::allocator<char>>;
246+
253247
Conn* conn_;
254248
Logger logger_;
255249
parse_ret_type res_{parse_result::resp, 0};
@@ -270,14 +264,14 @@ struct reader_op {
270264
BOOST_ASIO_CORO_YIELD
271265
async_append_some(
272266
conn_->next_layer(),
273-
conn_->dbuf_,
267+
dyn_buffer_type{conn_->read_buffer_, conn_->cfg_.max_read_size},
274268
conn_->get_suggested_buffer_growth(),
275269
std::move(self));
276270
} else {
277271
BOOST_ASIO_CORO_YIELD
278272
async_append_some(
279273
conn_->next_layer().next_layer(),
280-
conn_->dbuf_,
274+
dyn_buffer_type{conn_->read_buffer_, conn_->cfg_.max_read_size},
281275
conn_->get_suggested_buffer_growth(),
282276
std::move(self));
283277
}
@@ -302,7 +296,7 @@ struct reader_op {
302296
}
303297
}
304298

305-
res_ = conn_->on_read(buffer_view(conn_->dbuf_), ec);
299+
res_ = conn_->on_read(ec);
306300
if (ec) {
307301
logger_.trace("reader_op (3)", ec);
308302
conn_->cancel(operation::run);
@@ -501,21 +495,17 @@ class basic_connection {
501495
*
502496
* @param ex Executor on which connection operation will run.
503497
* @param ctx SSL context.
504-
* @param max_read_size Maximum read size that is passed to
505-
* the internal `asio::dynamic_buffer` constructor.
506498
*/
507499
explicit
508500
basic_connection(
509501
executor_type ex,
510-
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
511-
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)())
502+
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client})
512503
: ctx_{std::move(ctx)}
513504
, stream_{std::make_unique<next_layer_type>(ex, ctx_)}
514505
, writer_timer_{ex}
515506
, receive_channel_{ex, 256}
516507
, resv_{ex}
517508
, health_checker_{ex}
518-
, dbuf_{read_buffer_, max_read_size}
519509
{
520510
set_receive_response(ignore);
521511
writer_timer_.expires_at((std::chrono::steady_clock::time_point::max)());
@@ -525,9 +515,8 @@ class basic_connection {
525515
explicit
526516
basic_connection(
527517
asio::io_context& ioc,
528-
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
529-
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)())
530-
: basic_connection(ioc.get_executor(), std::move(ctx), max_read_size)
518+
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client})
519+
: basic_connection(ioc.get_executor(), std::move(ctx))
531520
{ }
532521

533522
/** @brief Starts underlying connection operations.
@@ -1126,13 +1115,13 @@ class basic_connection {
11261115
}
11271116

11281117
on_push_ = false;
1129-
dbuf_.consume(parser_.get_consumed());
1118+
read_buffer_.erase(0, parser_.get_consumed());
11301119
auto const res = std::make_pair(t, parser_.get_consumed());
11311120
parser_.reset();
11321121
return res;
11331122
}
11341123

1135-
parse_ret_type on_read(std::string_view data, system::error_code& ec)
1124+
parse_ret_type on_read(system::error_code& ec)
11361125
{
11371126
// We arrive here in two states:
11381127
//
@@ -1148,7 +1137,7 @@ class basic_connection {
11481137
on_push_ = is_next_push();
11491138

11501139
if (on_push_) {
1151-
if (!resp3::parse(parser_, data, receive_adapter_, ec))
1140+
if (!resp3::parse(parser_, read_buffer_, receive_adapter_, ec))
11521141
return std::make_pair(parse_result::needs_more, 0);
11531142

11541143
if (ec)
@@ -1162,7 +1151,7 @@ class basic_connection {
11621151
BOOST_ASSERT(reqs_.front() != nullptr);
11631152
BOOST_ASSERT(reqs_.front()->expected_responses_ != 0);
11641153

1165-
if (!resp3::parse(parser_, data, reqs_.front()->adapter_, ec))
1154+
if (!resp3::parse(parser_, read_buffer_, reqs_.front()->adapter_, ec))
11661155
return std::make_pair(parse_result::needs_more, 0);
11671156

11681157
if (ec) {
@@ -1205,11 +1194,8 @@ class basic_connection {
12051194
resp3_handshaker_type handshaker_;
12061195
receiver_adapter_type receive_adapter_;
12071196

1208-
using dyn_buffer_type = asio::dynamic_string_buffer<char, std::char_traits<char>, std::allocator<char>>;
1209-
12101197
config cfg_;
12111198
std::string read_buffer_;
1212-
dyn_buffer_type dbuf_;
12131199
std::string write_buffer_;
12141200
reqs_type reqs_;
12151201
resp3::parser parser_{};
@@ -1237,15 +1223,13 @@ class connection {
12371223
explicit
12381224
connection(
12391225
executor_type ex,
1240-
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
1241-
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)());
1226+
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client});
12421227

12431228
/// Contructs from a context.
12441229
explicit
12451230
connection(
12461231
asio::io_context& ioc,
1247-
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client},
1248-
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)());
1232+
asio::ssl::context ctx = asio::ssl::context{asio::ssl::context::tlsv12_client});
12491233

12501234
/// Returns the underlying executor.
12511235
executor_type get_executor() noexcept

include/boost/redis/impl/connection.ipp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,12 @@
99

1010
namespace boost::redis {
1111

12-
connection::connection(
13-
executor_type ex,
14-
asio::ssl::context ctx,
15-
std::size_t max_read_size)
16-
: impl_{ex, std::move(ctx), max_read_size}
12+
connection::connection(executor_type ex, asio::ssl::context ctx)
13+
: impl_{ex, std::move(ctx)}
1714
{ }
1815

19-
connection::connection(
20-
asio::io_context& ioc,
21-
asio::ssl::context ctx,
22-
std::size_t max_read_size)
23-
: impl_{ioc.get_executor(), std::move(ctx), max_read_size}
16+
connection::connection(asio::io_context& ioc, asio::ssl::context ctx)
17+
: impl_{ioc.get_executor(), std::move(ctx)}
2418
{ }
2519

2620
void

test/common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ boost::redis::config make_test_config()
5252
{
5353
boost::redis::config cfg;
5454
cfg.addr.host = get_server_hostname();
55+
cfg.max_read_size = 1000000;
5556
return cfg;
5657
}
5758

test/test_issue_181.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(issue_181)
3636
auto const level = boost::redis::logger::level::debug;
3737
net::io_context ioc;
3838
auto ctx = net::ssl::context{net::ssl::context::tlsv12_client};
39-
basic_connection conn{ioc.get_executor(), std::move(ctx), 1000000};
39+
basic_connection conn{ioc.get_executor(), std::move(ctx)};
4040
net::steady_timer timer{ioc};
4141
timer.expires_after(std::chrono::seconds{1});
4242

0 commit comments

Comments
 (0)