dovecot-2.2: lib-http: Pass connect failures all the way to requ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Apr 4 14:58:05 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/3580439c06d8
changeset: 16153:3580439c06d8
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Apr 04 14:58:00 2013 +0300
description:
lib-http: Pass connect failures all the way to request callback's error string.

diffstat:

 src/lib-http/http-client-connection.c |  30 +++++++++++++++---------------
 src/lib-http/http-client-host.c       |  30 +++++++++++++++---------------
 src/lib-http/http-client-peer.c       |   5 +++--
 src/lib-http/http-client-private.h    |   5 +++--
 4 files changed, 36 insertions(+), 34 deletions(-)

diffs (181 lines):

diff -r 998afe8ffed9 -r 3580439c06d8 src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c	Thu Apr 04 14:55:03 2013 +0300
+++ b/src/lib-http/http-client-connection.c	Thu Apr 04 14:58:00 2013 +0300
@@ -307,7 +307,8 @@
 
 	switch (_conn->disconnect_reason) {
 	case CONNECTION_DISCONNECT_CONNECT_TIMEOUT:
-		http_client_peer_connection_failure(conn->peer);
+		http_client_peer_connection_failure(conn->peer, t_strdup_printf(
+			"connect(%s) failed: Connection timed out", _conn->name));
 		break;
 	case CONNECTION_DISCONNECT_CONN_CLOSED:
 		/* retry pending requests if possible */
@@ -683,15 +684,13 @@
 }
 
 static int 
-http_client_connection_ssl_init(struct http_client_connection *conn)
+http_client_connection_ssl_init(struct http_client_connection *conn,
+				const char **error_r)
 {
 	struct ssl_iostream_settings ssl_set;
 	const char *source, *error;
 
-	if (conn->client->ssl_ctx == NULL) {
-		http_client_connection_error(conn, "No SSL context");
-		return -1;
-	}
+	i_assert(conn->client->ssl_ctx != NULL);
 
 	memset(&ssl_set, 0, sizeof(ssl_set));
 	if (conn->client->set.ssl_verify) {
@@ -708,15 +707,16 @@
 	if (io_stream_create_ssl(conn->client->ssl_ctx, source, &ssl_set,
 				 &conn->conn.input, &conn->conn.output,
 				 &conn->ssl_iostream, &error) < 0) {
-		http_client_connection_error(conn,
-			"Couldn't initialize SSL client: %s", error);
+		*error_r = t_strdup_printf(
+			"Couldn't initialize SSL client for %s: %s",
+			conn->conn.name, error);
 		return -1;
 	}
 	ssl_iostream_set_handshake_callback(conn->ssl_iostream,
 					    http_client_connection_ssl_handshaked, conn);
 	if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
-		http_client_connection_error(conn, "SSL handshake failed: %s",
-			ssl_iostream_get_last_error(conn->ssl_iostream));
+		*error_r = t_strdup_printf("SSL handshake to %s failed: %s",
+			conn->conn.name, ssl_iostream_get_last_error(conn->ssl_iostream));
 		return -1;
 	}
 
@@ -729,16 +729,16 @@
 {
 	struct http_client_connection *conn =
 		(struct http_client_connection *)_conn;
+	const char *error;
 
 	if (!success) {
-		http_client_connection_error(conn, "connect(%s) failed: %m",
-					     _conn->name);
-		http_client_peer_connection_failure(conn->peer);
+		http_client_peer_connection_failure(conn->peer, t_strdup_printf(
+			"connect(%s) failed: %m", _conn->name));
 	} else {
 		http_client_connection_debug(conn, "Connected");
 		if (conn->peer->addr.ssl) {
-			if (http_client_connection_ssl_init(conn) < 0) {
-				http_client_peer_connection_failure(conn->peer);
+			if (http_client_connection_ssl_init(conn, &error) < 0) {
+				http_client_peer_connection_failure(conn->peer, error);
 				http_client_connection_unref(&conn);
 			}
 			return;
diff -r 998afe8ffed9 -r 3580439c06d8 src/lib-http/http-client-host.c
--- a/src/lib-http/http-client-host.c	Thu Apr 04 14:55:03 2013 +0300
+++ b/src/lib-http/http-client-host.c	Thu Apr 04 14:58:00 2013 +0300
@@ -119,17 +119,6 @@
 	struct http_client_peer *peer = NULL;
 	struct http_client_peer_addr addr;
 
-	if (hport->ips_connect_idx == host->ips_count) {
-		/* all IPs failed, but retry all of them again on the
-		   next request. */
-		hport->ips_connect_idx = 0;
-		http_client_host_port_error
-			(hport, HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, "Connection failed");
-		if (host->client->ioloop != NULL)
-			io_loop_stop(host->client->ioloop);
-		return;
-	}
-
 	addr.ip = host->ips[hport->ips_connect_idx];
 	addr.port = hport->port;
 	addr.ssl = hport->ssl;
@@ -142,18 +131,28 @@
 }
 
 void http_client_host_connection_failure(struct http_client_host *host,
-	const struct http_client_peer_addr *addr)
+	const struct http_client_peer_addr *addr, const char *reason)
 {
 	struct http_client_host_port *hport;
 
-	http_client_host_debug(host, "Failed to connect to %s:%u", 
-		net_ip2addr(&addr->ip), addr->port);
+	http_client_host_debug(host, "Failed to connect to %s:%u: %s",
+		net_ip2addr(&addr->ip), addr->port, reason);
 
 	hport = http_client_host_port_find(host, addr->port, addr->ssl);
 	if (hport == NULL)
 		return;
 
-	hport->ips_connect_idx++;
+	i_assert(hport->ips_connect_idx < host->ips_count);
+	if (++hport->ips_connect_idx == host->ips_count) {
+		/* all IPs failed, but retry all of them again on the
+		   next request. */
+		hport->ips_connect_idx = 0;
+		http_client_host_port_error(hport,
+			HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, reason);
+		if (host->client->ioloop != NULL)
+			io_loop_stop(host->client->ioloop);
+		return;
+	}
 	http_client_host_connection_setup(host, hport);
 }
 
@@ -302,6 +301,7 @@
 	/* make a connection if we have an IP already */
 	if (host->ips_count == 0)
 		return;
+	i_assert(hport->ips_connect_idx == 0);
 	http_client_host_connection_setup(host, hport);
 }
 
diff -r 998afe8ffed9 -r 3580439c06d8 src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c	Thu Apr 04 14:55:03 2013 +0300
+++ b/src/lib-http/http-client-peer.c	Thu Apr 04 14:58:00 2013 +0300
@@ -279,7 +279,8 @@
 	return NULL;
 }
 
-void http_client_peer_connection_failure(struct http_client_peer *peer)
+void http_client_peer_connection_failure(struct http_client_peer *peer,
+					 const char *reason)
 {
 	struct http_client_host *const *host;
 	unsigned int num_urgent;
@@ -299,7 +300,7 @@
 		   failed. a second connect will probably also fail, so just
 		   abort all requests. */
 		array_foreach(&peer->hosts, host) {
-			http_client_host_connection_failure(*host, &peer->addr);
+			http_client_host_connection_failure(*host, &peer->addr, reason);
 		}
 	}
 	if (array_count(&peer->conns) == 0 &&
diff -r 998afe8ffed9 -r 3580439c06d8 src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h	Thu Apr 04 14:55:03 2013 +0300
+++ b/src/lib-http/http-client-private.h	Thu Apr 04 14:58:00 2013 +0300
@@ -232,7 +232,8 @@
 	http_client_peer_claim_request(struct http_client_peer *peer,
 		bool no_urgent);
 void http_client_peer_handle_requests(struct http_client_peer *peer);
-void http_client_peer_connection_failure(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);
 unsigned int http_client_peer_idle_connections(struct http_client_peer *peer);
 
@@ -245,7 +246,7 @@
 http_client_host_claim_request(struct http_client_host *host,
 	const struct http_client_peer_addr *addr, bool no_urgent);
 void http_client_host_connection_failure(struct http_client_host *host,
-	const struct http_client_peer_addr *addr);
+	const struct http_client_peer_addr *addr, const char *reason);
 unsigned int http_client_host_requests_pending(struct http_client_host *host,
 	const struct http_client_peer_addr *addr, unsigned int *num_urgent_r);
 void http_client_host_drop_request(struct http_client_host *host,


More information about the dovecot-cvs mailing list