-
Notifications
You must be signed in to change notification settings - Fork 9
Create body_write_stream (initial work in progress) #119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,248 @@ | ||
| // | ||
| // Copyright (c) 2025 Mungo Gill | ||
| // | ||
| // 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) | ||
| // | ||
| // Official repository: https://github.com/cppalliance/beast2 | ||
| // | ||
|
|
||
| #ifndef BOOST_BEAST2_BODY_WRITE_STREAM_HPP | ||
| #define BOOST_BEAST2_BODY_WRITE_STREAM_HPP | ||
|
|
||
| #include <boost/asio/async_result.hpp> | ||
| #include <boost/http_proto/serializer.hpp> | ||
| #include <boost/system/error_code.hpp> | ||
|
|
||
| namespace boost { | ||
| namespace beast2 { | ||
|
|
||
| /** A body writer for HTTP/1 messages. | ||
|
|
||
| This type meets the requirements of asio's AsyncWriteStream, and is | ||
| constructed with a reference to an underlying AsyncWriteStream. | ||
|
|
||
| Any call to `async_write_some` initially triggers writes from the underlying | ||
| stream until all of the HTTP headers and at least one byte of the body have | ||
| been write and processed. Thereafter, each subsequent call to | ||
| `async_write_some` processes at least one byte of the body, triggering, where | ||
| required, calls to the underlying stream's `async_write_some` method. The | ||
| resulting body data is stored in the referenced MutableBufferSequence. | ||
|
|
||
| All processing depends on a beast2::parser object owned by the caller and | ||
| referenced in the construction of this object. | ||
|
|
||
| @see | ||
| @ref http_proto::parser. | ||
| */ | ||
| template<class AsyncWriteStream> | ||
| class body_write_stream | ||
| { | ||
|
|
||
| public: | ||
| /** The type of the executor associated with the stream. | ||
|
|
||
| This will be the type of executor used to invoke completion handlers | ||
| which do not have an explicit associated executor. | ||
| */ | ||
| typedef typename AsyncWriteStream::executor_type executor_type; | ||
|
|
||
| /** Get the executor associated with the object. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The brief for functions which return a meaningful value should usually start with the word "Return" |
||
|
|
||
| This function may be used to obtain the executor object that the stream | ||
| uses to dispatch completion handlers without an assocaited executor. | ||
|
|
||
| @return A copy of the executor that stream will use to dispatch | ||
| handlers. | ||
| */ | ||
| executor_type | ||
| get_executor() | ||
| { | ||
| return stream_.get_executor(); | ||
| } | ||
|
|
||
| /** Constructor | ||
|
|
||
| This constructor creates the stream which retains a reference to the | ||
| underlying stream. The underlying stream then needs to be open before | ||
| data can be written | ||
|
|
||
| @param s The underlying stream to which the HTTP message is written. | ||
| This object's executor is initialized to that of the | ||
| underlying stream. | ||
|
|
||
| @param sr A http_proto::serializer object which will perform the serialization of | ||
| the HTTP message and extraction of the body. This must be | ||
| initialized by the caller and ownership of the serializer is | ||
| retained by the caller, which must guarantee that it remains | ||
| valid until the handler is called. | ||
|
|
||
| @param srs A http_proto::serializer::stream object which must have been | ||
| obtained by a call to `start_stream` on `sr`. Ownership of the | ||
| serializer::stream is | ||
| retained by the caller, which must guarantee that it remains | ||
| valid until the handler is called. | ||
| */ | ||
| explicit body_write_stream( | ||
| AsyncWriteStream& s, | ||
| http_proto::serializer& sr, | ||
| http_proto::serializer::stream& srs); | ||
|
|
||
| /** Write some data asynchronously. | ||
|
|
||
| This function is used to asynchronously write data to the stream. | ||
|
|
||
| This call always returns immediately. The asynchronous operation will | ||
| continue until one of the following conditions is true: | ||
|
|
||
| @li One or more bytes are written from `cb` to the body stored in the | ||
| serializer and one or more bytes are written from the serializer to the | ||
| underlying stream. | ||
|
|
||
| @li An error occurs. | ||
|
|
||
| The algorithm, known as a <em>composed asynchronous operation</em>, is | ||
| implemented in terms of calls to the underlying stream's | ||
| `async_write_some` function. The program must ensure that no other calls | ||
| implemented using the underlying stream's `async_write_some` are | ||
| performed until this operation completes. | ||
|
|
||
| @param cb The buffer sequence from which the body data will be read. If | ||
| the size of the buffer sequence is zero bytes, the operation always | ||
| completes immediately with no error. Although the buffers object may be | ||
| copied as necessary, ownership of the underlying memory blocks is | ||
| retained by the caller, which must guarantee that they remain valid until | ||
| the handler is called. Where the internal buffer of the contained | ||
| serializer is not of sufficient size to hold the data to be copied from | ||
| cb, the remainder may be write by subsequent calls to this function. | ||
|
|
||
| @param handler The completion handler to invoke when the operation | ||
| completes. The implementation takes ownership of the handler by | ||
| performing a decay-copy. The equivalent function signature of the | ||
| handler must be: | ||
| @code | ||
| void handler( | ||
| error_code const& error, // result of operation | ||
| std::size_t bytes_transferred // the number of bytes consumed from | ||
| // cb by the serializer | ||
| ); | ||
| @endcode | ||
| Regardless of whether the asynchronous operation | ||
| completes immediately or not, the completion handler will not be invoked | ||
| from within this function. On immediate completion, invocation of the | ||
| handler will be performed in a manner equivalent to using | ||
| `asio::async_immediate`. | ||
|
|
||
| @note The `async_write_some` operation may not transmit all of the | ||
| requested number of bytes. Consider using the function | ||
| `asio::async_write` if you need to ensure that the requested amount of | ||
| data is write before the asynchronous operation completes. | ||
|
|
||
| @note This function does not guarantee that all of the consumed data is | ||
| written to the underlying stream. For this reason one or more calls to | ||
| `async_write_some` must be followed by a call to `async_close` to put the | ||
| serializer into the `done` state and to write all data remaining in the | ||
| serializer to the underlying stream. | ||
|
|
||
| @par Per-Operation Cancellation | ||
|
|
||
| This asynchronous operation supports cancellation for the following | ||
| net::cancellation_type values: | ||
|
|
||
| @li @c net::cancellation_type::terminal | ||
| @li @c net::cancellation_type::partial | ||
| @li @c net::cancellation_type::total | ||
|
|
||
| if they are also supported by the underlying stream's @c async_write_some | ||
| operation. | ||
| */ | ||
| template< | ||
| class ConstBufferSequence, | ||
| BOOST_ASIO_COMPLETION_TOKEN_FOR(void(system::error_code, std::size_t)) | ||
| CompletionToken> | ||
| BOOST_ASIO_INITFN_AUTO_RESULT_TYPE( | ||
| CompletionToken, | ||
| void(system::error_code, std::size_t)) | ||
| async_write_some(ConstBufferSequence mb, CompletionToken&& handler); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pass the buffer sequence as |
||
|
|
||
| /** Close serializer::stream and flush remaining data to the underlying stream asynchronously. | ||
|
|
||
| This function is used to asynchronously call `close` on the | ||
| `serializer::stream` object referenced in the construction of this | ||
| `body_write_stream` and write all remaining data in the serializer to the | ||
| underlying stream. | ||
|
|
||
| This call always returns immediately. The asynchronous operation will | ||
| continue until one of the following conditions is true: | ||
|
|
||
| @li All remaining output bytes of the serializer are written to the | ||
| underlying stream and the serializer's `is_done()` method returns true. | ||
|
|
||
| @li An error occurs. | ||
|
|
||
| The algorithm, known as a <em>composed asynchronous operation</em>, is | ||
| implemented in terms of calls to the underlying stream's | ||
| `async_write_some` function. The program must ensure that no other calls | ||
| implemented using the underlying stream's `async_write_some` are | ||
| performed until this operation completes. | ||
|
|
||
| @param handler The completion handler to invoke when the operation | ||
| completes. The implementation takes ownership of the handler by | ||
| performing a decay-copy. The equivalent function signature of the | ||
| handler must be: | ||
| @code | ||
| void handler( | ||
| error_code const& error, // result of operation | ||
| std::size_t bytes_transferred // the number of bytes consumed from | ||
| // cb by the serializer | ||
| ); | ||
| @endcode | ||
| Regardless of whether the asynchronous operation | ||
| completes immediately or not, the completion handler will not be invoked | ||
| from within this function. On immediate completion, invocation of the | ||
| handler will be performed in a manner equivalent to using | ||
| `asio::async_immediate`. | ||
|
|
||
| @note The `async_write_some` operation may not transmit all of the | ||
| requested number of bytes. Consider using the function | ||
| `asio::async_write` if you need to ensure that the requested amount of | ||
| data is write before the asynchronous operation completes. | ||
|
|
||
| @note This function does not guarantee that all of the consumed data is | ||
| written to the underlying stream. For this reason one or more calls to | ||
| `async_write_some` must be followed by a call to `async_close` to put the | ||
| serializer into the `done` state and to write all data remaining in the | ||
| serializer to the underlying stream. | ||
|
|
||
| @par Per-Operation Cancellation | ||
|
|
||
| This asynchronous operation supports cancellation for the following | ||
| net::cancellation_type values: | ||
|
|
||
| @li @c net::cancellation_type::terminal | ||
| @li @c net::cancellation_type::partial | ||
| @li @c net::cancellation_type::total | ||
|
|
||
| if they are also supported by the underlying stream's @c async_write_some | ||
| operation. | ||
| */ | ||
| template< | ||
| BOOST_ASIO_COMPLETION_TOKEN_FOR(void(system::error_code)) | ||
| CompletionToken> | ||
| BOOST_ASIO_INITFN_AUTO_RESULT_TYPE( | ||
| CompletionToken, | ||
| void(system::error_code)) | ||
| async_close(CompletionToken&& handler); | ||
|
|
||
| private: | ||
| AsyncWriteStream& stream_; | ||
| http_proto::serializer& sr_; | ||
| http_proto::serializer::stream& srs_; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is right, the user should not have to create |
||
| }; | ||
|
|
||
| } // beast2 | ||
| } // boost | ||
|
|
||
| #include <boost/beast2/impl/body_write_stream.hpp> | ||
|
|
||
| #endif // BOOST_BEAST2_BODY_WRITE_STREAM_HPP | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not
using? actually this might be wrong... isexecutor_typeguaranteed to exist? it might be better to usedecltypeonget_executor()instead. see:https://original.boost.org/doc/libs/1_89_0/doc/html/boost_asio/reference/AsyncWriteStream.html