]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: Each peer doesn't need a separate ssl context, enough to have one for http_...
authorTimo Sirainen <tss@iki.fi>
Thu, 4 Apr 2013 09:48:52 +0000 (12:48 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 4 Apr 2013 09:48:52 +0000 (12:48 +0300)
Also removed #ifdefs for building with SSL support. lib-ssl-iostream
nowadays dynamically loads the SSL library when needed, and also handles
failures if Dovecot was built without SSL support.

src/lib-http/http-client-connection.c
src/lib-http/http-client-host.c
src/lib-http/http-client-peer.c
src/lib-http/http-client-private.h
src/lib-http/http-client.c

index 61d0713728bc831e0f9ee6d247c2c4c295d16df3..31ddbaef96bb95b1d57409bcebed2038a84b2717 100644 (file)
@@ -651,7 +651,6 @@ http_client_connection_ready(struct http_client_connection *conn)
        (void)http_client_connection_next_request(conn);
 }
 
-#ifdef HTTP_BUILD_SSL
 static int http_client_connection_ssl_handshaked(void *context)
 {
        struct http_client_connection *conn = context;
@@ -689,7 +688,7 @@ http_client_connection_ssl_init(struct http_client_connection *conn)
        struct ssl_iostream_settings ssl_set;
        const char *source;
 
-       if (conn->peer->ssl_ctx == NULL) {
+       if (conn->client->ssl_ctx == NULL) {
                http_client_connection_error(conn, "No SSL context");
                return -1;
        }
@@ -706,7 +705,7 @@ http_client_connection_ssl_init(struct http_client_connection *conn)
 
        source = t_strdup_printf
                ("connection %s: ", http_client_connection_label(conn));
-       if (io_stream_create_ssl(conn->peer->ssl_ctx, source, &ssl_set,
+       if (io_stream_create_ssl(conn->client->ssl_ctx, source, &ssl_set,
                                 &conn->conn.input, &conn->conn.output, &conn->ssl_iostream) < 0) {
                http_client_connection_error(conn, "Couldn't initialize SSL client");
                return -1;
@@ -722,7 +721,6 @@ http_client_connection_ssl_init(struct http_client_connection *conn)
        http_client_connection_ready(conn);
        return 0;
 }
-#endif
 
 static void 
 http_client_connection_connected(struct connection *_conn, bool success)
@@ -736,13 +734,11 @@ http_client_connection_connected(struct connection *_conn, bool success)
 
        } else {
                http_client_connection_debug(conn, "Connected");
-#ifdef HTTP_BUILD_SSL
                if (conn->peer->addr.ssl) {
                        if (http_client_connection_ssl_init(conn) < 0)
                                http_client_peer_connection_failure(conn->peer);
                        return;
                }
-#endif
                http_client_connection_ready(conn);
        }
 }
@@ -829,10 +825,8 @@ void http_client_connection_unref(struct http_client_connection **_conn)
        conn->closing = TRUE;
        conn->connected = FALSE;
 
-#ifdef HTTP_BUILD_SSL
        if (conn->ssl_iostream != NULL)
                ssl_iostream_unref(&conn->ssl_iostream);
-#endif
 
        connection_deinit(&conn->conn);
 
index c4bd885e93e81d89c02a7d7bd6bd652f3e3a9584..b0fc8533d8c36d3009c8404428b555a3f35976dc 100644 (file)
@@ -118,6 +118,17 @@ http_client_host_connection_setup(struct http_client_host *host,
 {
        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];
index d805a84634151c5770559cd435c9687c09ab1d7c..ab806af5ec2eba9ec0e8d0d073c1ce5cb091a515 100644 (file)
@@ -207,9 +207,8 @@ http_client_peer_create(struct http_client *client,
                              const struct http_client_peer_addr *addr)
 {
        struct http_client_peer *peer;
-#ifdef HTTP_BUILD_SSL
-       struct ssl_iostream_settings ssl_set;
-#endif
+
+       i_assert(!addr->ssl || client->ssl_ctx != NULL);
 
        peer = i_new(struct http_client_peer, 1);
        peer->client = client;
@@ -223,32 +222,6 @@ http_client_peer_create(struct http_client *client,
 
        http_client_peer_debug(peer, "Peer created");
 
-#ifdef HTTP_BUILD_SSL
-       if (peer->addr.ssl && peer->ssl_ctx == NULL) {
-               const char *source;
-               memset(&ssl_set, 0, sizeof(ssl_set));
-               ssl_set.ca_dir = peer->client->set.ssl_ca_dir;
-               ssl_set.ca = peer->client->set.ssl_ca;
-               ssl_set.verify_remote_cert = TRUE;
-               ssl_set.crypto_device = peer->client->set.ssl_crypto_device;
-
-               source = t_strdup_printf("http-client: peer %s:%u",
-                       net_ip2addr(&peer->addr.ip), peer->addr.port);
-               if (ssl_iostream_context_init_client
-                       (source, &ssl_set, &peer->ssl_ctx) < 0) {
-                       http_client_peer_error(peer, "Couldn't initialize SSL context");
-                       http_client_peer_free(&peer);
-                       return NULL;
-               }
-       }
-#else
-       if (peer->addr.ssl) {
-               http_client_peer_error(peer, "HTTPS is not supported");
-               http_client_peer_free(&peer);
-               return NULL;
-       }
-#endif
-
        if (http_client_peer_connect(peer, 1) < 0) {
                http_client_peer_free(&peer);
                return NULL;
@@ -281,11 +254,6 @@ void http_client_peer_free(struct http_client_peer **_peer)
        array_free(&peer->conns);
        array_free(&peer->hosts);
 
-#ifdef HTTP_BUILD_SSL
-       if (peer->ssl_ctx != NULL)
-               ssl_iostream_context_deinit(&peer->ssl_ctx);
-#endif
-
        hash_table_remove
                (peer->client->peers, (const struct http_client_peer_addr *)&peer->addr);
        DLLIST_REMOVE(&peer->client->peers_list, peer);
index 6c2ef75ae6610198a168479c62fbc6875ffa5b81..6002935ad818df4b4c5734595551085fa3a5a9e9 100644 (file)
@@ -5,8 +5,6 @@
 
 #include "http-client.h"
 
-#define HTTP_BUILD_SSL
-
 #define HTTP_DEFAULT_PORT 80
 #define HTTPS_DEFAULT_PORT 443
 
@@ -113,11 +111,6 @@ struct http_client_peer {
        /* active connections to this peer */
        ARRAY_TYPE(http_client_connection) conns;
 
-       /* ssl */
-#ifdef HTTP_BUILD_SSL
-       struct ssl_iostream_context *ssl_ctx;
-#endif
-
        unsigned int destroyed:1;        /* peer is being destroyed */
        unsigned int no_payload_sync:1;  /* expect: 100-continue failed before */
        unsigned int last_connect_failed:1;
@@ -133,11 +126,7 @@ struct http_client_connection {
 
        unsigned int id; // DEBUG: identify parallel connections
 
-       /* ssl */
-#ifdef HTTP_BUILD_SSL
        struct ssl_iostream *ssl_iostream;
-#endif
-
        struct http_response_parser *http_parser;
        struct timeout *to_input, *to_idle, *to_response;
 
@@ -161,6 +150,7 @@ struct http_client {
        struct http_client_settings set;
 
        struct ioloop *ioloop;
+       struct ssl_iostream_context *ssl_ctx;
 
        struct connection_list *conn_list;
 
@@ -185,6 +175,8 @@ http_client_connection_label(struct http_client_connection *conn)
                net_ip2addr(&conn->conn.ip), conn->conn.port, conn->id);
 }
 
+int http_client_init_ssl_ctx(struct http_client *client, const char **error_r);
+
 void http_client_request_ref(struct http_client_request *req);
 void http_client_request_unref(struct http_client_request **_req);
 int http_client_request_send(struct http_client_request *req,
index 4d9895ec65860e7927c5461aa6d23cc19c21ee41..dc134d86bc25f93afdd85b0cce243413471dbf73 100644 (file)
@@ -122,6 +122,9 @@ void http_client_deinit(struct http_client **_client)
        hash_table_destroy(&client->hosts);
 
        connection_list_deinit(&client->conn_list);
+
+       if (client->ssl_ctx != NULL)
+               ssl_iostream_context_deinit(&client->ssl_ctx);
        pool_unref(&client->pool);
        *_client = NULL;
 }
@@ -180,3 +183,23 @@ void http_client_wait(struct http_client *client)
        io_loop_destroy(&client->ioloop);
 }
 
+int http_client_init_ssl_ctx(struct http_client *client, const char **error_r)
+{
+       struct ssl_iostream_settings ssl_set;
+
+       if (client->ssl_ctx != NULL)
+               return 0;
+
+       memset(&ssl_set, 0, sizeof(ssl_set));
+       ssl_set.ca_dir = client->set.ssl_ca_dir;
+       ssl_set.ca = client->set.ssl_ca;
+       ssl_set.verify_remote_cert = TRUE;
+       ssl_set.crypto_device = client->set.ssl_crypto_device;
+
+       if (ssl_iostream_context_init_client("lib-http", &ssl_set,
+                                            &client->ssl_ctx) < 0) {
+               *error_r = "Couldn't initialize SSL context";
+               return -1;
+       }
+       return 0;
+}