dovecot-2.2: http-client: Added support for using an HTTP proxy ...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Aug 29 11:50:16 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/8f8f768937f5
changeset: 19039:8f8f768937f5
user: Stephan Bosch <stephan at rename-it.nl>
date: Sat Apr 25 11:42:06 2015 +0200
description:
http-client: Added support for using an HTTP proxy running on a unix socket.
diffstat:
src/lib-http/http-client-connection.c | 31 +++++++---
src/lib-http/http-client-host.c | 71 ++++++++++++++++++-------
src/lib-http/http-client-peer.c | 58 +++++++++++++++-----
src/lib-http/http-client-private.h | 96 +++++++++++++++++++++++-----------
src/lib-http/http-client-queue.c | 97 ++++++++++++++++++++++------------
src/lib-http/http-client-request.c | 48 +++++++++++++++--
src/lib-http/http-client.h | 6 +-
7 files changed, 286 insertions(+), 121 deletions(-)
diffs (truncated from 781 to 300 lines):
diff -r f8ab4f979e92 -r 8f8f768937f5 src/lib-http/http-client-connection.c
--- a/src/lib-http/http-client-connection.c Sat Aug 29 14:42:49 2015 +0300
+++ b/src/lib-http/http-client-connection.c Sat Apr 25 11:42:06 2015 +0200
@@ -1015,7 +1015,7 @@
http_client_connection_ssl_handshaked(const char **error_r, void *context)
{
struct http_client_connection *conn = context;
- const char *error, *host = conn->peer->addr.https_name;
+ const char *error, *host = conn->peer->addr.a.tcp.https_name;
if (ssl_iostream_check_cert_validity(conn->ssl_iostream, host, &error) == 0)
http_client_connection_debug(conn, "SSL handshake successful");
@@ -1049,7 +1049,7 @@
http_client_connection_debug(conn, "Starting SSL handshake");
if (io_stream_create_ssl_client(conn->client->ssl_ctx,
- conn->peer->addr.https_name, &ssl_set,
+ conn->peer->addr.a.tcp.https_name, &ssl_set,
&conn->conn.input, &conn->conn.output,
&conn->ssl_iostream, &error) < 0) {
*error_r = t_strdup_printf(
@@ -1089,7 +1089,7 @@
} else {
conn->connected_timestamp = ioloop_timeval;
http_client_connection_debug(conn, "Connected");
- if (conn->peer->addr.https_name != NULL) {
+ if (http_client_peer_addr_is_https(&conn->peer->addr)) {
if (http_client_connection_ssl_init(conn, &error) < 0) {
http_client_peer_connection_failure(conn->peer, error);
http_client_connection_debug(conn, "%s", error);
@@ -1104,7 +1104,8 @@
static const struct connection_settings http_client_connection_set = {
.input_max_size = (size_t)-1,
.output_max_size = (size_t)-1,
- .client = TRUE
+ .client = TRUE,
+ .delayed_unix_client_connected_callback = TRUE
};
static const struct connection_vfuncs http_client_connection_vfuncs = {
@@ -1248,6 +1249,9 @@
case HTTP_CLIENT_PEER_ADDR_RAW:
conn_type = "Raw";
break;
+ case HTTP_CLIENT_PEER_ADDR_UNIX:
+ conn_type = "Unix";
+ break;
}
conn = i_new(struct http_client_connection, 1);
@@ -1258,11 +1262,20 @@
if (peer->addr.type != HTTP_CLIENT_PEER_ADDR_RAW)
i_array_init(&conn->request_wait_list, 16);
- if (peer->addr.type == HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL) {
- http_client_connection_connect_tunnel(conn, &addr->ip, addr->port);
- } else {
- connection_init_client_ip
- (peer->client->conn_list, &conn->conn, &addr->ip, addr->port);
+ switch (peer->addr.type) {
+ case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
+ http_client_connection_connect_tunnel
+ (conn, &addr->a.tcp.ip, addr->a.tcp.port);
+ break;
+ case HTTP_CLIENT_PEER_ADDR_UNIX:
+ connection_init_client_unix(peer->client->conn_list, &conn->conn,
+ addr->a.un.path);
+ conn->connect_initialized = TRUE;
+ http_client_connection_connect(conn);
+ break;
+ default:
+ connection_init_client_ip(peer->client->conn_list, &conn->conn,
+ &addr->a.tcp.ip, addr->a.tcp.port);
conn->connect_initialized = TRUE;
http_client_connection_connect(conn);
}
diff -r f8ab4f979e92 -r 8f8f768937f5 src/lib-http/http-client-host.c
--- a/src/lib-http/http-client-host.c Sat Aug 29 14:42:49 2015 +0300
+++ b/src/lib-http/http-client-host.c Sat Apr 25 11:42:06 2015 +0200
@@ -137,31 +137,55 @@
}
}
+static struct http_client_host *http_client_host_create
+(struct http_client *client)
+{
+ struct http_client_host *host;
+
+ // FIXME: limit the maximum number of inactive cached hosts
+ host = i_new(struct http_client_host, 1);
+ host->client = client;
+ i_array_init(&host->queues, 4);
+ DLLIST_PREPEND(&client->hosts_list, host);
+
+ return host;
+}
+
struct http_client_host *http_client_host_get
(struct http_client *client, const struct http_url *host_url)
{
struct http_client_host *host;
- const char *hostname = host_url->host_name;
- host = hash_table_lookup(client->hosts, hostname);
- if (host == NULL) {
- // FIXME: limit the maximum number of inactive cached hosts
- host = i_new(struct http_client_host, 1);
- host->client = client;
- host->name = i_strdup(hostname);
- i_array_init(&host->queues, 4);
+ if (host_url == NULL) {
+ host = client->unix_host;
+ if (host == NULL) {
+ host = http_client_host_create(client);
+ host->name = i_strdup("[unix]");
+ host->unix_local = TRUE;
- hostname = host->name;
- hash_table_insert(client->hosts, hostname, host);
- DLLIST_PREPEND(&client->hosts_list, host);
+ client->unix_host = host;
- if (host_url->have_host_ip) {
- host->ips_count = 1;
- host->ips = i_new(struct ip_addr, host->ips_count);
- host->ips[0] = host_url->host_ip;
+ http_client_host_debug(host, "Unix host created");
}
- http_client_host_debug(host, "Host created");
+ } else {
+ const char *hostname = host_url->host_name;
+
+ host = hash_table_lookup(client->hosts, hostname);
+ if (host == NULL) {
+ host = http_client_host_create(client);
+ host->name = i_strdup(hostname);
+ hostname = host->name;
+ hash_table_insert(client->hosts, hostname, host);
+
+ if (host_url->have_host_ip) {
+ host->ips_count = 1;
+ host->ips = i_new(struct ip_addr, host->ips_count);
+ host->ips[0] = host_url->host_ip;
+ }
+
+ http_client_host_debug(host, "Host created");
+ }
}
return host;
}
@@ -170,13 +194,14 @@
struct http_client_request *req)
{
struct http_client_queue *queue;
- const struct http_url *host_url = req->host_url;
struct http_client_peer_addr addr;
const char *error;
req->host = host;
- if (host_url->have_ssl && host->client->ssl_ctx == NULL) {
+ http_client_request_get_peer_addr(req, &addr);
+ if (http_client_peer_addr_is_https(&addr) &&
+ 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);
@@ -184,12 +209,15 @@
}
}
- http_client_request_get_peer_addr(req, &addr);
-
/* add request to queue (grouped by tcp port) */
queue = http_client_queue_create(host, &addr);
http_client_queue_submit_request(queue, req);
+ if (host->unix_local) {
+ http_client_queue_connection_setup(queue);
+ return;
+ }
+
/* start DNS lookup if necessary */
if (host->ips_count == 0 && host->dns_lookup == NULL)
http_client_host_lookup(host);
@@ -210,7 +238,8 @@
http_client_host_debug(host, "Host destroy");
DLLIST_REMOVE(&host->client->hosts_list, host);
- hash_table_remove(host->client->hosts, hostname);
+ if (host != host->client->unix_host)
+ hash_table_remove(host->client->hosts, hostname);
if (host->dns_lookup != NULL)
dns_lookup_abort(&host->dns_lookup);
diff -r f8ab4f979e92 -r 8f8f768937f5 src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c Sat Aug 29 14:42:49 2015 +0300
+++ b/src/lib-http/http-client-peer.c Sat Apr 25 11:42:06 2015 +0200
@@ -45,13 +45,16 @@
{
switch (peer->type) {
case HTTP_CLIENT_PEER_ADDR_RAW:
- return net_ip_hash(&peer->ip) + peer->port + 1;
+ return net_ip_hash(&peer->a.tcp.ip) + peer->a.tcp.port + 1;
case HTTP_CLIENT_PEER_ADDR_HTTP:
- return net_ip_hash(&peer->ip) + peer->port;
+ return net_ip_hash(&peer->a.tcp.ip) + peer->a.tcp.port;
case HTTP_CLIENT_PEER_ADDR_HTTPS:
case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
- return net_ip_hash(&peer->ip) + peer->port +
- (peer->https_name == NULL ? 0 : str_hash(peer->https_name));
+ return net_ip_hash(&peer->a.tcp.ip) + peer->a.tcp.port +
+ (peer->a.tcp.https_name == NULL ?
+ 0 : str_hash(peer->a.tcp.https_name));
+ case HTTP_CLIENT_PEER_ADDR_UNIX:
+ return str_hash(peer->a.un.path);
}
i_unreached();
return 0;
@@ -65,13 +68,24 @@
if (peer1->type != peer2->type)
return (peer1->type > peer2->type ? 1 : -1);
- if ((ret=net_ip_cmp(&peer1->ip, &peer2->ip)) != 0)
- return ret;
- if (peer1->port != peer2->port)
- return (peer1->port > peer2->port ? 1 : -1);
- if (peer1->type != HTTP_CLIENT_PEER_ADDR_HTTPS)
- return 0;
- return null_strcmp(peer1->https_name, peer2->https_name);
+ switch (peer1->type) {
+ case HTTP_CLIENT_PEER_ADDR_RAW:
+ case HTTP_CLIENT_PEER_ADDR_HTTP:
+ case HTTP_CLIENT_PEER_ADDR_HTTPS:
+ case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
+ if ((ret=net_ip_cmp(&peer1->a.tcp.ip, &peer2->a.tcp.ip)) != 0)
+ return ret;
+ if (peer1->a.tcp.port != peer2->a.tcp.port)
+ return (peer1->a.tcp.port > peer2->a.tcp.port ? 1 : -1);
+ if (peer1->type != HTTP_CLIENT_PEER_ADDR_HTTPS)
+ return 0;
+ return null_strcmp
+ (peer1->a.tcp.https_name, peer2->a.tcp.https_name);
+ case HTTP_CLIENT_PEER_ADDR_UNIX:
+ return null_strcmp(peer1->a.un.path, peer2->a.un.path);
+ }
+ i_unreached();
+ return 0;
}
/*
@@ -438,13 +452,25 @@
{
struct http_client_peer *peer;
- i_assert(addr->https_name == NULL || client->ssl_ctx != NULL);
-
peer = i_new(struct http_client_peer, 1);
peer->client = client;
peer->addr = *addr;
- peer->https_name = i_strdup(addr->https_name);
- peer->addr.https_name = peer->https_name;
+
+ switch (addr->type) {
+ case HTTP_CLIENT_PEER_ADDR_HTTPS:
+ case HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL:
+ i_assert(client->ssl_ctx != NULL);
+ peer->addr_name = i_strdup(addr->a.tcp.https_name);
+ peer->addr.a.tcp.https_name = peer->addr_name;
+ break;
+ case HTTP_CLIENT_PEER_ADDR_UNIX:
+ peer->addr_name = i_strdup(addr->a.un.path);
+ peer->addr.a.un.path = peer->addr_name;
+ break;
+ default:
+ break;
+ }
+
i_array_init(&peer->queues, 16);
i_array_init(&peer->conns, 16);
@@ -479,7 +505,7 @@
(peer->client->peers, (const struct http_client_peer_addr *)&peer->addr);
DLLIST_REMOVE(&peer->client->peers_list, peer);
- i_free(peer->https_name);
+ i_free(peer->addr_name);
i_free(peer);
*_peer = NULL;
}
diff -r f8ab4f979e92 -r 8f8f768937f5 src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Sat Aug 29 14:42:49 2015 +0300
+++ b/src/lib-http/http-client-private.h Sat Apr 25 11:42:06 2015 +0200
@@ -38,14 +38,22 @@
HTTP_CLIENT_PEER_ADDR_HTTP = 0,
HTTP_CLIENT_PEER_ADDR_HTTPS,
HTTP_CLIENT_PEER_ADDR_HTTPS_TUNNEL,
- HTTP_CLIENT_PEER_ADDR_RAW
+ HTTP_CLIENT_PEER_ADDR_RAW,
More information about the dovecot-cvs
mailing list