mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge commit '2f9a8440c2432d8a196571d6300404cb76314125' into develop
This commit is contained in:
@@ -47,7 +47,7 @@ namespace beast {
|
||||
@note See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3896.pdf">
|
||||
Library Foundations For Asynchronous Operations</a>
|
||||
*/
|
||||
template <class CompletionHandler, class Signature>
|
||||
template<class CompletionHandler, class Signature>
|
||||
struct async_completion
|
||||
{
|
||||
/** The type of the final handler called by the asynchronous initiation function.
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Adapts a @b `MutableBufferSequence` into a @b `Streambuf`.
|
||||
/** Adapts a @b `MutableBufferSequence` into a @b `DynamicBuffer`.
|
||||
|
||||
This class wraps a @b `MutableBufferSequence` to meet the requirements
|
||||
of @b `Streambuf`. Upon construction the input and output sequences are
|
||||
of @b `DynamicBuffer`. Upon construction the input and output sequences are
|
||||
empty. A copy of the mutable buffer sequence object is stored; however,
|
||||
ownership of the underlying memory is not transferred. The caller is
|
||||
responsible for making sure that referenced memory remains valid
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace detail {
|
||||
|
||||
*/
|
||||
|
||||
template <class = void>
|
||||
template<class = void>
|
||||
std::string const&
|
||||
base64_alphabet()
|
||||
{
|
||||
@@ -62,7 +62,7 @@ is_base64(unsigned char c)
|
||||
return (std::isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
template<class = void>
|
||||
std::string
|
||||
base64_encode (std::uint8_t const* data,
|
||||
std::size_t in_len)
|
||||
@@ -112,7 +112,7 @@ base64_encode (std::uint8_t const* data,
|
||||
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
template<class = void>
|
||||
std::string
|
||||
base64_encode (std::string const& s)
|
||||
{
|
||||
@@ -120,11 +120,11 @@ base64_encode (std::string const& s)
|
||||
std::uint8_t const*> (s.data()), s.size());
|
||||
}
|
||||
|
||||
template <class = void>
|
||||
template<class = void>
|
||||
std::string
|
||||
base64_decode(std::string const& data)
|
||||
{
|
||||
int in_len = data.size();
|
||||
auto in_len = data.size();
|
||||
unsigned char c3[3], c4[4];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
@@ -54,14 +54,14 @@ public:
|
||||
operator()()
|
||||
{
|
||||
invoke(h_, args_,
|
||||
index_sequence_for<Args...> ());
|
||||
index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
void
|
||||
operator()() const
|
||||
{
|
||||
invoke(h_, args_,
|
||||
index_sequence_for<Args...> ());
|
||||
index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
friend
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
template<class T>
|
||||
struct empty_base_optimization_decide
|
||||
: std::integral_constant <bool,
|
||||
std::is_empty <T>::value
|
||||
@@ -25,7 +25,7 @@ struct empty_base_optimization_decide
|
||||
{
|
||||
};
|
||||
|
||||
template <
|
||||
template<
|
||||
class T,
|
||||
int UniqueID = 0,
|
||||
bool ShouldDeriveFrom =
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
template<
|
||||
class T,
|
||||
int UniqueID
|
||||
>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template <class R, class C, class ...A>
|
||||
template<class R, class C, class ...A>
|
||||
auto
|
||||
is_call_possible_test(C&& c, int, A&& ...a)
|
||||
-> decltype(std::is_convertible<
|
||||
@@ -21,7 +21,7 @@ is_call_possible_test(C&& c, int, A&& ...a)
|
||||
std::is_same<R, void>::value,
|
||||
std::true_type());
|
||||
|
||||
template <class R, class C, class ...A>
|
||||
template<class R, class C, class ...A>
|
||||
std::false_type
|
||||
is_call_possible_test(C&& c, long, A&& ...a);
|
||||
|
||||
@@ -30,13 +30,13 @@ is_call_possible_test(C&& c, long, A&& ...a);
|
||||
is_call_possible<T, void(std::string)>
|
||||
*/
|
||||
/** @{ */
|
||||
template <class C, class F>
|
||||
template<class C, class F>
|
||||
struct is_call_possible
|
||||
: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class C, class R, class ...A>
|
||||
template<class C, class R, class ...A>
|
||||
struct is_call_possible<C, R(A...)>
|
||||
: decltype(is_call_possible_test<R>(
|
||||
std::declval<C>(), 1, std::declval<A>()...))
|
||||
|
||||
@@ -281,10 +281,10 @@ finish(sha1_context& ctx, void* digest) noexcept
|
||||
ctx.buf[ctx.buflen++] = 0x00;
|
||||
std::uint32_t block[BLOCK_INTS];
|
||||
sha1::make_block(ctx.buf, block);
|
||||
if (buflen > BLOCK_BYTES - 8)
|
||||
if(buflen > BLOCK_BYTES - 8)
|
||||
{
|
||||
sha1::transform(ctx.digest, block);
|
||||
for (size_t i = 0; i < BLOCK_INTS - 2; i++)
|
||||
for(size_t i = 0; i < BLOCK_INTS - 2; i++)
|
||||
block[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class has_get_io_service
|
||||
decltype(std::declval<U>().get_io_service()),
|
||||
boost::asio::io_service&>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
public:
|
||||
using type = decltype(check<T>(0));
|
||||
|
||||
@@ -227,7 +227,7 @@ public:
|
||||
|
||||
/// Write the given data to the stream. Returns the number of bytes written,
|
||||
/// or 0 if an error occurred.
|
||||
template <class ConstBufferSequence>
|
||||
template<class ConstBufferSequence>
|
||||
std::size_t
|
||||
write_some(ConstBufferSequence const& buffers,
|
||||
error_code& ec)
|
||||
|
||||
@@ -34,10 +34,10 @@ namespace beast {
|
||||
caller is still responsible for freeing memory.
|
||||
*/
|
||||
#if GENERATING_DOCS
|
||||
template <class T, class CompletionHandler>
|
||||
template<class T, class CompletionHandler>
|
||||
class handler_alloc;
|
||||
#else
|
||||
template <class T, class CompletionHandler>
|
||||
template<class T, class CompletionHandler>
|
||||
class handler_alloc
|
||||
{
|
||||
private:
|
||||
@@ -46,7 +46,7 @@ private:
|
||||
// should produce a compile error if CompletionHandler is not
|
||||
// constructible from H.
|
||||
//
|
||||
template <class U, class H>
|
||||
template<class U, class H>
|
||||
friend class handler_alloc;
|
||||
|
||||
CompletionHandler h_;
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
is_continuation(op->d_->h);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, read_some_op* op)
|
||||
{
|
||||
|
||||
@@ -129,7 +129,7 @@ protected:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A `Streambuf` with a fixed size internal buffer.
|
||||
/** A `DynamicBuffer` with a fixed size internal buffer.
|
||||
|
||||
@tparam N The number of bytes in the internal buffer.
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** A @b `Streambuf` that uses multiple buffers internally.
|
||||
/** A @b `DynamicBuffer` that uses multiple buffers internally.
|
||||
|
||||
The implementation uses a sequence of one or more character arrays
|
||||
of varying sizes. Additional character array objects are appended to
|
||||
the sequence to accommodate changes in the size of the character
|
||||
sequence.
|
||||
|
||||
@note Meets the requirements of @b `Streambuf`.
|
||||
@note Meets the requirements of @b `DynamicBuffer`.
|
||||
*/
|
||||
using streambuf = basic_streambuf<std::allocator<char>>;
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ protected:
|
||||
using list_t = typename boost::intrusive::make_list<
|
||||
element, boost::intrusive::constant_time_size<false>>::type;
|
||||
|
||||
using set_t = typename boost::intrusive::make_set<
|
||||
using set_t = typename boost::intrusive::make_multiset<
|
||||
element, boost::intrusive::constant_time_size<true>,
|
||||
boost::intrusive::compare<less>>::type;
|
||||
|
||||
@@ -117,7 +117,6 @@ protected:
|
||||
: set_(std::move(set))
|
||||
, list_(std::move(list))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -244,9 +243,10 @@ public:
|
||||
value.
|
||||
|
||||
Field names are stored as-is, but comparison are case-insensitive.
|
||||
The container preserves the order of insertion of fields with
|
||||
different names. For fields with the same name, the implementation
|
||||
concatenates values inserted with duplicate names as per rfc7230.
|
||||
When the container is iterated, the fields are presented in the order
|
||||
of insertion. For fields with the same name, the container behaves
|
||||
as a std::multiset; there will be a separate value for each occurrence
|
||||
of the field name.
|
||||
|
||||
@note Meets the requirements of @b `FieldSequence`.
|
||||
*/
|
||||
@@ -359,27 +359,44 @@ public:
|
||||
return set_.size();
|
||||
}
|
||||
|
||||
/** Returns `true` if the specified field exists. */
|
||||
/// Returns `true` if the specified field exists.
|
||||
bool
|
||||
exists(boost::string_ref const& name) const
|
||||
{
|
||||
return set_.find(name, less{}) != set_.end();
|
||||
}
|
||||
|
||||
/** Returns an iterator to the case-insensitive matching header. */
|
||||
/// Returns the number of values for the specified field.
|
||||
std::size_t
|
||||
count(boost::string_ref const& name) const;
|
||||
|
||||
/** Returns an iterator to the case-insensitive matching field name.
|
||||
|
||||
If more than one field with the specified name exists, the
|
||||
first field defined by insertion order is returned.
|
||||
*/
|
||||
iterator
|
||||
find(boost::string_ref const& name) const;
|
||||
|
||||
/** Returns the value for a case-insensitive matching header, or "" */
|
||||
/** Returns the value for a case-insensitive matching header, or `""`.
|
||||
|
||||
If more than one field with the specified name exists, the
|
||||
first field defined by insertion order is returned.
|
||||
*/
|
||||
boost::string_ref
|
||||
operator[](boost::string_ref const& name) const;
|
||||
|
||||
/** Clear the contents of the basic_headers. */
|
||||
/// Clear the contents of the basic_headers.
|
||||
void
|
||||
clear() noexcept;
|
||||
|
||||
/** Remove a field.
|
||||
|
||||
If more than one field with the specified name exists, all
|
||||
matching fields will be removed.
|
||||
|
||||
@param name The name of the field(s) to remove.
|
||||
|
||||
@return The number of fields removed.
|
||||
*/
|
||||
std::size_t
|
||||
@@ -387,39 +404,57 @@ public:
|
||||
|
||||
/** Insert a field value.
|
||||
|
||||
If a field value already exists the new value will be
|
||||
extended as per RFC2616 Section 4.2.
|
||||
If a field with the same name already exists, the
|
||||
existing field is untouched and a new field value pair
|
||||
is inserted into the container.
|
||||
|
||||
@param name The name of the field.
|
||||
|
||||
@param value A string holding the value of the field.
|
||||
*/
|
||||
// VFALCO TODO Consider allowing rvalue references for std::move?
|
||||
void
|
||||
insert(boost::string_ref const& name, boost::string_ref value);
|
||||
|
||||
/** Insert a field value.
|
||||
|
||||
If a field value already exists the new value will be
|
||||
extended as per RFC2616 Section 4.2.
|
||||
If a field with the same name already exists, the
|
||||
existing field is untouched and a new field value pair
|
||||
is inserted into the container.
|
||||
|
||||
@param name The name of the field
|
||||
|
||||
@param value The value of the field. The object will be
|
||||
converted to a string using `boost::lexical_cast`.
|
||||
*/
|
||||
template<class T>
|
||||
typename std::enable_if<
|
||||
! std::is_constructible<boost::string_ref, T>::value>::type
|
||||
insert(boost::string_ref name, T const& value)
|
||||
{
|
||||
insert(name,
|
||||
boost::lexical_cast<std::string>(value));
|
||||
insert(name, boost::lexical_cast<std::string>(value));
|
||||
}
|
||||
|
||||
/** Replace a field value.
|
||||
|
||||
The current field value, if any, is removed. Then the
|
||||
specified value is inserted as if by `insert(field, value)`.
|
||||
First removes any values with matching field names, then
|
||||
inserts the new field value.
|
||||
|
||||
@param name The name of the field.
|
||||
|
||||
@param value A string holding the value of the field.
|
||||
*/
|
||||
void
|
||||
replace(boost::string_ref const& name, boost::string_ref value);
|
||||
|
||||
/** Replace a field value.
|
||||
|
||||
The current field value, if any, is removed. Then the
|
||||
specified value is inserted as if by `insert(field, value)`.
|
||||
First removes any values with matching field names, then
|
||||
inserts the new field value.
|
||||
|
||||
@param name The name of the field
|
||||
|
||||
@param value The value of the field. The object will be
|
||||
converted to a string using `boost::lexical_cast`.
|
||||
*/
|
||||
template<class T>
|
||||
typename std::enable_if<
|
||||
|
||||
@@ -482,7 +482,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -501,7 +501,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -520,7 +520,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -539,7 +539,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -557,7 +557,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -575,7 +575,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -594,7 +594,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -613,7 +613,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -630,7 +630,7 @@ private:
|
||||
decltype(std::declval<T>().on_headers(
|
||||
std::declval<std::uint64_t>(), std::declval<error_code&>()))>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -649,7 +649,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
@@ -667,7 +667,7 @@ private:
|
||||
std::declval<error_code&>()),
|
||||
std::true_type{})>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<C>(0));
|
||||
public:
|
||||
|
||||
@@ -29,7 +29,7 @@ class chunk_encode_text
|
||||
// Storage for the longest hex string we might need, plus delimiters.
|
||||
std::array<char, 2 * sizeof(std::size_t) + 2> buf_;
|
||||
|
||||
template <class OutIter>
|
||||
template<class OutIter>
|
||||
static
|
||||
OutIter
|
||||
to_hex(OutIter last, std::size_t n)
|
||||
|
||||
@@ -22,7 +22,7 @@ class has_content_length_value
|
||||
decltype(std::declval<U>().content_length()),
|
||||
std::uint64_t>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
template<class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(0));
|
||||
public:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define BEAST_HTTP_IMPL_BASIC_HEADERS_IPP
|
||||
|
||||
#include <beast/http/detail/rfc7230.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@@ -204,6 +205,18 @@ basic_headers(FwdIt first, FwdIt last)
|
||||
insert(first->name(), first->value());
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
std::size_t
|
||||
basic_headers<Allocator>::
|
||||
count(boost::string_ref const& name) const
|
||||
{
|
||||
auto const it = set_.find(name, less{});
|
||||
if(it == set_.end())
|
||||
return 0;
|
||||
auto const last = set_.upper_bound(name, less{});
|
||||
return static_cast<std::size_t>(std::distance(it, last));
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
auto
|
||||
basic_headers<Allocator>::
|
||||
@@ -221,11 +234,9 @@ boost::string_ref
|
||||
basic_headers<Allocator>::
|
||||
operator[](boost::string_ref const& name) const
|
||||
{
|
||||
// VFALCO This none object looks sketchy
|
||||
static boost::string_ref const none;
|
||||
auto const it = find(name);
|
||||
if(it == end())
|
||||
return none;
|
||||
return {};
|
||||
return it->second;
|
||||
}
|
||||
|
||||
@@ -244,15 +255,23 @@ std::size_t
|
||||
basic_headers<Allocator>::
|
||||
erase(boost::string_ref const& name)
|
||||
{
|
||||
auto const it = set_.find(name, less{});
|
||||
auto it = set_.find(name, less{});
|
||||
if(it == set_.end())
|
||||
return 0;
|
||||
auto& e = *it;
|
||||
set_.erase(set_.iterator_to(e));
|
||||
list_.erase(list_.iterator_to(e));
|
||||
alloc_traits::destroy(this->member(), &e);
|
||||
alloc_traits::deallocate(this->member(), &e, 1);
|
||||
return 1;
|
||||
auto const last = set_.upper_bound(name, less{});
|
||||
std::size_t n = 1;
|
||||
for(;;)
|
||||
{
|
||||
auto& e = *it++;
|
||||
set_.erase(set_.iterator_to(e));
|
||||
list_.erase(list_.iterator_to(e));
|
||||
alloc_traits::destroy(this->member(), &e);
|
||||
alloc_traits::deallocate(this->member(), &e, 1);
|
||||
if(it == last)
|
||||
break;
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
@@ -262,25 +281,10 @@ insert(boost::string_ref const& name,
|
||||
boost::string_ref value)
|
||||
{
|
||||
value = detail::trim(value);
|
||||
typename set_t::insert_commit_data d;
|
||||
auto const result =
|
||||
set_.insert_check(name, less{}, d);
|
||||
if(result.second)
|
||||
{
|
||||
auto const p = alloc_traits::allocate(
|
||||
this->member(), 1);
|
||||
alloc_traits::construct(
|
||||
this->member(), p, name, value);
|
||||
list_.push_back(*p);
|
||||
set_.insert_commit(*p, d);
|
||||
return;
|
||||
}
|
||||
// If field already exists, insert comma
|
||||
// separated value as per RFC2616 section 4.2
|
||||
auto& cur = result.first->data.second;
|
||||
cur.reserve(cur.size() + 1 + value.size());
|
||||
cur.append(1, ',');
|
||||
cur.append(value.data(), value.size());
|
||||
auto const p = alloc_traits::allocate(this->member(), 1);
|
||||
alloc_traits::construct(this->member(), p, name, value);
|
||||
set_.insert_before(set_.upper_bound(name, less{}), *p);
|
||||
list_.push_back(*p);
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_HTTP_IMPL_MESSAGE_V1_IPP
|
||||
#define BEAST_HTTP_IMPL_MESSAGE_V1_IPP
|
||||
|
||||
#include <beast/core/error.hpp>
|
||||
#include <beast/http/rfc7230.hpp>
|
||||
#include <beast/http/detail/has_content_length.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
@@ -87,7 +88,11 @@ prepare_content_length(prepare_info& pi,
|
||||
std::true_type)
|
||||
{
|
||||
typename Body::writer w(msg);
|
||||
//w.init(ec); // VFALCO This is a design problem!
|
||||
// VFALCO This is a design problem!
|
||||
error_code ec;
|
||||
w.init(ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
pi.content_length = w.content_length();
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, parse_op* op)
|
||||
{
|
||||
@@ -277,7 +277,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, read_op* op)
|
||||
{
|
||||
@@ -412,7 +412,7 @@ read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
static_assert(is_ReadableBody<Body>::value,
|
||||
"ReadableBody requirements not met");
|
||||
error_code ec;
|
||||
read(stream, dynabuf, msg, ec);
|
||||
beast::http::read(stream, dynabuf, msg, ec);
|
||||
if(ec)
|
||||
throw system_error{ec};
|
||||
}
|
||||
@@ -431,7 +431,7 @@ read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||
static_assert(is_ReadableBody<Body>::value,
|
||||
"ReadableBody requirements not met");
|
||||
parser_v1<isRequest, Body, Headers> p;
|
||||
parse(stream, dynabuf, p, ec);
|
||||
beast::http::parse(stream, dynabuf, p, ec);
|
||||
if(ec)
|
||||
return;
|
||||
assert(p.complete());
|
||||
|
||||
@@ -262,7 +262,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, write_op* op)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace http {
|
||||
|
||||
enum class parse_error
|
||||
{
|
||||
success = 0,
|
||||
|
||||
connection_closed,
|
||||
|
||||
bad_method,
|
||||
|
||||
@@ -35,6 +35,37 @@ struct parser_response
|
||||
|
||||
} // detail
|
||||
|
||||
/** Skip body option.
|
||||
|
||||
The options controls whether or not the parser expects to see a
|
||||
HTTP body, regardless of the presence or absence of certain fields
|
||||
such as Content-Length.
|
||||
|
||||
Depending on the request, some responses do not carry a body.
|
||||
For example, a 200 response to a CONNECT request from a tunneling
|
||||
proxy. In these cases, callers use the @ref skip_body option to
|
||||
inform the parser that no body is expected. The parser will consider
|
||||
the message complete after the all headers have been received.
|
||||
|
||||
Example:
|
||||
@code
|
||||
parser_v1<true, empty_body, headers> p;
|
||||
p.set_option(skip_body{true});
|
||||
@endcode
|
||||
|
||||
@note Objects of this type are passed to @ref basic_parser_v1::set_option.
|
||||
*/
|
||||
struct skip_body
|
||||
{
|
||||
bool value;
|
||||
|
||||
explicit
|
||||
skip_body(bool v)
|
||||
: value(v)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/** A parser for producing HTTP/1 messages.
|
||||
|
||||
This class uses the basic HTTP/1 wire format parser to convert
|
||||
@@ -62,6 +93,7 @@ private:
|
||||
std::string value_;
|
||||
message_type m_;
|
||||
typename message_type::body_type::reader r_;
|
||||
std::uint8_t skip_body_ = 0;
|
||||
|
||||
public:
|
||||
parser_v1(parser_v1&&) = default;
|
||||
@@ -81,6 +113,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/// Set the expect body option.
|
||||
void
|
||||
set_option(skip_body const& o)
|
||||
{
|
||||
skip_body_ = o.value ? 1 : 0;
|
||||
}
|
||||
|
||||
/** Returns the parsed message.
|
||||
|
||||
Only valid if `complete()` would return `true`.
|
||||
@@ -176,7 +215,7 @@ private:
|
||||
{
|
||||
flush();
|
||||
m_.version = 10 * this->http_major() + this->http_minor();
|
||||
return 0;
|
||||
return skip_body_;
|
||||
}
|
||||
|
||||
void on_request(error_code& ec)
|
||||
|
||||
@@ -30,6 +30,16 @@ namespace http {
|
||||
the behavior of the container will be as if a string containing
|
||||
only characters up to but excluding the first invalid character
|
||||
was used to construct the list.
|
||||
|
||||
@code
|
||||
for(auto const& param : param_list{";level=9;no_context_takeover;bits=15"})
|
||||
{
|
||||
std::cout << ";" << param.first;
|
||||
if(! param.second.empty())
|
||||
std::cout << "=" << param.second;
|
||||
std::cout << "\n";
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class param_list
|
||||
{
|
||||
@@ -98,6 +108,24 @@ public:
|
||||
the behavior of the container will be as if a string containing
|
||||
only characters up to but excluding the first invalid character
|
||||
was used to construct the list.
|
||||
|
||||
To use this class, construct with the string to be parsed and
|
||||
then use @ref begin and @end, or range-for to iterate each
|
||||
item:
|
||||
|
||||
@code
|
||||
for(auto const& ext : ext_list{"none, 7z;level=9, zip;no_context_takeover;bits=15"})
|
||||
{
|
||||
std::cout << ext.first << "\n";
|
||||
for(auto const& param : ext.second)
|
||||
{
|
||||
std::cout << ";" << param.first;
|
||||
if(! param.second.empty())
|
||||
std::cout << "=" << param.second;
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class ext_list
|
||||
{
|
||||
@@ -181,6 +209,15 @@ public:
|
||||
the behavior of the container will be as if a string containing
|
||||
only characters up to but excluding the first invalid character
|
||||
was used to construct the list.
|
||||
|
||||
To use this class, construct with the string to be parsed and
|
||||
then use @ref begin and @end, or range-for to iterate each
|
||||
item:
|
||||
|
||||
@code
|
||||
for(auto const& token : token_list{"apple, pear, banana"})
|
||||
std::cout << token << "\n";
|
||||
@endcode
|
||||
*/
|
||||
class token_list
|
||||
{
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_STATUS_HPP
|
||||
#define BEAST_HTTP_STATUS_HPP
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Returns the string corresponding to the numeric HTTP status code. */
|
||||
template<class = void>
|
||||
char const*
|
||||
status_text(int status)
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case 100: return "Continue";
|
||||
case 101: return "Switching Protocols";
|
||||
case 200: return "OK";
|
||||
case 201: return "Created";
|
||||
case 202: return "Accepted";
|
||||
case 203: return "Non-Authoritative Information";
|
||||
case 204: return "No Content";
|
||||
case 205: return "Reset Content";
|
||||
case 206: return "Partial Content";
|
||||
case 300: return "Multiple Choices";
|
||||
case 301: return "Moved Permanently";
|
||||
case 302: return "Found";
|
||||
case 303: return "See Other";
|
||||
case 304: return "Not Modified";
|
||||
case 305: return "Use Proxy";
|
||||
// case 306: return "<reserved>";
|
||||
case 307: return "Temporary Redirect";
|
||||
case 400: return "Bad Request";
|
||||
case 401: return "Unauthorized";
|
||||
case 402: return "Payment Required";
|
||||
case 403: return "Forbidden";
|
||||
case 404: return "Not Found";
|
||||
case 405: return "Method Not Allowed";
|
||||
case 406: return "Not Acceptable";
|
||||
case 407: return "Proxy Authentication Required";
|
||||
case 408: return "Request Timeout";
|
||||
case 409: return "Conflict";
|
||||
case 410: return "Gone";
|
||||
case 411: return "Length Required";
|
||||
case 412: return "Precondition Failed";
|
||||
case 413: return "Request Entity Too Large";
|
||||
case 414: return "Request-URI Too Long";
|
||||
case 415: return "Unsupported Media Type";
|
||||
case 416: return "Requested Range Not Satisfiable";
|
||||
case 417: return "Expectation Failed";
|
||||
case 500: return "Internal Server Error";
|
||||
case 501: return "Not Implemented";
|
||||
case 502: return "Bad Gateway";
|
||||
case 503: return "Service Unavailable";
|
||||
case 504: return "Gateway Timeout";
|
||||
case 505: return "HTTP Version Not Supported";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown HTTP status";
|
||||
}
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
||||
@@ -14,8 +14,8 @@
|
||||
// BEAST_VERSION / 100 % 1000 is the minor version
|
||||
// BEAST_VERSION / 100000 is the major version
|
||||
//
|
||||
#define BEAST_VERSION 100006
|
||||
#define BEAST_VERSION 100000
|
||||
|
||||
#define BEAST_VERSION_STRING "1.0.0-b6"
|
||||
#define BEAST_VERSION_STRING "1.0.0-b13"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -110,7 +110,7 @@ is_valid(close_code::value code)
|
||||
if(v >= 1016 && v <= 2999)
|
||||
return false;
|
||||
// not used
|
||||
if(v >= 0 && v <= 999)
|
||||
if(v <= 999)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -136,12 +136,12 @@ write(DynamicBuffer& db, frame_header const& fh)
|
||||
if(fh.rsv3)
|
||||
b[0] |= 0x10;
|
||||
b[1] = fh.mask ? 0x80 : 0x00;
|
||||
if (fh.len <= 125)
|
||||
if(fh.len <= 125)
|
||||
{
|
||||
b[1] |= fh.len;
|
||||
n = 2;
|
||||
}
|
||||
else if (fh.len <= 65535)
|
||||
else if(fh.len <= 65535)
|
||||
{
|
||||
b[1] |= 126;
|
||||
::new(&b[2]) big_uint16_buf_t{
|
||||
|
||||
@@ -113,7 +113,7 @@ mask_inplace_general(
|
||||
{
|
||||
using boost::asio::buffer_cast;
|
||||
using boost::asio::buffer_size;
|
||||
auto n = buffer_size(b);
|
||||
auto const n = buffer_size(b);
|
||||
auto p = buffer_cast<std::uint8_t*>(b);
|
||||
for(auto i = n / sizeof(key); i; --i)
|
||||
{
|
||||
@@ -122,13 +122,14 @@ mask_inplace_general(
|
||||
*p ^= (key >>16); ++p;
|
||||
*p ^= (key >>24); ++p;
|
||||
}
|
||||
n %= sizeof(key);
|
||||
switch(n)
|
||||
auto const m =
|
||||
static_cast<std::uint8_t>(n % sizeof(key));
|
||||
switch(m)
|
||||
{
|
||||
case 3: p[2] ^= (key >>16);
|
||||
case 2: p[1] ^= (key >> 8);
|
||||
case 1: p[0] ^= key;
|
||||
key = ror(key, n*8);
|
||||
key = ror(key, m*8);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -144,7 +145,7 @@ mask_inplace_general(
|
||||
{
|
||||
using boost::asio::buffer_cast;
|
||||
using boost::asio::buffer_size;
|
||||
auto n = buffer_size(b);
|
||||
auto const n = buffer_size(b);
|
||||
auto p = buffer_cast<std::uint8_t*>(b);
|
||||
for(auto i = n / sizeof(key); i; --i)
|
||||
{
|
||||
@@ -157,8 +158,9 @@ mask_inplace_general(
|
||||
*p ^= (key >>48); ++p;
|
||||
*p ^= (key >>56); ++p;
|
||||
}
|
||||
n %= sizeof(key);
|
||||
switch(n)
|
||||
auto const m =
|
||||
static_cast<std::uint8_t>(n % sizeof(key));
|
||||
switch(m)
|
||||
{
|
||||
case 7: p[6] ^= (key >>16);
|
||||
case 6: p[5] ^= (key >> 8);
|
||||
@@ -167,7 +169,7 @@ mask_inplace_general(
|
||||
case 3: p[2] ^= (key >>16);
|
||||
case 2: p[1] ^= (key >> 8);
|
||||
case 1: p[0] ^= key;
|
||||
key = ror(key, n*8);
|
||||
key = ror(key, m*8);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ utf8_checker_t<_>::write(BufferSequence const& bs)
|
||||
{
|
||||
using boost::asio::buffer_cast;
|
||||
using boost::asio::buffer_size;
|
||||
for (auto const& b : bs)
|
||||
for(auto const& b : bs)
|
||||
if(! write(buffer_cast<void const*>(b),
|
||||
buffer_size(b)))
|
||||
return false;
|
||||
|
||||
@@ -16,8 +16,10 @@ namespace websocket {
|
||||
/// Error codes returned from @ref stream operations.
|
||||
enum class error
|
||||
{
|
||||
success = 0,
|
||||
|
||||
/// Both sides performed a WebSocket close
|
||||
closed = 1,
|
||||
closed,
|
||||
|
||||
/// WebSocket connection failed, protocol violation
|
||||
failed,
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, accept_op* op)
|
||||
{
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, close_op* op)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, handshake_op* op)
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, ping_op* op)
|
||||
{
|
||||
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, read_frame_op* op)
|
||||
{
|
||||
@@ -252,7 +252,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||
break;
|
||||
}
|
||||
d.state = do_read_fh + 2;
|
||||
if (n == 0)
|
||||
if(n == 0)
|
||||
{
|
||||
bytes_transferred = 0;
|
||||
break;
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, read_op* op)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, response_op* op)
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f,
|
||||
teardown_ssl_op* op)
|
||||
@@ -129,7 +129,7 @@ operator()(error_code ec, bool again)
|
||||
|
||||
template<class AsyncStream>
|
||||
void
|
||||
teardown(
|
||||
teardown(teardown_tag,
|
||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||
error_code& ec)
|
||||
{
|
||||
@@ -138,7 +138,7 @@ teardown(
|
||||
|
||||
template<class AsyncStream, class TeardownHandler>
|
||||
void
|
||||
async_teardown(
|
||||
async_teardown(teardown_tag,
|
||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||
TeardownHandler&& handler)
|
||||
{
|
||||
|
||||
@@ -920,7 +920,7 @@ build_request(boost::string_ref const& host,
|
||||
boost::string_ref const& resource, std::string& key)
|
||||
{
|
||||
http::request_v1<http::empty_body> req;
|
||||
req.url = "/";
|
||||
req.url = { resource.data(), resource.size() };
|
||||
req.version = 11;
|
||||
req.method = "GET";
|
||||
req.headers.insert("Host", host);
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f,
|
||||
teardown_tcp_op* op)
|
||||
@@ -128,7 +128,7 @@ operator()(error_code ec, std::size_t, bool again)
|
||||
|
||||
inline
|
||||
void
|
||||
teardown(
|
||||
teardown(teardown_tag,
|
||||
boost::asio::ip::tcp::socket& socket,
|
||||
error_code& ec)
|
||||
{
|
||||
@@ -151,7 +151,7 @@ teardown(
|
||||
template<class TeardownHandler>
|
||||
inline
|
||||
void
|
||||
async_teardown(
|
||||
async_teardown(teardown_tag,
|
||||
boost::asio::ip::tcp::socket& socket,
|
||||
TeardownHandler&& handler)
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, write_frame_op* op)
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
return op->d_->cont;
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
template<class Function>
|
||||
friend
|
||||
void asio_handler_invoke(Function&& f, write_op* op)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace websocket {
|
||||
*/
|
||||
template<class SyncStream>
|
||||
void
|
||||
teardown(
|
||||
teardown(teardown_tag,
|
||||
boost::asio::ssl::stream<SyncStream>& stream,
|
||||
error_code& ec);
|
||||
|
||||
@@ -62,7 +62,7 @@ teardown(
|
||||
template<class AsyncStream, class TeardownHandler>
|
||||
inline
|
||||
void
|
||||
async_teardown(
|
||||
async_teardown(teardown_tag,
|
||||
boost::asio::ssl::stream<AsyncStream>& stream,
|
||||
TeardownHandler&& handler);
|
||||
|
||||
|
||||
@@ -13,8 +13,17 @@
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace websocket {
|
||||
|
||||
/** Tag type used to find teardown and async_teardown overloads
|
||||
|
||||
Overloads of @ref teardown and @async_teardown for user defined
|
||||
types must take a value of type @ref teardown_tag in the first
|
||||
argument in order to be found by the implementation.
|
||||
*/
|
||||
struct teardown_tag {};
|
||||
|
||||
/** Tear down a connection.
|
||||
|
||||
This tears down a connection. The implementation will call
|
||||
@@ -30,7 +39,19 @@ namespace websocket {
|
||||
*/
|
||||
template<class Socket>
|
||||
void
|
||||
teardown(Socket& socket, error_code& ec) = delete;
|
||||
teardown(teardown_tag, Socket& socket, error_code& ec)
|
||||
{
|
||||
/*
|
||||
If you are trying to use OpenSSL and this goes off, you need to
|
||||
add an include for <beast/websocket/ssl.hpp>.
|
||||
|
||||
If you are creating an instance of beast::websocket::stream with your
|
||||
own user defined type, you must provide an overload of teardown with
|
||||
the corresponding signature (including the teardown_tag).
|
||||
*/
|
||||
static_assert(sizeof(Socket)==-1,
|
||||
"Unknown Socket type in teardown.");
|
||||
}
|
||||
|
||||
/** Start tearing down a connection.
|
||||
|
||||
@@ -49,7 +70,8 @@ teardown(Socket& socket, error_code& ec) = delete;
|
||||
function signature of the handler must be:
|
||||
@code void handler(
|
||||
error_code const& error // result of operation
|
||||
); @endcode
|
||||
);
|
||||
@endcode
|
||||
Regardless of whether the asynchronous operation completes
|
||||
immediately or not, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
@@ -58,57 +80,19 @@ teardown(Socket& socket, error_code& ec) = delete;
|
||||
*/
|
||||
template<class Socket, class TeardownHandler>
|
||||
void
|
||||
async_teardown(Socket& socket, TeardownHandler&& handler) = delete;
|
||||
async_teardown(teardown_tag, Socket& socket, TeardownHandler&& handler)
|
||||
{
|
||||
/*
|
||||
If you are trying to use OpenSSL and this goes off, you need to
|
||||
add an include for <beast/websocket/ssl.hpp>.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Tear down a `boost::asio::ip::tcp::socket`.
|
||||
|
||||
This tears down a connection. The implementation will call
|
||||
the overload of this function based on the `Stream` parameter
|
||||
used to consruct the socket. When `Stream` is a user defined
|
||||
type, and not a `boost::asio::ip::tcp::socket` or any
|
||||
`boost::asio::ssl::stream`, callers are responsible for
|
||||
providing a suitable overload of this function.
|
||||
|
||||
@param socket The socket to tear down.
|
||||
|
||||
@param ec Set to the error if any occurred.
|
||||
If you are creating an instance of beast::websocket::stream with your
|
||||
own user defined type, you must provide an overload of teardown with
|
||||
the corresponding signature (including the teardown_tag).
|
||||
*/
|
||||
void
|
||||
teardown(
|
||||
boost::asio::ip::tcp::socket& socket,
|
||||
error_code& ec);
|
||||
|
||||
/** Start tearing down a `boost::asio::ip::tcp::socket`.
|
||||
|
||||
This begins tearing down a connection asynchronously.
|
||||
The implementation will call the overload of this function
|
||||
based on the `Stream` parameter used to consruct the socket.
|
||||
When `Stream` is a user defined type, and not a
|
||||
`boost::asio::ip::tcp::socket` or any `boost::asio::ssl::stream`,
|
||||
callers are responsible for providing a suitable overload
|
||||
of this function.
|
||||
|
||||
@param socket The socket to tear down.
|
||||
|
||||
@param handler The handler to be called when the request completes.
|
||||
Copies will be made of the handler as required. The equivalent
|
||||
function signature of the handler must be:
|
||||
@code void handler(
|
||||
error_code const& error // result of operation
|
||||
); @endcode
|
||||
Regardless of whether the asynchronous operation completes
|
||||
immediately or not, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using boost::asio::io_service::post().
|
||||
|
||||
*/
|
||||
template<class TeardownHandler>
|
||||
void
|
||||
async_teardown(
|
||||
boost::asio::ip::tcp::socket& socket,
|
||||
TeardownHandler&& handler);
|
||||
static_assert(sizeof(Socket)==-1,
|
||||
"Unknown Socket type in async_teardown.");
|
||||
}
|
||||
|
||||
} // websocket
|
||||
|
||||
@@ -127,7 +111,7 @@ void
|
||||
call_teardown(Socket& socket, error_code& ec)
|
||||
{
|
||||
using websocket::teardown;
|
||||
teardown(socket, ec);
|
||||
teardown(websocket::teardown_tag{}, socket, ec);
|
||||
}
|
||||
|
||||
template<class Socket, class TeardownHandler>
|
||||
@@ -136,12 +120,65 @@ void
|
||||
call_async_teardown(Socket& socket, TeardownHandler&& handler)
|
||||
{
|
||||
using websocket::async_teardown;
|
||||
async_teardown(socket,
|
||||
async_teardown(websocket::teardown_tag{}, socket,
|
||||
std::forward<TeardownHandler>(handler));
|
||||
}
|
||||
|
||||
} // websocket_helpers
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace websocket {
|
||||
|
||||
/** Tear down a `boost::asio::ip::tcp::socket`.
|
||||
|
||||
This tears down a connection. The implementation will call
|
||||
the overload of this function based on the `Stream` parameter
|
||||
used to consruct the socket. When `Stream` is a user defined
|
||||
type, and not a `boost::asio::ip::tcp::socket` or any
|
||||
`boost::asio::ssl::stream`, callers are responsible for
|
||||
providing a suitable overload of this function.
|
||||
|
||||
@param socket The socket to tear down.
|
||||
|
||||
@param ec Set to the error if any occurred.
|
||||
*/
|
||||
void
|
||||
teardown(teardown_tag,
|
||||
boost::asio::ip::tcp::socket& socket, error_code& ec);
|
||||
|
||||
/** Start tearing down a `boost::asio::ip::tcp::socket`.
|
||||
|
||||
This begins tearing down a connection asynchronously.
|
||||
The implementation will call the overload of this function
|
||||
based on the `Stream` parameter used to consruct the socket.
|
||||
When `Stream` is a user defined type, and not a
|
||||
`boost::asio::ip::tcp::socket` or any `boost::asio::ssl::stream`,
|
||||
callers are responsible for providing a suitable overload
|
||||
of this function.
|
||||
|
||||
@param socket The socket to tear down.
|
||||
|
||||
@param handler The handler to be called when the request completes.
|
||||
Copies will be made of the handler as required. The equivalent
|
||||
function signature of the handler must be:
|
||||
@code void handler(
|
||||
error_code const& error // result of operation
|
||||
);
|
||||
@endcode
|
||||
Regardless of whether the asynchronous operation completes
|
||||
immediately or not, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using boost::asio::io_service::post().
|
||||
|
||||
*/
|
||||
template<class TeardownHandler>
|
||||
void
|
||||
async_teardown(teardown_tag,
|
||||
boost::asio::ip::tcp::socket& socket, TeardownHandler&& handler);
|
||||
|
||||
} // websocket
|
||||
|
||||
} // beast
|
||||
|
||||
#include <beast/websocket/impl/teardown.ipp>
|
||||
|
||||
Reference in New Issue
Block a user