dovecot-2.2: lib-http: client: Connection erroneously indicated ...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Oct 20 15:55:24 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/7d3325713356
changeset: 17970:7d3325713356
user: Stephan Bosch <stephan at rename-it.nl>
date: Mon Oct 20 08:54:27 2014 -0700
description:
lib-http: client: Connection erroneously indicated that it was ready while SSL handshake was not yet completed.
diffstat:
src/lib-http/http-client-connection.c | 59 ++++++++++++++++++++++++++++++----
1 files changed, 52 insertions(+), 7 deletions(-)
diffs (114 lines):
diff -r c9ea647cba87 -r 7d3325713356 src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c Mon Oct 20 08:54:27 2014 -0700
+++ b/src/lib-http/http-client-connection.c Mon Oct 20 08:54:27 2014 -0700
@@ -44,6 +44,7 @@
* Connection
*/
+static void http_client_connection_ready(struct http_client_connection *conn);
static void http_client_connection_input(struct connection *_conn);
static void
http_client_connection_disconnect(struct http_client_connection *conn);
@@ -382,7 +383,7 @@
msecs = timeval_diff_msecs(&ioloop_timeval,
&conn->connected_timestamp);
error = t_strdup_printf(
- "SSL handshaking to %s failed: Connection timed out in %u.%03u secs",
+ "SSL handshaking with %s failed: Connection timed out in %u.%03u secs",
_conn->name, msecs/1000, msecs%1000);
}
http_client_connection_debug(conn, "%s", error);
@@ -556,6 +557,41 @@
i_assert(conn->incoming_payload == NULL);
+ if (conn->ssl_iostream != NULL &&
+ !ssl_iostream_is_handshaked(conn->ssl_iostream)) {
+ /* finish SSL negotiation by reading from input stream */
+ while ((ret=i_stream_read(conn->conn.input)) > 0) {
+ if (ssl_iostream_is_handshaked(conn->ssl_iostream))
+ break;
+ }
+ if (ret < 0) {
+ int stream_errno = conn->conn.input->stream_errno;
+
+ /* failed somehow */
+ i_assert(ret != -2);
+ error = t_strdup_printf(
+ "SSL handshaking with %s failed: "
+ "read(%s) failed: %s",
+ _conn->name,
+ i_stream_get_name(conn->conn.input),
+ stream_errno != 0 ?
+ i_stream_get_error(conn->conn.input) : "EOF");
+ http_client_peer_connection_failure(conn->peer, error);
+ http_client_connection_debug(conn, "%s", error);
+ http_client_connection_close(&conn);
+ return;
+ }
+
+ if (!ssl_iostream_is_handshaked(conn->ssl_iostream)) {
+ /* not finished */
+ i_assert(ret == 0);
+ return;
+ }
+
+ /* ready for first request */
+ http_client_connection_ready(conn);
+ }
+
if (conn->to_input != NULL) {
/* We came here from a timeout added by
http_client_payload_destroyed(). The IO couldn't be added
@@ -763,6 +799,10 @@
return ret;
}
+ if (conn->ssl_iostream != NULL &&
+ !ssl_iostream_is_handshaked(conn->ssl_iostream))
+ return 1;
+
if (array_count(&conn->request_wait_list) > 0 && conn->output_locked) {
req_idx = array_idx(&conn->request_wait_list,
array_count(&conn->request_wait_list)-1);
@@ -815,12 +855,12 @@
static void
http_client_connection_ready(struct http_client_connection *conn)
{
+ http_client_connection_debug(conn, "Ready for requests");
+
/* connected */
conn->connected = TRUE;
conn->last_ioloop = current_ioloop;
- if (conn->to_connect != NULL &&
- (conn->ssl_iostream == NULL ||
- ssl_iostream_is_handshaked(conn->ssl_iostream)))
+ if (conn->to_connect != NULL)
timeout_remove(&conn->to_connect);
/* indicate connection success */
@@ -883,8 +923,6 @@
*error_r = error;
return -1;
}
- if (conn->to_connect != NULL)
- timeout_remove(&conn->to_connect);
return 0;
}
@@ -924,7 +962,14 @@
return -1;
}
- http_client_connection_ready(conn);
+ if (ssl_iostream_is_handshaked(conn->ssl_iostream)) {
+ http_client_connection_ready(conn);
+ } else {
+ /* wait for handshake to complete; connection input handler does the rest
+ by reading from the input stream */
+ o_stream_set_flush_callback(conn->conn.output,
+ http_client_connection_output, conn);
+ }
return 0;
}
More information about the dovecot-cvs
mailing list