20 #ifndef RIPPLE_SERVER_BASEHTTPPEER_H_INCLUDED
21 #define RIPPLE_SERVER_BASEHTTPPEER_H_INCLUDED
23 #include <ripple/basics/Log.h>
24 #include <ripple/beast/net/IPAddressConversion.h>
25 #include <ripple/server/Session.h>
26 #include <ripple/server/impl/io_list.h>
27 #include <boost/asio/ip/tcp.hpp>
28 #include <boost/asio/spawn.hpp>
29 #include <boost/asio/ssl/stream.hpp>
30 #include <boost/asio/streambuf.hpp>
31 #include <boost/beast/core/stream_traits.hpp>
32 #include <boost/beast/http/dynamic_body.hpp>
33 #include <boost/beast/http/message.hpp>
34 #include <boost/beast/http/parser.hpp>
35 #include <boost/beast/http/read.hpp>
48 template <
class Handler,
class Impl>
81 boost::asio::executor_work_guard<boost::asio::executor>
work_;
82 boost::asio::strand<boost::asio::executor>
strand_;
96 boost::system::error_code
ec_;
105 template <
class ConstBufferSequence>
109 boost::asio::executor
const& executor,
112 ConstBufferSequence
const& buffers);
129 return *
static_cast<Impl*
>(
this);
201 close(
bool graceful)
override;
206 template <
class Handler,
class Impl>
207 template <
class ConstBufferSequence>
211 boost::asio::executor
const& executor,
214 ConstBufferSequence
const& buffers)
219 , remote_address_(remote_address)
222 read_buf_.commit(boost::asio::buffer_copy(
223 read_buf_.prepare(boost::asio::buffer_size(buffers)), buffers));
227 JLOG(journal_.trace()) << id_ <<
"accept: " << remote_address_.address();
230 template <
class Handler,
class Impl>
233 handler_.onClose(session(), ec_);
234 JLOG(journal_.trace()) << id_ <<
"destroyed: " << request_count_
235 << ((request_count_ == 1) ?
" request"
239 template <
class Handler,
class Impl>
243 if (!strand_.running_in_this_thread())
248 impl().shared_from_this()));
249 boost::beast::get_lowest_layer(impl().stream_).close();
254 template <
class Handler,
class Impl>
258 if (!ec_ && ec != boost::asio::error::operation_aborted)
261 JLOG(journal_.trace())
262 << id_ <<
std::string(what) <<
": " << ec.message();
263 boost::beast::get_lowest_layer(impl().stream_).close();
267 template <
class Handler,
class Impl>
271 boost::beast::get_lowest_layer(impl().stream_)
273 remote_address_.address().is_loopback() ? timeoutSecondsLocal
278 template <
class Handler,
class Impl>
282 boost::beast::get_lowest_layer(impl().stream_).expires_never();
286 template <
class Handler,
class Impl>
291 boost::system::errc::make_error_code(boost::system::errc::timed_out);
297 template <
class Handler,
class Impl>
304 boost::beast::http::async_read(
305 impl().stream_, read_buf_, message_, do_yield[ec]);
307 if (ec == boost::beast::http::error::end_of_stream)
309 if (ec == boost::beast::error::timeout)
312 return fail(ec,
"http::read");
318 template <
class Handler,
class Impl>
325 if (ec == boost::beast::error::timeout)
328 return fail(ec,
"write");
329 bytes_out_ += bytes_transferred;
333 wq2_.reserve(wq_.size());
340 for (
auto const& b : wq2_)
343 return boost::asio::async_write(
349 &BaseHTTPPeer::on_write,
350 impl().shared_from_this(),
351 std::placeholders::_1,
352 std::placeholders::_2)));
362 impl().shared_from_this(),
363 std::placeholders::_1));
366 template <
class Handler,
class Impl>
375 auto const p = impl().shared_from_this();
384 std::placeholders::_1));
390 if (!writer->prepare(bufferSize, resume))
393 auto const bytes_transferred = boost::asio::async_write(
396 boost::asio::transfer_at_least(1),
399 return fail(ec,
"writer");
400 writer->consume(bytes_transferred);
401 if (writer->complete())
412 impl().shared_from_this(),
413 std::placeholders::_1));
419 template <
class Handler,
class Impl>
427 wq_.emplace_back(buf, bytes);
428 return wq_.size() == 1 && wq2_.size() == 0;
431 if (!strand_.running_in_this_thread())
435 &BaseHTTPPeer::on_write,
436 impl().shared_from_this(),
444 template <
class Handler,
class Impl>
450 boost::asio::spawn(bind_executor(
454 impl().shared_from_this(),
457 std::placeholders::_1)));
462 template <
class Handler,
class Impl>
466 return impl().shared_from_this();
471 template <
class Handler,
class Impl>
475 if (!strand_.running_in_this_thread())
480 impl().shared_from_this()));
487 if (!wq_.empty() && !wq2_.empty())
492 boost::asio::spawn(bind_executor(
496 impl().shared_from_this(),
497 std::placeholders::_1)));
502 template <
class Handler,
class Impl>
506 if (!strand_.running_in_this_thread())
512 impl().shared_from_this(),
521 if (!wq_.empty() || !wq2_.empty())
527 boost::beast::get_lowest_layer(impl().stream_).close();