]> git.proxmox.com Git - ceph.git/blame - ceph/src/Beast/include/beast/http/impl/read.ipp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / http / impl / read.ipp
CommitLineData
7c673cae
FG
1//
2// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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
8#ifndef BEAST_HTTP_IMPL_READ_IPP_HPP
9#define BEAST_HTTP_IMPL_READ_IPP_HPP
10
11#include <beast/http/concepts.hpp>
12#include <beast/http/error.hpp>
13#include <beast/http/message_parser.hpp>
14#include <beast/http/read.hpp>
15#include <beast/core/bind_handler.hpp>
16#include <beast/core/handler_helpers.hpp>
17#include <beast/core/handler_ptr.hpp>
18#include <beast/core/stream_concepts.hpp>
19#include <boost/assert.hpp>
20#include <boost/optional.hpp>
21
22namespace beast {
23namespace http {
24
25namespace detail {
26
27template<
28 class SyncReadStream,
29 class DynamicBuffer,
30 bool isRequest, bool isDirect, class Derived>
31inline
32std::size_t
33read_some_buffer(
34 SyncReadStream& stream,
35 DynamicBuffer& dynabuf,
36 basic_parser<isRequest, isDirect, Derived>& parser,
37 error_code& ec)
38{
39 std::size_t bytes_used;
40 if(dynabuf.size() == 0)
41 goto do_read;
42 for(;;)
43 {
44 bytes_used = parser.write(
45 dynabuf.data(), ec);
46 if(ec)
47 return 0;
48 if(bytes_used > 0)
49 goto do_finish;
50 do_read:
51 boost::optional<typename
52 DynamicBuffer::mutable_buffers_type> mb;
53 auto const size =
54 read_size_helper(dynabuf, 65536);
55 BOOST_ASSERT(size > 0);
56 try
57 {
58 mb.emplace(dynabuf.prepare(size));
59 }
60 catch(std::length_error const&)
61 {
62 ec = error::buffer_overflow;
63 return 0;
64 }
65 auto const bytes_transferred =
66 stream.read_some(*mb, ec);
67 if(ec == boost::asio::error::eof)
68 {
69 BOOST_ASSERT(bytes_transferred == 0);
70 bytes_used = 0;
71 if(parser.got_some())
72 {
73 // caller sees EOF on next read
74 ec = {};
75 parser.write_eof(ec);
76 if(ec)
77 return 0;
78 BOOST_ASSERT(parser.is_complete());
79 }
80 break;
81 }
82 else if(ec)
83 {
84 return 0;
85 }
86 BOOST_ASSERT(bytes_transferred > 0);
87 dynabuf.commit(bytes_transferred);
88 }
89do_finish:
90 return bytes_used;
91}
92
93template<
94 class SyncReadStream,
95 class DynamicBuffer,
96 bool isRequest, class Derived>
97inline
98std::size_t
99read_some_body(
100 SyncReadStream& stream,
101 DynamicBuffer& dynabuf,
102 basic_parser<isRequest, true, Derived>& parser,
103 error_code& ec)
104{
105 if(dynabuf.size() > 0)
106 return parser.copy_body(dynabuf);
107 boost::optional<typename
108 Derived::mutable_buffers_type> mb;
109 try
110 {
111 parser.prepare_body(mb, 65536);
112 }
113 catch(std::length_error const&)
114 {
115 ec = error::buffer_overflow;
116 return 0;
117 }
118 auto const bytes_transferred =
119 stream.read_some(*mb, ec);
120 if(ec == boost::asio::error::eof)
121 {
122 BOOST_ASSERT(bytes_transferred == 0);
123 // caller sees EOF on next read
124 ec = {};
125 parser.write_eof(ec);
126 if(ec)
127 return 0;
128 BOOST_ASSERT(parser.is_complete());
129 }
130 else if(! ec)
131 {
132 parser.commit_body(bytes_transferred);
133 return 0;
134 }
135 return 0;
136}
137
138template<
139 class SyncReadStream,
140 class DynamicBuffer,
141 bool isRequest, class Derived>
142inline
143std::size_t
144read_some(
145 SyncReadStream& stream,
146 DynamicBuffer& dynabuf,
147 basic_parser<isRequest, true, Derived>& parser,
148 error_code& ec)
149{
150 switch(parser.state())
151 {
152 case parse_state::header:
153 case parse_state::chunk_header:
154 return detail::read_some_buffer(
155 stream, dynabuf, parser, ec);
156
157 default:
158 return detail::read_some_body(
159 stream, dynabuf, parser, ec);
160 }
161}
162
163template<
164 class SyncReadStream,
165 class DynamicBuffer,
166 bool isRequest, class Derived>
167inline
168std::size_t
169read_some(
170 SyncReadStream& stream,
171 DynamicBuffer& dynabuf,
172 basic_parser<isRequest, false, Derived>& parser,
173 error_code& ec)
174{
175 return detail::read_some_buffer(
176 stream, dynabuf, parser, ec);
177}
178
179} // detail
180
181//------------------------------------------------------------------------------
182
183template<
184 class SyncReadStream,
185 class DynamicBuffer,
186 bool isRequest, bool isDirect, class Derived>
187std::size_t
188read_some(
189 SyncReadStream& stream,
190 DynamicBuffer& dynabuf,
191 basic_parser<isRequest, isDirect, Derived>& parser)
192{
193 static_assert(is_SyncReadStream<SyncReadStream>::value,
194 "SyncReadStream requirements not met");
195 static_assert(is_DynamicBuffer<DynamicBuffer>::value,
196 "DynamicBuffer requirements not met");
197 BOOST_ASSERT(! parser.is_complete());
198 error_code ec;
199 auto const bytes_used =
200 read_some(stream, dynabuf, parser, ec);
201 if(ec)
202 throw system_error{ec};
203 return bytes_used;
204}
205
206template<
207 class SyncReadStream,
208 class DynamicBuffer,
209 bool isRequest, bool isDirect, class Derived>
210std::size_t
211read_some(
212 SyncReadStream& stream,
213 DynamicBuffer& dynabuf,
214 basic_parser<isRequest, isDirect, Derived>& parser,
215 error_code& ec)
216{
217 static_assert(is_SyncReadStream<SyncReadStream>::value,
218 "SyncReadStream requirements not met");
219 static_assert(is_DynamicBuffer<DynamicBuffer>::value,
220 "DynamicBuffer requirements not met");
221 BOOST_ASSERT(! parser.is_complete());
222 return detail::read_some(stream, dynabuf, parser, ec);
223}
224
225template<
226 class SyncReadStream,
227 class DynamicBuffer,
228 bool isRequest, bool isDirect, class Derived>
229void
230read(
231 SyncReadStream& stream,
232 DynamicBuffer& dynabuf,
233 basic_parser<isRequest, isDirect, Derived>& parser)
234{
235 static_assert(is_SyncReadStream<SyncReadStream>::value,
236 "SyncReadStream requirements not met");
237 static_assert(is_DynamicBuffer<DynamicBuffer>::value,
238 "DynamicBuffer requirements not met");
239 BOOST_ASSERT(! parser.is_complete());
240 error_code ec;
241 read(stream, dynabuf, parser, ec);
242 if(ec)
243 throw system_error{ec};
244}
245
246template<
247 class SyncReadStream,
248 class DynamicBuffer,
249 bool isRequest, bool isDirect, class Derived>
250void
251read(
252 SyncReadStream& stream,
253 DynamicBuffer& dynabuf,
254 basic_parser<isRequest, isDirect, Derived>& parser,
255 error_code& ec)
256{
257 static_assert(is_SyncReadStream<SyncReadStream>::value,
258 "SyncReadStream requirements not met");
259 static_assert(is_DynamicBuffer<DynamicBuffer>::value,
260 "DynamicBuffer requirements not met");
261 BOOST_ASSERT(! parser.is_complete());
262 do
263 {
264 auto const bytes_used =
265 read_some(stream, dynabuf, parser, ec);
266 if(ec)
267 return;
268 dynabuf.consume(bytes_used);
269 }
270 while(! parser.is_complete());
271}
272
273template<
274 class SyncReadStream,
275 class DynamicBuffer,
276 bool isRequest, class Body, class Fields>
277void
278read(
279 SyncReadStream& stream,
280 DynamicBuffer& dynabuf,
281 message<isRequest, Body, Fields>& msg)
282{
283 static_assert(is_SyncReadStream<SyncReadStream>::value,
284 "SyncReadStream requirements not met");
285 static_assert(is_DynamicBuffer<DynamicBuffer>::value,
286 "DynamicBuffer requirements not met");
287 static_assert(is_Body<Body>::value,
288 "Body requirements not met");
289 static_assert(has_reader<Body>::value,
290 "Body has no reader");
291 static_assert(is_Reader<typename Body::reader,
292 message<isRequest, Body, Fields>>::value,
293 "Reader requirements not met");
294 error_code ec;
295 beast::http::read(stream, dynabuf, msg, ec);
296 if(ec)
297 throw system_error{ec};
298}
299
300template<
301 class SyncReadStream,
302 class DynamicBuffer,
303 bool isRequest, class Body, class Fields>
304void
305read(
306 SyncReadStream& stream,
307 DynamicBuffer& dynabuf,
308 message<isRequest, Body, Fields>& msg,
309 error_code& ec)
310{
311 static_assert(is_SyncReadStream<SyncReadStream>::value,
312 "SyncReadStream requirements not met");
313 static_assert(is_DynamicBuffer<DynamicBuffer>::value,
314 "DynamicBuffer requirements not met");
315 static_assert(is_Body<Body>::value,
316 "Body requirements not met");
317 static_assert(has_reader<Body>::value,
318 "Body has no reader");
319 static_assert(is_Reader<typename Body::reader,
320 message<isRequest, Body, Fields>>::value,
321 "Reader requirements not met");
322 message_parser<isRequest, Body, Fields> p;
323 beast::http::read(stream, dynabuf, p, ec);
324 if(ec)
325 return;
326 msg = p.release();
327}
328
329} // http
330} // beast
331
332#endif