Line data Source code
1 : //
2 : // Copyright (c) 2025 Mungo Gill
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/beast2
8 : //
9 :
10 : #ifndef BOOST_BEAST2_IMPL_BODY_READ_STREAM_HPP
11 : #define BOOST_BEAST2_IMPL_BODY_READ_STREAM_HPP
12 :
13 : #include <boost/beast2/detail/config.hpp>
14 : #include <boost/beast2/read.hpp>
15 :
16 : #include <boost/asio/buffer.hpp>
17 : #include <boost/asio/buffers_iterator.hpp>
18 : #include <boost/asio/coroutine.hpp>
19 : #include <boost/core/ignore_unused.hpp>
20 :
21 : #include <iostream>
22 :
23 : namespace boost {
24 : namespace beast2 {
25 :
26 : namespace detail {
27 :
28 : template<class MutableBufferSequence, class AsyncReadStream>
29 : class body_read_stream_op : public asio::coroutine
30 : {
31 :
32 : AsyncReadStream& stream_;
33 : MutableBufferSequence mb_;
34 : http_proto::parser& pr_;
35 :
36 : public:
37 32559 : body_read_stream_op(
38 : AsyncReadStream& s,
39 : MutableBufferSequence&& mb,
40 : http_proto::parser& pr) noexcept
41 32559 : : stream_(s)
42 32559 : , mb_(std::move(mb))
43 32559 : , pr_(pr)
44 : {
45 32559 : }
46 :
47 : template<class Self>
48 : void
49 67863 : operator()(
50 : Self& self,
51 : system::error_code ec = {},
52 : std::size_t bytes_transferred = 0)
53 : {
54 : boost::ignore_unused(bytes_transferred);
55 :
56 135726 : BOOST_ASIO_CORO_REENTER(*this)
57 : {
58 32559 : self.reset_cancellation_state(asio::enable_total_cancellation());
59 :
60 32559 : if(buffers::size(mb_) == 0)
61 : {
62 3 : BOOST_ASIO_CORO_YIELD
63 : {
64 : BOOST_ASIO_HANDLER_LOCATION(
65 : (__FILE__, __LINE__, "immediate"));
66 1 : auto io_ex = self.get_io_executor();
67 1 : asio::async_immediate(
68 : io_ex,
69 1 : asio::append(
70 1 : std::move(self), system::error_code{}));
71 1 : }
72 1 : goto upcall;
73 : }
74 :
75 32558 : if(!pr_.got_header())
76 : {
77 8388 : BOOST_ASIO_CORO_YIELD
78 : {
79 : BOOST_ASIO_HANDLER_LOCATION(
80 : (__FILE__, __LINE__, "async_read_header"));
81 2796 : beast2::async_read_header<AsyncReadStream, Self>(
82 2796 : stream_, pr_, std::move(self));
83 : }
84 2796 : if(ec.failed())
85 39 : goto upcall;
86 : }
87 :
88 32519 : if(!!self.cancelled())
89 : {
90 12 : ec = asio::error::operation_aborted;
91 12 : goto upcall;
92 : }
93 :
94 97521 : BOOST_ASIO_CORO_YIELD
95 : {
96 : BOOST_ASIO_HANDLER_LOCATION(
97 : (__FILE__, __LINE__, "async_read_some"));
98 32507 : beast2::async_read_some(stream_, pr_, std::move(self));
99 : }
100 :
101 32559 : upcall:
102 32559 : std::size_t n = 0;
103 :
104 32559 : if(!ec.failed())
105 : {
106 32507 : auto dbs = asio::buffer_size(mb_);
107 :
108 32507 : if(dbs > 0)
109 : {
110 32506 : auto source_buf = pr_.pull_body();
111 :
112 32506 : n = asio::buffer_copy(mb_, source_buf);
113 :
114 32506 : pr_.consume_body(n);
115 :
116 32506 : ec = (n != 0) ? system::error_code{}
117 : : asio::stream_errc::eof;
118 : }
119 : }
120 :
121 32559 : self.complete(ec, n);
122 : }
123 67863 : }
124 : };
125 :
126 : } // detail
127 :
128 : //------------------------------------------------
129 :
130 : // TODO: copy in Beast's stream traits to check if AsyncReadStream
131 : // is an AsyncReadStream, and also static_assert that body_read_stream is too.
132 :
133 : template<class AsyncReadStream>
134 2760 : body_read_stream<AsyncReadStream>::body_read_stream(
135 : AsyncReadStream& s,
136 : http_proto::parser& pr)
137 2760 : : stream_(s)
138 2760 : , pr_(pr)
139 : {
140 2760 : }
141 :
142 : template<class AsyncReadStream>
143 : template<
144 : class MutableBufferSequence,
145 : BOOST_ASIO_COMPLETION_TOKEN_FOR(void(system::error_code, std::size_t))
146 : CompletionToken>
147 : BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(
148 : CompletionToken,
149 : void(system::error_code, std::size_t))
150 32559 : body_read_stream<AsyncReadStream>::async_read_some(
151 : MutableBufferSequence mb,
152 : CompletionToken&& token)
153 : {
154 : return asio::
155 32559 : async_compose<CompletionToken, void(system::error_code, std::size_t)>(
156 : detail::body_read_stream_op<MutableBufferSequence, AsyncReadStream>{
157 32559 : stream_, std::move(mb), pr_ },
158 : token,
159 32559 : stream_);
160 : }
161 :
162 : } // beast2
163 : } // boost
164 :
165 : #endif // BOOST_BEAST2_IMPL_BODY_READ_STREAM_HPP
|