20#include <xrpl/basics/Log.h>
21#include <xrpl/beast/core/LexicalCast.h>
22#include <xrpl/net/AutoSocket.h>
23#include <xrpl/net/HTTPClient.h>
24#include <xrpl/net/HTTPClientSSLContext.h>
26#include <boost/asio.hpp>
27#include <boost/asio/ip/tcp.hpp>
28#include <boost/asio/ssl.hpp>
29#include <boost/regex.hpp>
58 boost::asio::io_service& io_service,
59 unsigned short const port,
77 boost::asio::streambuf& sb,
82 osRequest <<
"GET " << strPath
88 "Connection: close\r\n\r\n";
98 void(boost::asio::streambuf& sb,
std::string const& strHost)> build,
101 boost::system::error_code
const& ecResult,
122 boost::system::error_code
const& ecResult,
136 std::placeholders::_1,
137 std::placeholders::_2),
152 boost::asio::ip::resolver_query_base::numeric_service);
164 std::placeholders::_1));
176 std::placeholders::_1,
177 std::placeholders::_2));
187 if (ecResult == boost::asio::error::operation_aborted)
190 JLOG(
j_.
trace()) <<
"Deadline cancelled.";
197 << ecResult.message();
204 JLOG(
j_.
trace()) <<
"Deadline arrived.";
209 boost::system::errc::bad_address,
210 boost::system::system_category()};
219 std::placeholders::_1));
229 << ecResult.message();
235 boost::system::error_code
const& ecResult,
236 boost::asio::ip::tcp::resolver::iterator itrEndpoint)
254 JLOG(
j_.
trace()) <<
"Resolve complete.";
256 boost::asio::async_connect(
262 std::placeholders::_1));
279 JLOG(
j_.
trace()) <<
"Connected.";
298 AutoSocket::ssl_socket::client,
302 std::placeholders::_1));
324 JLOG(
j_.
trace()) <<
"Session started.";
333 std::placeholders::_1,
334 std::placeholders::_2));
340 boost::system::error_code
const& ecResult,
362 std::placeholders::_1,
363 std::placeholders::_2));
369 boost::system::error_code
const& ecResult,
375 JLOG(
j_.
trace()) <<
"Header: \"" << strHeader <<
"\"";
377 static boost::regex reStatus{
378 "\\`HTTP/1\\S+ (\\d{3}) .*\\'"};
379 static boost::regex reSize{
380 "\\`.*\\r\\nContent-Length:\\s+([0-9]+).*\\'"};
381 static boost::regex reBody{
"\\`.*\\r\\n\\r\\n(.*)\\'"};
383 boost::smatch smMatch;
385 if (!boost::regex_match(strHeader, smMatch, reStatus))
388 JLOG(
j_.
trace()) <<
"No status code";
390 boost::system::errc::bad_address,
391 boost::system::system_category()});
397 if (boost::regex_match(strHeader, smMatch, reBody))
401 if (boost::regex_match(strHeader, smMatch, reSize))
402 return beast::lexicalCast<std::size_t>(
409 JLOG(
j_.
trace()) <<
"Response field too large";
411 boost::system::errc::value_too_large,
412 boost::system::system_category()});
416 if (responseSize == 0)
430 boost::asio::transfer_all(),
434 std::placeholders::_1,
435 std::placeholders::_2));
441 boost::system::error_code
const& ecResult,
457 JLOG(
j_.
trace()) <<
"Complete.";
473 boost::system::error_code
const& ecResult,
477 boost::system::error_code ecCancel;
483 JLOG(
j_.
trace()) <<
"invokeComplete: Deadline cancel error: "
484 << ecCancel.message();
487 JLOG(
j_.
debug()) <<
"invokeComplete: Deadline popping: "
503 mComplete(ecResult ? ecResult : ecCancel, iStatus, strData);
529 boost::system::error_code
const& ecResult,
534 boost::asio::basic_waitable_timer<std::chrono::steady_clock>
mDeadline;
549 boost::asio::io_service& io_service,
551 unsigned short const port,
556 boost::system::error_code
const& ecResult,
563 client->get(bSSL, deqSites, strPath, timeout, complete);
569 boost::asio::io_service& io_service,
571 unsigned short const port,
576 boost::system::error_code
const& ecResult,
585 client->get(bSSL, deqSites, strPath, timeout, complete);
591 boost::asio::io_service& io_service,
593 unsigned short const port,
599 boost::system::error_code
const& ecResult,
608 client->request(bSSL, deqSites, setRequest, timeout, complete);
void async_handshake(handshake_type type, callback cbFunc)
void async_write(Buf const &buffers, Handler handler)
lowest_layer_type & lowest_layer()
void async_read_until(Seq const &buffers, Condition condition, Handler handler)
void async_read(Buf const &buffers, Condition cond, Handler handler)
void async_shutdown(ShutdownHandler handler)
A generic endpoint for log messages.
Stream trace() const
Severity stream access functions.
void handleResolve(boost::system::error_code const &ecResult, boost::asio::ip::tcp::resolver::iterator itrEndpoint)
void handleWrite(boost::system::error_code const &ecResult, std::size_t bytes_transferred)
void makeGet(std::string const &strPath, boost::asio::streambuf &sb, std::string const &strHost)
HTTPClientImp(boost::asio::io_service &io_service, unsigned short const port, std::size_t maxResponseSize, beast::Journal &j)
std::chrono::seconds mTimeout
std::function< void(boost::asio::streambuf &sb, std::string const &strHost)> mBuild
std::size_t const maxResponseSize_
std::shared_ptr< boost::asio::ip::tcp::resolver::query > mQuery
void handleShutdown(boost::system::error_code const &ecResult)
void invokeComplete(boost::system::error_code const &ecResult, int iStatus=0, std::string const &strData="")
void get(bool bSSL, std::deque< std::string > deqSites, std::string const &strPath, std::chrono::seconds timeout, std::function< bool(boost::system::error_code const &ecResult, int iStatus, std::string const &strData)> complete)
boost::asio::streambuf mHeader
boost::asio::ip::tcp::resolver mResolver
boost::asio::streambuf mRequest
void handleHeader(boost::system::error_code const &ecResult, std::size_t bytes_transferred)
void handleConnect(boost::system::error_code const &ecResult)
std::function< bool(boost::system::error_code const &ecResult, int iStatus, std::string const &strData)> mComplete
void handleRequest(boost::system::error_code const &ecResult)
void request(bool bSSL, std::deque< std::string > deqSites, std::function< void(boost::asio::streambuf &sb, std::string const &strHost)> build, std::chrono::seconds timeout, std::function< bool(boost::system::error_code const &ecResult, int iStatus, std::string const &strData)> complete)
boost::asio::basic_waitable_timer< std::chrono::steady_clock > mDeadline
unsigned short const mPort
std::deque< std::string > mDeqSites
void handleData(boost::system::error_code const &ecResult, std::size_t bytes_transferred)
void handleDeadline(boost::system::error_code const &ecResult)
boost::asio::streambuf mResponse
boost::system::error_code mShutdown
Provides an asynchronous HTTP client implementation with optional SSL.
static void get(bool bSSL, boost::asio::io_service &io_service, std::deque< std::string > deqSites, unsigned short const port, std::string const &strPath, std::size_t responseMax, std::chrono::seconds timeout, std::function< bool(boost::system::error_code const &ecResult, int iStatus, std::string const &strData)> complete, beast::Journal &j)
static void initializeSSLContext(std::string const &sslVerifyDir, std::string const &sslVerifyFile, bool sslVerify, beast::Journal j)
static void request(bool bSSL, boost::asio::io_service &io_service, std::string strSite, unsigned short const port, std::function< void(boost::asio::streambuf &sb, std::string const &strHost)> build, std::size_t responseMax, std::chrono::seconds timeout, std::function< bool(boost::system::error_code const &ecResult, int iStatus, std::string const &strData)> complete, beast::Journal &j)
static constexpr auto maxClientHeaderBytes
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static std::optional< HTTPClientSSLContext > httpClientSSLContext
T shared_from_this(T... args)