dovecot-2.2: lib-http: Simplify error handling by delaying conne...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 4 14:20:48 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/1bd5972eac0a
changeset: 16148:1bd5972eac0a
user: Timo Sirainen <tss at iki.fi>
date: Thu Apr 04 14:18:38 2013 +0300
description:
lib-http: Simplify error handling by delaying connect() failures.
diffstat:
src/lib-http/http-client-connection.c | 30 ++++++++++++-----------
src/lib-http/http-client-host.c | 44 ++++++++++++++--------------------
src/lib-http/http-client-peer.c | 27 +++------------------
src/lib-http/http-client-private.h | 1 +
4 files changed, 39 insertions(+), 63 deletions(-)
diffs (197 lines):
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-connection.c Thu Apr 04 14:18:38 2013 +0300
@@ -731,7 +731,8 @@
(struct http_client_connection *)_conn;
if (!success) {
- http_client_connection_error(conn, "Connect failed: %m");
+ http_client_connection_error(conn, "connect(%s) failed: %m",
+ _conn->name);
http_client_peer_connection_failure(conn->peer);
} else {
@@ -764,16 +765,21 @@
(&http_client_connection_set, &http_client_connection_vfuncs);
}
-static int http_client_connection_connect(struct http_client_connection *conn)
+static void
+http_client_connection_delayed_connect_error(struct http_client_connection *conn)
{
- if (conn->conn.fd_in == -1) {
- if (connection_client_connect(&conn->conn) < 0) {
- http_client_connection_error(conn, "Could not connect");
- return -1;
- }
+ timeout_remove(&conn->to_input);
+ errno = conn->connect_errno;
+ http_client_connection_connected(&conn->conn, FALSE);
+}
+
+static void http_client_connection_connect(struct http_client_connection *conn)
+{
+ if (connection_client_connect(&conn->conn) < 0) {
+ conn->connect_errno = errno;
+ conn->to_input = timeout_add_short(0,
+ http_client_connection_delayed_connect_error, conn);
}
-
- return 0;
}
struct http_client_connection *
@@ -790,11 +796,7 @@
connection_init_client_ip
(peer->client->conn_list, &conn->conn, &peer->addr.ip, peer->addr.port);
-
- if (http_client_connection_connect(conn) < 0) {
- http_client_connection_unref(&conn);
- return NULL;
- }
+ http_client_connection_connect(conn);
conn->id = id++;
array_append(&peer->conns, &conn, 1);
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-host.c
--- a/src/lib-http/http-client-host.c Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-host.c Thu Apr 04 14:18:38 2013 +0300
@@ -118,33 +118,8 @@
{
struct http_client_peer *peer = NULL;
struct http_client_peer_addr addr;
- const char *error;
- if (hport->ssl && host->client->ssl_ctx == NULL) {
- if (http_client_init_ssl_ctx(host->client, &error) < 0) {
- http_client_host_port_error(hport,
- HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error);
- if (host->client->ioloop != NULL)
- io_loop_stop(host->client->ioloop);
- return;
- }
- }
-
- while (hport->ips_connect_idx < host->ips_count) {
- addr.ip = host->ips[hport->ips_connect_idx];
- addr.port = hport->port;
- addr.ssl = hport->ssl;
-
- http_client_host_debug(host, "Setting up connection to %s:%u (ssl=%s)",
- net_ip2addr(&addr.ip), addr.port, (addr.ssl ? "yes" : "no"));
-
- if ((peer=http_client_peer_get(host->client, &addr)) != NULL)
- break;
-
- hport->ips_connect_idx++;
- }
-
- if (peer == NULL) {
+ 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;
@@ -155,6 +130,14 @@
return;
}
+ addr.ip = host->ips[hport->ips_connect_idx];
+ addr.port = hport->port;
+ addr.ssl = hport->ssl;
+
+ http_client_host_debug(host, "Setting up connection to %s:%u (ssl=%s)",
+ net_ip2addr(&addr.ip), addr.port, (addr.ssl ? "yes" : "no"));
+
+ peer = http_client_peer_get(host->client, &addr);
http_client_peer_add_host(peer, host);
}
@@ -293,9 +276,18 @@
struct http_client_request *req)
{
struct http_client_host_port *hport;
+ const char *error;
req->host = host;
+ if (req->ssl && host->client->ssl_ctx == NULL) {
+ if (http_client_init_ssl_ctx(host->client, &error) < 0) {
+ http_client_request_error(req,
+ HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error);
+ return;
+ }
+ }
+
/* add request to host (grouped by tcp port) */
hport = http_client_host_port_init(host, req->port, req->ssl);
if (req->urgent)
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-peer.c Thu Apr 04 14:18:38 2013 +0300
@@ -78,23 +78,15 @@
return (*host)->name;
}
-static int
+static void
http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
{
- struct http_client_connection *conn;
unsigned int i;
for (i = 0; i < count; i++) {
http_client_peer_debug(peer, "Making new connection %u of %u", i+1, count);
-
- conn = http_client_connection_create(peer);
- if (conn == NULL) {
- http_client_peer_debug(peer, "Failed to make new connection");
- return -1;
- }
+ (void)http_client_connection_create(peer);
}
-
- return 0;
}
static unsigned int
@@ -173,13 +165,7 @@
} else {
new_connections = (num_urgent > connecting ? num_urgent - connecting : 0);
}
- if (http_client_peer_connect(peer, new_connections) < 0) {
- /* connection failed */
- if (conn == NULL)
- return FALSE;
- /* pipeline it on the least busy connection we found */
- return http_client_connection_next_request(conn);
- }
+ http_client_peer_connect(peer, new_connections);
/* now we wait until it is connected */
return FALSE;
@@ -209,12 +195,7 @@
DLLIST_PREPEND(&client->peers_list, peer);
http_client_peer_debug(peer, "Peer created");
-
- if (http_client_peer_connect(peer, 1) < 0) {
- http_client_peer_free(&peer);
- return NULL;
- }
-
+ http_client_peer_connect(peer, 1);
return peer;
}
diff -r b4927eea33fd -r 1bd5972eac0a src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Thu Apr 04 14:11:10 2013 +0300
+++ b/src/lib-http/http-client-private.h Thu Apr 04 14:18:38 2013 +0300
@@ -133,6 +133,7 @@
const char *label;
unsigned int id; // DEBUG: identify parallel connections
+ int connect_errno;
struct ssl_iostream *ssl_iostream;
struct http_response_parser *http_parser;
More information about the dovecot-cvs
mailing list