changeset 21036:1baf5ee5bbb4

lib-http: client: Cleaned up headers and added some more documentation there.
author Stephan Bosch <stephan@dovecot.fi>
date Sat, 16 Apr 2016 02:03:10 +0200
parents 1590d1ff0551
children 33fd15859036
files src/lib-http/http-client-private.h src/lib-http/http-client.h
diffstat 2 files changed, 307 insertions(+), 171 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-http/http-client-private.h	Thu Sep 15 02:09:47 2016 +0200
+++ b/src/lib-http/http-client-private.h	Sat Apr 16 02:03:10 2016 +0200
@@ -6,6 +6,10 @@
 #include "http-url.h"
 #include "http-client.h"
 
+/*
+ * Defaults
+ */
+
 #define HTTP_DEFAULT_PORT 80
 #define HTTPS_DEFAULT_PORT 443
 
@@ -15,6 +19,10 @@
 #define HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS (100)
 #define HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS (1000*60)
 
+/*
+ * Types
+ */
+
 enum http_response_payload_type;
 
 struct http_client_host;
@@ -55,6 +63,10 @@
 	} a;
 };
 
+/*
+ * Objects
+ */
+
 struct http_client_request {
 	pool_t pool;
 	unsigned int refcount;
@@ -278,144 +290,9 @@
 	unsigned int requests_count;
 };
 
-int http_client_init_ssl_ctx(struct http_client *client, const char **error_r);
-
-void http_client_request_ref(struct http_client_request *req);
-/* Returns FALSE if unrefing destroyed the request entirely */
-bool http_client_request_unref(struct http_client_request **_req);
-void http_client_request_destroy(struct http_client_request **_req);
-
-int http_client_request_delay_from_response(struct http_client_request *req,
-	const struct http_response *response);
-void http_client_request_get_peer_addr(const struct http_client_request *req,
-	struct http_client_peer_addr *addr);
-enum http_response_payload_type
-http_client_request_get_payload_type(struct http_client_request *req);
-int http_client_request_send(struct http_client_request *req,
-			    bool pipelined, const char **error_r);
-int http_client_request_send_more(struct http_client_request *req,
-				  bool pipelined, const char **error_r);
-bool http_client_request_callback(struct http_client_request *req,
-	struct http_response *response);
-void http_client_request_connect_callback(struct http_client_request *req,
-			     const struct http_client_tunnel *tunnel,
-			     struct http_response *response);
-void http_client_request_resubmit(struct http_client_request *req);
-void http_client_request_retry(struct http_client_request *req,
-	unsigned int status, const char *error);
-void http_client_request_error_delayed(struct http_client_request **_req);
-void http_client_request_error(struct http_client_request **req,
-	unsigned int status, const char *error);
-void http_client_request_redirect(struct http_client_request *req,
-	unsigned int status, const char *location);
-void http_client_request_finish(struct http_client_request *req);
-
-struct connection_list *http_client_connection_list_init(void);
-
-struct http_client_connection *
-	http_client_connection_create(struct http_client_peer *peer);
-void http_client_connection_ref(struct http_client_connection *conn);
-/* Returns FALSE if unrefing destroyed the connection entirely */
-bool http_client_connection_unref(struct http_client_connection **_conn);
-void http_client_connection_close(struct http_client_connection **_conn);
-
-void http_client_connection_peer_closed(struct http_client_connection **_conn);
-
-int http_client_connection_output(struct http_client_connection *conn);
-void http_client_connection_start_request_timeout(
-	struct http_client_connection *conn);
-void http_client_connection_reset_request_timeout(
-	struct http_client_connection *conn);
-void http_client_connection_stop_request_timeout(
-	struct http_client_connection *conn);
-unsigned int
-http_client_connection_count_pending(struct http_client_connection *conn);
-int http_client_connection_check_ready(struct http_client_connection *conn);
-bool http_client_connection_is_idle(struct http_client_connection *conn);
-bool http_client_connection_is_active(struct http_client_connection *conn);
-int http_client_connection_next_request(struct http_client_connection *conn);
-void http_client_connection_check_idle(struct http_client_connection *conn);
-void http_client_connection_switch_ioloop(struct http_client_connection *conn);
-void http_client_connection_start_tunnel(struct http_client_connection **_conn,
-	struct http_client_tunnel *tunnel);
-
-
-unsigned int http_client_peer_addr_hash
-	(const struct http_client_peer_addr *peer) ATTR_PURE;
-int http_client_peer_addr_cmp
-	(const struct http_client_peer_addr *peer1,
-		const struct http_client_peer_addr *peer2) ATTR_PURE;
-
-struct http_client_peer *
-	http_client_peer_get(struct http_client *client,
-		const struct http_client_peer_addr *addr);
-void http_client_peer_ref(struct http_client_peer *peer);
-bool http_client_peer_unref(struct http_client_peer **_peer);
-void http_client_peer_close(struct http_client_peer **_peer);
-
-bool http_client_peer_have_queue(struct http_client_peer *peer,
-				struct http_client_queue *queue);
-void http_client_peer_link_queue(struct http_client_peer *peer,
-	struct http_client_queue *queue);
-void http_client_peer_unlink_queue(struct http_client_peer *peer,
-				struct http_client_queue *queue);
-struct http_client_request *
-	http_client_peer_claim_request(struct http_client_peer *peer,
-		bool no_urgent);
-void http_client_peer_trigger_request_handler(struct http_client_peer *peer);
-void http_client_peer_connection_success(struct http_client_peer *peer);
-void http_client_peer_connection_failure(struct http_client_peer *peer,
-					 const char *reason);
-void http_client_peer_connection_lost(struct http_client_peer *peer);
-bool http_client_peer_is_connected(struct http_client_peer *peer);
-unsigned int
-http_client_peer_idle_connections(struct http_client_peer *peer);
-unsigned int
-http_client_peer_active_connections(struct http_client_peer *peer);
-unsigned int
-http_client_peer_pending_connections(struct http_client_peer *peer);
-void http_client_peer_switch_ioloop(struct http_client_peer *peer);
-
-struct http_client_queue *
-http_client_queue_create(struct http_client_host *host,
-	const struct http_client_peer_addr *addr);
-void http_client_queue_free(struct http_client_queue *queue);
-void http_client_queue_fail(struct http_client_queue *queue,
-	unsigned int status, const char *error);
-void http_client_queue_connection_setup(struct http_client_queue *queue);
-void http_client_queue_submit_request(struct http_client_queue *queue,
-	struct http_client_request *req);
-void
-http_client_queue_drop_request(struct http_client_queue *queue,
-	struct http_client_request *req);
-struct http_client_request *
-http_client_queue_claim_request(struct http_client_queue *queue,
-	const struct http_client_peer_addr *addr, bool no_urgent);
-unsigned int
-http_client_queue_requests_pending(struct http_client_queue *queue,
-	unsigned int *num_urgent_r) ATTR_NULL(2);
-void
-http_client_queue_connection_success(struct http_client_queue *queue,
-					 const struct http_client_peer_addr *addr);
-void http_client_queue_connection_failure(struct http_client_queue *queue,
- 	const struct http_client_peer_addr *addr, const char *reason);
-void http_client_queue_peer_disconnected(struct http_client_queue *queue,
-	struct http_client_peer *peer);
-void http_client_queue_switch_ioloop(struct http_client_queue *queue);
-
-struct http_client_host *
-http_client_host_get(struct http_client *client,
-	const struct http_url *host_url);
-void http_client_host_free(struct http_client_host **_host);
-void http_client_host_submit_request(struct http_client_host *host,
-	struct http_client_request *req);
-void http_client_host_switch_ioloop(struct http_client_host *host);
-
-void http_client_delay_request_error(struct http_client *client,
-	struct http_client_request *req);
-void http_client_remove_request_error(struct http_client *client,
-	struct http_client_request *req);
-
+/*
+ * Peer address
+ */
 
 static inline bool
 http_client_peer_addr_is_https(const struct http_client_peer_addr *addr)
@@ -466,6 +343,10 @@
 	return "";
 }
 
+/*
+ * Request
+ */
+
 static inline const char *
 http_client_request_label(struct http_client_request *req)
 {
@@ -482,6 +363,40 @@
 	return (req->host_url != &req->origin_url);
 }
 
+void http_client_request_ref(struct http_client_request *req);
+/* Returns FALSE if unrefing destroyed the request entirely */
+bool http_client_request_unref(struct http_client_request **_req);
+void http_client_request_destroy(struct http_client_request **_req);
+
+int http_client_request_delay_from_response(struct http_client_request *req,
+	const struct http_response *response);
+void http_client_request_get_peer_addr(const struct http_client_request *req,
+	struct http_client_peer_addr *addr);
+enum http_response_payload_type
+http_client_request_get_payload_type(struct http_client_request *req);
+int http_client_request_send(struct http_client_request *req,
+			    bool pipelined, const char **error_r);
+int http_client_request_send_more(struct http_client_request *req,
+				  bool pipelined, const char **error_r);
+bool http_client_request_callback(struct http_client_request *req,
+	struct http_response *response);
+void http_client_request_connect_callback(struct http_client_request *req,
+			     const struct http_client_tunnel *tunnel,
+			     struct http_response *response);
+void http_client_request_resubmit(struct http_client_request *req);
+void http_client_request_retry(struct http_client_request *req,
+	unsigned int status, const char *error);
+void http_client_request_error_delayed(struct http_client_request **_req);
+void http_client_request_error(struct http_client_request **req,
+	unsigned int status, const char *error);
+void http_client_request_redirect(struct http_client_request *req,
+	unsigned int status, const char *location);
+void http_client_request_finish(struct http_client_request *req);
+
+/*
+ * Connection
+ */
+
 static inline const char *
 http_client_connection_label(struct http_client_connection *conn)
 {
@@ -491,6 +406,39 @@
 			" (tunnel)" : ""), conn->id);
 }
 
+struct connection_list *http_client_connection_list_init(void);
+
+struct http_client_connection *
+	http_client_connection_create(struct http_client_peer *peer);
+void http_client_connection_ref(struct http_client_connection *conn);
+/* Returns FALSE if unrefing destroyed the connection entirely */
+bool http_client_connection_unref(struct http_client_connection **_conn);
+void http_client_connection_close(struct http_client_connection **_conn);
+
+void http_client_connection_peer_closed(struct http_client_connection **_conn);
+
+int http_client_connection_output(struct http_client_connection *conn);
+void http_client_connection_start_request_timeout(
+	struct http_client_connection *conn);
+void http_client_connection_reset_request_timeout(
+	struct http_client_connection *conn);
+void http_client_connection_stop_request_timeout(
+	struct http_client_connection *conn);
+unsigned int
+http_client_connection_count_pending(struct http_client_connection *conn);
+int http_client_connection_check_ready(struct http_client_connection *conn);
+bool http_client_connection_is_idle(struct http_client_connection *conn);
+bool http_client_connection_is_active(struct http_client_connection *conn);
+int http_client_connection_next_request(struct http_client_connection *conn);
+void http_client_connection_check_idle(struct http_client_connection *conn);
+void http_client_connection_switch_ioloop(struct http_client_connection *conn);
+void http_client_connection_start_tunnel(struct http_client_connection **_conn,
+	struct http_client_tunnel *tunnel);
+
+/*
+ * Peer
+ */
+
 static inline const char *
 http_client_peer_label(struct http_client_peer *peer)
 {
@@ -501,6 +449,77 @@
 	return http_client_peer_addr2str(&peer->addr);
 }
 
+unsigned int http_client_peer_addr_hash
+	(const struct http_client_peer_addr *peer) ATTR_PURE;
+int http_client_peer_addr_cmp
+	(const struct http_client_peer_addr *peer1,
+		const struct http_client_peer_addr *peer2) ATTR_PURE;
+
+struct http_client_peer *
+	http_client_peer_get(struct http_client *client,
+		const struct http_client_peer_addr *addr);
+void http_client_peer_ref(struct http_client_peer *peer);
+bool http_client_peer_unref(struct http_client_peer **_peer);
+void http_client_peer_close(struct http_client_peer **_peer);
+
+bool http_client_peer_have_queue(struct http_client_peer *peer,
+				struct http_client_queue *queue);
+void http_client_peer_link_queue(struct http_client_peer *peer,
+	struct http_client_queue *queue);
+void http_client_peer_unlink_queue(struct http_client_peer *peer,
+				struct http_client_queue *queue);
+struct http_client_request *
+	http_client_peer_claim_request(struct http_client_peer *peer,
+		bool no_urgent);
+void http_client_peer_trigger_request_handler(struct http_client_peer *peer);
+void http_client_peer_connection_success(struct http_client_peer *peer);
+void http_client_peer_connection_failure(struct http_client_peer *peer,
+					 const char *reason);
+void http_client_peer_connection_lost(struct http_client_peer *peer);
+bool http_client_peer_is_connected(struct http_client_peer *peer);
+unsigned int
+http_client_peer_idle_connections(struct http_client_peer *peer);
+unsigned int
+http_client_peer_active_connections(struct http_client_peer *peer);
+unsigned int
+http_client_peer_pending_connections(struct http_client_peer *peer);
+void http_client_peer_switch_ioloop(struct http_client_peer *peer);
+
+/*
+ * Queue
+ */
+
+struct http_client_queue *
+http_client_queue_create(struct http_client_host *host,
+	const struct http_client_peer_addr *addr);
+void http_client_queue_free(struct http_client_queue *queue);
+void http_client_queue_fail(struct http_client_queue *queue,
+	unsigned int status, const char *error);
+void http_client_queue_connection_setup(struct http_client_queue *queue);
+void http_client_queue_submit_request(struct http_client_queue *queue,
+	struct http_client_request *req);
+void
+http_client_queue_drop_request(struct http_client_queue *queue,
+	struct http_client_request *req);
+struct http_client_request *
+http_client_queue_claim_request(struct http_client_queue *queue,
+	const struct http_client_peer_addr *addr, bool no_urgent);
+unsigned int
+http_client_queue_requests_pending(struct http_client_queue *queue,
+	unsigned int *num_urgent_r) ATTR_NULL(2);
+void
+http_client_queue_connection_success(struct http_client_queue *queue,
+					 const struct http_client_peer_addr *addr);
+void http_client_queue_connection_failure(struct http_client_queue *queue,
+ 	const struct http_client_peer_addr *addr, const char *reason);
+void http_client_queue_peer_disconnected(struct http_client_queue *queue,
+	struct http_client_peer *peer);
+void http_client_queue_switch_ioloop(struct http_client_queue *queue);
+
+/*
+ * Host
+ */
+
 static inline unsigned int
 http_client_host_get_ip_idx(struct http_client_host *host,
 			    const struct ip_addr *ip)
@@ -514,5 +533,24 @@
 	i_unreached();
 }
 
+struct http_client_host *
+http_client_host_get(struct http_client *client,
+	const struct http_url *host_url);
+void http_client_host_free(struct http_client_host **_host);
+void http_client_host_submit_request(struct http_client_host *host,
+	struct http_client_request *req);
+void http_client_host_switch_ioloop(struct http_client_host *host);
+
+/*
+ * Client
+ */
+
+int http_client_init_ssl_ctx(struct http_client *client,
+	const char **error_r);
+
+void http_client_delay_request_error(struct http_client *client,
+	struct http_client_request *req);
+void http_client_remove_request_error(struct http_client *client,
+	struct http_client_request *req);
 
 #endif
--- a/src/lib-http/http-client.h	Thu Sep 15 02:09:47 2016 +0200
+++ b/src/lib-http/http-client.h	Sat Apr 16 02:03:10 2016 +0200
@@ -11,28 +11,9 @@
 struct http_client;
 struct http_client_request;
 
-enum http_client_request_error {
-	HTTP_CLIENT_REQUEST_ERROR_ABORTED = 9000,
-	HTTP_CLIENT_REQUEST_ERROR_HOST_LOOKUP_FAILED,
-	HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED,
-	HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
-	HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
-	HTTP_CLIENT_REQUEST_ERROR_BROKEN_PAYLOAD,
-	HTTP_CLIENT_REQUEST_ERROR_BAD_RESPONSE,
-	HTTP_CLIENT_REQUEST_ERROR_TIMED_OUT,
-};
-
-enum http_request_state {
-	HTTP_REQUEST_STATE_NEW = 0,
-	HTTP_REQUEST_STATE_QUEUED,
-	HTTP_REQUEST_STATE_PAYLOAD_OUT,
-	HTTP_REQUEST_STATE_WAITING,
-	HTTP_REQUEST_STATE_GOT_RESPONSE,
-	HTTP_REQUEST_STATE_PAYLOAD_IN,
-	HTTP_REQUEST_STATE_FINISHED,
-	HTTP_REQUEST_STATE_ABORTED
-};
-extern const char *http_request_state_names[];
+/*
+ * Client settings
+ */
 
 struct http_client_settings {
 	/* a) If dns_client is set, all lookups are done via it.
@@ -42,6 +23,7 @@
 	struct dns_client *dns_client;
 	const char *dns_client_socket_path;
 
+	/* ssl configuration */
 	const char *ssl_ca_dir, *ssl_ca_file, *ssl_ca;
 	const char *ssl_crypto_device;
 	bool ssl_allow_invalid_cert;
@@ -59,8 +41,12 @@
 	const char *proxy_username;
 	const char *proxy_password;
 
+	/* directory for writing raw log data for debugging purposes */
 	const char *rawlog_dir;
 
+	/* maximum time a connection will idle. if parallel connections are idle,
+	   the duplicates will end earlier based on how many idle connections exist
+	   to that same service */
 	unsigned int max_idle_time_msecs;
 
 	/* maximum number of parallel connections per peer (default = 1) */
@@ -139,6 +125,55 @@
 	bool debug;
 };
 
+/*
+ * Request
+ */
+
+enum http_client_request_error {
+	/* The request was aborted */
+	HTTP_CLIENT_REQUEST_ERROR_ABORTED = 9000,
+	/* Failed to perform DNS lookup for the host */
+	HTTP_CLIENT_REQUEST_ERROR_HOST_LOOKUP_FAILED,
+	/* Failed to setup any connection for the host and client settings allowed
+	   no more attempts */
+	HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED,
+	/* Service returned an invalid redirect response for this request */
+	HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
+	/* The connection was lost unexpectedly while handling the request and
+	   client settings allowed no more attempts */
+	HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
+	/* The input stream passed to the request using
+	   http_client_request_set_payload() returned an error while sending the
+	   request. */
+	HTTP_CLIENT_REQUEST_ERROR_BROKEN_PAYLOAD,
+	/* The service returned a bad response */
+	HTTP_CLIENT_REQUEST_ERROR_BAD_RESPONSE,
+	/* The request timed out (either this was the last attempt or the
+	   absolute timeout was hit) */
+	HTTP_CLIENT_REQUEST_ERROR_TIMED_OUT,
+};
+
+enum http_request_state {
+	/* New request; not yet submitted */
+	HTTP_REQUEST_STATE_NEW = 0,
+	/* Request is queued; waiting for a connection */
+	HTTP_REQUEST_STATE_QUEUED,
+	/* Request header is sent; still sending request payload to server */
+	HTTP_REQUEST_STATE_PAYLOAD_OUT,
+	/* Request is fully sent; waiting for response */
+	HTTP_REQUEST_STATE_WAITING,
+	/* Response header is received for the request */
+	HTTP_REQUEST_STATE_GOT_RESPONSE,
+	/* Reading response payload; response handler still needs to read more
+	   payload. */
+	HTTP_REQUEST_STATE_PAYLOAD_IN,
+	/* Request is finished; still lingering due to references */
+	HTTP_REQUEST_STATE_FINISHED,
+	/* Request is aborted; still lingering due to references */
+	HTTP_REQUEST_STATE_ABORTED
+};
+extern const char *http_request_state_names[];
+
 struct http_client_tunnel {
 	int fd_in, fd_out;
 	struct istream *input;
@@ -149,9 +184,6 @@
 http_client_request_callback_t(const struct http_response *response,
 			       void *context);
 
-struct http_client *http_client_init(const struct http_client_settings *set);
-void http_client_deinit(struct http_client **_client);
-
 /* create new HTTP request */
 struct http_client_request *
 http_client_request(struct http_client *client,
@@ -163,6 +195,8 @@
 			const struct http_response *response, typeof(context))), \
 		(http_client_request_callback_t *)callback, context)
 
+/* create net HTTP request using provided URL. This implicitly sets
+   port, ssl, and username:password if provided. */
 struct http_client_request *
 http_client_request_url(struct http_client *client,
 		    const char *method, const struct http_url *target_url,
@@ -188,6 +222,9 @@
 		CALLBACK_TYPECHECK(callback, void (*)( \
 			const struct http_response *response, typeof(context))), \
 		(http_client_request_callback_t *)callback, context)
+
+/* same as http_client_request_connect, but uses an IP rather than a host
+   name. */
 struct http_client_request *
 http_client_request_connect_ip(struct http_client *client,
 		    const struct ip_addr *ip, in_port_t port,
@@ -199,25 +236,53 @@
 			const struct http_response *response, typeof(context))), \
 		(http_client_request_callback_t *)callback, context)
 
+/* set the port for the service the request is directed at */
 void http_client_request_set_port(struct http_client_request *req,
 	in_port_t port);
+/* indicate whether service the request is directed at uses ssl */
 void http_client_request_set_ssl(struct http_client_request *req,
 	bool ssl);
+/* set the urgent flag: this means that this request will get priority over
+   non-urgent request. Also, if no idle connection is available, a new
+   connection is created. Urgent requests are never pipelined. */
 void http_client_request_set_urgent(struct http_client_request *req);
 void http_client_request_set_preserve_exact_reason(struct http_client_request *req);
 
+/* add a custom header to the request. This can override headers that are
+   otherwise created implicitly. */
 void http_client_request_add_header(struct http_client_request *req,
 				    const char *key, const char *value);
+/* remove a header added earlier. This has no influence on implicitly created
+   headers. */
 void http_client_request_remove_header(struct http_client_request *req,
 				       const char *key);
+
+/* set the value of the "Date" header for the request using a time_t value.
+   Use this instead of setting it directly using
+   http_client_request_add_header() */
 void http_client_request_set_date(struct http_client_request *req,
 				    time_t date);
 
+/* assign an input stream for the outgoing payload of this request. The input
+   stream is read asynchronously while the request is sent to the server.
+
+   when sync=TRUE a "100 Continue" response is requested from the service. The
+   client will then postpone sending the payload until a provisional response
+   with code 100 is received. This way, an error response can be sent by the
+   service before any potentially big payload is transmitted. Use this only for
+   payload that can be large. */
 void http_client_request_set_payload(struct http_client_request *req,
 				     struct istream *input, bool sync);
+/* assign payload data to the request. The data is copied to the request pool.
+   If your data is already durably allocated during the existence of the
+   request, you should consider using http_client_request_set_payload() with
+   a data input stream instead. This will avoid copying the data unnecessarily.
+ */
 void http_client_request_set_payload_data(struct http_client_request *req,
 				     const unsigned char *data, size_t size);
 
+/* set an absolute timeout for this request specifically, overriding the
+   default client-wide absolute request timeout */
 void http_client_request_set_timeout_msecs(struct http_client_request *req,
 	unsigned int msecs);
 void http_client_request_set_timeout(struct http_client_request *req,
@@ -230,9 +295,17 @@
 void http_client_request_set_max_attempts(struct http_client_request *req,
 	unsigned int max_attempts);
 
+/* set the username:password credentials for this request for simple
+   authentication. This function is meant for simple schemes that use a
+   password. More complex schemes will need to be handled manually.
+
+   This currently only supports the "basic" authentication scheme. */
 void http_client_request_set_auth_simple(struct http_client_request *req,
 	const char *username, const char *password);
 
+/* delay handling of this request to a later time. This way, a request can be
+   submitted that is held for some time until a certain time period has passed.
+ */
 void http_client_request_delay_until(struct http_client_request *req,
 	time_t time);
 void http_client_request_delay(struct http_client_request *req,
@@ -240,39 +313,64 @@
 void http_client_request_delay_msecs(struct http_client_request *req,
 	unsigned int msecs);
 
-const char *http_client_request_get_method(struct http_client_request *req);
-const char *http_client_request_get_target(struct http_client_request *req);
+/* return the HTTP method for the request */
+const char *
+http_client_request_get_method(struct http_client_request *req);
+/* return the HTTP target for the request */
+const char *
+http_client_request_get_target(struct http_client_request *req);
+/* return the request state */
 enum http_request_state
 http_client_request_get_state(struct http_client_request *req);
+
+/* submit the request. It is queued for transmission to the service */
 void http_client_request_submit(struct http_client_request *req);
+
+/* attempt to retry the request. This function is called within the request
+   callback. It returns false if the request cannot be retried */
 bool http_client_request_try_retry(struct http_client_request *req);
 
+/* abort the request immediately. It may still linger for a while when it is
+   already sent to the service, but the callback will not be called anymore. */
 void http_client_request_abort(struct http_client_request **req);
 
-/* Call the specified callback when HTTP request is destroyed. */
+/* call the specified callback when HTTP request is destroyed. */
 void http_client_request_set_destroy_callback(struct http_client_request *req,
 					      void (*callback)(void *),
 					      void *context);
 
-/* submits request and blocks until provided payload is sent. Multiple calls
-   are allowed; payload transmission is ended with
+/* submits request and blocks until the provided payload is sent. Multiple
+   calls are allowed; payload transmission is ended with
    http_client_request_finish_payload(). If the sending fails, returns -1
    and sets req=NULL to indicate that the request was freed, otherwise
    returns 0 and req is unchanged. */
 int http_client_request_send_payload(struct http_client_request **req,
 	const unsigned char *data, size_t size);
-/* Finish sending the payload. Always frees req and sets it to NULL.
+/* finish sending the payload. Always frees req and sets it to NULL.
    Returns 0 on success, -1 on error. */
 int http_client_request_finish_payload(struct http_client_request **req);
 
+/* take over the connection this request was sent over for use as a HTTP
+   CONNECT tunnel. This only applies to requests that were created using
+   http_client_request_connect() or http_client_request_connect_ip(). */
 void http_client_request_start_tunnel(struct http_client_request *req,
 	struct http_client_tunnel *tunnel);
 
+/*
+ * Client
+ */
+
+struct http_client *http_client_init(const struct http_client_settings *set);
+void http_client_deinit(struct http_client **_client);
+
+/* switch this client to the current ioloop */
 void http_client_switch_ioloop(struct http_client *client);
 
 /* blocks until all currently submitted requests are handled */
 void http_client_wait(struct http_client *client);
-/* Returns number of pending HTTP requests. */
-unsigned int http_client_get_pending_request_count(struct http_client *client);
+
+/* Returns the total number of pending HTTP requests. */
+unsigned int
+http_client_get_pending_request_count(struct http_client *client);
 
 #endif