mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 06:15:24 +02:00
Add serializer::limit
This commit is contained in:
@@ -5,6 +5,7 @@ Version 75:
|
|||||||
* Shrink serializer buffers using buffers_ref
|
* Shrink serializer buffers using buffers_ref
|
||||||
* Tidy up BEAST_NO_BIG_VARIANTS
|
* Tidy up BEAST_NO_BIG_VARIANTS
|
||||||
* Shrink serializer buffers using buffers_ref
|
* Shrink serializer buffers using buffers_ref
|
||||||
|
* Add serializer::limit
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -28,8 +28,10 @@ namespace beast {
|
|||||||
template<class BufferSequence>
|
template<class BufferSequence>
|
||||||
class buffer_prefix_view
|
class buffer_prefix_view
|
||||||
{
|
{
|
||||||
using iter_type =
|
using buffers_type = typename
|
||||||
typename BufferSequence::const_iterator;
|
std::decay<BufferSequence>::type;
|
||||||
|
|
||||||
|
using iter_type = typename buffers_type::const_iterator;
|
||||||
|
|
||||||
BufferSequence bs_;
|
BufferSequence bs_;
|
||||||
iter_type back_;
|
iter_type back_;
|
||||||
|
@@ -48,11 +48,8 @@ class buffer_prefix_view<BufferSequence>::const_iterator
|
|||||||
{
|
{
|
||||||
friend class buffer_prefix_view<BufferSequence>;
|
friend class buffer_prefix_view<BufferSequence>;
|
||||||
|
|
||||||
using iter_type =
|
|
||||||
typename BufferSequence::const_iterator;
|
|
||||||
|
|
||||||
buffer_prefix_view const* b_ = nullptr;
|
buffer_prefix_view const* b_ = nullptr;
|
||||||
typename BufferSequence::const_iterator it_;
|
iter_type it_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = typename std::conditional<
|
using value_type = typename std::conditional<
|
||||||
|
@@ -36,6 +36,22 @@ frdinit(std::false_type)
|
|||||||
frd_.emplace(m_, m_.version, m_.result_int());
|
frd_.emplace(m_, m_.version, m_.result_int());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool isRequest, class Body,
|
||||||
|
class Fields, class ChunkDecorator>
|
||||||
|
template<class T1, class T2, class Visit>
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
||||||
|
do_visit(error_code& ec, Visit& visit)
|
||||||
|
{
|
||||||
|
// VFALCO work-around for missing variant::emplace
|
||||||
|
pv_.~variant();
|
||||||
|
new(&pv_) decltype(pv_){
|
||||||
|
T1{limit_, boost::get<T2>(v_)}};
|
||||||
|
visit(ec, beast::detail::make_buffers_ref(
|
||||||
|
boost::get<T1>(pv_)));
|
||||||
|
}
|
||||||
|
|
||||||
template<bool isRequest, class Body,
|
template<bool isRequest, class Body,
|
||||||
class Fields, class ChunkDecorator>
|
class Fields, class ChunkDecorator>
|
||||||
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
||||||
@@ -83,7 +99,7 @@ next(error_code& ec, Visit&& visit)
|
|||||||
if(! result)
|
if(! result)
|
||||||
goto go_header_only;
|
goto go_header_only;
|
||||||
more_ = result->second;
|
more_ = result->second;
|
||||||
v_ = cb0_t{
|
v_ = cb2_t{
|
||||||
boost::in_place_init,
|
boost::in_place_init,
|
||||||
frd_->get(),
|
frd_->get(),
|
||||||
result->first};
|
result->first};
|
||||||
@@ -92,16 +108,14 @@ next(error_code& ec, Visit&& visit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case do_header:
|
case do_header:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb2_t, cb2_t>(ec, visit);
|
||||||
boost::get<cb0_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
go_header_only:
|
go_header_only:
|
||||||
v_ = ch_t{frd_->get()};
|
v_ = cb1_t{frd_->get()};
|
||||||
s_ = do_header_only;
|
s_ = do_header_only;
|
||||||
case do_header_only:
|
case do_header_only:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb1_t, cb1_t>(ec, visit);
|
||||||
boost::get<ch_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case do_body:
|
case do_body:
|
||||||
@@ -122,14 +136,13 @@ next(error_code& ec, Visit&& visit)
|
|||||||
if(! result)
|
if(! result)
|
||||||
goto go_complete;
|
goto go_complete;
|
||||||
more_ = result->second;
|
more_ = result->second;
|
||||||
v_ = cb1_t{result->first};
|
v_ = cb3_t{result->first};
|
||||||
s_ = do_body + 2;
|
s_ = do_body + 2;
|
||||||
BEAST_FALLTHROUGH;
|
BEAST_FALLTHROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
case do_body + 2:
|
case do_body + 2:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb3_t, cb3_t>(ec, visit);
|
||||||
boost::get<cb1_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -155,7 +168,7 @@ next(error_code& ec, Visit&& visit)
|
|||||||
if(! more_)
|
if(! more_)
|
||||||
{
|
{
|
||||||
// do it all in one buffer
|
// do it all in one buffer
|
||||||
v_ = ch3_t{
|
v_ = cb7_t{
|
||||||
boost::in_place_init,
|
boost::in_place_init,
|
||||||
frd_->get(),
|
frd_->get(),
|
||||||
detail::chunk_header{
|
detail::chunk_header{
|
||||||
@@ -183,7 +196,7 @@ next(error_code& ec, Visit&& visit)
|
|||||||
goto go_all_c;
|
goto go_all_c;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
v_ = ch0_t{
|
v_ = cb4_t{
|
||||||
boost::in_place_init,
|
boost::in_place_init,
|
||||||
frd_->get(),
|
frd_->get(),
|
||||||
detail::chunk_header{
|
detail::chunk_header{
|
||||||
@@ -203,16 +216,14 @@ next(error_code& ec, Visit&& visit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case do_header_c:
|
case do_header_c:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb4_t, cb4_t>(ec, visit);
|
||||||
boost::get<ch0_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
go_header_only_c:
|
go_header_only_c:
|
||||||
v_ = ch_t{frd_->get()};
|
v_ = cb1_t{frd_->get()};
|
||||||
s_ = do_header_only_c;
|
s_ = do_header_only_c;
|
||||||
case do_header_only_c:
|
case do_header_only_c:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb1_t, cb1_t>(ec, visit);
|
||||||
boost::get<ch_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case do_body_c:
|
case do_body_c:
|
||||||
@@ -237,7 +248,7 @@ next(error_code& ec, Visit&& visit)
|
|||||||
if(! more_)
|
if(! more_)
|
||||||
{
|
{
|
||||||
// do it all in one buffer
|
// do it all in one buffer
|
||||||
v_ = ch2_t{
|
v_ = cb6_t{
|
||||||
boost::in_place_init,
|
boost::in_place_init,
|
||||||
detail::chunk_header{
|
detail::chunk_header{
|
||||||
buffer_size(result->first)},
|
buffer_size(result->first)},
|
||||||
@@ -264,7 +275,7 @@ next(error_code& ec, Visit&& visit)
|
|||||||
goto go_body_final_c;
|
goto go_body_final_c;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
v_ = ch1_t{
|
v_ = cb5_t{
|
||||||
boost::in_place_init,
|
boost::in_place_init,
|
||||||
detail::chunk_header{
|
detail::chunk_header{
|
||||||
buffer_size(result->first)},
|
buffer_size(result->first)},
|
||||||
@@ -283,29 +294,26 @@ next(error_code& ec, Visit&& visit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case do_body_c + 2:
|
case do_body_c + 2:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb5_t, cb5_t>(ec, visit);
|
||||||
boost::get<ch1_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef BEAST_NO_BIG_VARIANTS
|
#ifndef BEAST_NO_BIG_VARIANTS
|
||||||
go_body_final_c:
|
go_body_final_c:
|
||||||
s_ = do_body_final_c;
|
s_ = do_body_final_c;
|
||||||
case do_body_final_c:
|
case do_body_final_c:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb6_t, cb6_t>(ec, visit);
|
||||||
boost::get<ch2_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
go_all_c:
|
go_all_c:
|
||||||
s_ = do_all_c;
|
s_ = do_all_c;
|
||||||
case do_all_c:
|
case do_all_c:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb7_t, cb7_t>(ec, visit);
|
||||||
boost::get<ch3_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
go_final_c:
|
go_final_c:
|
||||||
case do_final_c:
|
case do_final_c:
|
||||||
v_ = ch4_t{
|
v_ = cb8_t{
|
||||||
boost::in_place_init,
|
boost::in_place_init,
|
||||||
detail::chunk_final(),
|
detail::chunk_final(),
|
||||||
[&]()
|
[&]()
|
||||||
@@ -321,8 +329,7 @@ next(error_code& ec, Visit&& visit)
|
|||||||
BEAST_FALLTHROUGH;
|
BEAST_FALLTHROUGH;
|
||||||
|
|
||||||
case do_final_c + 1:
|
case do_final_c + 1:
|
||||||
visit(ec, make_buffers_ref(
|
do_visit<pcb8_t, cb8_t>(ec, visit);
|
||||||
boost::get<ch4_t>(v_)));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -349,9 +356,9 @@ consume(std::size_t n)
|
|||||||
{
|
{
|
||||||
case do_header:
|
case do_header:
|
||||||
BOOST_ASSERT(n <= buffer_size(
|
BOOST_ASSERT(n <= buffer_size(
|
||||||
boost::get<cb0_t>(v_)));
|
boost::get<cb2_t>(v_)));
|
||||||
boost::get<cb0_t>(v_).consume(n);
|
boost::get<cb2_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<cb0_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb2_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
header_done_ = true;
|
header_done_ = true;
|
||||||
v_ = boost::blank{};
|
v_ = boost::blank{};
|
||||||
@@ -362,9 +369,9 @@ consume(std::size_t n)
|
|||||||
|
|
||||||
case do_header_only:
|
case do_header_only:
|
||||||
BOOST_ASSERT(n <= buffer_size(
|
BOOST_ASSERT(n <= buffer_size(
|
||||||
boost::get<ch_t>(v_)));
|
boost::get<cb1_t>(v_)));
|
||||||
boost::get<ch_t>(v_).consume(n);
|
boost::get<cb1_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<ch_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb1_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
frd_ = boost::none;
|
frd_ = boost::none;
|
||||||
header_done_ = true;
|
header_done_ = true;
|
||||||
@@ -376,9 +383,9 @@ consume(std::size_t n)
|
|||||||
case do_body + 2:
|
case do_body + 2:
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n <= buffer_size(
|
BOOST_ASSERT(n <= buffer_size(
|
||||||
boost::get<cb1_t>(v_)));
|
boost::get<cb3_t>(v_)));
|
||||||
boost::get<cb1_t>(v_).consume(n);
|
boost::get<cb3_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<cb1_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb3_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
v_ = boost::blank{};
|
v_ = boost::blank{};
|
||||||
if(! more_)
|
if(! more_)
|
||||||
@@ -391,9 +398,9 @@ consume(std::size_t n)
|
|||||||
|
|
||||||
case do_header_c:
|
case do_header_c:
|
||||||
BOOST_ASSERT(n <= buffer_size(
|
BOOST_ASSERT(n <= buffer_size(
|
||||||
boost::get<ch0_t>(v_)));
|
boost::get<cb4_t>(v_)));
|
||||||
boost::get<ch0_t>(v_).consume(n);
|
boost::get<cb4_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<ch0_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb4_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
header_done_ = true;
|
header_done_ = true;
|
||||||
v_ = boost::blank{};
|
v_ = boost::blank{};
|
||||||
@@ -406,9 +413,9 @@ consume(std::size_t n)
|
|||||||
case do_header_only_c:
|
case do_header_only_c:
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n <= buffer_size(
|
BOOST_ASSERT(n <= buffer_size(
|
||||||
boost::get<ch_t>(v_)));
|
boost::get<cb1_t>(v_)));
|
||||||
boost::get<ch_t>(v_).consume(n);
|
boost::get<cb1_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<ch_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb1_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
frd_ = boost::none;
|
frd_ = boost::none;
|
||||||
header_done_ = true;
|
header_done_ = true;
|
||||||
@@ -423,9 +430,9 @@ consume(std::size_t n)
|
|||||||
|
|
||||||
case do_body_c + 2:
|
case do_body_c + 2:
|
||||||
BOOST_ASSERT(n <= buffer_size(
|
BOOST_ASSERT(n <= buffer_size(
|
||||||
boost::get<ch1_t>(v_)));
|
boost::get<cb5_t>(v_)));
|
||||||
boost::get<ch1_t>(v_).consume(n);
|
boost::get<cb5_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<ch1_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb5_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
v_ = boost::blank{};
|
v_ = boost::blank{};
|
||||||
if(more_)
|
if(more_)
|
||||||
@@ -437,7 +444,7 @@ consume(std::size_t n)
|
|||||||
#ifndef BEAST_NO_BIG_VARIANTS
|
#ifndef BEAST_NO_BIG_VARIANTS
|
||||||
case do_body_final_c:
|
case do_body_final_c:
|
||||||
{
|
{
|
||||||
auto& b = boost::get<ch2_t>(v_);
|
auto& b = boost::get<cb6_t>(v_);
|
||||||
BOOST_ASSERT(n <= buffer_size(b));
|
BOOST_ASSERT(n <= buffer_size(b));
|
||||||
b.consume(n);
|
b.consume(n);
|
||||||
if(buffer_size(b) > 0)
|
if(buffer_size(b) > 0)
|
||||||
@@ -449,7 +456,7 @@ consume(std::size_t n)
|
|||||||
|
|
||||||
case do_all_c:
|
case do_all_c:
|
||||||
{
|
{
|
||||||
auto& b = boost::get<ch3_t>(v_);
|
auto& b = boost::get<cb7_t>(v_);
|
||||||
BOOST_ASSERT(n <= buffer_size(b));
|
BOOST_ASSERT(n <= buffer_size(b));
|
||||||
b.consume(n);
|
b.consume(n);
|
||||||
if(buffer_size(b) > 0)
|
if(buffer_size(b) > 0)
|
||||||
@@ -463,9 +470,9 @@ consume(std::size_t n)
|
|||||||
|
|
||||||
case do_final_c + 1:
|
case do_final_c + 1:
|
||||||
BOOST_ASSERT(buffer_size(
|
BOOST_ASSERT(buffer_size(
|
||||||
boost::get<ch4_t>(v_)));
|
boost::get<cb8_t>(v_)));
|
||||||
boost::get<ch4_t>(v_).consume(n);
|
boost::get<cb8_t>(v_).consume(n);
|
||||||
if(buffer_size(boost::get<ch4_t>(v_)) > 0)
|
if(buffer_size(boost::get<cb8_t>(v_)) > 0)
|
||||||
break;
|
break;
|
||||||
v_ = boost::blank{};
|
v_ = boost::blank{};
|
||||||
goto go_complete;
|
goto go_complete;
|
||||||
|
@@ -54,12 +54,12 @@ class write_some_op
|
|||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
void
|
||||||
operator()(error_code& ec,
|
operator()(error_code& ec,
|
||||||
ConstBufferSequence const& buffer)
|
ConstBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
invoked = true;
|
invoked = true;
|
||||||
return op_.s_.async_write_some(
|
return op_.s_.async_write_some(
|
||||||
buffer, std::move(op_));
|
buffers, std::move(op_));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,12 +211,12 @@ class write_op
|
|||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
void
|
||||||
operator()(error_code& ec,
|
operator()(error_code& ec,
|
||||||
ConstBufferSequence const& buffer)
|
ConstBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
ec.assign(0, ec.category());
|
ec.assign(0, ec.category());
|
||||||
invoked = true;
|
invoked = true;
|
||||||
return op_.s_.async_write_some(
|
return op_.s_.async_write_some(
|
||||||
buffer, std::move(op_));
|
buffers, std::move(op_));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -464,11 +464,11 @@ public:
|
|||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
void
|
||||||
operator()(error_code& ec,
|
operator()(error_code& ec,
|
||||||
ConstBufferSequence const& buffer)
|
ConstBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
invoked = true;
|
invoked = true;
|
||||||
bytes_transferred =
|
bytes_transferred =
|
||||||
stream_.write_some(buffer, ec);
|
stream_.write_some(buffers, ec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -490,11 +490,11 @@ public:
|
|||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
void
|
void
|
||||||
operator()(error_code& ec,
|
operator()(error_code& ec,
|
||||||
ConstBufferSequence const& buffer)
|
ConstBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
invoked = true;
|
invoked = true;
|
||||||
bytes_transferred = boost::asio::write(
|
bytes_transferred = boost::asio::write(
|
||||||
stream_, buffer, ec);
|
stream_, buffers, ec);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <beast/config.hpp>
|
#include <beast/config.hpp>
|
||||||
#include <beast/core/buffer_cat.hpp>
|
#include <beast/core/buffer_cat.hpp>
|
||||||
|
#include <beast/core/buffer_prefix.hpp>
|
||||||
#include <beast/core/consuming_buffers.hpp>
|
#include <beast/core/consuming_buffers.hpp>
|
||||||
#include <beast/core/string.hpp>
|
#include <beast/core/string.hpp>
|
||||||
#include <beast/core/type_traits.hpp>
|
#include <beast/core/type_traits.hpp>
|
||||||
@@ -157,35 +158,44 @@ class serializer
|
|||||||
void frdinit(std::true_type);
|
void frdinit(std::true_type);
|
||||||
void frdinit(std::false_type);
|
void frdinit(std::false_type);
|
||||||
|
|
||||||
|
template<class T1, class T2, class Visit>
|
||||||
|
void
|
||||||
|
do_visit(error_code& ec, Visit& visit);
|
||||||
|
|
||||||
using reader = typename Body::reader;
|
using reader = typename Body::reader;
|
||||||
|
|
||||||
using ch_t = consuming_buffers<typename
|
using cb1_t = consuming_buffers<typename
|
||||||
Fields::reader::const_buffers_type>; // header
|
Fields::reader::const_buffers_type>; // header
|
||||||
|
using pcb1_t = buffer_prefix_view<cb1_t const&>;
|
||||||
|
|
||||||
using cb0_t = consuming_buffers<buffer_cat_view<
|
using cb2_t = consuming_buffers<buffer_cat_view<
|
||||||
typename Fields::reader::const_buffers_type,// header
|
typename Fields::reader::const_buffers_type,// header
|
||||||
typename reader::const_buffers_type>>; // body
|
typename reader::const_buffers_type>>; // body
|
||||||
|
using pcb2_t = buffer_prefix_view<cb2_t const&>;
|
||||||
|
|
||||||
using cb1_t = consuming_buffers<
|
using cb3_t = consuming_buffers<
|
||||||
typename reader::const_buffers_type>; // body
|
typename reader::const_buffers_type>; // body
|
||||||
|
using pcb3_t = buffer_prefix_view<cb3_t const&>;
|
||||||
|
|
||||||
using ch0_t = consuming_buffers<buffer_cat_view<
|
using cb4_t = consuming_buffers<buffer_cat_view<
|
||||||
typename Fields::reader::const_buffers_type,// header
|
typename Fields::reader::const_buffers_type,// header
|
||||||
detail::chunk_header, // chunk-header
|
detail::chunk_header, // chunk-header
|
||||||
boost::asio::const_buffers_1, // chunk-ext
|
boost::asio::const_buffers_1, // chunk-ext
|
||||||
boost::asio::const_buffers_1, // crlf
|
boost::asio::const_buffers_1, // crlf
|
||||||
typename reader::const_buffers_type, // body
|
typename reader::const_buffers_type, // body
|
||||||
boost::asio::const_buffers_1>>; // crlf
|
boost::asio::const_buffers_1>>; // crlf
|
||||||
|
using pcb4_t = buffer_prefix_view<cb4_t const&>;
|
||||||
|
|
||||||
using ch1_t = consuming_buffers<buffer_cat_view<
|
using cb5_t = consuming_buffers<buffer_cat_view<
|
||||||
detail::chunk_header, // chunk-header
|
detail::chunk_header, // chunk-header
|
||||||
boost::asio::const_buffers_1, // chunk-ext
|
boost::asio::const_buffers_1, // chunk-ext
|
||||||
boost::asio::const_buffers_1, // crlf
|
boost::asio::const_buffers_1, // crlf
|
||||||
typename reader::const_buffers_type, // body
|
typename reader::const_buffers_type, // body
|
||||||
boost::asio::const_buffers_1>>; // crlf
|
boost::asio::const_buffers_1>>; // crlf
|
||||||
|
using pcb5_t = buffer_prefix_view<cb5_t const&>;
|
||||||
|
|
||||||
#ifndef BEAST_NO_BIG_VARIANTS
|
#ifndef BEAST_NO_BIG_VARIANTS
|
||||||
using ch2_t = consuming_buffers<buffer_cat_view<
|
using cb6_t = consuming_buffers<buffer_cat_view<
|
||||||
detail::chunk_header, // chunk-header
|
detail::chunk_header, // chunk-header
|
||||||
boost::asio::const_buffers_1, // chunk-ext
|
boost::asio::const_buffers_1, // chunk-ext
|
||||||
boost::asio::const_buffers_1, // crlf
|
boost::asio::const_buffers_1, // crlf
|
||||||
@@ -194,8 +204,9 @@ class serializer
|
|||||||
boost::asio::const_buffers_1, // chunk-final
|
boost::asio::const_buffers_1, // chunk-final
|
||||||
boost::asio::const_buffers_1, // trailers
|
boost::asio::const_buffers_1, // trailers
|
||||||
boost::asio::const_buffers_1>>; // crlf
|
boost::asio::const_buffers_1>>; // crlf
|
||||||
|
using pcb6_t = buffer_prefix_view<cb6_t const&>;
|
||||||
|
|
||||||
using ch3_t = consuming_buffers<buffer_cat_view<
|
using cb7_t = consuming_buffers<buffer_cat_view<
|
||||||
typename Fields::reader::const_buffers_type,// header
|
typename Fields::reader::const_buffers_type,// header
|
||||||
detail::chunk_header, // chunk-header
|
detail::chunk_header, // chunk-header
|
||||||
boost::asio::const_buffers_1, // chunk-ext
|
boost::asio::const_buffers_1, // chunk-ext
|
||||||
@@ -205,22 +216,32 @@ class serializer
|
|||||||
boost::asio::const_buffers_1, // chunk-final
|
boost::asio::const_buffers_1, // chunk-final
|
||||||
boost::asio::const_buffers_1, // trailers
|
boost::asio::const_buffers_1, // trailers
|
||||||
boost::asio::const_buffers_1>>; // crlf
|
boost::asio::const_buffers_1>>; // crlf
|
||||||
|
using pcb7_t = buffer_prefix_view<cb7_t const&>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using ch4_t = consuming_buffers<buffer_cat_view<
|
using cb8_t = consuming_buffers<buffer_cat_view<
|
||||||
boost::asio::const_buffers_1, // chunk-final
|
boost::asio::const_buffers_1, // chunk-final
|
||||||
boost::asio::const_buffers_1, // trailers
|
boost::asio::const_buffers_1, // trailers
|
||||||
boost::asio::const_buffers_1>>; // crlf
|
boost::asio::const_buffers_1>>; // crlf
|
||||||
|
using pcb8_t = buffer_prefix_view<cb8_t const&>;
|
||||||
|
|
||||||
message<isRequest, Body, Fields> const& m_;
|
message<isRequest, Body, Fields> const& m_;
|
||||||
boost::optional<typename Fields::reader> frd_;
|
boost::optional<typename Fields::reader> frd_;
|
||||||
boost::optional<reader> rd_;
|
boost::optional<reader> rd_;
|
||||||
boost::variant<boost::blank,
|
boost::variant<boost::blank,
|
||||||
ch_t, cb0_t, cb1_t, ch0_t, ch1_t
|
cb1_t, cb2_t, cb3_t, cb4_t, cb5_t
|
||||||
#ifndef BEAST_NO_BIG_VARIANTS
|
#ifndef BEAST_NO_BIG_VARIANTS
|
||||||
,ch2_t, ch3_t
|
,cb6_t, cb7_t
|
||||||
#endif
|
#endif
|
||||||
, ch4_t> v_;
|
, cb8_t> v_;
|
||||||
|
boost::variant<boost::blank,
|
||||||
|
pcb1_t, pcb2_t, pcb3_t, pcb4_t, pcb5_t
|
||||||
|
#ifndef BEAST_NO_BIG_VARIANTS
|
||||||
|
,pcb6_t, pcb7_t
|
||||||
|
#endif
|
||||||
|
, pcb8_t> pv_;
|
||||||
|
std::size_t limit_ =
|
||||||
|
(std::numeric_limits<std::size_t>::max)();
|
||||||
int s_ = do_construct;
|
int s_ = do_construct;
|
||||||
bool split_ = false;
|
bool split_ = false;
|
||||||
bool header_done_ = false;
|
bool header_done_ = false;
|
||||||
@@ -246,6 +267,31 @@ public:
|
|||||||
serializer(message<isRequest, Body, Fields> const& msg,
|
serializer(message<isRequest, Body, Fields> const& msg,
|
||||||
ChunkDecorator const& decorator = ChunkDecorator{});
|
ChunkDecorator const& decorator = ChunkDecorator{});
|
||||||
|
|
||||||
|
/// Returns the serialized buffer size limit
|
||||||
|
std::size_t
|
||||||
|
limit() const
|
||||||
|
{
|
||||||
|
return limit_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set the serialized buffer size limit
|
||||||
|
|
||||||
|
This function adjusts the limit on the maximum size of the
|
||||||
|
buffers passed to the visitor. The new size limit takes effect
|
||||||
|
in the following call to @ref next.
|
||||||
|
|
||||||
|
The default is no buffer size limit.
|
||||||
|
|
||||||
|
@param limit The new buffer size limit. If this number
|
||||||
|
is zero, the size limit is removed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
limit(std::size_t limit)
|
||||||
|
{
|
||||||
|
limit_ = limit > 0 ? limit:
|
||||||
|
(std::numeric_limits<std::size_t>::max)();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if we will pause after writing the complete header.
|
/** Returns `true` if we will pause after writing the complete header.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
|
@@ -7,3 +7,57 @@
|
|||||||
|
|
||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <beast/http/serializer.hpp>
|
#include <beast/http/serializer.hpp>
|
||||||
|
|
||||||
|
#include <beast/http/string_body.hpp>
|
||||||
|
#include <beast/unit_test/suite.hpp>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
namespace http {
|
||||||
|
|
||||||
|
class serializer_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct lambda
|
||||||
|
{
|
||||||
|
std::size_t size;
|
||||||
|
|
||||||
|
template<class ConstBufferSequence>
|
||||||
|
void
|
||||||
|
operator()(error_code&,
|
||||||
|
ConstBufferSequence const& buffers)
|
||||||
|
{
|
||||||
|
size = boost::asio::buffer_size(buffers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
testWriteLimit()
|
||||||
|
{
|
||||||
|
auto const limit = 30;
|
||||||
|
lambda visit;
|
||||||
|
error_code ec;
|
||||||
|
response<string_body> res;
|
||||||
|
res.body.append(1000, '*');
|
||||||
|
serializer<false, string_body> sr{res};
|
||||||
|
sr.limit(limit);
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
sr.next(ec, visit);
|
||||||
|
BEAST_EXPECT(visit.size <= limit);
|
||||||
|
sr.consume(visit.size);
|
||||||
|
if(sr.is_done())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
run() override
|
||||||
|
{
|
||||||
|
testWriteLimit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(serializer,http,beast);
|
||||||
|
|
||||||
|
} // http
|
||||||
|
} // beast
|
||||||
|
Reference in New Issue
Block a user