20 #ifndef RIPPLE_SERVER_BASEHTTPPEER_H_INCLUDED
21 #define RIPPLE_SERVER_BASEHTTPPEER_H_INCLUDED
23 #include <ripple/basics/Log.h>
24 #include <ripple/server/Session.h>
25 #include <ripple/server/impl/io_list.h>
26 #include <ripple/beast/net/IPAddressConversion.h>
27 #include <boost/beast/core/stream_traits.hpp>
28 #include <boost/beast/http/read.hpp>
29 #include <boost/beast/http/message.hpp>
30 #include <boost/beast/http/parser.hpp>
31 #include <boost/beast/http/dynamic_body.hpp>
32 #include <boost/asio/ip/tcp.hpp>
33 #include <boost/asio/ssl/stream.hpp>
34 #include <boost/asio/streambuf.hpp>
35 #include <boost/asio/spawn.hpp>
48 template<
class Handler,
class Impl>
86 boost::asio::executor_work_guard<boost::asio::executor>
work_;
87 boost::asio::strand<boost::asio::executor>
strand_;
101 boost::system::error_code
ec_;
110 template <
class ConstBufferSequence>
114 boost::asio::executor
const& executor,
117 ConstBufferSequence
const& buffers);
128 void close()
override;
134 return *
static_cast<Impl*
>(
this);
199 bool keep_alive)
override;
208 close(
bool graceful)
override;
213 template <
class Handler,
class Impl>
214 template <
class ConstBufferSequence>
218 boost::asio::executor
const& executor,
221 ConstBufferSequence
const& buffers)
226 , remote_address_(remote_address)
229 read_buf_.commit(boost::asio::buffer_copy(read_buf_.prepare(
230 boost::asio::buffer_size(buffers)), buffers));
234 JLOG(journal_.trace()) << id_ <<
235 "accept: " << remote_address_.address();
238 template<
class Handler,
class Impl>
242 handler_.onClose(session(), ec_);
243 JLOG(journal_.trace()) << id_ <<
244 "destroyed: " << request_count_ <<
245 ((request_count_ == 1) ?
" request" :
" requests");
248 template<
class Handler,
class Impl>
253 if(! strand_.running_in_this_thread())
258 impl().shared_from_this()));
259 boost::beast::get_lowest_layer(impl().stream_).close();
264 template<
class Handler,
class Impl>
269 if(! ec_ && ec != boost::asio::error::operation_aborted)
272 JLOG(journal_.trace()) << id_ <<
274 boost::beast::get_lowest_layer(impl().stream_).close();
278 template<
class Handler,
class Impl>
283 boost::beast::get_lowest_layer(impl().stream_).expires_after(
285 remote_address_.address().is_loopback() ?
286 timeoutSecondsLocal :
292 template<
class Handler,
class Impl>
297 boost::beast::get_lowest_layer(impl().stream_).expires_never();
301 template<
class Handler,
class Impl>
306 auto ec = boost::system::errc::make_error_code(
307 boost::system::errc::timed_out);
313 template<
class Handler,
class Impl>
321 boost::beast::http::async_read(impl().stream_,
322 read_buf_, message_, do_yield[ec]);
324 if(ec == boost::beast::http::error::end_of_stream)
326 if(ec == boost::beast::error::timeout)
329 return fail(ec,
"http::read");
335 template<
class Handler,
class Impl>
342 if(ec == boost::beast::error::timeout)
345 return fail(ec,
"write");
346 bytes_out_ += bytes_transferred;
350 wq2_.reserve(wq_.size());
357 for(
auto const& b : wq2_)
360 return boost::asio::async_write(
366 &BaseHTTPPeer::on_write,
367 impl().shared_from_this(),
368 std::placeholders::_1,
369 std::placeholders::_2)));
375 boost::asio::spawn(strand_,
377 impl().shared_from_this(), std::placeholders::_1));
380 template<
class Handler,
class Impl>
388 auto const p = impl().shared_from_this();
390 [
this, p, writer, keep_alive]()
394 std::placeholders::_1));
400 if(! writer->prepare(bufferSize, resume))
403 auto const bytes_transferred = boost::asio::async_write(
404 impl().stream_, writer->data(), boost::asio::transfer_at_least(1),
407 return fail(ec,
"writer");
408 writer->consume(bytes_transferred);
409 if(writer->complete())
417 impl().shared_from_this(), std::placeholders::_1));
423 template<
class Handler,
class Impl>
434 wq_.emplace_back(buf, bytes);
435 return wq_.size() == 1 && wq2_.size() == 0;
438 if(! strand_.running_in_this_thread())
442 &BaseHTTPPeer::on_write,
443 impl().shared_from_this(),
451 template<
class Handler,
class Impl>
457 boost::asio::spawn(bind_executor(
461 impl().shared_from_this(),
464 std::placeholders::_1)));
469 template<
class Handler,
class Impl>
474 return impl().shared_from_this();
479 template<
class Handler,
class Impl>
484 if(! strand_.running_in_this_thread())
489 impl().shared_from_this()));
496 if(! wq_.empty() && ! wq2_.empty())
501 boost::asio::spawn(bind_executor(
505 impl().shared_from_this(),
506 std::placeholders::_1)));
511 template<
class Handler,
class Impl>
516 if(! strand_.running_in_this_thread())
522 impl().shared_from_this(),
531 if(! wq_.empty() || ! wq2_.empty())
537 boost::beast::get_lowest_layer(impl().stream_).close();