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();
1331 std::shared_ptr<TLSSocket<SocketCallback>>) {};
1332 io_service_->post(std::bind(f, timer_, tcp_socket_, tls_socket_));
1338Connection::isMySocket(
int socket_fd)
const {
1340 return (tcp_socket_->getNative() == socket_fd);
1341 }
else if (tls_socket_) {
1342 return (tls_socket_->getNative() == socket_fd);
1345 std::cerr <<
"internal error: can't find my socket\n";
1350Connection::checkPrematureTimeout(
const uint64_t transid) {
1352 std::lock_guard<std::mutex> lk(mutex_);
1353 return (checkPrematureTimeoutInternal(transid));
1355 return (checkPrematureTimeoutInternal(transid));
1360Connection::checkPrematureTimeoutInternal(
const uint64_t transid) {
1366 if (!isTransactionOngoing() || (transid != current_transid_)) {
1368 .arg(isTransactionOngoing())
1370 .arg(current_transid_);
1378Connection::terminate(
const boost::system::error_code& ec,
1379 const std::string& parsing_error) {
1381 std::lock_guard<std::mutex> lk(mutex_);
1382 terminateInternal(ec, parsing_error);
1384 terminateInternal(ec, parsing_error);
1389Connection::terminateInternal(
const boost::system::error_code& ec,
1390 const std::string& parsing_error) {
1392 if (isTransactionOngoing()) {
1396 tcp_socket_->cancel();
1399 tls_socket_->cancel();
1402 if (!ec && current_response_->isFinalized()) {
1403 response = current_response_;
1407 .arg(url_.toText());
1413 parser_->getBufferAsString(MAX_LOGGED_MESSAGE_SIZE) :
1414 "[HttpResponseParser is null]");
1417 std::string err = parsing_error.empty() ? ec.message() :
1427 if (!parsing_error.empty()) {
1432 parser_->getBufferAsString(MAX_LOGGED_MESSAGE_SIZE) :
1433 "[HttpResponseParser is null]");
1442 current_callback_(ec, response, parsing_error);
1444 current_callback_(ec, response, parsing_error);
1452 (!current_request_->isPersistent() ||
1453 (ec == boost::asio::error::timed_out))) {
1462 ConnectionPoolPtr conn_pool = conn_pool_.lock();
1464 conn_pool->postProcessNextRequest(url_, tls_context_);
1469Connection::scheduleTimer(
const long request_timeout) {
1470 if (request_timeout > 0) {
1471 timer_->setup(std::bind(&Connection::timerCallback,
this), request_timeout,
1477Connection::doHandshake(
const uint64_t transid) {
1479 if (!need_handshake_) {
1484 SocketCallback socket_cb(std::bind(&Connection::handshakeCallback,
1486 handshake_callback_,
1490 tls_socket_->handshake(socket_cb);
1493 terminate(boost::asio::error::not_connected);
1498Connection::doSend(
const uint64_t transid) {
1499 SocketCallback socket_cb(std::bind(&Connection::sendCallback,
1506 tcp_socket_->asyncSend(&buf_[0], buf_.size(), socket_cb);
1511 tls_socket_->asyncSend(&buf_[0], buf_.size(), socket_cb);
1516 std::cerr <<
"internal error: can't find a socket to send to\n";
1518 "internal error: can't find a socket to send to");
1520 terminate(boost::asio::error::not_connected);
1525Connection::doReceive(
const uint64_t transid) {
1527 SocketCallback socket_cb(std::bind(&Connection::receiveCallback,
1534 tcp_socket_->asyncReceive(
static_cast<void*
>(input_buf_.data()),
1535 input_buf_.size(), 0,
1536 &endpoint, socket_cb);
1540 tls_socket_->asyncReceive(
static_cast<void*
>(input_buf_.data()),
1541 input_buf_.size(), 0,
1542 &endpoint, socket_cb);
1546 std::cerr <<
"internal error: can't find a socket to receive from\n";
1548 "internal error: can't find a socket to receive from");
1551 terminate(boost::asio::error::not_connected);
1557 const uint64_t transid,
1558 const boost::system::error_code& ec) {
1559 if (checkPrematureTimeout(transid)) {
1564 if (connect_callback) {
1568 if (!connect_callback(ec, tcp_socket_->getNative())) {
1571 }
else if (tls_socket_) {
1572 if (!connect_callback(ec, tls_socket_->getNative())) {
1577 std::cerr <<
"internal error: can't find a socket to connect\n";
1581 if (ec && (ec.value() == boost::asio::error::operation_aborted)) {
1589 (ec.value() != boost::asio::error::in_progress) &&
1590 (ec.value() != boost::asio::error::already_connected)) {
1595 doHandshake(transid);
1601 const uint64_t transid,
1602 const boost::system::error_code& ec) {
1603 need_handshake_ =
false;
1604 if (checkPrematureTimeout(transid)) {
1609 if (handshake_callback) {
1613 if (!handshake_callback(ec, tls_socket_->getNative())) {
1618 std::cerr <<
"internal error: can't find TLS socket\n";
1622 if (ec && (ec.value() == boost::asio::error::operation_aborted)) {
1634Connection::sendCallback(
const uint64_t transid,
1635 const boost::system::error_code& ec,
1637 if (checkPrematureTimeout(transid)) {
1642 if (ec.value() == boost::asio::error::operation_aborted) {
1647 }
else if ((ec.value() == boost::asio::error::would_block) ||
1648 (ec.value() == boost::asio::error::try_again)) {
1659 scheduleTimer(timer_->getInterval());
1664 buf_.erase(0, length);
1678Connection::receiveCallback(
const uint64_t transid,
1679 const boost::system::error_code& ec,
1681 if (checkPrematureTimeout(transid)) {
1686 if (ec.value() == boost::asio::error::operation_aborted) {
1692 if ((ec.value() != boost::asio::error::try_again) &&
1693 (ec.value() != boost::asio::error::would_block)) {
1705 scheduleTimer(timer_->getInterval());
1707 if (runParser(ec, length)) {
1713Connection::runParser(
const boost::system::error_code& ec,
size_t length) {
1715 std::lock_guard<std::mutex> lk(mutex_);
1716 return (runParserInternal(ec, length));
1718 return (runParserInternal(ec, length));
1723Connection::runParserInternal(
const boost::system::error_code& ec,
1727 parser_->postBuffer(
static_cast<void*
>(input_buf_.data()), length);
1732 if (parser_->needData()) {
1735 }
else if (parser_->httpParseOk()) {
1739 current_response_->finalize();
1740 terminateInternal(ec);
1742 }
catch (
const std::exception& ex) {
1744 terminateInternal(ec, ex.what());
1750 terminateInternal(ec, parser_->getErrorMessage());
1757Connection::timerCallback() {
1759 terminate(boost::asio::error::timed_out);
1794 bool defer_thread_start =
false)
1795 : thread_pool_size_(thread_pool_size), thread_pool_() {
1796 if (thread_pool_size_ > 0) {
1798 thread_io_service_.reset(
new IOService());
1802 conn_pool_.reset(
new ConnectionPool(thread_io_service_, thread_pool_size_));
1806 defer_thread_start));
1809 .arg(thread_pool_size_);
1813 conn_pool_.reset(
new ConnectionPool(io_service, 1));
1831 thread_pool_->checkPausePermissions();
1838 thread_pool_->run();
1850 thread_pool_->stop();
1859 if (!thread_pool_) {
1864 thread_pool_->pause();
1872 if (!thread_pool_) {
1877 thread_pool_->run();
1886 return (thread_pool_->isRunning());
1898 return (thread_pool_->isStopped());
1910 return (thread_pool_->isPaused());
1921 return (thread_io_service_);
1928 return (thread_pool_size_);
1935 if (!thread_pool_) {
1938 return (thread_pool_->getThreadCount());
1947 size_t thread_pool_size_;
1958 size_t thread_pool_size,
bool defer_thread_start) {
1959 if (!multi_threading_enabled && thread_pool_size) {
1961 "HttpClient thread_pool_size must be zero "
1962 "when Kea core multi-threading is disabled");
1966 defer_thread_start));
1998 if (!request_callback) {
2002 impl_->conn_pool_->queueRequest(url, tls_context, request, response,
2004 request_callback, connect_callback,
2005 handshake_callback, close_callback);
2010 return (impl_->conn_pool_->closeIfOutOfBand(socket_fd));
2020 impl_->checkPermissions();
2040 return (impl_->getThreadIOService());
2045 return (impl_->getThreadPoolSize());
2050 return (impl_->getThreadCount());
2055 return (impl_->isRunning());
2060 return (impl_->isStopped());
2065 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.
std::function< void(const boost::system::error_code &, const HttpResponsePtr &, const std::string &)> RequestHandler
Callback type used in call to HttpClient::asyncSendRequest.
void stop()
Halts client-side IO activity.
bool isPaused()
Indicates if the thread pool is paused.
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)> ConnectHandler
Optional handler invoked when client connects to the server.
uint16_t getThreadPoolSize() const
Fetches the maximum size of the thread pool.
std::function< bool(const boost::system::error_code &, const int)> HandshakeHandler
Optional handler invoked when client performs the TLS handshake with the server.
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.
Scheme getScheme() const
Returns parsed scheme.
bool isValid() const
Checks if the URL is valid.
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.
long value_
Timeout value specified.