mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 21:34:46 +02:00
Rename concept to DynamicBuffer (API change):
Conform to the Networking TS by renaming the Streambuf concept to DynamicBuffer in all places. Values of types meeting the requirements of DynamicBuffer are renamed to dynabuf. See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4478.html#requirements.dynamic_buffers * Headers renamed * Formal parameter names renamed * Template argument types renamed * Documentation updated
This commit is contained in:
@@ -11,4 +11,7 @@ API Changes:
|
|||||||
|
|
||||||
* ci_equal is moved to beast::http namespace, in rfc7230.hpp
|
* ci_equal is moved to beast::http namespace, in rfc7230.hpp
|
||||||
|
|
||||||
|
* "DynamicBuffer","dynabuf" renamed from "Streambuf", "streambuf". See:
|
||||||
|
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4478.html#requirements.dynamic_buffers
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@@ -15,6 +15,11 @@ Requirements:
|
|||||||
* C++11 or greater
|
* C++11 or greater
|
||||||
* OpenSSL (optional)
|
* OpenSSL (optional)
|
||||||
|
|
||||||
|
This software is currently in beta: interfaces are subject to change. For
|
||||||
|
recent changes see [CHANGELOG](CHANGELOG).
|
||||||
|
The library has been submitted to the
|
||||||
|
[Boost Library Incubator](http://rrsd.com/blincubator.com/bi_library/beast-2/?gform_post_id=1579)
|
||||||
|
|
||||||
Example WebSocket program:
|
Example WebSocket program:
|
||||||
```C++
|
```C++
|
||||||
#include <beast/to_string.hpp>
|
#include <beast/to_string.hpp>
|
||||||
|
@@ -192,11 +192,11 @@ supporting its development.
|
|||||||
[section:types Type Requirements]
|
[section:types Type Requirements]
|
||||||
[include types/Body.qbk]
|
[include types/Body.qbk]
|
||||||
[include types/BufferSequence.qbk]
|
[include types/BufferSequence.qbk]
|
||||||
|
[include types/DynamicBuffer.qbk]
|
||||||
[include types/Field.qbk]
|
[include types/Field.qbk]
|
||||||
[include types/FieldSequence.qbk]
|
[include types/FieldSequence.qbk]
|
||||||
[include types/Parser.qbk]
|
[include types/Parser.qbk]
|
||||||
[include types/Reader.qbk]
|
[include types/Reader.qbk]
|
||||||
[include types/Streambuf.qbk]
|
|
||||||
[include types/Streams.qbk]
|
[include types/Streams.qbk]
|
||||||
[include types/Writer.qbk]
|
[include types/Writer.qbk]
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@@ -25,13 +25,13 @@ libraries:
|
|||||||
* Let library users make the important decisions such as how to
|
* Let library users make the important decisions such as how to
|
||||||
allocate memory or how to leverage flow control.
|
allocate memory or how to leverage flow control.
|
||||||
|
|
||||||
Beast formalizes the [link beast.types.Streambuf [*`Streambuf`]] concept,
|
Beast uses the [link beast.types.DynamicBuffer [*`DynamicBuffer`]] concept
|
||||||
and relies heavily on the Boost.Asio [*`ConstBufferSequence`] and
|
presented in the Netwoking TS, and relies heavily on the Boost.Asio
|
||||||
[*`MutableBufferSequence`] concepts for passing buffers to functions.
|
[*`ConstBufferSequence`] and [*`MutableBufferSequence`] concepts for passing
|
||||||
The authors have found the `Streambuf` and buffer sequence interfaces
|
buffers to functions. The authors have found the dynamic buffer and buffer
|
||||||
to be optimal for interacting with Asio, and for other tasks such as
|
sequence interfaces to be optimal for interacting with Asio, and for other
|
||||||
incremental parsing of data in buffers (for example, parsing websocket
|
tasks such as incremental parsing of data in buffers (for example, parsing
|
||||||
frames stored in a [link beast.ref.static_streambuf `static_streambuf`]).
|
websocket frames stored in a [link beast.ref.static_streambuf `static_streambuf`]).
|
||||||
|
|
||||||
During the development of Beast the authors have studied other software
|
During the development of Beast the authors have studied other software
|
||||||
packages and in particular the comments left during the Boost Review process
|
packages and in particular the comments left during the Boost Review process
|
||||||
|
24
doc/http.qbk
24
doc/http.qbk
@@ -182,21 +182,9 @@ used in the examples:
|
|||||||
resp.body = "Here is the data you requested";
|
resp.body = "Here is the data you requested";
|
||||||
```
|
```
|
||||||
|
|
||||||
* [link beast.ref.http__basic_streambuf_body [*`basic_streambuf_body`:]] A body with a
|
* [link beast.ref.http__streambuf_body [*`streambuf_body`:]] A body with a
|
||||||
`value_type` of `streambuf`. A streambuf is an efficient storage object which
|
`value_type` of [link beast.ref.streambuf `streambuf`]: an efficient storage
|
||||||
uses multiple octet arrays of varying lengths to represent data. Here is
|
object which uses multiple octet arrays of varying lengths to represent data.
|
||||||
a body that uses a `boost::asio::streambuf` as its container:
|
|
||||||
```
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
http::response<http::basic_streambuf_body<boost::asio::streambuf>>
|
|
||||||
make_response(ConstBufferSequence const& buffers)
|
|
||||||
{
|
|
||||||
http::response<http::streambuf_body<boost::asio::streambuf>> resp;
|
|
||||||
resp.body.commit(boost::asio::buffer_copy(resp.body.prepare(
|
|
||||||
boost::asio::buffer_size(buffers)), buffers));
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[heading Sockets]
|
[heading Sockets]
|
||||||
|
|
||||||
@@ -234,7 +222,7 @@ When the implementation reads messages from a socket, it can read bytes lying
|
|||||||
after the end of the message if they are present (the alternative is to read
|
after the end of the message if they are present (the alternative is to read
|
||||||
a single byte at a time which is unsuitable for performance reasons). To
|
a single byte at a time which is unsuitable for performance reasons). To
|
||||||
store and re-use these extra bytes on subsequent messages, the read interface
|
store and re-use these extra bytes on subsequent messages, the read interface
|
||||||
requires an additional paramter: a [link beast.types.Streambuf [*`Streambuf`]]
|
requires an additional paramter: a [link beast.types.DynamicBuffer [*`DynamicBuffer`]]
|
||||||
object. This example reads a message from the socket, with the extra bytes
|
object. This example reads a message from the socket, with the extra bytes
|
||||||
stored in the streambuf parameter for use in a subsequent call to read:
|
stored in the streambuf parameter for use in a subsequent call to read:
|
||||||
```
|
```
|
||||||
@@ -264,7 +252,7 @@ called:
|
|||||||
|
|
||||||
An alternative to using a `boost::asio::streambuf` is to use a
|
An alternative to using a `boost::asio::streambuf` is to use a
|
||||||
[link beast.ref.streambuf `beast::streambuf`], which meets the requirements of
|
[link beast.ref.streambuf `beast::streambuf`], which meets the requirements of
|
||||||
[*`Streambuf`] and is optimized for performance:
|
[*`DynamicBuffer`] and is optimized for performance:
|
||||||
```
|
```
|
||||||
void handle_read(boost::system::error_code);
|
void handle_read(boost::system::error_code);
|
||||||
...
|
...
|
||||||
@@ -274,7 +262,7 @@ An alternative to using a `boost::asio::streambuf` is to use a
|
|||||||
```
|
```
|
||||||
|
|
||||||
The `read` implementation can use any object meeting the requirements of
|
The `read` implementation can use any object meeting the requirements of
|
||||||
[link beast.types.Streambuf [*`Streambuf`]], allowing callers to define custom
|
[link beast.types.DynamicBuffer [*`DynamicBuffer`]], allowing callers to define custom
|
||||||
memory management strategies used by the implementation.
|
memory management strategies used by the implementation.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@@ -29,9 +29,9 @@
|
|||||||
<entry valign="top">
|
<entry valign="top">
|
||||||
<bridgehead renderas="sect3">Classes</bridgehead>
|
<bridgehead renderas="sect3">Classes</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
|
<member><link linkend="beast.ref.http__basic_dynabuf_body">basic_dynabuf_body</link></member>
|
||||||
<member><link linkend="beast.ref.http__basic_headers">basic_headers</link></member>
|
<member><link linkend="beast.ref.http__basic_headers">basic_headers</link></member>
|
||||||
<member><link linkend="beast.ref.http__basic_parser_v1">basic_parser_v1</link></member>
|
<member><link linkend="beast.ref.http__basic_parser_v1">basic_parser_v1</link></member>
|
||||||
<member><link linkend="beast.ref.http__basic_streambuf_body">basic_streambuf_body</link></member>
|
|
||||||
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
|
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
|
||||||
<member><link linkend="beast.ref.http__headers">headers</link></member>
|
<member><link linkend="beast.ref.http__headers">headers</link></member>
|
||||||
<member><link linkend="beast.ref.http__message">message</link></member>
|
<member><link linkend="beast.ref.http__message">message</link></member>
|
||||||
@@ -130,6 +130,7 @@
|
|||||||
<member><link linkend="beast.ref.basic_streambuf">basic_streambuf</link></member>
|
<member><link linkend="beast.ref.basic_streambuf">basic_streambuf</link></member>
|
||||||
<member><link linkend="beast.ref.buffers_adapter">buffers_adapter</link></member>
|
<member><link linkend="beast.ref.buffers_adapter">buffers_adapter</link></member>
|
||||||
<member><link linkend="beast.ref.consuming_buffers">consuming_buffers</link></member>
|
<member><link linkend="beast.ref.consuming_buffers">consuming_buffers</link></member>
|
||||||
|
<member><link linkend="beast.ref.dynabuf_readstream">dynabuf_readstream</link></member>
|
||||||
<member><link linkend="beast.ref.error_code">error_code</link></member>
|
<member><link linkend="beast.ref.error_code">error_code</link></member>
|
||||||
<member><link linkend="beast.ref.handler_alloc">handler_alloc</link></member>
|
<member><link linkend="beast.ref.handler_alloc">handler_alloc</link></member>
|
||||||
<member><link linkend="beast.ref.prepared_buffers">prepared_buffers</link></member>
|
<member><link linkend="beast.ref.prepared_buffers">prepared_buffers</link></member>
|
||||||
@@ -137,7 +138,6 @@
|
|||||||
<member><link linkend="beast.ref.static_streambuf_n">static_streambuf_n</link></member>
|
<member><link linkend="beast.ref.static_streambuf_n">static_streambuf_n</link></member>
|
||||||
<member><link linkend="beast.ref.static_string">static_string</link></member>
|
<member><link linkend="beast.ref.static_string">static_string</link></member>
|
||||||
<member><link linkend="beast.ref.streambuf">streambuf</link></member>
|
<member><link linkend="beast.ref.streambuf">streambuf</link></member>
|
||||||
<member><link linkend="beast.ref.streambuf_readstream">streambuf_readstream</link></member>
|
|
||||||
<member><link linkend="beast.ref.system_error">system_error</link></member>
|
<member><link linkend="beast.ref.system_error">system_error</link></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</entry>
|
</entry>
|
||||||
@@ -164,8 +164,8 @@
|
|||||||
<member><link linkend="beast.ref.is_BufferSequence">is_BufferSequence</link></member>
|
<member><link linkend="beast.ref.is_BufferSequence">is_BufferSequence</link></member>
|
||||||
<member><link linkend="beast.ref.is_CompletionHandler">is_CompletionHandler</link></member>
|
<member><link linkend="beast.ref.is_CompletionHandler">is_CompletionHandler</link></member>
|
||||||
<member><link linkend="beast.ref.is_ConstBufferSequence">is_ConstBufferSequence</link></member>
|
<member><link linkend="beast.ref.is_ConstBufferSequence">is_ConstBufferSequence</link></member>
|
||||||
|
<member><link linkend="beast.ref.is_DynamicBuffer">is_DynamicBuffer</link></member>
|
||||||
<member><link linkend="beast.ref.is_MutableBufferSequence">is_MutableBufferSequence</link></member>
|
<member><link linkend="beast.ref.is_MutableBufferSequence">is_MutableBufferSequence</link></member>
|
||||||
<member><link linkend="beast.ref.is_Streambuf">is_Streambuf</link></member>
|
|
||||||
<member><link linkend="beast.ref.is_SyncReadStream">is_SyncReadStream</link></member>
|
<member><link linkend="beast.ref.is_SyncReadStream">is_SyncReadStream</link></member>
|
||||||
<member><link linkend="beast.ref.is_SyncStream">is_SyncStream</link></member>
|
<member><link linkend="beast.ref.is_SyncStream">is_SyncStream</link></member>
|
||||||
<member><link linkend="beast.ref.is_SyncWriteStream">is_SyncWriteStream</link></member>
|
<member><link linkend="beast.ref.is_SyncWriteStream">is_SyncWriteStream</link></member>
|
||||||
@@ -174,10 +174,10 @@
|
|||||||
<entry valign="top">
|
<entry valign="top">
|
||||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
<bridgehead renderas="sect3">Concepts</bridgehead>
|
||||||
<simplelist type="vert" columns="1">
|
<simplelist type="vert" columns="1">
|
||||||
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member>
|
|
||||||
<member><link linkend="beast.types.streams.AsyncStream">AsyncStream</link></member>
|
<member><link linkend="beast.types.streams.AsyncStream">AsyncStream</link></member>
|
||||||
|
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member>
|
||||||
|
<member><link linkend="beast.types.DynamicBuffer">DynamicBuffer</link></member>
|
||||||
<member><link linkend="beast.types.streams.Stream">Stream</link></member>
|
<member><link linkend="beast.types.streams.Stream">Stream</link></member>
|
||||||
<member><link linkend="beast.types.Streambuf">Streambuf</link></member>
|
|
||||||
<member><link linkend="beast.types.streams.SyncStream">SyncStream</link></member>
|
<member><link linkend="beast.types.streams.SyncStream">SyncStream</link></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</entry>
|
</entry>
|
||||||
|
@@ -1552,15 +1552,15 @@
|
|||||||
<xsl:when test="declname = 'ConstBufferSequence' or type = 'class ConstBufferSequence'">
|
<xsl:when test="declname = 'ConstBufferSequence' or type = 'class ConstBufferSequence'">
|
||||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]``</xsl:text>
|
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]``</xsl:text>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
|
<xsl:when test="declname = 'DynamicBuffer' or type = 'class DynamicBuffer'">
|
||||||
|
<xsl:text>class ``[link beast.types.DynamicBuffer [*DynamicBuffer]]``</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
<xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'">
|
<xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'">
|
||||||
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]``</xsl:text>
|
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]``</xsl:text>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="declname = 'Stream' or type = 'class Stream'">
|
<xsl:when test="declname = 'Stream' or type = 'class Stream'">
|
||||||
<xsl:text>class ``[link beast.types.streams.Stream [*Stream]]``</xsl:text>
|
<xsl:text>class ``[link beast.types.streams.Stream [*Stream]]``</xsl:text>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
<xsl:when test="declname = 'Streambuf' or type = 'class Streambuf'">
|
|
||||||
<xsl:text>class ``[link beast.types.Streambuf [*Streambuf]]``</xsl:text>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="type = 'class SyncStream'">
|
<xsl:when test="type = 'class SyncStream'">
|
||||||
<xsl:text>class ``[link beast.types.streams.SyncStream [*SyncStream]]``</xsl:text>
|
<xsl:text>class ``[link beast.types.streams.SyncStream [*SyncStream]]``</xsl:text>
|
||||||
</xsl:when>
|
</xsl:when>
|
||||||
|
125
doc/types/DynamicBuffer.qbk
Normal file
125
doc/types/DynamicBuffer.qbk
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
[/
|
||||||
|
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)
|
||||||
|
]
|
||||||
|
|
||||||
|
[section:DynamicBuffer DynamicBuffer]
|
||||||
|
|
||||||
|
A dynamic buffer encapsulates memory storage that may be automatically resized
|
||||||
|
as required, where the memory is divided into an input sequence followed by an
|
||||||
|
output sequence. These memory regions are internal to the dynamic buffer, but
|
||||||
|
direct access to the elements is provided to permit them to be efficiently used
|
||||||
|
with I/O operations, such as the send or receive operations of a socket. Data
|
||||||
|
written to the output sequence of a dynamic buffer object is appended to the
|
||||||
|
input sequence of the same object.
|
||||||
|
|
||||||
|
The interface to this concept is intended to permit the following
|
||||||
|
implementation strategies:
|
||||||
|
|
||||||
|
* A single contiguous octet array, which is reallocated as necessary to
|
||||||
|
accommodate changes in the size of the octet sequence.
|
||||||
|
|
||||||
|
* A sequence of one or more octet arrays, where each array is of the same
|
||||||
|
size. Additional octet array objects are appended to the sequence to
|
||||||
|
accommodate changes in the size of the octet sequence.
|
||||||
|
|
||||||
|
* A sequence of one or more octet arrays of varying sizes. Additional octet
|
||||||
|
array objects are appended to the sequence to accommodate changes in the
|
||||||
|
size of the character sequence. This is the implementation approached
|
||||||
|
currently offered by [link beast.ref.basic_streambuf `basic_streambuf`].
|
||||||
|
|
||||||
|
In the table below:
|
||||||
|
|
||||||
|
* `X` denotes a dynamic buffer class.
|
||||||
|
* `a` denotes a value of type `X`.
|
||||||
|
* `c` denotes a (possibly const) value of type `X`.
|
||||||
|
* `n` denotes a value of type `std::size_t`.
|
||||||
|
* `T` denotes a type meeting the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html `ConstBufferSequence`].
|
||||||
|
* `U` denotes a type meeting the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html `MutableBufferSequence`].
|
||||||
|
|
||||||
|
[table DynamicBuffer requirements
|
||||||
|
[[operation] [type] [semantics, pre/post-conditions]]
|
||||||
|
[
|
||||||
|
[`X::const_buffers_type`]
|
||||||
|
[`T`]
|
||||||
|
[
|
||||||
|
This type represents the memory associated with the input sequence.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`X::mutable_buffers_type`]
|
||||||
|
[`U`]
|
||||||
|
[
|
||||||
|
This type represents the memory associated with the output sequence.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`c.size()`]
|
||||||
|
[`std::size_t`]
|
||||||
|
[
|
||||||
|
Returns the size, in bytes, of the input sequence.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`c.max_size()`]
|
||||||
|
[`std::size_t`]
|
||||||
|
[
|
||||||
|
Returns the permitted maximum of the sum of the sizes of the input
|
||||||
|
sequence and output sequence.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`c.capacity()`]
|
||||||
|
[`std::size_t`]
|
||||||
|
[
|
||||||
|
Returns the maximum sum of the sizes of the input sequence and output
|
||||||
|
sequence that the dynamic buffer can hold without requiring reallocation.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`c.data()`]
|
||||||
|
[`X::const_buffers_type`]
|
||||||
|
[
|
||||||
|
Returns a constant buffer sequence u that represents the memory
|
||||||
|
associated with the input sequence, and where `buffer_size(u) == size()`.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`a.prepare(n)`]
|
||||||
|
[`X:mutable_buffers_type`]
|
||||||
|
[
|
||||||
|
Returns a mutable buffer sequence u representing the output sequence,
|
||||||
|
and where `buffer_size(u) == n`. The dynamic buffer reallocates memory
|
||||||
|
as required. All constant or mutable buffer sequences previously
|
||||||
|
obtained using `data()` or `prepare()` are invalidated.
|
||||||
|
|
||||||
|
Throws: `length_error` if `size() + n` exceeds `max_size()`.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`a.commit(n)`]
|
||||||
|
[ ]
|
||||||
|
[
|
||||||
|
Appends `n` bytes from the start of the output sequence to the end of
|
||||||
|
the input sequence. The remainder of the output sequence is discarded.
|
||||||
|
If `n` is greater than the size of the output sequence, the entire
|
||||||
|
output sequence is appended to the input sequence. All constant or
|
||||||
|
mutable buffer sequences previously obtained using `data()` or
|
||||||
|
`prepare()` are invalidated.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
[`a.consume(n)`]
|
||||||
|
[ ]
|
||||||
|
[
|
||||||
|
Removes `n` bytes from beginning of the input sequence. If `n` is
|
||||||
|
greater than the size of the input sequence, the entire input sequence
|
||||||
|
is removed. All constant or mutable buffer sequences previously
|
||||||
|
obtained using `data()` or `prepare()` are invalidated.
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
[endsect]
|
@@ -1,96 +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)
|
|
||||||
]
|
|
||||||
|
|
||||||
[section:Streambuf Streambuf]
|
|
||||||
|
|
||||||
A [*`Streambuf`] represents a logical octet sequence divided in two sections,
|
|
||||||
the input sequence and the output sequence. Octets are written to the output
|
|
||||||
sequence, then moved to the input sequence where they are available for
|
|
||||||
reading. When some or all of the input sequence is no longer needed, it may
|
|
||||||
be consumed.
|
|
||||||
|
|
||||||
The interface to this concept is intended to permit the following
|
|
||||||
implementation strategies:
|
|
||||||
|
|
||||||
* A single contiguous octet array, which is reallocated as necessary to
|
|
||||||
accommodate changes in the size of the octet sequence.
|
|
||||||
|
|
||||||
* A sequence of one or more octet arrays, where each array is of the same
|
|
||||||
size. Additional octet array objects are appended to the sequence to
|
|
||||||
accommodate changes in the size of the octet sequence.
|
|
||||||
|
|
||||||
* A sequence of one or more octet arrays of varying sizes. Additional octet
|
|
||||||
array objects are appended to the sequence to accommodate changes in the
|
|
||||||
size of the character sequence. This is the implementation approached
|
|
||||||
currently offered by [link beast.ref.basic_streambuf `basic_streambuf`].
|
|
||||||
|
|
||||||
In the table below:
|
|
||||||
|
|
||||||
* `X` denotes a class meeting the requirements of [*`Streambuf`]
|
|
||||||
* `a` denotes a value of type `X`
|
|
||||||
* `n` denotes a value convertible to `std::size_t`
|
|
||||||
* `U`, `T` denote unspecified types.
|
|
||||||
|
|
||||||
[table Streambuf requirements
|
|
||||||
[[operation] [type] [semantics, pre/post-conditions]]
|
|
||||||
[
|
|
||||||
[`X::const_buffers_type`]
|
|
||||||
[`T`]
|
|
||||||
[`T` meets the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/ConstBufferSequence.html `ConstBufferSequence`].]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`X::mutable_buffers_type`]
|
|
||||||
[`U`]
|
|
||||||
[`U` meets the requirements for [@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/MutableBufferSequence.html `MutableBufferSequence`].]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`a.commit(n)`]
|
|
||||||
[`void`]
|
|
||||||
[Moves bytes from the output sequence to the input sequence.]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`a.consume(n)`]
|
|
||||||
[`void`]
|
|
||||||
[Removes bytes from the input sequence.]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`a.data()`]
|
|
||||||
[`T`]
|
|
||||||
[Returns a list of buffers that represents the input sequence.]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`a.prepare(n)`]
|
|
||||||
[`U`]
|
|
||||||
[Returns a list of buffers that represents the output sequence, with
|
|
||||||
the given size.]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`a.size()`]
|
|
||||||
[`std::size_t`]
|
|
||||||
[Returns the size of the input sequence.]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`a.max_size()`]
|
|
||||||
[`std::size_t`]
|
|
||||||
[Returns the maximum size of the stream buffer.]
|
|
||||||
]
|
|
||||||
[
|
|
||||||
[`read_size_helper(a, n)`]
|
|
||||||
[`std::size_t`]
|
|
||||||
[
|
|
||||||
Returns the suggested number of bytes to read into the output
|
|
||||||
sequence where `n` is an upper limit on this value. One possible
|
|
||||||
implementation is to return the number of bytes that may be prepared
|
|
||||||
without causing a dynamic allocation or `n`, whichever is smaller.
|
|
||||||
Calls to `read_size_helper` will be made without namespace
|
|
||||||
qualification, to allow the rules for argument dependent lookup to
|
|
||||||
take effect.
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
[endsect]
|
|
@@ -358,7 +358,7 @@ handler of the corresponding read function.]
|
|||||||
|
|
||||||
Because calls to read data may return a variable amount of bytes, the
|
Because calls to read data may return a variable amount of bytes, the
|
||||||
interface to calls that read data require an object that meets the requirements
|
interface to calls that read data require an object that meets the requirements
|
||||||
of [link beast.types.Streambuf [*`Streambuf`]]. This concept is modeled on
|
of [link beast.types.DynamicBuffer [*`DynamicBuffer`]]. This concept is modeled on
|
||||||
[@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/basic_streambuf.html `boost::asio::basic_streambuf`].
|
[@http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/basic_streambuf.html `boost::asio::basic_streambuf`].
|
||||||
|
|
||||||
The implementation does not perform queueing or buffering of messages. If
|
The implementation does not perform queueing or buffering of messages. If
|
||||||
|
@@ -24,8 +24,8 @@
|
|||||||
#include <beast/core/static_string.hpp>
|
#include <beast/core/static_string.hpp>
|
||||||
#include <beast/core/stream_concepts.hpp>
|
#include <beast/core/stream_concepts.hpp>
|
||||||
#include <beast/core/streambuf.hpp>
|
#include <beast/core/streambuf.hpp>
|
||||||
#include <beast/core/streambuf_readstream.hpp>
|
#include <beast/core/dynabuf_readstream.hpp>
|
||||||
#include <beast/core/to_string.hpp>
|
#include <beast/core/to_string.hpp>
|
||||||
#include <beast/core/write_streambuf.hpp>
|
#include <beast/core/write_dynabuf.hpp>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
namespace beast {
|
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
|
The implementation uses a sequence of one or more character arrays
|
||||||
of varying sizes. Additional character array objects are appended to
|
of varying sizes. Additional character array objects are appended to
|
||||||
the sequence to accommodate changes in the size of the character
|
the sequence to accommodate changes in the size of the character
|
||||||
sequence.
|
sequence.
|
||||||
|
|
||||||
@note Meets the requirements of @b Streambuf.
|
@note Meets the requirements of @b `DynamicBuffer`.
|
||||||
|
|
||||||
@tparam Allocator The allocator to use for managing memory.
|
@tparam Allocator The allocator to use for managing memory.
|
||||||
*/
|
*/
|
||||||
@@ -202,26 +202,37 @@ public:
|
|||||||
basic_streambuf(std::size_t alloc_size = 1024,
|
basic_streambuf(std::size_t alloc_size = 1024,
|
||||||
Allocator const& alloc = allocator_type{});
|
Allocator const& alloc = allocator_type{});
|
||||||
|
|
||||||
/// Get the associated allocator
|
/// Returns a copy of the associated allocator.
|
||||||
allocator_type
|
allocator_type
|
||||||
get_allocator() const
|
get_allocator() const
|
||||||
{
|
{
|
||||||
return this->member();
|
return this->member();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the maximum size of the basic_streambuf.
|
/// Returns the size of the input sequence.
|
||||||
|
size_type
|
||||||
|
size() const
|
||||||
|
{
|
||||||
|
return in_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the permitted maximum sum of the sizes of the input and output sequence.
|
||||||
size_type
|
size_type
|
||||||
max_size() const
|
max_size() const
|
||||||
{
|
{
|
||||||
return std::numeric_limits<std::size_t>::max();
|
return std::numeric_limits<std::size_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the size of the input sequence.
|
/// Returns the maximum sum of the sizes of the input sequence and output sequence the buffer can hold without requiring reallocation.
|
||||||
size_type
|
std::size_t
|
||||||
size() const
|
capacity() const;
|
||||||
{
|
|
||||||
return in_size_;
|
/** Get a list of buffers that represents the input sequence.
|
||||||
}
|
|
||||||
|
@note These buffers remain valid across subsequent calls to `prepare`.
|
||||||
|
*/
|
||||||
|
const_buffers_type
|
||||||
|
data() const;
|
||||||
|
|
||||||
/** Get a list of buffers that represents the output sequence, with the given size.
|
/** Get a list of buffers that represents the output sequence, with the given size.
|
||||||
|
|
||||||
@@ -239,22 +250,11 @@ public:
|
|||||||
void
|
void
|
||||||
commit(size_type n);
|
commit(size_type n);
|
||||||
|
|
||||||
/** Get a list of buffers that represents the input sequence.
|
|
||||||
|
|
||||||
@note These buffers remain valid across subsequent calls to `prepare`.
|
|
||||||
*/
|
|
||||||
const_buffers_type
|
|
||||||
data() const;
|
|
||||||
|
|
||||||
/// Remove bytes from the input sequence.
|
/// Remove bytes from the input sequence.
|
||||||
void
|
void
|
||||||
consume(size_type n);
|
consume(size_type n);
|
||||||
|
|
||||||
/// Clear everything.
|
// Helper for boost::asio::read_until
|
||||||
void
|
|
||||||
clear();
|
|
||||||
|
|
||||||
// Helper for read_until
|
|
||||||
template<class OtherAllocator>
|
template<class OtherAllocator>
|
||||||
friend
|
friend
|
||||||
std::size_t
|
std::size_t
|
||||||
@@ -262,6 +262,9 @@ public:
|
|||||||
OtherAllocator> const& streambuf, std::size_t max_size);
|
OtherAllocator> const& streambuf, std::size_t max_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void
|
||||||
|
clear();
|
||||||
|
|
||||||
void
|
void
|
||||||
move_assign(basic_streambuf& other, std::false_type);
|
move_assign(basic_streambuf& other, std::false_type);
|
||||||
|
|
||||||
@@ -277,20 +280,17 @@ private:
|
|||||||
void
|
void
|
||||||
delete_list();
|
delete_list();
|
||||||
|
|
||||||
std::size_t
|
|
||||||
prepare_size() const;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
debug_check() const;
|
debug_check() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Format output to a stream buffer.
|
/** Format output to a @ref basic_streambuf.
|
||||||
|
|
||||||
@param streambuf The streambuf to write to.
|
@param streambuf The @ref basic_streambuf to write to.
|
||||||
|
|
||||||
@param t The object to write.
|
@param t The object to write.
|
||||||
|
|
||||||
@return The stream buffer.
|
@return A reference to the @ref basic_streambuf.
|
||||||
*/
|
*/
|
||||||
template<class Allocator, class T>
|
template<class Allocator, class T>
|
||||||
basic_streambuf<Allocator>&
|
basic_streambuf<Allocator>&
|
||||||
|
@@ -35,6 +35,16 @@ struct is_ConstBufferSequence :
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Determine if `T` meets the requirements of @b `DynamicBuffer`.
|
||||||
|
template<class T>
|
||||||
|
#if GENERATING_DOCS
|
||||||
|
struct is_DynamicBuffer : std::integral_constant<bool, ...>
|
||||||
|
#else
|
||||||
|
struct is_DynamicBuffer : detail::is_DynamicBuffer<T>::type
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
/// Determine if `T` meets the requirements of @b `MutableBufferSequence`.
|
/// Determine if `T` meets the requirements of @b `MutableBufferSequence`.
|
||||||
template<class T>
|
template<class T>
|
||||||
#if GENERATING_DOCS
|
#if GENERATING_DOCS
|
||||||
@@ -46,16 +56,6 @@ struct is_MutableBufferSequence :
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Determine if `T` meets the requirements of @b `Streambuf`.
|
|
||||||
template<class T>
|
|
||||||
#if GENERATING_DOCS
|
|
||||||
struct is_Streambuf : std::integral_constant<bool, ...>
|
|
||||||
#else
|
|
||||||
struct is_Streambuf : detail::is_Streambuf<T>::type
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -86,7 +86,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class is_Streambuf
|
class is_DynamicBuffer
|
||||||
{
|
{
|
||||||
template<class U, class R = std::integral_constant<
|
template<class U, class R = std::integral_constant<
|
||||||
bool, is_BufferSequence<decltype(
|
bool, is_BufferSequence<decltype(
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
#ifndef BEAST_DETAIL_WRITE_DYNABUF_HPP
|
||||||
#define BEAST_DETAIL_WRITE_STREAMBUF_HPP
|
#define BEAST_DETAIL_WRITE_DYNABUF_HPP
|
||||||
|
|
||||||
#include <beast/core/buffer_concepts.hpp>
|
#include <beast/core/buffer_concepts.hpp>
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
@@ -42,73 +42,73 @@ public:
|
|||||||
! is_string_literal<T>::value;
|
! is_string_literal<T>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
write_streambuf(Streambuf& streambuf,
|
write_dynabuf(DynamicBuffer& dynabuf,
|
||||||
boost::asio::const_buffer const& buffer)
|
boost::asio::const_buffer const& buffer)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
streambuf.commit(buffer_copy(
|
dynabuf.commit(buffer_copy(
|
||||||
streambuf.prepare(buffer_size(buffer)),
|
dynabuf.prepare(buffer_size(buffer)),
|
||||||
buffer));
|
buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
write_streambuf(Streambuf& streambuf,
|
write_dynabuf(DynamicBuffer& dynabuf,
|
||||||
boost::asio::mutable_buffer const& buffer)
|
boost::asio::mutable_buffer const& buffer)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
streambuf.commit(buffer_copy(
|
dynabuf.commit(buffer_copy(
|
||||||
streambuf.prepare(buffer_size(buffer)),
|
dynabuf.prepare(buffer_size(buffer)),
|
||||||
buffer));
|
buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, class T>
|
template<class DynamicBuffer, class T>
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
is_BufferConvertible<T>::value &&
|
is_BufferConvertible<T>::value &&
|
||||||
! std::is_convertible<T, boost::asio::const_buffer>::value &&
|
! std::is_convertible<T, boost::asio::const_buffer>::value &&
|
||||||
! std::is_convertible<T, boost::asio::mutable_buffer>::value
|
! std::is_convertible<T, boost::asio::mutable_buffer>::value
|
||||||
>::type
|
>::type
|
||||||
write_streambuf(Streambuf& streambuf, T const& t)
|
write_dynabuf(DynamicBuffer& dynabuf, T const& t)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
auto const buffers = boost::asio::buffer(t);
|
auto const buffers = boost::asio::buffer(t);
|
||||||
streambuf.commit(buffer_copy(
|
dynabuf.commit(buffer_copy(
|
||||||
streambuf.prepare(buffer_size(buffers)),
|
dynabuf.prepare(buffer_size(buffers)),
|
||||||
buffers));
|
buffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, class Buffers>
|
template<class DynamicBuffer, class Buffers>
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
is_ConstBufferSequence<Buffers>::value &&
|
is_ConstBufferSequence<Buffers>::value &&
|
||||||
! is_BufferConvertible<Buffers>::value &&
|
! is_BufferConvertible<Buffers>::value &&
|
||||||
! std::is_convertible<Buffers, boost::asio::const_buffer>::value &&
|
! std::is_convertible<Buffers, boost::asio::const_buffer>::value &&
|
||||||
! std::is_convertible<Buffers, boost::asio::mutable_buffer>::value
|
! std::is_convertible<Buffers, boost::asio::mutable_buffer>::value
|
||||||
>::type
|
>::type
|
||||||
write_streambuf(Streambuf& streambuf, Buffers const& buffers)
|
write_dynabuf(DynamicBuffer& dynabuf, Buffers const& buffers)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
streambuf.commit(buffer_copy(
|
dynabuf.commit(buffer_copy(
|
||||||
streambuf.prepare(buffer_size(buffers)),
|
dynabuf.prepare(buffer_size(buffers)),
|
||||||
buffers));
|
buffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, std::size_t N>
|
template<class DynamicBuffer, std::size_t N>
|
||||||
void
|
void
|
||||||
write_streambuf(Streambuf& streambuf, const char (&s)[N])
|
write_dynabuf(DynamicBuffer& dynabuf, const char (&s)[N])
|
||||||
{
|
{
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
streambuf.commit(buffer_copy(
|
dynabuf.commit(buffer_copy(
|
||||||
streambuf.prepare(N - 1),
|
dynabuf.prepare(N - 1),
|
||||||
boost::asio::buffer(s, N - 1)));
|
boost::asio::buffer(s, N - 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, class T>
|
template<class DynamicBuffer, class T>
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
! is_string_literal<T>::value &&
|
! is_string_literal<T>::value &&
|
||||||
! is_ConstBufferSequence<T>::value &&
|
! is_ConstBufferSequence<T>::value &&
|
||||||
@@ -116,22 +116,22 @@ typename std::enable_if<
|
|||||||
! std::is_convertible<T, boost::asio::const_buffer>::value &&
|
! std::is_convertible<T, boost::asio::const_buffer>::value &&
|
||||||
! std::is_convertible<T, boost::asio::mutable_buffer>::value
|
! std::is_convertible<T, boost::asio::mutable_buffer>::value
|
||||||
>::type
|
>::type
|
||||||
write_streambuf(Streambuf& streambuf, T const& t)
|
write_dynabuf(DynamicBuffer& dynabuf, T const& t)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
auto const s = boost::lexical_cast<std::string>(t);
|
auto const s = boost::lexical_cast<std::string>(t);
|
||||||
streambuf.commit(buffer_copy(
|
dynabuf.commit(buffer_copy(
|
||||||
streambuf.prepare(s.size()), buffer(s)));
|
dynabuf.prepare(s.size()), buffer(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, class T0, class T1, class... TN>
|
template<class DynamicBuffer, class T0, class T1, class... TN>
|
||||||
void
|
void
|
||||||
write_streambuf(Streambuf& streambuf,
|
write_dynabuf(DynamicBuffer& dynabuf,
|
||||||
T0 const& t0, T1 const& t1, TN const&... tn)
|
T0 const& t0, T1 const& t1, TN const&... tn)
|
||||||
{
|
{
|
||||||
write_streambuf(streambuf, t0);
|
write_dynabuf(dynabuf, t0);
|
||||||
write_streambuf(streambuf, t1, tn...);
|
write_dynabuf(dynabuf, t1, tn...);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // detail
|
} // detail
|
@@ -5,8 +5,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BEAST_STREAMBUF_READSTREAM_HPP
|
#ifndef BEAST_DYNABUF_READSTREAM_HPP
|
||||||
#define BEAST_STREAMBUF_READSTREAM_HPP
|
#define BEAST_DYNABUF_READSTREAM_HPP
|
||||||
|
|
||||||
#include <beast/core/async_completion.hpp>
|
#include <beast/core/async_completion.hpp>
|
||||||
#include <beast/core/buffer_concepts.hpp>
|
#include <beast/core/buffer_concepts.hpp>
|
||||||
@@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
/** A @b `Stream` with attached @b `Streambuf` to buffer reads.
|
/** A @b `Stream` with attached @b `DynamicBuffer` to buffer reads.
|
||||||
|
|
||||||
This wraps a @b `Stream` implementation so that calls to write are
|
This wraps a @b `Stream` implementation so that calls to write are
|
||||||
passed through to the underlying stream, while calls to read will
|
passed through to the underlying stream, while calls to read will
|
||||||
first consume the input sequence stored in a @b `Streambuf` which
|
first consume the input sequence stored in a @b `DynamicBuffer` which
|
||||||
is part of the object.
|
is part of the object.
|
||||||
|
|
||||||
The use-case for this class is different than that of the
|
The use-case for this class is different than that of the
|
||||||
@@ -50,9 +50,9 @@ namespace beast {
|
|||||||
// Process the next HTTP headers on the stream,
|
// Process the next HTTP headers on the stream,
|
||||||
// leaving excess bytes behind for the next call.
|
// leaving excess bytes behind for the next call.
|
||||||
//
|
//
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void process_http_message(
|
void process_http_message(
|
||||||
streambuf_readstream<Streambuf>& stream)
|
dynabuf_readstream<DynamicBuffer>& stream)
|
||||||
{
|
{
|
||||||
// Read up to and including the end of the HTTP
|
// Read up to and including the end of the HTTP
|
||||||
// headers, leaving the sequence in the stream's
|
// headers, leaving the sequence in the stream's
|
||||||
@@ -85,24 +85,24 @@ namespace beast {
|
|||||||
|
|
||||||
@tparam Stream The type of stream to wrap.
|
@tparam Stream The type of stream to wrap.
|
||||||
|
|
||||||
@tparam Streambuf The type of stream buffer to use.
|
@tparam DynamicBuffer The type of stream buffer to use.
|
||||||
*/
|
*/
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
class streambuf_readstream
|
class dynabuf_readstream
|
||||||
{
|
{
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
|
|
||||||
template<class Buffers, class Handler>
|
template<class Buffers, class Handler>
|
||||||
class read_some_op;
|
class read_some_op;
|
||||||
|
|
||||||
Streambuf sb_;
|
DynamicBuffer sb_;
|
||||||
std::size_t capacity_ = 0;
|
std::size_t capacity_ = 0;
|
||||||
Stream next_layer_;
|
Stream next_layer_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The type of the internal buffer
|
/// The type of the internal buffer
|
||||||
using streambuf_type = Streambuf;
|
using dynabuf_type = DynamicBuffer;
|
||||||
|
|
||||||
/// The type of the next layer.
|
/// The type of the next layer.
|
||||||
using next_layer_type =
|
using next_layer_type =
|
||||||
@@ -122,14 +122,14 @@ public:
|
|||||||
@note The behavior of move assignment on or from streams
|
@note The behavior of move assignment on or from streams
|
||||||
with active or pending operations is undefined.
|
with active or pending operations is undefined.
|
||||||
*/
|
*/
|
||||||
streambuf_readstream(streambuf_readstream&&) = default;
|
dynabuf_readstream(dynabuf_readstream&&) = default;
|
||||||
|
|
||||||
/** Move assignment.
|
/** Move assignment.
|
||||||
|
|
||||||
@note The behavior of move assignment on or from streams
|
@note The behavior of move assignment on or from streams
|
||||||
with active or pending operations is undefined.
|
with active or pending operations is undefined.
|
||||||
*/
|
*/
|
||||||
streambuf_readstream& operator=(streambuf_readstream&&) = default;
|
dynabuf_readstream& operator=(dynabuf_readstream&&) = default;
|
||||||
|
|
||||||
/** Construct the wrapping stream.
|
/** Construct the wrapping stream.
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
explicit
|
explicit
|
||||||
streambuf_readstream(Args&&... args);
|
dynabuf_readstream(Args&&... args);
|
||||||
|
|
||||||
/// Get a reference to the next layer.
|
/// Get a reference to the next layer.
|
||||||
next_layer_type&
|
next_layer_type&
|
||||||
@@ -174,7 +174,7 @@ public:
|
|||||||
by causing the internal buffer size to increase beyond
|
by causing the internal buffer size to increase beyond
|
||||||
the caller defined maximum.
|
the caller defined maximum.
|
||||||
*/
|
*/
|
||||||
Streambuf&
|
DynamicBuffer&
|
||||||
buffer()
|
buffer()
|
||||||
{
|
{
|
||||||
return sb_;
|
return sb_;
|
||||||
@@ -187,7 +187,7 @@ public:
|
|||||||
by causing the internal buffer size to increase beyond
|
by causing the internal buffer size to increase beyond
|
||||||
the caller defined maximum.
|
the caller defined maximum.
|
||||||
*/
|
*/
|
||||||
Streambuf const&
|
DynamicBuffer const&
|
||||||
buffer() const
|
buffer() const
|
||||||
{
|
{
|
||||||
return sb_;
|
return sb_;
|
||||||
@@ -275,6 +275,6 @@ public:
|
|||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
|
|
||||||
#include <beast/core/impl/streambuf_readstream.ipp>
|
#include <beast/core/impl/dynabuf_readstream.ipp>
|
||||||
|
|
||||||
#endif
|
#endif
|
@@ -8,7 +8,7 @@
|
|||||||
#ifndef BEAST_IMPL_BASIC_STREAMBUF_IPP
|
#ifndef BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||||
#define BEAST_IMPL_BASIC_STREAMBUF_IPP
|
#define BEAST_IMPL_BASIC_STREAMBUF_IPP
|
||||||
|
|
||||||
#include <beast/core/detail/write_streambuf.hpp>
|
#include <beast/core/detail/write_dynabuf.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
@@ -527,6 +527,28 @@ basic_streambuf<Allocator>::basic_streambuf(
|
|||||||
"basic_streambuf: invalid alloc_size");
|
"basic_streambuf: invalid alloc_size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
std::size_t
|
||||||
|
basic_streambuf<Allocator>::capacity() const
|
||||||
|
{
|
||||||
|
auto pos = out_;
|
||||||
|
if(pos == list_.end())
|
||||||
|
return 0;
|
||||||
|
auto n = pos->size() - out_pos_;
|
||||||
|
while(++pos != list_.end())
|
||||||
|
n += pos->size();
|
||||||
|
return in_size_ + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
auto
|
||||||
|
basic_streambuf<Allocator>::
|
||||||
|
data() const ->
|
||||||
|
const_buffers_type
|
||||||
|
{
|
||||||
|
return const_buffers_type(*this);
|
||||||
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
auto
|
auto
|
||||||
basic_streambuf<Allocator>::prepare(size_type n) ->
|
basic_streambuf<Allocator>::prepare(size_type n) ->
|
||||||
@@ -646,14 +668,6 @@ basic_streambuf<Allocator>::commit(size_type n)
|
|||||||
debug_check();
|
debug_check();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
auto
|
|
||||||
basic_streambuf<Allocator>::data() const ->
|
|
||||||
const_buffers_type
|
|
||||||
{
|
|
||||||
return const_buffers_type(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
void
|
void
|
||||||
basic_streambuf<Allocator>::consume(size_type n)
|
basic_streambuf<Allocator>::consume(size_type n)
|
||||||
@@ -717,7 +731,8 @@ basic_streambuf<Allocator>::consume(size_type n)
|
|||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
void
|
void
|
||||||
basic_streambuf<Allocator>::clear()
|
basic_streambuf<Allocator>::
|
||||||
|
clear()
|
||||||
{
|
{
|
||||||
delete_list();
|
delete_list();
|
||||||
list_.clear();
|
list_.clear();
|
||||||
@@ -795,21 +810,6 @@ basic_streambuf<Allocator>::delete_list()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of bytes which can be
|
|
||||||
// prepared without causing a memory allocation.
|
|
||||||
template<class Allocator>
|
|
||||||
std::size_t
|
|
||||||
basic_streambuf<Allocator>::prepare_size() const
|
|
||||||
{
|
|
||||||
auto pos = out_;
|
|
||||||
if(pos == list_.end())
|
|
||||||
return 0;
|
|
||||||
auto n = pos->size() - out_pos_;
|
|
||||||
while(++pos != list_.end())
|
|
||||||
n += pos->size();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
void
|
void
|
||||||
basic_streambuf<Allocator>::debug_check() const
|
basic_streambuf<Allocator>::debug_check() const
|
||||||
@@ -855,7 +855,7 @@ std::size_t
|
|||||||
read_size_helper(basic_streambuf<
|
read_size_helper(basic_streambuf<
|
||||||
Allocator> const& streambuf, std::size_t max_size)
|
Allocator> const& streambuf, std::size_t max_size)
|
||||||
{
|
{
|
||||||
auto const avail = streambuf.prepare_size();
|
auto const avail = streambuf.capacity() - streambuf.size();
|
||||||
if(avail == 0)
|
if(avail == 0)
|
||||||
return std::min(max_size,
|
return std::min(max_size,
|
||||||
std::max<std::size_t>(512, streambuf.alloc_size_));
|
std::max<std::size_t>(512, streambuf.alloc_size_));
|
||||||
@@ -866,7 +866,7 @@ template<class Alloc, class T>
|
|||||||
basic_streambuf<Alloc>&
|
basic_streambuf<Alloc>&
|
||||||
operator<<(basic_streambuf<Alloc>& streambuf, T const& t)
|
operator<<(basic_streambuf<Alloc>& streambuf, T const& t)
|
||||||
{
|
{
|
||||||
detail::write_streambuf(streambuf, t);
|
detail::write_dynabuf(streambuf, t);
|
||||||
return streambuf;
|
return streambuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
#ifndef BEAST_IMPL_DYNABUF_READSTREAM_HPP
|
||||||
#define BEAST_IMPL_STREAMBUF_READSTREAM_IPP
|
#define BEAST_IMPL_DYNABUF_READSTREAM_HPP
|
||||||
|
|
||||||
#include <beast/core/bind_handler.hpp>
|
#include <beast/core/bind_handler.hpp>
|
||||||
#include <beast/core/handler_concepts.hpp>
|
#include <beast/core/handler_concepts.hpp>
|
||||||
@@ -16,24 +16,24 @@
|
|||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class MutableBufferSequence, class Handler>
|
template<class MutableBufferSequence, class Handler>
|
||||||
class streambuf_readstream<
|
class dynabuf_readstream<
|
||||||
Stream, Streambuf>::read_some_op
|
Stream, DynamicBuffer>::read_some_op
|
||||||
{
|
{
|
||||||
using alloc_type =
|
using alloc_type =
|
||||||
handler_alloc<char, Handler>;
|
handler_alloc<char, Handler>;
|
||||||
|
|
||||||
struct data
|
struct data
|
||||||
{
|
{
|
||||||
streambuf_readstream& srs;
|
dynabuf_readstream& srs;
|
||||||
MutableBufferSequence bs;
|
MutableBufferSequence bs;
|
||||||
Handler h;
|
Handler h;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
|
||||||
template<class DeducedHandler>
|
template<class DeducedHandler>
|
||||||
data(DeducedHandler&& h_,
|
data(DeducedHandler&& h_,
|
||||||
streambuf_readstream& srs_,
|
dynabuf_readstream& srs_,
|
||||||
MutableBufferSequence const& bs_)
|
MutableBufferSequence const& bs_)
|
||||||
: srs(srs_)
|
: srs(srs_)
|
||||||
, bs(bs_)
|
, bs(bs_)
|
||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
|
|
||||||
template<class DeducedHandler, class... Args>
|
template<class DeducedHandler, class... Args>
|
||||||
read_some_op(DeducedHandler&& h,
|
read_some_op(DeducedHandler&& h,
|
||||||
streambuf_readstream& srs, Args&&... args)
|
dynabuf_readstream& srs, Args&&... args)
|
||||||
: d_(std::allocate_shared<data>(alloc_type{h},
|
: d_(std::allocate_shared<data>(alloc_type{h},
|
||||||
std::forward<DeducedHandler>(h), srs,
|
std::forward<DeducedHandler>(h), srs,
|
||||||
std::forward<Args>(args)...))
|
std::forward<Args>(args)...))
|
||||||
@@ -94,10 +94,10 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class MutableBufferSequence, class Handler>
|
template<class MutableBufferSequence, class Handler>
|
||||||
void
|
void
|
||||||
streambuf_readstream<Stream, Streambuf>::
|
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||||
read_some_op<MutableBufferSequence, Handler>::operator()(
|
read_some_op<MutableBufferSequence, Handler>::operator()(
|
||||||
error_code const& ec, std::size_t bytes_transferred)
|
error_code const& ec, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
@@ -155,18 +155,18 @@ read_some_op<MutableBufferSequence, Handler>::operator()(
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
streambuf_readstream<Stream, Streambuf>::
|
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||||
streambuf_readstream(Args&&... args)
|
dynabuf_readstream(Args&&... args)
|
||||||
: next_layer_(std::forward<Args>(args)...)
|
: next_layer_(std::forward<Args>(args)...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class ConstBufferSequence, class WriteHandler>
|
template<class ConstBufferSequence, class WriteHandler>
|
||||||
auto
|
auto
|
||||||
streambuf_readstream<Stream, Streambuf>::
|
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||||
async_write_some(ConstBufferSequence const& buffers,
|
async_write_some(ConstBufferSequence const& buffers,
|
||||||
WriteHandler&& handler) ->
|
WriteHandler&& handler) ->
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
@@ -184,10 +184,10 @@ async_write_some(ConstBufferSequence const& buffers,
|
|||||||
std::forward<WriteHandler>(handler));
|
std::forward<WriteHandler>(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class MutableBufferSequence>
|
template<class MutableBufferSequence>
|
||||||
std::size_t
|
std::size_t
|
||||||
streambuf_readstream<Stream, Streambuf>::
|
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||||
read_some(
|
read_some(
|
||||||
MutableBufferSequence const& buffers)
|
MutableBufferSequence const& buffers)
|
||||||
{
|
{
|
||||||
@@ -203,10 +203,10 @@ read_some(
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class MutableBufferSequence>
|
template<class MutableBufferSequence>
|
||||||
std::size_t
|
std::size_t
|
||||||
streambuf_readstream<Stream, Streambuf>::
|
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||||
read_some(MutableBufferSequence const& buffers,
|
read_some(MutableBufferSequence const& buffers,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
@@ -232,10 +232,10 @@ read_some(MutableBufferSequence const& buffers,
|
|||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Stream, class Streambuf>
|
template<class Stream, class DynamicBuffer>
|
||||||
template<class MutableBufferSequence, class ReadHandler>
|
template<class MutableBufferSequence, class ReadHandler>
|
||||||
auto
|
auto
|
||||||
streambuf_readstream<Stream, Streambuf>::
|
dynabuf_readstream<Stream, DynamicBuffer>::
|
||||||
async_read_some(
|
async_read_some(
|
||||||
MutableBufferSequence const& buffers,
|
MutableBufferSequence const& buffers,
|
||||||
ReadHandler&& handler) ->
|
ReadHandler&& handler) ->
|
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
/** A @b `Streambuf` with a fixed size internal buffer.
|
/** A @b `DynamicBuffer` with a fixed size internal buffer.
|
||||||
|
|
||||||
Ownership of the underlying storage belongs to the derived class.
|
Ownership of the underlying storage belongs to the derived class.
|
||||||
|
|
||||||
|
@@ -5,20 +5,20 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef BEAST_WRITE_STREAMBUF_HPP
|
#ifndef BEAST_WRITE_DYNABUF_HPP
|
||||||
#define BEAST_WRITE_STREAMBUF_HPP
|
#define BEAST_WRITE_DYNABUF_HPP
|
||||||
|
|
||||||
#include <beast/core/buffer_concepts.hpp>
|
#include <beast/core/buffer_concepts.hpp>
|
||||||
#include <beast/core/detail/write_streambuf.hpp>
|
#include <beast/core/detail/write_dynabuf.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
/** Write to a Streambuf.
|
/** Write to a @b `DynamicBuffer`.
|
||||||
|
|
||||||
This function appends the serialized representation of each provided
|
This function appends the serialized representation of each provided
|
||||||
argument into the stream buffer. It is capable of converting the
|
argument into the dynamic buffer. It is capable of converting the
|
||||||
following types of arguments:
|
following types of arguments:
|
||||||
|
|
||||||
@li `boost::asio::const_buffer`
|
@li `boost::asio::const_buffer`
|
||||||
@@ -33,29 +33,29 @@ namespace beast {
|
|||||||
|
|
||||||
For all types not listed above, the function will invoke
|
For all types not listed above, the function will invoke
|
||||||
`boost::lexical_cast` on the argument in an attempt to convert to
|
`boost::lexical_cast` on the argument in an attempt to convert to
|
||||||
a string, which is then appended to the stream buffer.
|
a string, which is then appended to the dynamic buffer.
|
||||||
|
|
||||||
When this function serializes numbers, it converts them to
|
When this function serializes numbers, it converts them to
|
||||||
their text representation as if by a call to `std::to_string`.
|
their text representation as if by a call to `std::to_string`.
|
||||||
|
|
||||||
@param streambuf The stream buffer to write to.
|
@param dynabuf The dynamic buffer to write to.
|
||||||
|
|
||||||
@param args A list of one or more arguments to write.
|
@param args A list of one or more arguments to write.
|
||||||
|
|
||||||
@throws unspecified Any exceptions thrown by `boost::lexical_cast`.
|
@throws unspecified Any exceptions thrown by `boost::lexical_cast`.
|
||||||
|
|
||||||
@note This function participates in overload resolution only if
|
@note This function participates in overload resolution only if
|
||||||
the `streambuf` parameter meets the requirements of @b `Streambuf`.
|
the `dynabuf` parameter meets the requirements of @b `DynamicBuffer`.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf, class... Args>
|
template<class DynamicBuffer, class... Args>
|
||||||
#if GENERATING_DOCS
|
#if GENERATING_DOCS
|
||||||
void
|
void
|
||||||
#else
|
#else
|
||||||
typename std::enable_if<is_Streambuf<Streambuf>::value>::type
|
typename std::enable_if<is_DynamicBuffer<DynamicBuffer>::value>::type
|
||||||
#endif
|
#endif
|
||||||
write(Streambuf& streambuf, Args const&... args)
|
write(DynamicBuffer& dynabuf, Args const&... args)
|
||||||
{
|
{
|
||||||
detail::write_streambuf(streambuf, args...);
|
detail::write_dynabuf(dynabuf, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // beast
|
} // beast
|
95
include/beast/http/basic_dynabuf_body.hpp
Normal file
95
include/beast/http/basic_dynabuf_body.hpp
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// 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_BASIC_DYNABUF_BODY_HPP
|
||||||
|
#define BEAST_HTTP_BASIC_DYNABUF_BODY_HPP
|
||||||
|
|
||||||
|
#include <beast/http/body_type.hpp>
|
||||||
|
#include <boost/asio/buffer.hpp>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
namespace http {
|
||||||
|
|
||||||
|
/** A message body represented by a @b `DynamicBuffer`
|
||||||
|
|
||||||
|
Meets the requirements of @b `Body`.
|
||||||
|
*/
|
||||||
|
template<class DynamicBuffer>
|
||||||
|
struct basic_dynabuf_body
|
||||||
|
{
|
||||||
|
/// The type of the `message::body` member
|
||||||
|
using value_type = DynamicBuffer;
|
||||||
|
|
||||||
|
#if GENERATING_DOCS
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class reader
|
||||||
|
{
|
||||||
|
value_type& sb_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<bool isRequest, class Headers>
|
||||||
|
explicit
|
||||||
|
reader(message<isRequest,
|
||||||
|
basic_dynabuf_body, Headers>& m) noexcept
|
||||||
|
: sb_(m.body)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write(void const* data,
|
||||||
|
std::size_t size, error_code&) noexcept
|
||||||
|
{
|
||||||
|
using boost::asio::buffer;
|
||||||
|
using boost::asio::buffer_copy;
|
||||||
|
sb_.commit(buffer_copy(
|
||||||
|
sb_.prepare(size), buffer(data, size)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class writer
|
||||||
|
{
|
||||||
|
DynamicBuffer const& body_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
writer(writer const&) = delete;
|
||||||
|
writer& operator=(writer const&) = delete;
|
||||||
|
|
||||||
|
template<bool isRequest, class Headers>
|
||||||
|
explicit
|
||||||
|
writer(message<
|
||||||
|
isRequest, basic_dynabuf_body, Headers> const& m)
|
||||||
|
: body_(m.body)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
init(error_code& ec)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint64_t
|
||||||
|
content_length() const
|
||||||
|
{
|
||||||
|
return body_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Write>
|
||||||
|
boost::tribool
|
||||||
|
operator()(resume_context&&, error_code&, Write&& write)
|
||||||
|
{
|
||||||
|
write(body_.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // http
|
||||||
|
} // beast
|
||||||
|
|
||||||
|
#endif
|
@@ -9,7 +9,6 @@
|
|||||||
#define BEAST_HTTP_EMPTY_BODY_HPP
|
#define BEAST_HTTP_EMPTY_BODY_HPP
|
||||||
|
|
||||||
#include <beast/http/body_type.hpp>
|
#include <beast/http/body_type.hpp>
|
||||||
#include <beast/core/streambuf.hpp>
|
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@@ -21,7 +21,7 @@ namespace http {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class Stream,
|
template<class Stream,
|
||||||
class Streambuf, class Parser, class Handler>
|
class DynamicBuffer, class Parser, class Handler>
|
||||||
class parse_op
|
class parse_op
|
||||||
{
|
{
|
||||||
using alloc_type =
|
using alloc_type =
|
||||||
@@ -30,7 +30,7 @@ class parse_op
|
|||||||
struct data
|
struct data
|
||||||
{
|
{
|
||||||
Stream& s;
|
Stream& s;
|
||||||
Streambuf& sb;
|
DynamicBuffer& db;
|
||||||
Parser& p;
|
Parser& p;
|
||||||
Handler h;
|
Handler h;
|
||||||
bool started = false;
|
bool started = false;
|
||||||
@@ -39,9 +39,9 @@ class parse_op
|
|||||||
|
|
||||||
template<class DeducedHandler>
|
template<class DeducedHandler>
|
||||||
data(DeducedHandler&& h_, Stream& s_,
|
data(DeducedHandler&& h_, Stream& s_,
|
||||||
Streambuf& sb_, Parser& p_)
|
DynamicBuffer& sb_, Parser& p_)
|
||||||
: s(s_)
|
: s(s_)
|
||||||
, sb(sb_)
|
, db(sb_)
|
||||||
, p(p_)
|
, p(p_)
|
||||||
, h(std::forward<DeducedHandler>(h_))
|
, h(std::forward<DeducedHandler>(h_))
|
||||||
, cont(boost_asio_handler_cont_helpers::
|
, cont(boost_asio_handler_cont_helpers::
|
||||||
@@ -101,9 +101,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class Stream,
|
template<class Stream,
|
||||||
class Streambuf, class Parser, class Handler>
|
class DynamicBuffer, class Parser, class Handler>
|
||||||
void
|
void
|
||||||
parse_op<Stream, Streambuf, Parser, Handler>::
|
parse_op<Stream, DynamicBuffer, Parser, Handler>::
|
||||||
operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
||||||
{
|
{
|
||||||
auto& d = *d_;
|
auto& d = *d_;
|
||||||
@@ -115,7 +115,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
|||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
auto const used =
|
auto const used =
|
||||||
d.p.write(d.sb.data(), ec);
|
d.p.write(d.db.data(), ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
{
|
{
|
||||||
// call handler
|
// call handler
|
||||||
@@ -126,7 +126,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
|||||||
}
|
}
|
||||||
if(used > 0)
|
if(used > 0)
|
||||||
d.started = true;
|
d.started = true;
|
||||||
d.sb.consume(used);
|
d.db.consume(used);
|
||||||
if(d.p.complete())
|
if(d.p.complete())
|
||||||
{
|
{
|
||||||
// call handler
|
// call handler
|
||||||
@@ -142,8 +142,8 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
|||||||
case 1:
|
case 1:
|
||||||
// read
|
// read
|
||||||
d.state = 2;
|
d.state = 2;
|
||||||
d.s.async_read_some(d.sb.prepare(
|
d.s.async_read_some(d.db.prepare(
|
||||||
read_size_helper(d.sb, 65536)),
|
read_size_helper(d.db, 65536)),
|
||||||
std::move(*this));
|
std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -172,8 +172,8 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
|||||||
d.state = 99;
|
d.state = 99;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
d.sb.commit(bytes_transferred);
|
d.db.commit(bytes_transferred);
|
||||||
auto const used = d.p.write(d.sb.data(), ec);
|
auto const used = d.p.write(d.db.data(), ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
{
|
{
|
||||||
// call handler
|
// call handler
|
||||||
@@ -182,7 +182,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
|||||||
}
|
}
|
||||||
if(used > 0)
|
if(used > 0)
|
||||||
d.started = true;
|
d.started = true;
|
||||||
d.sb.consume(used);
|
d.db.consume(used);
|
||||||
if(d.p.complete())
|
if(d.p.complete())
|
||||||
{
|
{
|
||||||
// call handler
|
// call handler
|
||||||
@@ -199,7 +199,7 @@ operator()(error_code ec, std::size_t bytes_transferred, bool again)
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class Stream, class Streambuf,
|
template<class Stream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers,
|
bool isRequest, class Body, class Headers,
|
||||||
class Handler>
|
class Handler>
|
||||||
class read_op
|
class read_op
|
||||||
@@ -216,7 +216,7 @@ class read_op
|
|||||||
struct data
|
struct data
|
||||||
{
|
{
|
||||||
Stream& s;
|
Stream& s;
|
||||||
Streambuf& sb;
|
DynamicBuffer& db;
|
||||||
message_type& m;
|
message_type& m;
|
||||||
parser_type p;
|
parser_type p;
|
||||||
Handler h;
|
Handler h;
|
||||||
@@ -226,9 +226,9 @@ class read_op
|
|||||||
|
|
||||||
template<class DeducedHandler>
|
template<class DeducedHandler>
|
||||||
data(DeducedHandler&& h_, Stream& s_,
|
data(DeducedHandler&& h_, Stream& s_,
|
||||||
Streambuf& sb_, message_type& m_)
|
DynamicBuffer& sb_, message_type& m_)
|
||||||
: s(s_)
|
: s(s_)
|
||||||
, sb(sb_)
|
, db(sb_)
|
||||||
, m(m_)
|
, m(m_)
|
||||||
, h(std::forward<DeducedHandler>(h_))
|
, h(std::forward<DeducedHandler>(h_))
|
||||||
, cont(boost_asio_handler_cont_helpers::
|
, cont(boost_asio_handler_cont_helpers::
|
||||||
@@ -286,11 +286,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Stream, class Streambuf,
|
template<class Stream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers,
|
bool isRequest, class Body, class Headers,
|
||||||
class Handler>
|
class Handler>
|
||||||
void
|
void
|
||||||
read_op<Stream, Streambuf, isRequest, Body, Headers, Handler>::
|
read_op<Stream, DynamicBuffer, isRequest, Body, Headers, Handler>::
|
||||||
operator()(error_code ec, bool again)
|
operator()(error_code ec, bool again)
|
||||||
{
|
{
|
||||||
auto& d = *d_;
|
auto& d = *d_;
|
||||||
@@ -301,7 +301,7 @@ operator()(error_code ec, bool again)
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
d.state = 1;
|
d.state = 1;
|
||||||
async_parse(d.s, d.sb, d.p, std::move(*this));
|
async_parse(d.s, d.db, d.p, std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@@ -318,49 +318,49 @@ operator()(error_code ec, bool again)
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class SyncReadStream, class Streambuf, class Parser>
|
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||||
void
|
void
|
||||||
parse(SyncReadStream& stream,
|
parse(SyncReadStream& stream,
|
||||||
Streambuf& streambuf, Parser& parser)
|
DynamicBuffer& dynabuf, Parser& parser)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_Parser<Parser>::value,
|
static_assert(is_Parser<Parser>::value,
|
||||||
"Parser requirements not met");
|
"Parser requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
parse(stream, streambuf, parser, ec);
|
parse(stream, dynabuf, parser, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
throw boost::system::system_error{ec};
|
throw boost::system::system_error{ec};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SyncReadStream, class Streambuf, class Parser>
|
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||||
void
|
void
|
||||||
parse(SyncReadStream& stream, Streambuf& streambuf,
|
parse(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
Parser& parser, error_code& ec)
|
Parser& parser, error_code& ec)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_Parser<Parser>::value,
|
static_assert(is_Parser<Parser>::value,
|
||||||
"Parser requirements not met");
|
"Parser requirements not met");
|
||||||
bool started = false;
|
bool started = false;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
auto used =
|
auto used =
|
||||||
parser.write(streambuf.data(), ec);
|
parser.write(dynabuf.data(), ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
return;
|
return;
|
||||||
streambuf.consume(used);
|
dynabuf.consume(used);
|
||||||
if(used > 0)
|
if(used > 0)
|
||||||
started = true;
|
started = true;
|
||||||
if(parser.complete())
|
if(parser.complete())
|
||||||
break;
|
break;
|
||||||
streambuf.commit(stream.read_some(
|
dynabuf.commit(stream.read_some(
|
||||||
streambuf.prepare(read_size_helper(
|
dynabuf.prepare(read_size_helper(
|
||||||
streambuf, 65536)), ec));
|
dynabuf, 65536)), ec));
|
||||||
if(ec && ec != boost::asio::error::eof)
|
if(ec && ec != boost::asio::error::eof)
|
||||||
return;
|
return;
|
||||||
if(ec == boost::asio::error::eof)
|
if(ec == boost::asio::error::eof)
|
||||||
@@ -379,86 +379,86 @@ parse(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class AsyncReadStream,
|
template<class AsyncReadStream,
|
||||||
class Streambuf, class Parser, class ReadHandler>
|
class DynamicBuffer, class Parser, class ReadHandler>
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
async_parse(AsyncReadStream& stream,
|
async_parse(AsyncReadStream& stream,
|
||||||
Streambuf& streambuf, Parser& parser, ReadHandler&& handler)
|
DynamicBuffer& dynabuf, Parser& parser, ReadHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
||||||
"AsyncReadStream requirements not met");
|
"AsyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_Parser<Parser>::value,
|
static_assert(is_Parser<Parser>::value,
|
||||||
"Parser requirements not met");
|
"Parser requirements not met");
|
||||||
beast::async_completion<ReadHandler,
|
beast::async_completion<ReadHandler,
|
||||||
void(error_code)> completion(handler);
|
void(error_code)> completion(handler);
|
||||||
detail::parse_op<AsyncReadStream, Streambuf,
|
detail::parse_op<AsyncReadStream, DynamicBuffer,
|
||||||
Parser, decltype(completion.handler)>{
|
Parser, decltype(completion.handler)>{
|
||||||
completion.handler, stream, streambuf, parser};
|
completion.handler, stream, dynabuf, parser};
|
||||||
return completion.result.get();
|
return completion.result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SyncReadStream, class Streambuf,
|
template<class SyncReadStream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers>
|
bool isRequest, class Body, class Headers>
|
||||||
void
|
void
|
||||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
message_v1<isRequest, Body, Headers>& msg)
|
message_v1<isRequest, Body, Headers>& msg)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_ReadableBody<Body>::value,
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
"ReadableBody requirements not met");
|
"ReadableBody requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
read(stream, streambuf, msg, ec);
|
read(stream, dynabuf, msg, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
throw system_error{ec};
|
throw system_error{ec};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SyncReadStream, class Streambuf,
|
template<class SyncReadStream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers>
|
bool isRequest, class Body, class Headers>
|
||||||
void
|
void
|
||||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
message_v1<isRequest, Body, Headers>& m,
|
message_v1<isRequest, Body, Headers>& m,
|
||||||
error_code& ec)
|
error_code& ec)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||||
"SyncReadStream requirements not met");
|
"SyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_ReadableBody<Body>::value,
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
"ReadableBody requirements not met");
|
"ReadableBody requirements not met");
|
||||||
parser_v1<isRequest, Body, Headers> p;
|
parser_v1<isRequest, Body, Headers> p;
|
||||||
parse(stream, streambuf, p, ec);
|
parse(stream, dynabuf, p, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
return;
|
return;
|
||||||
assert(p.complete());
|
assert(p.complete());
|
||||||
m = p.release();
|
m = p.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class AsyncReadStream, class Streambuf,
|
template<class AsyncReadStream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers,
|
bool isRequest, class Body, class Headers,
|
||||||
class ReadHandler>
|
class ReadHandler>
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
message_v1<isRequest, Body, Headers>& m,
|
message_v1<isRequest, Body, Headers>& m,
|
||||||
ReadHandler&& handler)
|
ReadHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
||||||
"AsyncReadStream requirements not met");
|
"AsyncReadStream requirements not met");
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
static_assert(is_ReadableBody<Body>::value,
|
static_assert(is_ReadableBody<Body>::value,
|
||||||
"ReadableBody requirements not met");
|
"ReadableBody requirements not met");
|
||||||
beast::async_completion<ReadHandler,
|
beast::async_completion<ReadHandler,
|
||||||
void(error_code)> completion(handler);
|
void(error_code)> completion(handler);
|
||||||
detail::read_op<AsyncReadStream, Streambuf,
|
detail::read_op<AsyncReadStream, DynamicBuffer,
|
||||||
isRequest, Body, Headers, decltype(
|
isRequest, Body, Headers, decltype(
|
||||||
completion.handler)>{completion.handler,
|
completion.handler)>{completion.handler,
|
||||||
stream, streambuf, m};
|
stream, dynabuf, m};
|
||||||
return completion.result.get();
|
return completion.result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
#include <beast/core/handler_alloc.hpp>
|
#include <beast/core/handler_alloc.hpp>
|
||||||
#include <beast/core/stream_concepts.hpp>
|
#include <beast/core/stream_concepts.hpp>
|
||||||
#include <beast/core/streambuf.hpp>
|
#include <beast/core/streambuf.hpp>
|
||||||
#include <beast/core/write_streambuf.hpp>
|
#include <beast/core/write_dynabuf.hpp>
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
#include <boost/logic/tribool.hpp>
|
#include <boost/logic/tribool.hpp>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -32,51 +32,51 @@ namespace http {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class Streambuf, class Body, class Headers>
|
template<class DynamicBuffer, class Body, class Headers>
|
||||||
void
|
void
|
||||||
write_firstline(Streambuf& streambuf,
|
write_firstline(DynamicBuffer& dynabuf,
|
||||||
message_v1<true, Body, Headers> const& msg)
|
message_v1<true, Body, Headers> const& msg)
|
||||||
{
|
{
|
||||||
write(streambuf, msg.method);
|
write(dynabuf, msg.method);
|
||||||
write(streambuf, " ");
|
write(dynabuf, " ");
|
||||||
write(streambuf, msg.url);
|
write(dynabuf, msg.url);
|
||||||
write(streambuf, " HTTP/");
|
write(dynabuf, " HTTP/");
|
||||||
write(streambuf, msg.version / 10);
|
write(dynabuf, msg.version / 10);
|
||||||
write(streambuf, ".");
|
write(dynabuf, ".");
|
||||||
write(streambuf, msg.version % 10);
|
write(dynabuf, msg.version % 10);
|
||||||
write(streambuf, "\r\n");
|
write(dynabuf, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, class Body, class Headers>
|
template<class DynamicBuffer, class Body, class Headers>
|
||||||
void
|
void
|
||||||
write_firstline(Streambuf& streambuf,
|
write_firstline(DynamicBuffer& dynabuf,
|
||||||
message_v1<false, Body, Headers> const& msg)
|
message_v1<false, Body, Headers> const& msg)
|
||||||
{
|
{
|
||||||
write(streambuf, "HTTP/");
|
write(dynabuf, "HTTP/");
|
||||||
write(streambuf, msg.version / 10);
|
write(dynabuf, msg.version / 10);
|
||||||
write(streambuf, ".");
|
write(dynabuf, ".");
|
||||||
write(streambuf, msg.version % 10);
|
write(dynabuf, msg.version % 10);
|
||||||
write(streambuf, " ");
|
write(dynabuf, " ");
|
||||||
write(streambuf, msg.status);
|
write(dynabuf, msg.status);
|
||||||
write(streambuf, " ");
|
write(dynabuf, " ");
|
||||||
write(streambuf, msg.reason);
|
write(dynabuf, msg.reason);
|
||||||
write(streambuf, "\r\n");
|
write(dynabuf, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf, class FieldSequence>
|
template<class DynamicBuffer, class FieldSequence>
|
||||||
void
|
void
|
||||||
write_fields(Streambuf& streambuf, FieldSequence const& fields)
|
write_fields(DynamicBuffer& dynabuf, FieldSequence const& fields)
|
||||||
{
|
{
|
||||||
static_assert(is_Streambuf<Streambuf>::value,
|
static_assert(is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
//static_assert(is_FieldSequence<FieldSequence>::value,
|
//static_assert(is_FieldSequence<FieldSequence>::value,
|
||||||
// "FieldSequence requirements not met");
|
// "FieldSequence requirements not met");
|
||||||
for(auto const& field : fields)
|
for(auto const& field : fields)
|
||||||
{
|
{
|
||||||
write(streambuf, field.name());
|
write(dynabuf, field.name());
|
||||||
write(streambuf, ": ");
|
write(dynabuf, ": ");
|
||||||
write(streambuf, field.value());
|
write(dynabuf, field.value());
|
||||||
write(streambuf, "\r\n");
|
write(dynabuf, "\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,17 +378,17 @@ operator()(error_code ec, std::size_t, bool again)
|
|||||||
d.copy = {};
|
d.copy = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SyncWriteStream, class Streambuf>
|
template<class SyncWriteStream, class DynamicBuffer>
|
||||||
class writef0_lambda
|
class writef0_lambda
|
||||||
{
|
{
|
||||||
Streambuf const& sb_;
|
DynamicBuffer const& sb_;
|
||||||
SyncWriteStream& stream_;
|
SyncWriteStream& stream_;
|
||||||
bool chunked_;
|
bool chunked_;
|
||||||
error_code& ec_;
|
error_code& ec_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
writef0_lambda(SyncWriteStream& stream,
|
writef0_lambda(SyncWriteStream& stream,
|
||||||
Streambuf const& sb, bool chunked, error_code& ec)
|
DynamicBuffer const& sb, bool chunked, error_code& ec)
|
||||||
: sb_(sb)
|
: sb_(sb)
|
||||||
, stream_(stream)
|
, stream_(stream)
|
||||||
, chunked_(chunked)
|
, chunked_(chunked)
|
||||||
@@ -548,9 +548,8 @@ async_write(AsyncWriteStream& stream,
|
|||||||
message_v1<isRequest, Body, Headers> const& msg,
|
message_v1<isRequest, Body, Headers> const& msg,
|
||||||
WriteHandler&& handler)
|
WriteHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(is_AsyncWriteStream<AsyncWriteStream>::value,
|
||||||
is_AsyncWriteStream<AsyncWriteStream>::value,
|
"AsyncWriteStream requirements not met");
|
||||||
"AsyncWriteStream requirements not met");
|
|
||||||
static_assert(is_WritableBody<Body>::value,
|
static_assert(is_WritableBody<Body>::value,
|
||||||
"WritableBody requirements not met");
|
"WritableBody requirements not met");
|
||||||
beast::async_completion<WriteHandler,
|
beast::async_completion<WriteHandler,
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
#include <beast/core/error.hpp>
|
#include <beast/core/error.hpp>
|
||||||
#include <beast/core/async_completion.hpp>
|
#include <beast/core/async_completion.hpp>
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
@@ -36,7 +35,7 @@ namespace http {
|
|||||||
@param stream The stream from which the data is to be read.
|
@param stream The stream from which the data is to be read.
|
||||||
The type must support the @b `SyncReadStream` concept.
|
The type must support the @b `SyncReadStream` concept.
|
||||||
|
|
||||||
@param streambuf A `Streambuf` holding additional bytes
|
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||||
read by the implementation from the stream. This is both
|
read by the implementation from the stream. This is both
|
||||||
an input and an output parameter; on entry, any data in the
|
an input and an output parameter; on entry, any data in the
|
||||||
stream buffer's input sequence will be given to the parser
|
stream buffer's input sequence will be given to the parser
|
||||||
@@ -47,10 +46,10 @@ namespace http {
|
|||||||
|
|
||||||
@throws boost::system::system_error on failure.
|
@throws boost::system::system_error on failure.
|
||||||
*/
|
*/
|
||||||
template<class SyncReadStream, class Streambuf, class Parser>
|
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||||
void
|
void
|
||||||
parse(SyncReadStream& stream,
|
parse(SyncReadStream& stream,
|
||||||
Streambuf& streambuf, Parser& parser);
|
DynamicBuffer& dynabuf, Parser& parser);
|
||||||
|
|
||||||
/** Parse a HTTP/1 message from a stream.
|
/** Parse a HTTP/1 message from a stream.
|
||||||
|
|
||||||
@@ -71,7 +70,7 @@ parse(SyncReadStream& stream,
|
|||||||
@param stream The stream from which the data is to be read.
|
@param stream The stream from which the data is to be read.
|
||||||
The type must support the @b `SyncReadStream` concept.
|
The type must support the @b `SyncReadStream` concept.
|
||||||
|
|
||||||
@param streambuf A `Streambuf` holding additional bytes
|
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||||
read by the implementation from the stream. This is both
|
read by the implementation from the stream. This is both
|
||||||
an input and an output parameter; on entry, any data in the
|
an input and an output parameter; on entry, any data in the
|
||||||
stream buffer's input sequence will be given to the parser
|
stream buffer's input sequence will be given to the parser
|
||||||
@@ -82,10 +81,10 @@ parse(SyncReadStream& stream,
|
|||||||
|
|
||||||
@param ec Set to the error, if any occurred.
|
@param ec Set to the error, if any occurred.
|
||||||
*/
|
*/
|
||||||
template<class SyncReadStream, class Streambuf, class Parser>
|
template<class SyncReadStream, class DynamicBuffer, class Parser>
|
||||||
void
|
void
|
||||||
parse(SyncReadStream& stream,
|
parse(SyncReadStream& stream,
|
||||||
Streambuf& streambuf, Parser& parser, error_code& ec);
|
DynamicBuffer& dynabuf, Parser& parser, error_code& ec);
|
||||||
|
|
||||||
/** Start an asynchronous operation to parse a HTTP/1 message from a stream.
|
/** Start an asynchronous operation to parse a HTTP/1 message from a stream.
|
||||||
|
|
||||||
@@ -106,7 +105,7 @@ parse(SyncReadStream& stream,
|
|||||||
@param stream The stream from which the data is to be read.
|
@param stream The stream from which the data is to be read.
|
||||||
The type must support the @b `AsyncReadStream` concept.
|
The type must support the @b `AsyncReadStream` concept.
|
||||||
|
|
||||||
@param streambuf A `Streambuf` holding additional bytes
|
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||||
read by the implementation from the stream. This is both
|
read by the implementation from the stream. This is both
|
||||||
an input and an output parameter; on entry, any data in the
|
an input and an output parameter; on entry, any data in the
|
||||||
stream buffer's input sequence will be given to the parser
|
stream buffer's input sequence will be given to the parser
|
||||||
@@ -128,14 +127,14 @@ parse(SyncReadStream& stream,
|
|||||||
manner equivalent to using `boost::asio::io_service::post`.
|
manner equivalent to using `boost::asio::io_service::post`.
|
||||||
*/
|
*/
|
||||||
template<class AsyncReadStream,
|
template<class AsyncReadStream,
|
||||||
class Streambuf, class Parser, class ReadHandler>
|
class DynamicBuffer, class Parser, class ReadHandler>
|
||||||
#if GENERATING_DOCS
|
#if GENERATING_DOCS
|
||||||
void_or_deduced
|
void_or_deduced
|
||||||
#else
|
#else
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
#endif
|
#endif
|
||||||
async_parse(AsyncReadStream& stream, Streambuf& streambuf,
|
async_parse(AsyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
Parser& parser, ReadHandler&& handler);
|
Parser& parser, ReadHandler&& handler);
|
||||||
|
|
||||||
/** Read a HTTP/1 message from a stream.
|
/** Read a HTTP/1 message from a stream.
|
||||||
@@ -157,7 +156,7 @@ async_parse(AsyncReadStream& stream, Streambuf& streambuf,
|
|||||||
@param stream The stream from which the data is to be read.
|
@param stream The stream from which the data is to be read.
|
||||||
The type must support the @b `SyncReadStream` concept.
|
The type must support the @b `SyncReadStream` concept.
|
||||||
|
|
||||||
@param streambuf A `Streambuf` holding additional bytes
|
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||||
read by the implementation from the stream. This is both
|
read by the implementation from the stream. This is both
|
||||||
an input and an output parameter; on entry, any data in the
|
an input and an output parameter; on entry, any data in the
|
||||||
stream buffer's input sequence will be given to the parser
|
stream buffer's input sequence will be given to the parser
|
||||||
@@ -168,10 +167,10 @@ async_parse(AsyncReadStream& stream, Streambuf& streambuf,
|
|||||||
|
|
||||||
@throws boost::system::system_error Thrown on failure.
|
@throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
template<class SyncReadStream, class Streambuf,
|
template<class SyncReadStream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers>
|
bool isRequest, class Body, class Headers>
|
||||||
void
|
void
|
||||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
message_v1<isRequest, Body, Headers>& msg);
|
message_v1<isRequest, Body, Headers>& msg);
|
||||||
|
|
||||||
/** Read a HTTP/1 message from a stream.
|
/** Read a HTTP/1 message from a stream.
|
||||||
@@ -193,7 +192,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
@param stream The stream from which the data is to be read.
|
@param stream The stream from which the data is to be read.
|
||||||
The type must support the @b `SyncReadStream` concept.
|
The type must support the @b `SyncReadStream` concept.
|
||||||
|
|
||||||
@param streambuf A `Streambuf` holding additional bytes
|
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||||
read by the implementation from the stream. This is both
|
read by the implementation from the stream. This is both
|
||||||
an input and an output parameter; on entry, any data in the
|
an input and an output parameter; on entry, any data in the
|
||||||
stream buffer's input sequence will be given to the parser
|
stream buffer's input sequence will be given to the parser
|
||||||
@@ -204,10 +203,10 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
|
|
||||||
@param ec Set to the error, if any occurred.
|
@param ec Set to the error, if any occurred.
|
||||||
*/
|
*/
|
||||||
template<class SyncReadStream, class Streambuf,
|
template<class SyncReadStream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers>
|
bool isRequest, class Body, class Headers>
|
||||||
void
|
void
|
||||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
read(SyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
message_v1<isRequest, Body, Headers>& msg,
|
message_v1<isRequest, Body, Headers>& msg,
|
||||||
error_code& ec);
|
error_code& ec);
|
||||||
|
|
||||||
@@ -229,7 +228,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
@param stream The stream to read the message from.
|
@param stream The stream to read the message from.
|
||||||
The type must support the @b `AsyncReadStream` concept.
|
The type must support the @b `AsyncReadStream` concept.
|
||||||
|
|
||||||
@param streambuf A `Streambuf` holding additional bytes
|
@param dynabuf A @b `DynamicBuffer` holding additional bytes
|
||||||
read by the implementation from the stream. This is both
|
read by the implementation from the stream. This is both
|
||||||
an input and an output parameter; on entry, any data in the
|
an input and an output parameter; on entry, any data in the
|
||||||
stream buffer's input sequence will be given to the parser
|
stream buffer's input sequence will be given to the parser
|
||||||
@@ -249,7 +248,7 @@ read(SyncReadStream& stream, Streambuf& streambuf,
|
|||||||
this function. Invocation of the handler will be performed in a
|
this function. Invocation of the handler will be performed in a
|
||||||
manner equivalent to using `boost::asio::io_service::post`.
|
manner equivalent to using `boost::asio::io_service::post`.
|
||||||
*/
|
*/
|
||||||
template<class AsyncReadStream, class Streambuf,
|
template<class AsyncReadStream, class DynamicBuffer,
|
||||||
bool isRequest, class Body, class Headers,
|
bool isRequest, class Body, class Headers,
|
||||||
class ReadHandler>
|
class ReadHandler>
|
||||||
#if GENERATING_DOCS
|
#if GENERATING_DOCS
|
||||||
@@ -258,7 +257,7 @@ void_or_deduced
|
|||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
#endif
|
#endif
|
||||||
async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
async_read(AsyncReadStream& stream, DynamicBuffer& dynabuf,
|
||||||
message_v1<isRequest, Body, Headers>& msg,
|
message_v1<isRequest, Body, Headers>& msg,
|
||||||
ReadHandler&& handler);
|
ReadHandler&& handler);
|
||||||
|
|
||||||
|
@@ -8,91 +8,17 @@
|
|||||||
#ifndef BEAST_HTTP_STREAMBUF_BODY_HPP
|
#ifndef BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||||
#define BEAST_HTTP_STREAMBUF_BODY_HPP
|
#define BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||||
|
|
||||||
#include <beast/http/body_type.hpp>
|
#include <beast/http/basic_dynabuf_body.hpp>
|
||||||
#include <beast/core/buffer_cat.hpp>
|
|
||||||
#include <beast/core/streambuf.hpp>
|
#include <beast/core/streambuf.hpp>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
/** A message body represented by a Streambuf
|
/** A message body represented by a @ref streambuf
|
||||||
|
|
||||||
Meets the requirements of @b `Body`.
|
Meets the requirements of @b `Body`.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf>
|
using streambuf_body = basic_dynabuf_body<streambuf>;
|
||||||
struct basic_streambuf_body
|
|
||||||
{
|
|
||||||
/// The type of the `message::body` member
|
|
||||||
using value_type = Streambuf;
|
|
||||||
|
|
||||||
#if GENERATING_DOCS
|
|
||||||
private:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class reader
|
|
||||||
{
|
|
||||||
value_type& sb_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template<bool isRequest, class Headers>
|
|
||||||
explicit
|
|
||||||
reader(message<isRequest,
|
|
||||||
basic_streambuf_body, Headers>& m) noexcept
|
|
||||||
: sb_(m.body)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
write(void const* data,
|
|
||||||
std::size_t size, error_code&) noexcept
|
|
||||||
{
|
|
||||||
using boost::asio::buffer;
|
|
||||||
using boost::asio::buffer_copy;
|
|
||||||
sb_.commit(buffer_copy(
|
|
||||||
sb_.prepare(size), buffer(data, size)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class writer
|
|
||||||
{
|
|
||||||
Streambuf const& body_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
writer(writer const&) = delete;
|
|
||||||
writer& operator=(writer const&) = delete;
|
|
||||||
|
|
||||||
template<bool isRequest, class Headers>
|
|
||||||
explicit
|
|
||||||
writer(message<
|
|
||||||
isRequest, basic_streambuf_body, Headers> const& m)
|
|
||||||
: body_(m.body)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
init(error_code& ec)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint64_t
|
|
||||||
content_length() const
|
|
||||||
{
|
|
||||||
return body_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Write>
|
|
||||||
boost::tribool
|
|
||||||
operator()(resume_context&&, error_code&, Write&& write)
|
|
||||||
{
|
|
||||||
write(body_.data());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
using streambuf_body = basic_streambuf_body<streambuf>;
|
|
||||||
|
|
||||||
} // http
|
} // http
|
||||||
} // beast
|
} // beast
|
||||||
|
@@ -9,8 +9,7 @@
|
|||||||
#define BEAST_HTTP_STRING_BODY_HPP
|
#define BEAST_HTTP_STRING_BODY_HPP
|
||||||
|
|
||||||
#include <beast/http/body_type.hpp>
|
#include <beast/http/body_type.hpp>
|
||||||
#include <beast/core/buffer_cat.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
#include <beast/core/streambuf.hpp>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@@ -117,11 +117,11 @@ is_valid(close_code::value code)
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Write frame header to streambuf
|
// Write frame header to dynamic buffer
|
||||||
//
|
//
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
write(Streambuf& sb, frame_header const& fh)
|
write(DynamicBuffer& db, frame_header const& fh)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
@@ -159,24 +159,24 @@ write(Streambuf& sb, frame_header const& fh)
|
|||||||
native_to_little_uint32(fh.key, &b[n]);
|
native_to_little_uint32(fh.key, &b[n]);
|
||||||
n += 4;
|
n += 4;
|
||||||
}
|
}
|
||||||
sb.commit(buffer_copy(
|
db.commit(buffer_copy(
|
||||||
sb.prepare(n), buffer(b)));
|
db.prepare(n), buffer(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read fixed frame header
|
// Read fixed frame header
|
||||||
// Requires at least 2 bytes
|
// Requires at least 2 bytes
|
||||||
//
|
//
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
std::size_t
|
std::size_t
|
||||||
read_fh1(frame_header& fh, Streambuf& sb,
|
read_fh1(frame_header& fh, DynamicBuffer& db,
|
||||||
role_type role, close_code::value& code)
|
role_type role, close_code::value& code)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
using boost::asio::buffer_copy;
|
using boost::asio::buffer_copy;
|
||||||
using boost::asio::buffer_size;
|
using boost::asio::buffer_size;
|
||||||
std::uint8_t b[2];
|
std::uint8_t b[2];
|
||||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
assert(buffer_size(db.data()) >= sizeof(b));
|
||||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
db.consume(buffer_copy(buffer(b), db.data()));
|
||||||
std::size_t need;
|
std::size_t need;
|
||||||
fh.len = b[1] & 0x7f;
|
fh.len = b[1] & 0x7f;
|
||||||
switch(fh.len)
|
switch(fh.len)
|
||||||
@@ -236,9 +236,9 @@ read_fh1(frame_header& fh, Streambuf& sb,
|
|||||||
|
|
||||||
// Decode variable frame header from stream
|
// Decode variable frame header from stream
|
||||||
//
|
//
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
read_fh2(frame_header& fh, Streambuf& sb,
|
read_fh2(frame_header& fh, DynamicBuffer& db,
|
||||||
role_type role, close_code::value& code)
|
role_type role, close_code::value& code)
|
||||||
{
|
{
|
||||||
using boost::asio::buffer;
|
using boost::asio::buffer;
|
||||||
@@ -250,8 +250,8 @@ read_fh2(frame_header& fh, Streambuf& sb,
|
|||||||
case 126:
|
case 126:
|
||||||
{
|
{
|
||||||
std::uint8_t b[2];
|
std::uint8_t b[2];
|
||||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
assert(buffer_size(db.data()) >= sizeof(b));
|
||||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
db.consume(buffer_copy(buffer(b), db.data()));
|
||||||
fh.len = big_uint16_to_native(&b[0]);
|
fh.len = big_uint16_to_native(&b[0]);
|
||||||
// length not canonical
|
// length not canonical
|
||||||
if(fh.len < 126)
|
if(fh.len < 126)
|
||||||
@@ -264,8 +264,8 @@ read_fh2(frame_header& fh, Streambuf& sb,
|
|||||||
case 127:
|
case 127:
|
||||||
{
|
{
|
||||||
std::uint8_t b[8];
|
std::uint8_t b[8];
|
||||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
assert(buffer_size(db.data()) >= sizeof(b));
|
||||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
db.consume(buffer_copy(buffer(b), db.data()));
|
||||||
fh.len = big_uint64_to_native(&b[0]);
|
fh.len = big_uint64_to_native(&b[0]);
|
||||||
// length not canonical
|
// length not canonical
|
||||||
if(fh.len < 65536)
|
if(fh.len < 65536)
|
||||||
@@ -279,8 +279,8 @@ read_fh2(frame_header& fh, Streambuf& sb,
|
|||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
{
|
{
|
||||||
std::uint8_t b[4];
|
std::uint8_t b[4];
|
||||||
assert(buffer_size(sb.data()) >= sizeof(b));
|
assert(buffer_size(db.data()) >= sizeof(b));
|
||||||
sb.consume(buffer_copy(buffer(b), sb.data()));
|
db.consume(buffer_copy(buffer(b), db.data()));
|
||||||
fh.key = little_uint32_to_native(&b[0]);
|
fh.key = little_uint32_to_native(&b[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include <beast/http/empty_body.hpp>
|
#include <beast/http/empty_body.hpp>
|
||||||
#include <beast/http/message.hpp>
|
#include <beast/http/message.hpp>
|
||||||
#include <beast/http/string_body.hpp>
|
#include <beast/http/string_body.hpp>
|
||||||
#include <beast/core/streambuf.hpp>
|
|
||||||
#include <boost/asio/error.hpp>
|
#include <boost/asio/error.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -107,15 +106,13 @@ protected:
|
|||||||
void
|
void
|
||||||
prepare_fh(close_code::value& code);
|
prepare_fh(close_code::value& code);
|
||||||
|
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
write_close(Streambuf& sb,
|
write_close(DynamicBuffer& db, close_reason const& rc);
|
||||||
close_reason const& rc);
|
|
||||||
|
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
write_ping(Streambuf& sb, opcode op,
|
write_ping(DynamicBuffer& db, opcode op, ping_data const& data);
|
||||||
ping_data const& data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
@@ -23,7 +23,7 @@ namespace websocket {
|
|||||||
// processes any received control frames.
|
// processes any received control frames.
|
||||||
//
|
//
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf, class Handler>
|
template<class DynamicBuffer, class Handler>
|
||||||
class stream<NextLayer>::read_frame_op
|
class stream<NextLayer>::read_frame_op
|
||||||
{
|
{
|
||||||
using alloc_type =
|
using alloc_type =
|
||||||
@@ -35,27 +35,27 @@ class stream<NextLayer>::read_frame_op
|
|||||||
using fmb_type =
|
using fmb_type =
|
||||||
typename fb_type::mutable_buffers_type;
|
typename fb_type::mutable_buffers_type;
|
||||||
|
|
||||||
using smb_type =
|
using dmb_type =
|
||||||
typename Streambuf::mutable_buffers_type;
|
typename DynamicBuffer::mutable_buffers_type;
|
||||||
|
|
||||||
struct data : op
|
struct data : op
|
||||||
{
|
{
|
||||||
stream<NextLayer>& ws;
|
stream<NextLayer>& ws;
|
||||||
frame_info& fi;
|
frame_info& fi;
|
||||||
Streambuf& sb;
|
DynamicBuffer& db;
|
||||||
Handler h;
|
Handler h;
|
||||||
fb_type fb;
|
fb_type fb;
|
||||||
boost::optional<smb_type> smb;
|
boost::optional<dmb_type> dmb;
|
||||||
boost::optional<fmb_type> fmb;
|
boost::optional<fmb_type> fmb;
|
||||||
bool cont;
|
bool cont;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
|
||||||
template<class DeducedHandler>
|
template<class DeducedHandler>
|
||||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||||
frame_info& fi_, Streambuf& sb_)
|
frame_info& fi_, DynamicBuffer& sb_)
|
||||||
: ws(ws_)
|
: ws(ws_)
|
||||||
, fi(fi_)
|
, fi(fi_)
|
||||||
, sb(sb_)
|
, db(sb_)
|
||||||
, h(std::forward<DeducedHandler>(h_))
|
, h(std::forward<DeducedHandler>(h_))
|
||||||
, cont(boost_asio_handler_cont_helpers::
|
, cont(boost_asio_handler_cont_helpers::
|
||||||
is_continuation(h))
|
is_continuation(h))
|
||||||
@@ -127,9 +127,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Buffers, class Handler>
|
template<class DynamicBuffer, class Handler>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::read_frame_op<Buffers, Handler>::
|
stream<NextLayer>::read_frame_op<DynamicBuffer, Handler>::
|
||||||
operator()(error_code ec, std::size_t bytes_transferred)
|
operator()(error_code ec, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
auto& d = *d_;
|
auto& d = *d_;
|
||||||
@@ -139,9 +139,9 @@ operator()(error_code ec, std::size_t bytes_transferred)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Buffers, class Handler>
|
template<class DynamicBuffer, class Handler>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::read_frame_op<Buffers, Handler>::
|
stream<NextLayer>::read_frame_op<DynamicBuffer, Handler>::
|
||||||
operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
||||||
{
|
{
|
||||||
enum
|
enum
|
||||||
@@ -187,18 +187,18 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
|
|
||||||
case do_read_payload:
|
case do_read_payload:
|
||||||
d.state = do_read_payload + 1;
|
d.state = do_read_payload + 1;
|
||||||
d.smb = d.sb.prepare(
|
d.dmb = d.db.prepare(
|
||||||
detail::clamp(d.ws.rd_need_));
|
detail::clamp(d.ws.rd_need_));
|
||||||
// receive payload data
|
// receive payload data
|
||||||
d.ws.stream_.async_read_some(
|
d.ws.stream_.async_read_some(
|
||||||
*d.smb, std::move(*this));
|
*d.dmb, std::move(*this));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case do_read_payload + 1:
|
case do_read_payload + 1:
|
||||||
{
|
{
|
||||||
d.ws.rd_need_ -= bytes_transferred;
|
d.ws.rd_need_ -= bytes_transferred;
|
||||||
auto const pb = prepare_buffers(
|
auto const pb = prepare_buffers(
|
||||||
bytes_transferred, *d.smb);
|
bytes_transferred, *d.dmb);
|
||||||
if(d.ws.rd_fh_.mask)
|
if(d.ws.rd_fh_.mask)
|
||||||
detail::mask_inplace(pb, d.ws.rd_key_);
|
detail::mask_inplace(pb, d.ws.rd_key_);
|
||||||
if(d.ws.rd_opcode_ == opcode::text)
|
if(d.ws.rd_opcode_ == opcode::text)
|
||||||
@@ -213,7 +213,7 @@ operator()(error_code ec,std::size_t bytes_transferred, bool again)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.sb.commit(bytes_transferred);
|
d.db.commit(bytes_transferred);
|
||||||
if(d.ws.rd_need_ > 0)
|
if(d.ws.rd_need_ > 0)
|
||||||
{
|
{
|
||||||
d.state = do_read_payload;
|
d.state = do_read_payload;
|
||||||
|
@@ -17,7 +17,7 @@ namespace websocket {
|
|||||||
// read an entire message
|
// read an entire message
|
||||||
//
|
//
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf, class Handler>
|
template<class DynamicBuffer, class Handler>
|
||||||
class stream<NextLayer>::read_op
|
class stream<NextLayer>::read_op
|
||||||
{
|
{
|
||||||
using alloc_type =
|
using alloc_type =
|
||||||
@@ -27,7 +27,7 @@ class stream<NextLayer>::read_op
|
|||||||
{
|
{
|
||||||
stream<NextLayer>& ws;
|
stream<NextLayer>& ws;
|
||||||
opcode& op;
|
opcode& op;
|
||||||
Streambuf& sb;
|
DynamicBuffer& db;
|
||||||
Handler h;
|
Handler h;
|
||||||
frame_info fi;
|
frame_info fi;
|
||||||
bool cont;
|
bool cont;
|
||||||
@@ -36,10 +36,10 @@ class stream<NextLayer>::read_op
|
|||||||
template<class DeducedHandler>
|
template<class DeducedHandler>
|
||||||
data(DeducedHandler&& h_,
|
data(DeducedHandler&& h_,
|
||||||
stream<NextLayer>& ws_, opcode& op_,
|
stream<NextLayer>& ws_, opcode& op_,
|
||||||
Streambuf& sb_)
|
DynamicBuffer& sb_)
|
||||||
: ws(ws_)
|
: ws(ws_)
|
||||||
, op(op_)
|
, op(op_)
|
||||||
, sb(sb_)
|
, db(sb_)
|
||||||
, h(std::forward<DeducedHandler>(h_))
|
, h(std::forward<DeducedHandler>(h_))
|
||||||
, cont(boost_asio_handler_cont_helpers::
|
, cont(boost_asio_handler_cont_helpers::
|
||||||
is_continuation(h))
|
is_continuation(h))
|
||||||
@@ -98,9 +98,9 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf, class Handler>
|
template<class DynamicBuffer, class Handler>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::read_op<Streambuf, Handler>::
|
stream<NextLayer>::read_op<DynamicBuffer, Handler>::
|
||||||
operator()(error_code const& ec, bool again)
|
operator()(error_code const& ec, bool again)
|
||||||
{
|
{
|
||||||
auto& d = *d_;
|
auto& d = *d_;
|
||||||
@@ -117,9 +117,9 @@ operator()(error_code const& ec, bool again)
|
|||||||
// the handler is moved from the data block
|
// the handler is moved from the data block
|
||||||
// before asio_handler_deallocate is called.
|
// before asio_handler_deallocate is called.
|
||||||
d.ws.async_read_frame(
|
d.ws.async_read_frame(
|
||||||
d.fi, d.sb, std::move(*this));
|
d.fi, d.db, std::move(*this));
|
||||||
#else
|
#else
|
||||||
d.ws.async_read_frame(d.fi, d.sb, *this);
|
d.ws.async_read_frame(d.fi, d.db, *this);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
#include <beast/core/prepare_buffers.hpp>
|
#include <beast/core/prepare_buffers.hpp>
|
||||||
#include <beast/core/static_streambuf.hpp>
|
#include <beast/core/static_streambuf.hpp>
|
||||||
#include <beast/core/stream_concepts.hpp>
|
#include <beast/core/stream_concepts.hpp>
|
||||||
#include <beast/core/streambuf.hpp>
|
|
||||||
#include <boost/endian/buffers.hpp>
|
#include <boost/endian/buffers.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -94,10 +93,10 @@ stream_base::prepare_fh(close_code::value& code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
stream_base::write_close(
|
stream_base::write_close(
|
||||||
Streambuf& sb, close_reason const& cr)
|
DynamicBuffer& db, close_reason const& cr)
|
||||||
{
|
{
|
||||||
using namespace boost::endian;
|
using namespace boost::endian;
|
||||||
frame_header fh;
|
frame_header fh;
|
||||||
@@ -111,7 +110,7 @@ stream_base::write_close(
|
|||||||
fh.mask = role_ == detail::role_type::client;
|
fh.mask = role_ == detail::role_type::client;
|
||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
fh.key = maskgen_();
|
fh.key = maskgen_();
|
||||||
detail::write(sb, fh);
|
detail::write(db, fh);
|
||||||
if(cr.code != close_code::none)
|
if(cr.code != close_code::none)
|
||||||
{
|
{
|
||||||
detail::prepared_key_type key;
|
detail::prepared_key_type key;
|
||||||
@@ -121,29 +120,29 @@ stream_base::write_close(
|
|||||||
std::uint8_t b[2];
|
std::uint8_t b[2];
|
||||||
::new(&b[0]) big_uint16_buf_t{
|
::new(&b[0]) big_uint16_buf_t{
|
||||||
(std::uint16_t)cr.code};
|
(std::uint16_t)cr.code};
|
||||||
auto d = sb.prepare(2);
|
auto d = db.prepare(2);
|
||||||
boost::asio::buffer_copy(d,
|
boost::asio::buffer_copy(d,
|
||||||
boost::asio::buffer(b));
|
boost::asio::buffer(b));
|
||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
detail::mask_inplace(d, key);
|
detail::mask_inplace(d, key);
|
||||||
sb.commit(2);
|
db.commit(2);
|
||||||
}
|
}
|
||||||
if(! cr.reason.empty())
|
if(! cr.reason.empty())
|
||||||
{
|
{
|
||||||
auto d = sb.prepare(cr.reason.size());
|
auto d = db.prepare(cr.reason.size());
|
||||||
boost::asio::buffer_copy(d,
|
boost::asio::buffer_copy(d,
|
||||||
boost::asio::const_buffer(
|
boost::asio::const_buffer(
|
||||||
cr.reason.data(), cr.reason.size()));
|
cr.reason.data(), cr.reason.size()));
|
||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
detail::mask_inplace(d, key);
|
detail::mask_inplace(d, key);
|
||||||
sb.commit(cr.reason.size());
|
db.commit(cr.reason.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
stream_base::write_ping(Streambuf& sb,
|
stream_base::write_ping(DynamicBuffer& db,
|
||||||
opcode op, ping_data const& data)
|
opcode op, ping_data const& data)
|
||||||
{
|
{
|
||||||
frame_header fh;
|
frame_header fh;
|
||||||
@@ -156,19 +155,19 @@ stream_base::write_ping(Streambuf& sb,
|
|||||||
fh.mask = role_ == role_type::client;
|
fh.mask = role_ == role_type::client;
|
||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
fh.key = maskgen_();
|
fh.key = maskgen_();
|
||||||
detail::write(sb, fh);
|
detail::write(db, fh);
|
||||||
if(data.empty())
|
if(data.empty())
|
||||||
return;
|
return;
|
||||||
detail::prepared_key_type key;
|
detail::prepared_key_type key;
|
||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
detail::prepare_key(key, fh.key);
|
detail::prepare_key(key, fh.key);
|
||||||
auto d = sb.prepare(data.size());
|
auto d = db.prepare(data.size());
|
||||||
boost::asio::buffer_copy(d,
|
boost::asio::buffer_copy(d,
|
||||||
boost::asio::const_buffers_1(
|
boost::asio::const_buffers_1(
|
||||||
data.data(), data.size()));
|
data.data(), data.size()));
|
||||||
if(fh.mask)
|
if(fh.mask)
|
||||||
detail::mask_inplace(d, key);
|
detail::mask_inplace(d, key);
|
||||||
sb.commit(data.size());
|
db.commit(data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
@@ -453,10 +452,10 @@ void
|
|||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
ping(ping_data const& payload, error_code& ec)
|
ping(ping_data const& payload, error_code& ec)
|
||||||
{
|
{
|
||||||
detail::frame_streambuf sb;
|
detail::frame_streambuf db;
|
||||||
write_ping<static_streambuf>(
|
write_ping<static_streambuf>(
|
||||||
sb, opcode::ping, payload);
|
db, opcode::ping, payload);
|
||||||
boost::asio::write(stream_, sb.data(), ec);
|
boost::asio::write(stream_, db.data(), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
@@ -477,31 +476,35 @@ async_ping(ping_data const& payload, PingHandler&& handler)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
read(opcode& op, Streambuf& streambuf)
|
read(opcode& op, DynamicBuffer& dynabuf)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncStream<next_layer_type>::value,
|
static_assert(is_SyncStream<next_layer_type>::value,
|
||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
|
"DynamicBuffer requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
read(op, streambuf, ec);
|
read(op, dynabuf, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
throw system_error{ec};
|
throw system_error{ec};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
read(opcode& op, Streambuf& streambuf, error_code& ec)
|
read(opcode& op, DynamicBuffer& dynabuf, error_code& ec)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncStream<next_layer_type>::value,
|
static_assert(is_SyncStream<next_layer_type>::value,
|
||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
|
"DynamicBuffer requirements not met");
|
||||||
frame_info fi;
|
frame_info fi;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
read_frame(fi, streambuf, ec);
|
read_frame(fi, dynabuf, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
break;
|
break;
|
||||||
op = fi.op;
|
op = fi.op;
|
||||||
@@ -511,47 +514,51 @@ read(opcode& op, Streambuf& streambuf, error_code& ec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf, class ReadHandler>
|
template<class DynamicBuffer, class ReadHandler>
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
async_read(opcode& op,
|
async_read(opcode& op,
|
||||||
Streambuf& streambuf, ReadHandler&& handler)
|
DynamicBuffer& dynabuf, ReadHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(is_AsyncStream<next_layer_type>::value,
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
||||||
"AsyncStream requirements requirements not met");
|
"AsyncStream requirements requirements not met");
|
||||||
static_assert(beast::is_Streambuf<Streambuf>::value,
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
beast::async_completion<
|
beast::async_completion<
|
||||||
ReadHandler, void(error_code)
|
ReadHandler, void(error_code)
|
||||||
> completion(handler);
|
> completion(handler);
|
||||||
read_op<Streambuf, decltype(completion.handler)>{
|
read_op<DynamicBuffer, decltype(completion.handler)>{
|
||||||
completion.handler, *this, op, streambuf};
|
completion.handler, *this, op, dynabuf};
|
||||||
return completion.result.get();
|
return completion.result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
read_frame(frame_info& fi, Streambuf& streambuf)
|
read_frame(frame_info& fi, DynamicBuffer& dynabuf)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncStream<next_layer_type>::value,
|
static_assert(is_SyncStream<next_layer_type>::value,
|
||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
|
"DynamicBuffer requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
read_frame(fi, streambuf, ec);
|
read_frame(fi, dynabuf, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
throw system_error{ec};
|
throw system_error{ec};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec)
|
||||||
{
|
{
|
||||||
static_assert(is_SyncStream<next_layer_type>::value,
|
static_assert(is_SyncStream<next_layer_type>::value,
|
||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
|
"DynamicBuffer requirements not met");
|
||||||
close_code::value code{};
|
close_code::value code{};
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
@@ -630,7 +637,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// read payload
|
// read payload
|
||||||
auto smb = streambuf.prepare(
|
auto smb = dynabuf.prepare(
|
||||||
detail::clamp(rd_need_));
|
detail::clamp(rd_need_));
|
||||||
auto const bytes_transferred =
|
auto const bytes_transferred =
|
||||||
stream_.read_some(smb, ec);
|
stream_.read_some(smb, ec);
|
||||||
@@ -652,7 +659,7 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
streambuf.commit(bytes_transferred);
|
dynabuf.commit(bytes_transferred);
|
||||||
fi.op = rd_opcode_;
|
fi.op = rd_opcode_;
|
||||||
fi.fin = rd_fh_.fin && rd_need_ == 0;
|
fi.fin = rd_fh_.fin && rd_need_ == 0;
|
||||||
return;
|
return;
|
||||||
@@ -686,21 +693,21 @@ read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
template<class Streambuf, class ReadHandler>
|
template<class DynamicBuffer, class ReadHandler>
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
stream<NextLayer>::
|
stream<NextLayer>::
|
||||||
async_read_frame(frame_info& fi,
|
async_read_frame(frame_info& fi,
|
||||||
Streambuf& streambuf, ReadHandler&& handler)
|
DynamicBuffer& dynabuf, ReadHandler&& handler)
|
||||||
{
|
{
|
||||||
static_assert(is_AsyncStream<next_layer_type>::value,
|
static_assert(is_AsyncStream<next_layer_type>::value,
|
||||||
"AsyncStream requirements requirements not met");
|
"AsyncStream requirements requirements not met");
|
||||||
static_assert(beast::is_Streambuf<Streambuf>::value,
|
static_assert(beast::is_DynamicBuffer<DynamicBuffer>::value,
|
||||||
"Streambuf requirements not met");
|
"DynamicBuffer requirements not met");
|
||||||
beast::async_completion<
|
beast::async_completion<
|
||||||
ReadHandler, void(error_code)> completion(handler);
|
ReadHandler, void(error_code)> completion(handler);
|
||||||
read_frame_op<Streambuf, decltype(completion.handler)>{
|
read_frame_op<DynamicBuffer, decltype(completion.handler)>{
|
||||||
completion.handler, *this, fi, streambuf};
|
completion.handler, *this, fi, dynabuf};
|
||||||
return completion.result.get();
|
return completion.result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,6 +719,9 @@ write(ConstBufferSequence const& buffers)
|
|||||||
{
|
{
|
||||||
static_assert(is_SyncStream<next_layer_type>::value,
|
static_assert(is_SyncStream<next_layer_type>::value,
|
||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
|
static_assert(beast::is_ConstBufferSequence<
|
||||||
|
ConstBufferSequence>::value,
|
||||||
|
"ConstBufferSequence requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
write(buffers, ec);
|
write(buffers, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
@@ -774,6 +784,9 @@ write_frame(bool fin, ConstBufferSequence const& buffers)
|
|||||||
{
|
{
|
||||||
static_assert(is_SyncStream<next_layer_type>::value,
|
static_assert(is_SyncStream<next_layer_type>::value,
|
||||||
"SyncStream requirements not met");
|
"SyncStream requirements not met");
|
||||||
|
static_assert(beast::is_ConstBufferSequence<
|
||||||
|
ConstBufferSequence>::value,
|
||||||
|
"ConstBufferSequence requirements not met");
|
||||||
error_code ec;
|
error_code ec;
|
||||||
write_frame(fin, buffers, ec);
|
write_frame(fin, buffers, ec);
|
||||||
if(ec)
|
if(ec)
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#include <beast/websocket/detail/stream_base.hpp>
|
#include <beast/websocket/detail/stream_base.hpp>
|
||||||
#include <beast/http/message_v1.hpp>
|
#include <beast/http/message_v1.hpp>
|
||||||
#include <beast/http/string_body.hpp>
|
#include <beast/http/string_body.hpp>
|
||||||
#include <beast/core/streambuf_readstream.hpp>
|
#include <beast/core/dynabuf_readstream.hpp>
|
||||||
#include <beast/core/async_completion.hpp>
|
#include <beast/core/async_completion.hpp>
|
||||||
#include <beast/core/detail/get_lowest_layer.hpp>
|
#include <beast/core/detail/get_lowest_layer.hpp>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
@@ -78,7 +78,7 @@ struct frame_info
|
|||||||
@par Concepts
|
@par Concepts
|
||||||
@b `AsyncStream`,
|
@b `AsyncStream`,
|
||||||
@b `Decorator`,
|
@b `Decorator`,
|
||||||
@b `Streambuf`,
|
@b `DynamicBuffer`,
|
||||||
@b `SyncStream`
|
@b `SyncStream`
|
||||||
*/
|
*/
|
||||||
template<class NextLayer>
|
template<class NextLayer>
|
||||||
@@ -86,7 +86,7 @@ class stream : public detail::stream_base
|
|||||||
{
|
{
|
||||||
friend class stream_test;
|
friend class stream_test;
|
||||||
|
|
||||||
streambuf_readstream<NextLayer, streambuf> stream_;
|
dynabuf_readstream<NextLayer, streambuf> stream_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The type of the next layer.
|
/// The type of the next layer.
|
||||||
@@ -567,7 +567,7 @@ public:
|
|||||||
|
|
||||||
@throws boost::system::system_error Thrown on failure.
|
@throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
// VFALCO TODO This should also take a streambuf with any leftover bytes.
|
// VFALCO TODO This should also take a DynamicBuffer with any leftover bytes.
|
||||||
template<class Body, class Headers>
|
template<class Body, class Headers>
|
||||||
void
|
void
|
||||||
accept(http::request_v1<Body, Headers> const& request);
|
accept(http::request_v1<Body, Headers> const& request);
|
||||||
@@ -1007,14 +1007,14 @@ public:
|
|||||||
@param op A value to receive the message type.
|
@param op A value to receive the message type.
|
||||||
This object must remain valid until the handler is called.
|
This object must remain valid until the handler is called.
|
||||||
|
|
||||||
@param streambuf A stream buffer to hold the message data.
|
@param dynabuf A dynamic buffer to hold the message data after
|
||||||
This object must remain valid until the handler is called.
|
any masking or decompression has been applied.
|
||||||
|
|
||||||
@throws boost::system::system_error Thrown on failure.
|
@throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
read(opcode& op, Streambuf& streambuf);
|
read(opcode& op, DynamicBuffer& dynabuf);
|
||||||
|
|
||||||
/** Read a message from the stream.
|
/** Read a message from the stream.
|
||||||
|
|
||||||
@@ -1042,15 +1042,14 @@ public:
|
|||||||
@param op A value to receive the message type.
|
@param op A value to receive the message type.
|
||||||
This object must remain valid until the handler is called.
|
This object must remain valid until the handler is called.
|
||||||
|
|
||||||
@param streambuf A stream buffer to hold the message data.
|
@param dynabuf A dynamic buffer to hold the message data after
|
||||||
This object must remain valid until the handler is called.
|
any masking or decompression has been applied.
|
||||||
|
|
||||||
@param ec Set to indicate what error occurred, if any.
|
@param ec Set to indicate what error occurred, if any.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
read(opcode& op,
|
read(opcode& op, DynamicBuffer& dynabuf, error_code& ec);
|
||||||
Streambuf& streambuf, error_code& ec);
|
|
||||||
|
|
||||||
/** Start an asynchronous operation to read a message from the stream.
|
/** Start an asynchronous operation to read a message from the stream.
|
||||||
|
|
||||||
@@ -1086,8 +1085,9 @@ public:
|
|||||||
@param op A value to receive the message type.
|
@param op A value to receive the message type.
|
||||||
This object must remain valid until the handler is called.
|
This object must remain valid until the handler is called.
|
||||||
|
|
||||||
@param streambuf A stream buffer to hold the message data.
|
@param dynabuf A dynamic buffer to hold the message data after
|
||||||
This object must remain valid until the handler is called.
|
any masking or decompression has been applied. This object must
|
||||||
|
remain valid until the handler is called.
|
||||||
|
|
||||||
@param handler The handler to be called when the read operation
|
@param handler The handler to be called when the read operation
|
||||||
completes. Copies will be made of the handler as required. The
|
completes. Copies will be made of the handler as required. The
|
||||||
@@ -1102,15 +1102,14 @@ public:
|
|||||||
this function. Invocation of the handler will be performed in a
|
this function. Invocation of the handler will be performed in a
|
||||||
manner equivalent to using `boost::asio::io_service::post`.
|
manner equivalent to using `boost::asio::io_service::post`.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf, class ReadHandler>
|
template<class DynamicBuffer, class ReadHandler>
|
||||||
#if GENERATING_DOCS
|
#if GENERATING_DOCS
|
||||||
void_or_deduced
|
void_or_deduced
|
||||||
#else
|
#else
|
||||||
typename async_completion<
|
typename async_completion<
|
||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
#endif
|
#endif
|
||||||
async_read(opcode& op,
|
async_read(opcode& op, DynamicBuffer& dynabuf, ReadHandler&& handler);
|
||||||
Streambuf& streambuf, ReadHandler&& handler);
|
|
||||||
|
|
||||||
/** Read a message frame from the stream.
|
/** Read a message frame from the stream.
|
||||||
|
|
||||||
@@ -1141,13 +1140,14 @@ public:
|
|||||||
|
|
||||||
@param fi An object to store metadata about the message.
|
@param fi An object to store metadata about the message.
|
||||||
|
|
||||||
@param streambuf A stream buffer to hold the message data.
|
@param dynabuf A dynamic buffer to hold the message data after
|
||||||
|
any masking or decompression has been applied.
|
||||||
|
|
||||||
@throws boost::system::system_error Thrown on failure.
|
@throws boost::system::system_error Thrown on failure.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
read_frame(frame_info& fi, Streambuf& streambuf);
|
read_frame(frame_info& fi, DynamicBuffer& dynabuf);
|
||||||
|
|
||||||
/** Read a message frame from the stream.
|
/** Read a message frame from the stream.
|
||||||
|
|
||||||
@@ -1178,13 +1178,14 @@ public:
|
|||||||
|
|
||||||
@param fi An object to store metadata about the message.
|
@param fi An object to store metadata about the message.
|
||||||
|
|
||||||
@param streambuf A stream buffer to hold the message data.
|
@param dynabuf A dynamic buffer to hold the message data after
|
||||||
|
any masking or decompression has been applied.
|
||||||
|
|
||||||
@param ec Set to indicate what error occurred, if any.
|
@param ec Set to indicate what error occurred, if any.
|
||||||
*/
|
*/
|
||||||
template<class Streambuf>
|
template<class DynamicBuffer>
|
||||||
void
|
void
|
||||||
read_frame(frame_info& fi, Streambuf& streambuf, error_code& ec);
|
read_frame(frame_info& fi, DynamicBuffer& dynabuf, error_code& ec);
|
||||||
|
|
||||||
/** Start an asynchronous operation to read a message frame from the stream.
|
/** Start an asynchronous operation to read a message frame from the stream.
|
||||||
|
|
||||||
@@ -1225,7 +1226,7 @@ public:
|
|||||||
@param fi An object to store metadata about the message.
|
@param fi An object to store metadata about the message.
|
||||||
This object must remain valid until the handler is called.
|
This object must remain valid until the handler is called.
|
||||||
|
|
||||||
@param streambuf A stream buffer to hold the message data after
|
@param dynabuf A dynamic buffer to hold the message data after
|
||||||
any masking or decompression has been applied. This object must
|
any masking or decompression has been applied. This object must
|
||||||
remain valid until the handler is called.
|
remain valid until the handler is called.
|
||||||
|
|
||||||
@@ -1242,7 +1243,7 @@ public:
|
|||||||
this function. Invocation of the handler will be performed in a
|
this function. Invocation of the handler will be performed in a
|
||||||
manner equivalent to using boost::asio::io_service::post().
|
manner equivalent to using boost::asio::io_service::post().
|
||||||
*/
|
*/
|
||||||
template<class Streambuf, class ReadHandler>
|
template<class DynamicBuffer, class ReadHandler>
|
||||||
#if GENERATING_DOCS
|
#if GENERATING_DOCS
|
||||||
void_or_deduced
|
void_or_deduced
|
||||||
#else
|
#else
|
||||||
@@ -1250,7 +1251,7 @@ public:
|
|||||||
ReadHandler, void(error_code)>::result_type
|
ReadHandler, void(error_code)>::result_type
|
||||||
#endif
|
#endif
|
||||||
async_read_frame(frame_info& fi,
|
async_read_frame(frame_info& fi,
|
||||||
Streambuf& streambuf, ReadHandler&& handler);
|
DynamicBuffer& dynabuf, ReadHandler&& handler);
|
||||||
|
|
||||||
/** Write a message to the stream.
|
/** Write a message to the stream.
|
||||||
|
|
||||||
@@ -1495,8 +1496,8 @@ private:
|
|||||||
template<class Handler> class response_op;
|
template<class Handler> class response_op;
|
||||||
template<class Buffers, class Handler> class write_op;
|
template<class Buffers, class Handler> class write_op;
|
||||||
template<class Buffers, class Handler> class write_frame_op;
|
template<class Buffers, class Handler> class write_frame_op;
|
||||||
template<class Streambuf, class Handler> class read_op;
|
template<class DynamicBuffer, class Handler> class read_op;
|
||||||
template<class Streambuf, class Handler> class read_frame_op;
|
template<class DynamicBuffer, class Handler> class read_frame_op;
|
||||||
|
|
||||||
void
|
void
|
||||||
reset();
|
reset();
|
||||||
|
@@ -21,6 +21,7 @@ unit-test core-tests :
|
|||||||
core/buffer_concepts.cpp
|
core/buffer_concepts.cpp
|
||||||
core/buffers_adapter.cpp
|
core/buffers_adapter.cpp
|
||||||
core/consuming_buffers.cpp
|
core/consuming_buffers.cpp
|
||||||
|
core/dynabuf_readstream.cpp
|
||||||
core/error.cpp
|
core/error.cpp
|
||||||
core/handler_alloc.cpp
|
core/handler_alloc.cpp
|
||||||
core/handler_concepts.cpp
|
core/handler_concepts.cpp
|
||||||
@@ -30,9 +31,8 @@ unit-test core-tests :
|
|||||||
core/static_string.cpp
|
core/static_string.cpp
|
||||||
core/stream_concepts.cpp
|
core/stream_concepts.cpp
|
||||||
core/streambuf.cpp
|
core/streambuf.cpp
|
||||||
core/streambuf_readstream.cpp
|
|
||||||
core/to_string.cpp
|
core/to_string.cpp
|
||||||
core/write_streambuf.cpp
|
core/write_dynabuf.cpp
|
||||||
core/detail/base64.cpp
|
core/detail/base64.cpp
|
||||||
core/detail/empty_base_optimization.cpp
|
core/detail/empty_base_optimization.cpp
|
||||||
core/detail/get_lowest_layer.cpp
|
core/detail/get_lowest_layer.cpp
|
||||||
@@ -41,6 +41,7 @@ unit-test core-tests :
|
|||||||
|
|
||||||
unit-test http-tests :
|
unit-test http-tests :
|
||||||
../extras/beast/unit_test/main.cpp
|
../extras/beast/unit_test/main.cpp
|
||||||
|
http/basic_dynabuf_body.cpp
|
||||||
http/basic_headers.cpp
|
http/basic_headers.cpp
|
||||||
http/basic_parser_v1.cpp
|
http/basic_parser_v1.cpp
|
||||||
http/body_type.cpp
|
http/body_type.cpp
|
||||||
|
@@ -15,6 +15,7 @@ add_executable (core-tests
|
|||||||
buffer_concepts.cpp
|
buffer_concepts.cpp
|
||||||
buffers_adapter.cpp
|
buffers_adapter.cpp
|
||||||
consuming_buffers.cpp
|
consuming_buffers.cpp
|
||||||
|
dynabuf_readstream.cpp
|
||||||
error.cpp
|
error.cpp
|
||||||
handler_alloc.cpp
|
handler_alloc.cpp
|
||||||
handler_concepts.cpp
|
handler_concepts.cpp
|
||||||
@@ -24,9 +25,8 @@ add_executable (core-tests
|
|||||||
static_string.cpp
|
static_string.cpp
|
||||||
stream_concepts.cpp
|
stream_concepts.cpp
|
||||||
streambuf.cpp
|
streambuf.cpp
|
||||||
streambuf_readstream.cpp
|
|
||||||
to_string.cpp
|
to_string.cpp
|
||||||
write_streambuf.cpp
|
write_dynabuf.cpp
|
||||||
detail/base64.cpp
|
detail/base64.cpp
|
||||||
detail/empty_base_optimization.cpp
|
detail/empty_base_optimization.cpp
|
||||||
detail/get_lowest_layer.cpp
|
detail/get_lowest_layer.cpp
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <beast/core/streambuf_readstream.hpp>
|
#include <beast/core/dynabuf_readstream.hpp>
|
||||||
|
|
||||||
#include <beast/core/streambuf.hpp>
|
#include <beast/core/streambuf.hpp>
|
||||||
#include <beast/test/fail_stream.hpp>
|
#include <beast/test/fail_stream.hpp>
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
class streambuf_readstream_test
|
class dynabuf_readstream_test
|
||||||
: public unit_test::suite
|
: public unit_test::suite
|
||||||
, public test::enable_yield_to
|
, public test::enable_yield_to
|
||||||
{
|
{
|
||||||
using self = streambuf_readstream_test;
|
using self = dynabuf_readstream_test;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void testSpecialMembers()
|
void testSpecialMembers()
|
||||||
@@ -29,16 +29,16 @@ public:
|
|||||||
using socket_type = boost::asio::ip::tcp::socket;
|
using socket_type = boost::asio::ip::tcp::socket;
|
||||||
boost::asio::io_service ios;
|
boost::asio::io_service ios;
|
||||||
{
|
{
|
||||||
streambuf_readstream<socket_type, streambuf> srs(ios);
|
dynabuf_readstream<socket_type, streambuf> srs(ios);
|
||||||
streambuf_readstream<socket_type, streambuf> srs2(std::move(srs));
|
dynabuf_readstream<socket_type, streambuf> srs2(std::move(srs));
|
||||||
srs = std::move(srs2);
|
srs = std::move(srs2);
|
||||||
expect(&srs.get_io_service() == &ios);
|
expect(&srs.get_io_service() == &ios);
|
||||||
expect(&srs.get_io_service() == &srs2.get_io_service());
|
expect(&srs.get_io_service() == &srs2.get_io_service());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
socket_type sock(ios);
|
socket_type sock(ios);
|
||||||
streambuf_readstream<socket_type&, streambuf> srs(sock);
|
dynabuf_readstream<socket_type&, streambuf> srs(sock);
|
||||||
streambuf_readstream<socket_type&, streambuf> srs2(std::move(srs));
|
dynabuf_readstream<socket_type&, streambuf> srs2(std::move(srs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
{
|
{
|
||||||
test::fail_stream<
|
test::fail_stream<
|
||||||
test::string_stream> fs(n, ios_, ", world!");
|
test::string_stream> fs(n, ios_, ", world!");
|
||||||
streambuf_readstream<
|
dynabuf_readstream<
|
||||||
decltype(fs)&, streambuf> srs(fs);
|
decltype(fs)&, streambuf> srs(fs);
|
||||||
srs.buffer().commit(buffer_copy(
|
srs.buffer().commit(buffer_copy(
|
||||||
srs.buffer().prepare(5), buffer("Hello", 5)));
|
srs.buffer().prepare(5), buffer("Hello", 5)));
|
||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
{
|
{
|
||||||
test::fail_stream<
|
test::fail_stream<
|
||||||
test::string_stream> fs(n, ios_, ", world!");
|
test::string_stream> fs(n, ios_, ", world!");
|
||||||
streambuf_readstream<
|
dynabuf_readstream<
|
||||||
decltype(fs)&, streambuf> srs(fs);
|
decltype(fs)&, streambuf> srs(fs);
|
||||||
srs.capacity(3);
|
srs.capacity(3);
|
||||||
srs.buffer().commit(buffer_copy(
|
srs.buffer().commit(buffer_copy(
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
{
|
{
|
||||||
test::fail_stream<
|
test::fail_stream<
|
||||||
test::string_stream> fs(n, ios_, ", world!");
|
test::string_stream> fs(n, ios_, ", world!");
|
||||||
streambuf_readstream<
|
dynabuf_readstream<
|
||||||
decltype(fs)&, streambuf> srs(fs);
|
decltype(fs)&, streambuf> srs(fs);
|
||||||
srs.buffer().commit(buffer_copy(
|
srs.buffer().commit(buffer_copy(
|
||||||
srs.buffer().prepare(5), buffer("Hello", 5)));
|
srs.buffer().prepare(5), buffer("Hello", 5)));
|
||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
{
|
{
|
||||||
test::fail_stream<
|
test::fail_stream<
|
||||||
test::string_stream> fs(n, ios_, ", world!");
|
test::string_stream> fs(n, ios_, ", world!");
|
||||||
streambuf_readstream<
|
dynabuf_readstream<
|
||||||
decltype(fs)&, streambuf> srs(fs);
|
decltype(fs)&, streambuf> srs(fs);
|
||||||
srs.capacity(3);
|
srs.capacity(3);
|
||||||
srs.buffer().commit(buffer_copy(
|
srs.buffer().commit(buffer_copy(
|
||||||
@@ -137,7 +137,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(streambuf_readstream,core,beast);
|
BEAST_DEFINE_TESTSUITE(dynabuf_readstream,core,beast);
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
|
|
@@ -6,14 +6,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Test that header file is self-contained.
|
// Test that header file is self-contained.
|
||||||
#include <beast/core/write_streambuf.hpp>
|
#include <beast/core/write_dynabuf.hpp>
|
||||||
|
|
||||||
#include <beast/core/streambuf.hpp>
|
#include <beast/core/streambuf.hpp>
|
||||||
#include <beast/unit_test/suite.hpp>
|
#include <beast/unit_test/suite.hpp>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
class write_streambuf_test : public beast::unit_test::suite
|
class write_dynabuf_test : public beast::unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void run() override
|
void run() override
|
||||||
@@ -31,6 +31,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BEAST_DEFINE_TESTSUITE(write_streambuf,core,beast);
|
BEAST_DEFINE_TESTSUITE(write_dynabuf,core,beast);
|
||||||
|
|
||||||
} // beast
|
} // beast
|
@@ -7,6 +7,7 @@ GroupSources(test/http "/")
|
|||||||
add_executable (http-tests
|
add_executable (http-tests
|
||||||
${BEAST_INCLUDES}
|
${BEAST_INCLUDES}
|
||||||
../../extras/beast/unit_test/main.cpp
|
../../extras/beast/unit_test/main.cpp
|
||||||
|
basic_dynabuf_body.cpp
|
||||||
basic_headers.cpp
|
basic_headers.cpp
|
||||||
basic_parser_v1.cpp
|
basic_parser_v1.cpp
|
||||||
body_type.cpp
|
body_type.cpp
|
||||||
|
9
test/http/basic_dynabuf_body.cpp
Normal file
9
test/http/basic_dynabuf_body.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
|
||||||
|
// Test that header file is self-contained.
|
||||||
|
#include <beast/http/basic_dynabuf_body.hpp>
|
@@ -11,7 +11,7 @@
|
|||||||
#include "message_fuzz.hpp"
|
#include "message_fuzz.hpp"
|
||||||
|
|
||||||
#include <beast/core/streambuf.hpp>
|
#include <beast/core/streambuf.hpp>
|
||||||
#include <beast/core/write_streambuf.hpp>
|
#include <beast/core/write_dynabuf.hpp>
|
||||||
#include <beast/core/detail/ci_char_traits.hpp>
|
#include <beast/core/detail/ci_char_traits.hpp>
|
||||||
#include <beast/http/rfc7230.hpp>
|
#include <beast/http/rfc7230.hpp>
|
||||||
#include <beast/unit_test/suite.hpp>
|
#include <beast/unit_test/suite.hpp>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
#ifndef BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
#ifndef BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
||||||
#define BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
#define BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
||||||
|
|
||||||
#include <beast/core/write_streambuf.hpp>
|
#include <beast/core/write_dynabuf.hpp>
|
||||||
#include <beast/http/detail/basic_parser_v1.hpp>
|
#include <beast/http/detail/basic_parser_v1.hpp>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
Reference in New Issue
Block a user