2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
8 #ifndef BEAST_HTTP_IMPL_READ_IPP_HPP
9 #define BEAST_HTTP_IMPL_READ_IPP_HPP
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>
30 bool isRequest, bool isDirect, class Derived>
34 SyncReadStream& stream,
35 DynamicBuffer& dynabuf,
36 basic_parser<isRequest, isDirect, Derived>& parser,
39 std::size_t bytes_used;
40 if(dynabuf.size() == 0)
44 bytes_used = parser.write(
51 boost::optional<typename
52 DynamicBuffer::mutable_buffers_type> mb;
54 read_size_helper(dynabuf, 65536);
55 BOOST_ASSERT(size > 0);
58 mb.emplace(dynabuf.prepare(size));
60 catch(std::length_error const&)
62 ec = error::buffer_overflow;
65 auto const bytes_transferred =
66 stream.read_some(*mb, ec);
67 if(ec == boost::asio::error::eof)
69 BOOST_ASSERT(bytes_transferred == 0);
73 // caller sees EOF on next read
78 BOOST_ASSERT(parser.is_complete());
86 BOOST_ASSERT(bytes_transferred > 0);
87 dynabuf.commit(bytes_transferred);
96 bool isRequest, class Derived>
100 SyncReadStream& stream,
101 DynamicBuffer& dynabuf,
102 basic_parser<isRequest, true, Derived>& parser,
105 if(dynabuf.size() > 0)
106 return parser.copy_body(dynabuf);
107 boost::optional<typename
108 Derived::mutable_buffers_type> mb;
111 parser.prepare_body(mb, 65536);
113 catch(std::length_error const&)
115 ec = error::buffer_overflow;
118 auto const bytes_transferred =
119 stream.read_some(*mb, ec);
120 if(ec == boost::asio::error::eof)
122 BOOST_ASSERT(bytes_transferred == 0);
123 // caller sees EOF on next read
125 parser.write_eof(ec);
128 BOOST_ASSERT(parser.is_complete());
132 parser.commit_body(bytes_transferred);
139 class SyncReadStream,
141 bool isRequest, class Derived>
145 SyncReadStream& stream,
146 DynamicBuffer& dynabuf,
147 basic_parser<isRequest, true, Derived>& parser,
150 switch(parser.state())
152 case parse_state::header:
153 case parse_state::chunk_header:
154 return detail::read_some_buffer(
155 stream, dynabuf, parser, ec);
158 return detail::read_some_body(
159 stream, dynabuf, parser, ec);
164 class SyncReadStream,
166 bool isRequest, class Derived>
170 SyncReadStream& stream,
171 DynamicBuffer& dynabuf,
172 basic_parser<isRequest, false, Derived>& parser,
175 return detail::read_some_buffer(
176 stream, dynabuf, parser, ec);
181 //------------------------------------------------------------------------------
184 class SyncReadStream,
186 bool isRequest, bool isDirect, class Derived>
189 SyncReadStream& stream,
190 DynamicBuffer& dynabuf,
191 basic_parser<isRequest, isDirect, Derived>& parser)
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());
199 auto const bytes_used =
200 read_some(stream, dynabuf, parser, ec);
202 throw system_error{ec};
207 class SyncReadStream,
209 bool isRequest, bool isDirect, class Derived>
212 SyncReadStream& stream,
213 DynamicBuffer& dynabuf,
214 basic_parser<isRequest, isDirect, Derived>& parser,
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);
226 class SyncReadStream,
228 bool isRequest, bool isDirect, class Derived>
231 SyncReadStream& stream,
232 DynamicBuffer& dynabuf,
233 basic_parser<isRequest, isDirect, Derived>& parser)
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());
241 read(stream, dynabuf, parser, ec);
243 throw system_error{ec};
247 class SyncReadStream,
249 bool isRequest, bool isDirect, class Derived>
252 SyncReadStream& stream,
253 DynamicBuffer& dynabuf,
254 basic_parser<isRequest, isDirect, Derived>& parser,
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());
264 auto const bytes_used =
265 read_some(stream, dynabuf, parser, ec);
268 dynabuf.consume(bytes_used);
270 while(! parser.is_complete());
274 class SyncReadStream,
276 bool isRequest, class Body, class Fields>
279 SyncReadStream& stream,
280 DynamicBuffer& dynabuf,
281 message<isRequest, Body, Fields>& msg)
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");
295 beast::http::read(stream, dynabuf, msg, ec);
297 throw system_error{ec};
301 class SyncReadStream,
303 bool isRequest, class Body, class Fields>
306 SyncReadStream& stream,
307 DynamicBuffer& dynabuf,
308 message<isRequest, Body, Fields>& msg,
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);