Kea: isc::http::HttpClient Class Reference

| Kea 3.2.0-git

isc::http::HttpClient Class Reference

HTTP client class. More...

`#include <client.h>`

## Classes
struct | RequestTimeout
| HTTP request/response timeout value. More...

## Public Types
typedef std::function< void(const int)> | CloseHandler
| Optional handler invoked when client closes the connection to the server.
typedef std::function< bool(const boost::system::error_code &, const int)> | ConnectHandler
| Optional handler invoked when client connects to the server.
typedef std::function< bool(const boost::system::error_code &, const int)> | HandshakeHandler
| Optional handler invoked when client performs the TLS handshake with the server.
typedef std::function< void(const boost::system::error_code &, const HttpResponsePtr &, const std::string &)> | RequestHandler
| Callback type used in call to HttpClient::asyncSendRequest.

## Public Member Functions
| HttpClient (const asiolink::IOServicePtr &io_service, bool multi_threading_enabled, size_t thread_pool_size=0, bool defer_thread_start=false)
| Constructor.
| ~HttpClient ()
| Destructor.
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.
void | checkPermissions ()
| Check if the current thread can perform thread pool state transition.
void | closeIfOutOfBand (int socket_fd)
| Closes a connection if it has an out-of-band socket event.
uint16_t | getThreadCount () const
| Fetches the number of threads in the pool.
const asiolink::IOServicePtr | getThreadIOService () const
| Fetches a pointer to the internal IOService used to drive the thread-pool in multi-threaded mode.
uint16_t | getThreadPoolSize () const
| Fetches the maximum size of the thread pool.
bool | isPaused ()
| Indicates if the thread pool is paused.
bool | isRunning ()
| Indicates if the thread pool is running.
bool | isStopped ()
| Indicates if the thread pool is stopped.
void | pause ()
| Pauses the client's thread pool.
void | resume ()
| Resumes running the client's thread pool.
void | start ()
| Starts running the client's thread pool, if multi-threaded.
void | stop ()
| Halts client-side IO activity.

## Detailed Description

HTTP client class.

This class implements an asynchronous HTTP client. The caller can schedule transmission of the HTTP request using HttpClient::asyncSendRequest method. The caller specifies target URL for each request. The caller also specifies a pointer to the HttpRequest or derived class, holding a request that should be transmitted to the destination. Such request must be finalized, i.e. HttpRequest::finalize method must be called prior to sending it. The caller must also provide a pointer to the HttpResponse object or an object derived from it. The type of the response object must match the expected content type to be returned in the server's response. The last argument specified in this call is the pointer to the callback function, which should be launched when the response is received, an error occurs or when a timeout in the transmission is signaled.

The HTTP client supports multiple simultaneous and persistent connections with different destinations. The client determines if the connection is persistent by looking into the Connection header and HTTP version of the request. If the connection should be persistent the client doesn't close the connection after sending a request and receiving a response from the server. If the client is provided with the request to be sent to the particular destination, but there is an ongoing communication with this destination, e.g. as a result of sending previous request, the new request is queued in the FIFO queue. When the previous request completes, the next request in the queue for the particular URL will be initiated.

Furthermore, the class supports two modes of operation: single-threaded and multi-threaded mode. In single-threaded mode, all IO is driven by an external IOService passed into the class constructor, and ultimately only a single connection per URL can be open at any given time.

In multi-threaded mode an internal thread pool driven by a private IOService instance is used to support multiple concurrent connections per URL. Currently, the number of connections per URL is set to the number of threads in the thread pool.

The client tests the persistent connection for usability before sending a request by trying to read from the socket (with message peeking). If the socket is usable the client uses it to transmit the request.

This classes exposes the underlying transport socket's descriptor for each connection via connect, handshake and close callbacks. This is done to permit the sockets to be monitored for IO readiness by external code that's something other than boost::asio (e.g. select() or poll()), and would thus otherwise starve the client's IOService and cause a backlog of ready event handlers.

All errors are reported to the caller via the callback function supplied to the HttpClient::asyncSendRequest. The IO errors are communicated via the `boost::system::error` code value. The response parsing errors are returned via the 3rd parameter of the callback.

Definition at line 86 of file lib/http/client.h.

## Member Typedef Documentation

## ◆ CloseHandler

typedef std::function<void(const int)> isc::http::HttpClient::CloseHandler

Optional handler invoked when client closes the connection to the server.

It is passed the native socket handler of the connection's TCP socket.

Definition at line 132 of file lib/http/client.h.

## ◆ ConnectHandler

typedef std::function<bool(const boost::system::error_code&, const int)> isc::http::HttpClient::ConnectHandler

Optional handler invoked when client connects to the server.

Returned boolean value indicates whether the client should continue connecting to the server (if true) or not (false). It is passed the IO error code along with the native socket handle of the connection's TCP socket. The passed socket descriptor may be used to monitor the readiness of the events via select() or poll().

Note
  Beware that the IO error code can be set to "in progress" so a not null error code does not always mean the connect failed.

Definition at line 114 of file lib/http/client.h.

## ◆ HandshakeHandler

typedef std::function<bool(const boost::system::error_code&, const int)> isc::http::HttpClient::HandshakeHandler

Optional handler invoked when client performs the TLS handshake with the server.

It is called when the TLS handshake completes:

- if the handshake succeeds it is called with error code 0
- if the handshake fails it is called with error code != 0
- if TLS is not enabled, it is not called at all

Returned boolean value indicates whether the client should continue connecting to the server (if true) or not (false).

Note
  The second argument is not used.

Definition at line 127 of file lib/http/client.h.

## ◆ RequestHandler

typedef std::function<void(const boost::system::error_code&, const HttpResponsePtr&, const std::string&)> isc::http::HttpClient::RequestHandler

Callback type used in call to HttpClient::asyncSendRequest.

Definition at line 102 of file lib/http/client.h.

## Constructor & Destructor Documentation

## ◆ HttpClient()

isc::http::HttpClient::HttpClient | ( | const asiolink::IOServicePtr & | io_service,
|  | bool | multi_threading_enabled,
|  | size_t | thread_pool_size = 0,
|  | bool | defer_thread_start = false )
| explicit

Constructor.

Parameters

  io_service | IO service to be used by the HTTP client.
  multi_threading_enabled | The flag which indicates if MT is enabled.
  thread_pool_size | maximum number of threads in the thread pool. A value greater than zero enables multi-threaded mode and sets the maximum number of concurrent connections per URL. A value of zero (default) enables single-threaded mode with one connection per URL.
  defer_thread_start | When true, starting of the pool threads is deferred until a subsequent call to start(). In this case the pool's operational state after construction is STOPPED. Otherwise, the thread pool threads will be created and started, with the operational state being RUNNING. Applicable only when thread-pool size is greater than zero.

Definition at line 1958 of file client.cc.

References isc_throw.

## ◆ ~HttpClient()

isc::http::HttpClient::~HttpClient | ( |  | ) |

Destructor.

Definition at line 1970 of file client.cc.

## Member Function Documentation

## ◆ asyncSendRequest()

void isc::http::HttpClient::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.

The client maintains an internal connection pool which manages lists of connections per URL. In single-threaded mode, each URL is limited to a single connection. In multi-threaded mode, each URL may have more than one open connection per URL, enabling the client to carry on multiple concurrent requests per URL.

The client will search the pool for an open, idle connection for the given URL. If there are no idle connections, the client will open a new connection up to the maximum number of connections allowed by the thread mode. If all possible connections are busy, the request is pushed on to back of a URL-specific FIFO queue of pending requests.

If however, there is an idle connection available than a new transaction for the request will be initiated immediately upon that connection.

Note that when a connection completes a transaction, and its URL queue is not empty, it will pop a pending request from the front of the queue and begin a new transaction for that request. The net effect is that requests are always pulled from the front of the queue unless the queue is empty.

The existing connection is tested before it is used for the new transaction by attempting to read (with message peeking) from the open transport socket. If the read attempt is successful, the client will transmit the HTTP request to the server using this connection. It is possible that the server closes the connection between the connection test and sending the request. In such case, an error will be returned and the caller will need to try re-sending the request.

If the connection test fails, the client will close the socket and reconnect to the server prior to sending the request.

Pointers to the request and response objects are provided as arguments of this method. These pointers should have appropriate types derived from the HttpRequest and HttpResponse classes. For example, if the request has content type "application/json", a pointer to the HttpResponseJson should be passed. In this case, the response type should be HttpResponseJson. These types are used to validate both the request provided by the caller and the response received from the server.

The callback function provided by the caller is invoked when the transaction terminates, i.e. when the server has responded or when an error occurred. The callback is expected to be exception safe, but the client internally guards against exceptions thrown by the callback.

The first argument of the callback indicates an IO error during communication with the server. If the communication is successful the error code of 0 is returned. However, in this case it is still possible that the transaction is unsuccessful due to HTTP response parsing error, e.g. invalid content type, malformed response etc. Such errors are indicated via third argument.

If message parsing was successful the second argument of the callback contains a pointer to the parsed response (the same pointer as provided by the caller as the argument). If parsing was unsuccessful, the null pointer is returned.

The default timeout for the transaction is set to 10 seconds (10 000 ms). If the timeout occurs, the callback is invoked with the error code of `boost::asio::error::timed_out`. The timeout covers both the connect and the transaction phases so when connecting to the server takes too long (e.g. with a misconfigured firewall) the timeout is triggered. The connect callback can be used to recognize this condition.

Parameters

  url | URL where the request should be send.
  tls_context | TLS context.
  request | Pointer to the object holding a request.
  response | Pointer to the object where response should be stored.
  request_callback | Pointer to the user callback function invoked when transaction ends.
  request_timeout | Timeout for the transaction in milliseconds.
  connect_callback | Optional callback invoked when the client connects to the server.
  handshake_callback | Optional callback invoked when the client performs the TLS handshake with the server.
  close_callback | Optional callback invoked when the client closes the connection to the server.

Exceptions

  HttpClientError | If invalid arguments were provided.

Definition at line 1975 of file client.cc.

References isc::http::Url::getScheme(), isc::http::Url::HTTPS, isc_throw, isc::http::Url::isValid(), and isc::http::HttpClient::RequestTimeout::value_.

Referenced by isc::ha::HAService::asyncDisableDHCPService(), isc::ha::HAService::asyncEnableDHCPService(), isc::ha::HAService::asyncSendHAReset(), isc::ha::HAService::asyncSendLeaseUpdatesFromBacklog(), isc::ha::HAService::asyncSyncCompleteNotify(), isc::ha::HAService::asyncSyncLeasesInternal(), isc::ha::HAService::processMaintenanceCancel(), and isc::ha::HAService::processMaintenanceStart().

Here is the call graph for this function:

## ◆ checkPermissions()

void isc::http::HttpClient::checkPermissions | ( |  | ) |

Check if the current thread can perform thread pool state transition.

Exceptions

  MultiThreadingInvalidOperation | if the state transition is done on any of the worker threads.

Definition at line 2021 of file client.cc.

## ◆ closeIfOutOfBand()

void isc::http::HttpClient::closeIfOutOfBand | ( | int | socket_fd | ) |

Closes a connection if it has an out-of-band socket event.

If the client owns a connection using the given socket and that connection is currently in a transaction the method returns as this indicates a normal ready event. If the connection is not in an ongoing transaction, then the connection is closed.

This is method is intended to be used to detect and clean up then sockets that are marked ready outside of transactions. The most common case is the other end of the socket being closed.

Parameters

  socket_fd | socket descriptor to check

Definition at line 2011 of file client.cc.

## ◆ getThreadCount()

uint16_t isc::http::HttpClient::getThreadCount | ( |  | ) | const

Fetches the number of threads in the pool.

Returns
  the number of running threads.

Definition at line 2051 of file client.cc.

## ◆ getThreadIOService()

const IOServicePtr isc::http::HttpClient::getThreadIOService | ( |  | ) | const

Fetches a pointer to the internal IOService used to drive the thread-pool in multi-threaded mode.

Returns
  pointer to the IOService instance, or an empty pointer in single-threaded mode.

Definition at line 2041 of file client.cc.

## ◆ getThreadPoolSize()

uint16_t isc::http::HttpClient::getThreadPoolSize | ( |  | ) | const

Fetches the maximum size of the thread pool.

Returns
  the maximum size of the thread pool.

Definition at line 2046 of file client.cc.

## ◆ isPaused()

bool isc::http::HttpClient::isPaused | ( |  | ) |

Indicates if the thread pool is paused.

Returns
  True if the thread pool exists and it is in the PAUSED state, false otherwise.

Definition at line 2066 of file client.cc.

## ◆ isRunning()

bool isc::http::HttpClient::isRunning | ( |  | ) |

Indicates if the thread pool is running.

Returns
  True if the thread pool exists and it is in the RUNNING state, false otherwise.

Definition at line 2056 of file client.cc.

## ◆ isStopped()

bool isc::http::HttpClient::isStopped | ( |  | ) |

Indicates if the thread pool is stopped.

Returns
  True if the thread pool exists and it is in the STOPPED state, false otherwise.

Definition at line 2061 of file client.cc.

## ◆ pause()

void isc::http::HttpClient::pause | ( |  | ) |

Pauses the client's thread pool.

Suspends thread pool event processing.

Exceptions

  InvalidOperation | if the thread pool does not exist.

Definition at line 2026 of file client.cc.

## ◆ resume()

void isc::http::HttpClient::resume | ( |  | ) |

Resumes running the client's thread pool.

Resumes thread pool event processing.

Exceptions

  InvalidOperation | if the thread pool does not exist.

Definition at line 2031 of file client.cc.

## ◆ start()

void isc::http::HttpClient::start | ( |  | ) |

Starts running the client's thread pool, if multi-threaded.

Definition at line 2016 of file client.cc.

## ◆ stop()

void isc::http::HttpClient::stop | ( |  | ) |

Halts client-side IO activity.

Closes all connections, discards any queued requests, and in multi-threaded mode discards the thread-pool and the internal IOService.

Definition at line 2036 of file client.cc.

Referenced by isc::ha::HAService::sendHAReset(), isc::ha::HAService::sendLeaseUpdatesFromBacklog(), and isc::ha::HAService::synchronize().

The documentation for this class was generated from the following files:

- lib/http/client.h
- client.cc