22#include <boost/enable_shared_from_this.hpp>
23#include <boost/weak_ptr.hpp>
39using namespace boost::posix_time;
41namespace ph = std::placeholders;
48constexpr size_t MAX_LOGGED_MESSAGE_SIZE = 1024;
51typedef std::function<void(boost::system::error_code ec,
size_t length)>
52SocketCallbackFunction;
67 SocketCallback(SocketCallbackFunction socket_callback)
68 : callback_(socket_callback) {
77 void operator()(boost::system::error_code ec,
size_t length = 0) {
78 if (ec.value() == boost::asio::error::operation_aborted) {
81 callback_(ec, length);
87 SocketCallbackFunction callback_;
94typedef boost::shared_ptr<ConnectionPool> ConnectionPoolPtr;
111class Connection :
public boost::enable_shared_from_this<Connection> {
123 const ConnectionPoolPtr& conn_pool,
149 const long request_timeout,
161 bool isTransactionOngoing()
const {
168 bool isClosed()
const {
176 void isClosedByPeer();
183 bool isMySocket(
int socket_fd)
const;
200 bool checkPrematureTimeout(
const uint64_t transid);
226 const long request_timeout,
235 void closeInternal();
243 void isClosedByPeerInternal();
262 bool checkPrematureTimeoutInternal(
const uint64_t transid);
281 void terminate(
const boost::system::error_code& ec,
282 const std::string& parsing_error =
"");
295 void terminateInternal(
const boost::system::error_code& ec,
296 const std::string& parsing_error =
"");
304 bool runParser(
const boost::system::error_code& ec,
size_t length);
314 bool runParserInternal(
const boost::system::error_code& ec,
size_t length);
319 void scheduleTimer(
const long request_timeout);
326 void doHandshake(
const uint64_t transid);
333 void doSend(
const uint64_t transid);
340 void doReceive(
const uint64_t transid);
353 const uint64_t transid,
354 const boost::system::error_code& ec);
366 const uint64_t transid,
367 const boost::system::error_code& ec);
379 void sendCallback(
const uint64_t transid,
const boost::system::error_code& ec,
388 void receiveCallback(
const uint64_t transid,
const boost::system::error_code& ec,
392 void timerCallback();
403 void closeCallback(
const bool clear =
false);
412 boost::weak_ptr<ConnectionPool> conn_pool_;
421 std::shared_ptr<TCPSocket<SocketCallback>> tcp_socket_;
424 std::shared_ptr<TLSSocket<SocketCallback>> tls_socket_;
445 std::array<char, 32768> input_buf_;
448 uint64_t current_transid_;
457 std::atomic<bool> started_;
460 std::atomic<bool> need_handshake_;
463 std::atomic<bool> closed_;
470typedef boost::shared_ptr<Connection> ConnectionPtr;
479class ConnectionPool :
public boost::enable_shared_from_this<ConnectionPool> {
488 explicit ConnectionPool(
const IOServicePtr& io_service,
size_t max_url_connections)
489 : io_service_(io_service), destinations_(), pool_mutex_(),
490 max_url_connections_(max_url_connections) {
507 std::lock_guard<std::mutex> lk(pool_mutex_);
508 return (processNextRequestInternal(url, tls_context));
510 return (processNextRequestInternal(url, tls_context));
519 void postProcessNextRequest(
const Url& url,
521 io_service_->post(std::bind(&ConnectionPool::processNextRequest,
522 shared_from_this(), url, tls_context));
545 void queueRequest(
const Url& url,
549 const long request_timeout,
555 std::lock_guard<std::mutex> lk(pool_mutex_);
556 return (queueRequestInternal(url, tls_context, request, response,
557 request_timeout, request_callback,
558 connect_callback, handshake_callback,
561 return (queueRequestInternal(url, tls_context, request, response,
562 request_timeout, request_callback,
563 connect_callback, handshake_callback,
572 std::lock_guard<std::mutex> lk(pool_mutex_);
591 void closeIfOutOfBand(
int socket_fd) {
593 std::lock_guard<std::mutex> lk(pool_mutex_);
594 closeIfOutOfBandInternal(socket_fd);
596 closeIfOutOfBandInternal(socket_fd);
609 void processNextRequestInternal(
const Url& url,
613 DestinationPtr destination = findDestination(url, tls_context);
616 destination->garbageCollectConnections();
617 if (!destination->queueEmpty()) {
620 ConnectionPtr connection = destination->getIdleConnection();
623 if (destination->connectionsFull()) {
628 connection.reset(
new Connection(io_service_, tls_context,
629 shared_from_this(), url));
630 destination->addConnection(connection);
635 RequestDescriptor desc = destination->popNextRequest();
636 connection->doTransaction(desc.request_, desc.response_,
637 desc.request_timeout_, desc.callback_,
638 desc.connect_callback_,
639 desc.handshake_callback_,
640 desc.close_callback_);
667 void queueRequestInternal(
const Url& url,
671 const long request_timeout,
676 ConnectionPtr connection;
678 DestinationPtr destination = findDestination(url, tls_context);
681 destination->garbageCollectConnections();
683 connection = destination->getIdleConnection();
686 destination = addDestination(url, tls_context);
690 if (destination->connectionsFull()) {
692 destination->pushRequest(RequestDescriptor(request, response,
702 connection.reset(
new Connection(io_service_, tls_context,
703 shared_from_this(), url));
704 destination->addConnection(connection);
708 connection->doTransaction(request, response, request_timeout, request_callback,
709 connect_callback, handshake_callback, close_callback);
716 void closeAllInternal() {
717 for (
auto const& destination : destinations_) {
718 destination.second->closeAllConnections();
721 destinations_.clear();
738 void closeIfOutOfBandInternal(
int socket_fd) {
739 for (
auto const& destination : destinations_) {
741 ConnectionPtr connection = destination.second->findBySocketFd(socket_fd);
743 if (!connection->isTransactionOngoing()) {
749 destination.second->closeConnection(connection);
759 struct RequestDescriptor {
775 const long& request_timeout,
780 : request_(request), response_(response),
781 request_timeout_(request_timeout), callback_(callback),
782 connect_callback_(connect_callback),
783 handshake_callback_(handshake_callback),
784 close_callback_(close_callback) {
794 long request_timeout_;
810 typedef std::pair<Url, TlsContextPtr> DestinationDescriptor;
816 const size_t QUEUE_SIZE_THRESHOLD = 2048;
818 const int QUEUE_WARN_SECS = 5;
826 Destination(
Url const& url,
TlsContextPtr tls_context,
size_t max_connections)
827 : url_(url), tls_context_(tls_context),
828 max_connections_(max_connections), connections_(), queue_(),
829 last_queue_warn_time_(min_date_time), last_queue_size_(0) {
834 closeAllConnections();
844 void addConnection(ConnectionPtr connection) {
845 if (connectionsFull()) {
847 <<
", already at maximum connections: "
848 << max_connections_);
851 connections_.push_back(connection);
858 void closeConnection(ConnectionPtr connection) {
859 for (
auto it = connections_.begin(); it != connections_.end(); ++it) {
860 if (*it == connection) {
862 connections_.erase(it);
870 void closeAllConnections() {
872 while (!queue_.empty()) {
876 for (
auto const& connection : connections_) {
880 connections_.clear();
906 void garbageCollectConnections() {
907 for (
auto it = connections_.begin(); it != connections_.end();) {
908 (*it)->isClosedByPeer();
909 if (!(*it)->isClosed()) {
912 it = connections_.erase(it);
928 ConnectionPtr getIdleConnection() {
929 for (
auto const& connection : connections_) {
930 if (!connection->isTransactionOngoing() &&
931 !connection->isClosed()) {
936 return (ConnectionPtr());
945 ConnectionPtr findBySocketFd(
int socket_fd) {
946 for (
auto const& connection : connections_) {
947 if (connection->isMySocket(socket_fd)) {
952 return (ConnectionPtr());
958 bool connectionsEmpty() {
959 return (connections_.empty());
965 bool connectionsFull() {
966 return (connections_.size() >= max_connections_);
972 size_t connectionCount() {
973 return (connections_.size());
979 size_t getMaxConnections()
const {
980 return (max_connections_);
986 bool queueEmpty()
const {
987 return (queue_.empty());
996 void pushRequest(RequestDescriptor
const& desc) {
998 size_t size = queue_.size();
1001 if ((size > QUEUE_SIZE_THRESHOLD) && (size > last_queue_size_)) {
1002 ptime now = microsec_clock::universal_time();
1003 if ((now - last_queue_warn_time_) > seconds(QUEUE_WARN_SECS)) {
1008 last_queue_warn_time_ = now;
1013 last_queue_size_ = size;
1019 RequestDescriptor popNextRequest() {
1020 if (queue_.empty()) {
1024 RequestDescriptor desc = queue_.front();
1037 size_t max_connections_;
1040 std::list<ConnectionPtr> connections_;
1043 std::queue<RequestDescriptor> queue_;
1046 ptime last_queue_warn_time_;
1049 size_t last_queue_size_;
1053 typedef boost::shared_ptr<Destination> DestinationPtr;
1062 DestinationPtr addDestination(
const Url& url,
1064 const DestinationDescriptor& desc = std::make_pair(url, tls_context);
1065 DestinationPtr destination(
new Destination(url, tls_context,
1066 max_url_connections_));
1067 destinations_[desc] = destination;
1068 return (destination);
1079 DestinationPtr findDestination(
const Url& url,
1081 const DestinationDescriptor& desc = std::make_pair(url, tls_context);
1082 auto it = destinations_.find(desc);
1083 if (it != destinations_.end()) {
1084 return (it->second);
1087 return (DestinationPtr());
1101 void removeDestination(
const Url& url,
1103 const DestinationDescriptor& desc = std::make_pair(url, tls_context);
1104 auto it = destinations_.find(desc);
1105 if (it != destinations_.end()) {
1106 it->second->closeAllConnections();
1107 destinations_.erase(it);
1115 std::map<DestinationDescriptor, DestinationPtr> destinations_;
1118 std::mutex pool_mutex_;
1121 size_t max_url_connections_;
1126 const ConnectionPoolPtr& conn_pool,
1128 : io_service_(io_service), conn_pool_(conn_pool), url_(url),
1129 tls_context_(tls_context), tcp_socket_(), tls_socket_(),
1131 current_response_(), parser_(), current_callback_(), buf_(), input_buf_(),
1132 current_transid_(0), close_callback_(), started_(false),
1133 need_handshake_(false), closed_(false) {
1139 need_handshake_ =
true;
1143Connection::~Connection() {
1148Connection::resetState() {
1150 current_request_.reset();
1151 current_response_.reset();
1157Connection::closeCallback(
const bool clear) {
1158 if (close_callback_) {
1161 close_callback_(tcp_socket_->getNative());
1162 }
else if (tls_socket_) {
1163 close_callback_(tls_socket_->getNative());
1166 "internal error: can't find a socket to close");
1179Connection::isClosedByPeer() {
1181 if (started_ || closed_) {
1186 std::lock_guard<std::mutex> lk(mutex_);
1187 isClosedByPeerInternal();
1189 isClosedByPeerInternal();
1194Connection::isClosedByPeerInternal() {
1203 if (tcp_socket_->getASIOSocket().is_open() &&
1204 !tcp_socket_->isUsable()) {
1207 tcp_socket_->close();
1209 }
else if (tls_socket_) {
1210 if (tls_socket_->getASIOSocket().is_open() &&
1211 !tls_socket_->isUsable()) {
1214 tls_socket_->close();
1224 const long request_timeout,
1230 std::lock_guard<std::mutex> lk(mutex_);
1231 doTransactionInternal(request, response, request_timeout,
1232 callback, connect_callback, handshake_callback,
1235 doTransactionInternal(request, response, request_timeout,
1236 callback, connect_callback, handshake_callback,
1244 const long request_timeout,
1251 current_request_ = request;
1252 current_response_ = response;
1254 parser_->initModel();
1255 current_callback_ = callback;
1256 handshake_callback_ = handshake_callback;
1257 close_callback_ = close_callback;
1262 buf_ = request->toString();
1266 .arg(request->toBriefString())
1267 .arg(url_.toText());
1273 MAX_LOGGED_MESSAGE_SIZE));
1276 scheduleTimer(request_timeout);
1282 static_cast<unsigned short>(url_.getPort()));
1283 SocketCallback socket_cb(std::bind(&Connection::connectCallback, shared_from_this(),
1284 connect_callback, current_transid_,
1289 tcp_socket_->open(&endpoint, socket_cb);
1293 tls_socket_->open(&endpoint, socket_cb);
1300 }
catch (
const std::exception& ex) {
1307Connection::close() {
1309 std::lock_guard<std::mutex> lk(mutex_);
1310 return (closeInternal());
1312 return (closeInternal());
1317Connection::closeInternal() {
1319 closeCallback(
true);
1324 tcp_socket_->close();
1327 tls_socket_->close();
1334Connection::isMySocket(
int socket_fd)
const {
1336 return (tcp_socket_->getNative() == socket_fd);
1337 }
else if (tls_socket_) {
1338 return (tls_socket_->getNative() == socket_fd);
1341 std::cerr <<
"internal error: can't find my socket\n";
1346Connection::checkPrematureTimeout(
const uint64_t transid) {
1348 std::lock_guard<std::mutex> lk(mutex_);
1349 return (checkPrematureTimeoutInternal(transid));
1351 return (checkPrematureTimeoutInternal(transid));
1356Connection::checkPrematureTimeoutInternal(
const uint64_t transid) {
1362 if (!isTransactionOngoing() || (transid != current_transid_)) {
1364 .arg(isTransactionOngoing())
1366 .arg(current_transid_);
1374Connection::terminate(
const boost::system::error_code& ec,
1375 const std::string& parsing_error) {
1377 std::lock_guard<std::mutex> lk(mutex_);
1378 terminateInternal(ec, parsing_error);
1380 terminateInternal(ec, parsing_error);
1385Connection::terminateInternal(
const boost::system::error_code& ec,
1386 const std::string& parsing_error) {
1388 if (isTransactionOngoing()) {
1392 tcp_socket_->cancel();
1395 tls_socket_->cancel();
1398 if (!ec && current_response_->isFinalized()) {
1399 response = current_response_;
1403 .arg(url_.toText());
1409 parser_->getBufferAsString(MAX_LOGGED_MESSAGE_SIZE) :
1410 "[HttpResponseParser is null]");
1413 std::string err = parsing_error.empty() ? ec.message() :
1423 if (!parsing_error.empty()) {
1428 parser_->getBufferAsString(MAX_LOGGED_MESSAGE_SIZE) :
1429 "[HttpResponseParser is null]");
1437 UnlockGuard<std::mutex> lock(mutex_);
1438 current_callback_(ec, response, parsing_error);
1440 current_callback_(ec, response, parsing_error);
1448 (!current_request_->isPersistent() ||
1449 (ec == boost::asio::error::timed_out))) {
1458 ConnectionPoolPtr conn_pool = conn_pool_.lock();
1460 conn_pool->postProcessNextRequest(url_, tls_context_);
1465Connection::scheduleTimer(
const long request_timeout) {
1466 if (request_timeout > 0) {
1467 timer_->setup(std::bind(&Connection::timerCallback,
this), request_timeout,
1473Connection::doHandshake(
const uint64_t transid) {
1475 if (!need_handshake_) {
1480 SocketCallback socket_cb(std::bind(&Connection::handshakeCallback,
1482 handshake_callback_,
1486 tls_socket_->handshake(socket_cb);
1489 terminate(boost::asio::error::not_connected);
1494Connection::doSend(
const uint64_t transid) {
1495 SocketCallback socket_cb(std::bind(&Connection::sendCallback,
1502 tcp_socket_->asyncSend(&buf_[0], buf_.size(), socket_cb);
1507 tls_socket_->asyncSend(&buf_[0], buf_.size(), socket_cb);
1512 std::cerr <<
"internal error: can't find a socket to send to\n";
1514 "internal error: can't find a socket to send to");
1516 terminate(boost::asio::error::not_connected);
1521Connection::doReceive(
const uint64_t transid) {
1523 SocketCallback socket_cb(std::bind(&Connection::receiveCallback,
1530 tcp_socket_->asyncReceive(
static_cast<void*
>(input_buf_.data()),
1531 input_buf_.size(), 0,
1532 &endpoint, socket_cb);
1536 tls_socket_->asyncReceive(
static_cast<void*
>(input_buf_.data()),
1537 input_buf_.size(), 0,
1538 &endpoint, socket_cb);
1542 std::cerr <<
"internal error: can't find a socket to receive from\n";
1544 "internal error: can't find a socket to receive from");
1547 terminate(boost::asio::error::not_connected);
1553 const uint64_t transid,
1554 const boost::system::error_code& ec) {
1555 if (checkPrematureTimeout(transid)) {
1560 if (connect_callback) {
1564 if (!connect_callback(ec, tcp_socket_->getNative())) {
1567 }
else if (tls_socket_) {
1568 if (!connect_callback(ec, tls_socket_->getNative())) {
1573 std::cerr <<
"internal error: can't find a socket to connect\n";
1577 if (ec && (ec.value() == boost::asio::error::operation_aborted)) {
1585 (ec.value() != boost::asio::error::in_progress) &&
1586 (ec.value() != boost::asio::error::already_connected)) {
1591 doHandshake(transid);
1597 const uint64_t transid,
1598 const boost::system::error_code& ec) {
1599 need_handshake_ =
false;
1600 if (checkPrematureTimeout(transid)) {
1605 if (handshake_callback) {
1609 if (!handshake_callback(ec, tls_socket_->getNative())) {
1614 std::cerr <<
"internal error: can't find TLS socket\n";
1618 if (ec && (ec.value() == boost::asio::error::operation_aborted)) {
1630Connection::sendCallback(
const uint64_t transid,
1631 const boost::system::error_code& ec,
1633 if (checkPrematureTimeout(transid)) {
1638 if (ec.value() == boost::asio::error::operation_aborted) {
1643 }
else if ((ec.value() == boost::asio::error::would_block) ||
1644 (ec.value() == boost::asio::error::try_again)) {
1655 scheduleTimer(timer_->getInterval());
1660 buf_.erase(0, length);
1674Connection::receiveCallback(
const uint64_t transid,
1675 const boost::system::error_code& ec,
1677 if (checkPrematureTimeout(transid)) {
1682 if (ec.value() == boost::asio::error::operation_aborted) {
1688 if ((ec.value() != boost::asio::error::try_again) &&
1689 (ec.value() != boost::asio::error::would_block)) {
1701 scheduleTimer(timer_->getInterval());
1703 if (runParser(ec, length)) {
1709Connection::runParser(
const boost::system::error_code& ec,
size_t length) {
1711 std::lock_guard<std::mutex> lk(mutex_);
1712 return (runParserInternal(ec, length));
1714 return (runParserInternal(ec, length));
1719Connection::runParserInternal(
const boost::system::error_code& ec,
1723 parser_->postBuffer(
static_cast<void*
>(input_buf_.data()), length);
1728 if (parser_->needData()) {
1731 }
else if (parser_->httpParseOk()) {
1735 current_response_->finalize();
1736 terminateInternal(ec);
1738 }
catch (
const std::exception& ex) {
1740 terminateInternal(ec, ex.what());
1746 terminateInternal(ec, parser_->getErrorMessage());
1753Connection::timerCallback() {
1755 terminate(boost::asio::error::timed_out);
1790 bool defer_thread_start =
false)
1791 : thread_pool_size_(thread_pool_size), thread_pool_() {
1792 if (thread_pool_size_ > 0) {
1794 thread_io_service_.reset(
new IOService());
1798 conn_pool_.reset(
new ConnectionPool(thread_io_service_, thread_pool_size_));
1802 defer_thread_start));
1805 .arg(thread_pool_size_);
1809 conn_pool_.reset(
new ConnectionPool(io_service, 1));
1827 thread_pool_->checkPausePermissions();
1834 thread_pool_->run();
1846 thread_pool_->stop();
1849 if (thread_io_service_) {
1850 thread_io_service_->stopAndPoll();
1851 thread_io_service_->stop();
1860 if (!thread_pool_) {
1865 thread_pool_->pause();
1873 if (!thread_pool_) {
1878 thread_pool_->run();
1887 return (thread_pool_->isRunning());
1899 return (thread_pool_->isStopped());
1911 return (thread_pool_->isPaused());
1922 return (thread_io_service_);
1929 return (thread_pool_size_);
1936 if (!thread_pool_) {
1939 return (thread_pool_->getThreadCount());
1948 size_t thread_pool_size_;
1959 size_t thread_pool_size,
bool defer_thread_start) {
1960 if (!multi_threading_enabled && thread_pool_size) {
1962 "HttpClient thread_pool_size must be zero "
1963 "when Kea core multi-threading is disabled");
1967 defer_thread_start));
1984 if (!url.isValid()) {
2000 if (!request_callback) {
2004 impl_->conn_pool_->queueRequest(url, tls_context, request, response,
2005 request_timeout.value_,
2006 request_callback, connect_callback,
2007 handshake_callback, close_callback);
2012 return (impl_->conn_pool_->closeIfOutOfBand(socket_fd));
2022 impl_->checkPermissions();
2042 return (impl_->getThreadIOService());
2047 return (impl_->getThreadPoolSize());
2052 return (impl_->getThreadCount());
2057 return (impl_->isRunning());
2062 return (impl_->isStopped());
2067 return (impl_->isPaused());
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
The IOService class is a wrapper for the ASIO io_service class.
The IntervalTimer class is a wrapper for the ASIO boost::asio::deadline_timer class.
Implements a pausable pool of IOService driven threads.
The TCPEndpoint class is a concrete derived class of IOEndpoint that represents an endpoint of a TCP ...
The TCPSocket class is a concrete derived class of IOAsioSocket that represents a TCP socket.
The TLSSocket class is a concrete derived class of IOAsioSocket that represents a TLS socket.
A generic error raised by the HttpClient class.
HttpClient implementation.
ConnectionPoolPtr conn_pool_
Holds a pointer to the connection pool.
uint16_t getThreadCount()
Fetches the number of threads in the pool.
~HttpClientImpl()
Destructor.
void pause()
Pauses the client's thread pool.
uint16_t getThreadPoolSize()
Fetches the maximum size of the thread pool.
void start()
Starts running the client's thread pool, if multi-threaded.
void stop()
Close all connections, and if multi-threaded, stops the client's thread pool.
asiolink::IOServicePtr getThreadIOService()
Fetches the internal IOService used in multi-threaded mode.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
bool isPaused()
Indicates if the thread pool is paused.
void resume()
Resumes running the client's thread pool.
HttpClientImpl(const IOServicePtr &io_service, size_t thread_pool_size=0, bool defer_thread_start=false)
Constructor.
bool isStopped()
Indicates if the thread pool is stopped.
bool isRunning()
Indicates if the thread pool is running.
uint16_t getThreadCount() const
Fetches the number of threads in the pool.
bool isRunning()
Indicates if the thread pool is running.
HttpClient(const asiolink::IOServicePtr &io_service, bool multi_threading_enabled, size_t thread_pool_size=0, bool defer_thread_start=false)
Constructor.
void stop()
Halts client-side IO activity.
bool isPaused()
Indicates if the thread pool is paused.
std::function< bool(const boost::system::error_code &, const int) ConnectHandler)
Optional handler invoked when client connects to the server.
void pause()
Pauses the client's thread pool.
std::function< void(const int)> CloseHandler
Optional handler invoked when client closes the connection to the server.
const asiolink::IOServicePtr getThreadIOService() const
Fetches a pointer to the internal IOService used to drive the thread-pool in multi-threaded mode.
void start()
Starts running the client's thread pool, if multi-threaded.
std::function< bool(const boost::system::error_code &, const int) HandshakeHandler)
Optional handler invoked when client performs the TLS handshake with the server.
std::function< void(const boost::system::error_code &, const HttpResponsePtr &, const std::string &) RequestHandler)
Callback type used in call to HttpClient::asyncSendRequest.
uint16_t getThreadPoolSize() const
Fetches the maximum size of the thread pool.
void closeIfOutOfBand(int socket_fd)
Closes a connection if it has an out-of-band socket event.
void resume()
Resumes running the client's thread pool.
void asyncSendRequest(const Url &url, const asiolink::TlsContextPtr &tls_context, const HttpRequestPtr &request, const HttpResponsePtr &response, const RequestHandler &request_callback, const RequestTimeout &request_timeout=RequestTimeout(10000), const ConnectHandler &connect_callback=ConnectHandler(), const HandshakeHandler &handshake_callback=HandshakeHandler(), const CloseHandler &close_callback=CloseHandler())
Queues new asynchronous HTTP request for a given URL.
bool isStopped()
Indicates if the thread pool is stopped.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
static std::string logFormatHttpMessage(const std::string &message, const size_t limit=0)
Formats provided HTTP message for logging.
A generic parser for HTTP responses.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< TlsContext > TlsContextPtr
The type of shared pointers to TlsContext objects.
boost::shared_ptr< IoServiceThreadPool > IoServiceThreadPoolPtr
Defines a pointer to a thread pool.
boost::shared_ptr< isc::asiolink::IntervalTimer > IntervalTimerPtr
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
const isc::log::MessageID HTTP_CLIENT_MT_STARTED
const isc::log::MessageID HTTP_CONNECTION_CLOSE_CALLBACK_FAILED
const isc::log::MessageID HTTP_BAD_SERVER_RESPONSE_RECEIVED
isc::log::Logger http_logger("http")
Defines the logger used within libkea-http library.
const isc::log::MessageID HTTP_SERVER_RESPONSE_RECEIVED
boost::shared_ptr< HttpResponseParser > HttpResponseParserPtr
Pointer to the HttpResponseParser.
const isc::log::MessageID HTTP_CLIENT_REQUEST_SEND
boost::shared_ptr< HttpResponse > HttpResponsePtr
Pointer to the HttpResponse object.
const isc::log::MessageID HTTP_BAD_SERVER_RESPONSE_RECEIVED_DETAILS
const isc::log::MessageID HTTP_CLIENT_REQUEST_SEND_DETAILS
const isc::log::MessageID HTTP_CLIENT_QUEUE_SIZE_GROWING
const isc::log::MessageID HTTP_SERVER_RESPONSE_RECEIVED_DETAILS
boost::shared_ptr< HttpRequest > HttpRequestPtr
Pointer to the HttpRequest object.
const isc::log::MessageID HTTP_PREMATURE_CONNECTION_TIMEOUT_OCCURRED
const int DBGLVL_TRACE_BASIC
Trace basic operations.
const int DBGLVL_TRACE_DETAIL_DATA
Trace data associated with detailed operations.
const int DBGLVL_TRACE_BASIC_DATA
Trace data associated with the basic operations.
const int DBGLVL_TRACE_DETAIL
Trace detailed operations.
Defines the logger used by the top-level component of kea-lfc.
HTTP request/response timeout value.