From: Stephan Bosch Date: Tue, 29 Nov 2016 15:17:59 +0000 (+0100) Subject: lib-http: client: Created basic shared context between clients. X-Git-Tag: 2.3.0.rc1~269 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fab1a1c57f467c19c728d2391ff5e5025bb832f7;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: Created basic shared context between clients. In this basic form it only shares default settings. --- diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index 87c4f0204d..28d3ef2411 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -289,7 +289,7 @@ struct http_client_host { struct http_client { pool_t pool; - + struct http_client_context *cctx; struct http_client_settings set; struct ioloop *ioloop; @@ -310,6 +310,13 @@ struct http_client { unsigned int requests_count; }; +struct http_client_context { + pool_t pool; + unsigned int refcount; + + struct http_client_settings set; +}; + /* * Peer address */ diff --git a/src/lib-http/http-client.c b/src/lib-http/http-client.c index 0aeea72e49..ada2573d04 100644 --- a/src/lib-http/http-client.c +++ b/src/lib-http/http-client.c @@ -84,7 +84,9 @@ http_client_debug(struct http_client *client, * Client */ -struct http_client *http_client_init(const struct http_client_settings *set) +struct http_client * +http_client_init_shared(struct http_client_context *cctx, + const struct http_client_settings *set) { struct http_client *client; pool_t pool; @@ -93,65 +95,97 @@ struct http_client *http_client_init(const struct http_client_settings *set) client = p_new(pool, struct http_client, 1); client->pool = pool; - client->set.dns_client = set->dns_client; - client->set.dns_client_socket_path = - p_strdup_empty(pool, set->dns_client_socket_path); - client->set.dns_ttl_msecs = (set->dns_ttl_msecs == 0 ? - HTTP_CLIENT_DEFAULT_DNS_TTL_MSECS : set->dns_ttl_msecs); - client->set.user_agent = p_strdup_empty(pool, set->user_agent); - client->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir); + /* create private context if none is provided */ + if (cctx != NULL) { + client->cctx = cctx; + http_client_context_ref(cctx); + } else { + client->cctx = cctx = http_client_context_create(set); + } - if (set->ssl != NULL) - client->set.ssl = ssl_iostream_settings_dup(client->pool, set->ssl); + /* merge provided settings with context defaults */ + i_assert(cctx != NULL || set != NULL); + client->set = cctx->set; + if (cctx != NULL && set != NULL) { + if (set->dns_client != NULL) + client->set.dns_client = set->dns_client; + if (set->dns_client_socket_path != NULL && + *set->dns_client_socket_path != '\0') { + client->set.dns_client_socket_path = + p_strdup_empty(pool, set->dns_client_socket_path); + } + if (set->dns_ttl_msecs > 0) + client->set.dns_ttl_msecs = set->dns_ttl_msecs; + if (set->user_agent != NULL && *set->user_agent != '\0') + client->set.user_agent = p_strdup_empty(pool, set->user_agent); + if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0') + client->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir); + + if (set->ssl != NULL) + client->set.ssl = ssl_iostream_settings_dup(pool, set->ssl); + + if (set->proxy_socket_path != NULL && *set->proxy_socket_path != '\0') { + client->set.proxy_socket_path = p_strdup(pool, set->proxy_socket_path); + client->set.proxy_url = NULL; + } else if (set->proxy_url != NULL) { + client->set.proxy_url = http_url_clone(pool, set->proxy_url); + client->set.proxy_socket_path = NULL; + } + if (set->proxy_username != NULL && *set->proxy_username != '\0') { + client->set.proxy_username = p_strdup_empty(pool, set->proxy_username); + client->set.proxy_password = p_strdup(pool, set->proxy_password); + } else if (set->proxy_url != NULL && set->proxy_url->user != NULL && + *set->proxy_url->user != '\0') { + client->set.proxy_username = + p_strdup_empty(pool, set->proxy_url->user); + client->set.proxy_password = + p_strdup(pool, set->proxy_url->password); + } - if (set->proxy_socket_path != NULL && *set->proxy_socket_path != '\0') { - client->set.proxy_socket_path = p_strdup(pool, set->proxy_socket_path); - } else if (set->proxy_url != NULL) { - client->set.proxy_url = http_url_clone(pool, set->proxy_url); - } - if (set->proxy_username != NULL && *set->proxy_username != '\0') { - client->set.proxy_username = p_strdup_empty(pool, set->proxy_username); - client->set.proxy_password = p_strdup(pool, set->proxy_password); - } else if (set->proxy_url != NULL) { - client->set.proxy_username = - p_strdup_empty(pool, set->proxy_url->user); - client->set.proxy_password = - p_strdup(pool, set->proxy_url->password); + if (set->max_idle_time_msecs > 0) + client->set.max_idle_time_msecs = set->max_idle_time_msecs; + if (set->max_parallel_connections > 0) + client->set.max_parallel_connections = set->max_parallel_connections; + if (set->max_pipelined_requests > 0) + client->set.max_pipelined_requests = set->max_pipelined_requests; + if (set->max_attempts > 0) + client->set.max_attempts = set->max_attempts; + if (set->max_connect_attempts > 0) + client->set.max_connect_attempts = set->max_connect_attempts; + if (set->connect_backoff_time_msecs > 0) { + client->set.connect_backoff_time_msecs = + set->connect_backoff_time_msecs; + } + if (set->connect_backoff_max_time_msecs > 0) { + client->set.connect_backoff_max_time_msecs = + set->connect_backoff_max_time_msecs; + } + client->set.no_auto_redirect = + client->set.no_auto_redirect || set->no_auto_redirect; + client->set.no_auto_retry = + client->set.no_auto_retry || set->no_auto_retry; + client->set.no_ssl_tunnel = + client->set.no_ssl_tunnel || set->no_ssl_tunnel; + if (set->max_redirects > 0) + client->set.max_redirects = set->max_redirects; + client->set.response_hdr_limits = set->response_hdr_limits; + if (set->request_absolute_timeout_msecs > 0) { + client->set.request_absolute_timeout_msecs = + set->request_absolute_timeout_msecs; + } + if (set->request_timeout_msecs > 0) + client->set.request_timeout_msecs = set->request_timeout_msecs; + if (set->connect_timeout_msecs > 0) + client->set.connect_timeout_msecs = set->connect_timeout_msecs; + if (set->soft_connect_timeout_msecs > 0) + client->set.soft_connect_timeout_msecs = set->soft_connect_timeout_msecs; + if (set->max_auto_retry_delay > 0) + client->set.max_auto_retry_delay = set->max_auto_retry_delay; + client->set.socket_send_buffer_size = set->socket_send_buffer_size; + client->set.socket_recv_buffer_size = set->socket_recv_buffer_size; + client->set.debug = client->set.debug || set->debug; } - client->set.max_idle_time_msecs = set->max_idle_time_msecs; - client->set.max_parallel_connections = - (set->max_parallel_connections > 0 ? set->max_parallel_connections : 1); - client->set.max_pipelined_requests = - (set->max_pipelined_requests > 0 ? set->max_pipelined_requests : 1); - client->set.max_attempts = set->max_attempts; - client->set.max_connect_attempts = set->max_connect_attempts; - client->set.connect_backoff_time_msecs = - set->connect_backoff_time_msecs == 0 ? - HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS : - set->connect_backoff_time_msecs; - client->set.connect_backoff_max_time_msecs = - set->connect_backoff_max_time_msecs == 0 ? - HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS : - set->connect_backoff_max_time_msecs; - client->set.no_auto_redirect = set->no_auto_redirect; - client->set.no_auto_retry = set->no_auto_retry; - client->set.no_ssl_tunnel = set->no_ssl_tunnel; - client->set.max_redirects = set->max_redirects; - client->set.response_hdr_limits = set->response_hdr_limits; - client->set.request_absolute_timeout_msecs = - set->request_absolute_timeout_msecs; - client->set.request_timeout_msecs = - set->request_timeout_msecs == 0 ? - HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS : - set->request_timeout_msecs; - client->set.connect_timeout_msecs = set->connect_timeout_msecs; - client->set.soft_connect_timeout_msecs = set->soft_connect_timeout_msecs; - client->set.max_auto_retry_delay = set->max_auto_retry_delay; - client->set.socket_send_buffer_size = set->socket_send_buffer_size; - client->set.socket_recv_buffer_size = set->socket_recv_buffer_size; - client->set.debug = set->debug; - i_array_init(&client->delayed_failing_requests, 1); client->conn_list = http_client_connection_list_init(); @@ -163,6 +197,12 @@ struct http_client *http_client_init(const struct http_client_settings *set) return client; } +struct http_client * +http_client_init(const struct http_client_settings *set) +{ + return http_client_init_shared(NULL, set); +} + void http_client_deinit(struct http_client **_client) { struct http_client *client = *_client; @@ -202,6 +242,7 @@ void http_client_deinit(struct http_client **_client) if (client->ssl_ctx != NULL) ssl_iostream_context_unref(&client->ssl_ctx); + http_client_context_unref(&client->cctx); pool_unref(&client->pool); } @@ -339,3 +380,98 @@ void http_client_remove_request_error(struct http_client *client, } } } + +/* + * Client shared context + */ + +struct http_client_context * +http_client_context_create(const struct http_client_settings *set) +{ + struct http_client_context *cctx; + pool_t pool; + + pool = pool_alloconly_create("http client context", 1024); + cctx = p_new(pool, struct http_client_context, 1); + cctx->pool = pool; + cctx->refcount = 1; + + cctx->set.dns_client = set->dns_client; + cctx->set.dns_client_socket_path = + p_strdup_empty(pool, set->dns_client_socket_path); + cctx->set.dns_ttl_msecs = (set->dns_ttl_msecs == 0 ? + HTTP_CLIENT_DEFAULT_DNS_TTL_MSECS : set->dns_ttl_msecs); + cctx->set.user_agent = p_strdup_empty(pool, set->user_agent); + cctx->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir); + + if (set->ssl != NULL) + cctx->set.ssl = ssl_iostream_settings_dup(pool, set->ssl); + + if (set->proxy_socket_path != NULL && *set->proxy_socket_path != '\0') { + cctx->set.proxy_socket_path = p_strdup(pool, set->proxy_socket_path); + } else if (set->proxy_url != NULL) { + cctx->set.proxy_url = http_url_clone(pool, set->proxy_url); + } + if (set->proxy_username != NULL && *set->proxy_username != '\0') { + cctx->set.proxy_username = p_strdup_empty(pool, set->proxy_username); + cctx->set.proxy_password = p_strdup(pool, set->proxy_password); + } else if (set->proxy_url != NULL) { + cctx->set.proxy_username = + p_strdup_empty(pool, set->proxy_url->user); + cctx->set.proxy_password = + p_strdup(pool, set->proxy_url->password); + } + + cctx->set.max_idle_time_msecs = set->max_idle_time_msecs; + cctx->set.max_pipelined_requests = + (set->max_pipelined_requests > 0 ? set->max_pipelined_requests : 1); + cctx->set.max_parallel_connections = + (set->max_parallel_connections > 0 ? set->max_parallel_connections : 1); + cctx->set.max_attempts = set->max_attempts; + cctx->set.max_connect_attempts = set->max_connect_attempts; + cctx->set.connect_backoff_time_msecs = + set->connect_backoff_time_msecs == 0 ? + HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS : + set->connect_backoff_time_msecs; + cctx->set.connect_backoff_max_time_msecs = + set->connect_backoff_max_time_msecs == 0 ? + HTTP_CLIENT_DEFAULT_BACKOFF_MAX_TIME_MSECS : + set->connect_backoff_max_time_msecs; + cctx->set.no_auto_redirect = set->no_auto_redirect; + cctx->set.no_auto_retry = set->no_auto_retry; + cctx->set.no_ssl_tunnel = set->no_ssl_tunnel; + cctx->set.max_redirects = set->max_redirects; + cctx->set.response_hdr_limits = set->response_hdr_limits; + cctx->set.request_absolute_timeout_msecs = + set->request_absolute_timeout_msecs; + cctx->set.request_timeout_msecs = + set->request_timeout_msecs == 0 ? + HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS : + set->request_timeout_msecs; + cctx->set.connect_timeout_msecs = set->connect_timeout_msecs; + cctx->set.soft_connect_timeout_msecs = set->soft_connect_timeout_msecs; + cctx->set.max_auto_retry_delay = set->max_auto_retry_delay; + cctx->set.socket_send_buffer_size = set->socket_send_buffer_size; + cctx->set.socket_recv_buffer_size = set->socket_recv_buffer_size; + cctx->set.debug = set->debug; + + return cctx; +} + +void http_client_context_ref(struct http_client_context *cctx) +{ + cctx->refcount++; +} + +void http_client_context_unref(struct http_client_context **_cctx) +{ + struct http_client_context *cctx = *_cctx; + + *_cctx = NULL; + + i_assert(cctx->refcount > 0); + if (--cctx->refcount > 0) + return; + + pool_unref(&cctx->pool); +} diff --git a/src/lib-http/http-client.h b/src/lib-http/http-client.h index c1a3760299..93f1d95ff6 100644 --- a/src/lib-http/http-client.h +++ b/src/lib-http/http-client.h @@ -8,8 +8,9 @@ struct timeval; struct http_response; -struct http_client; struct http_client_request; +struct http_client; +struct http_client_context; struct ssl_iostream_settings; @@ -415,7 +416,11 @@ void http_client_request_start_tunnel(struct http_client_request *req, * Client */ -struct http_client *http_client_init(const struct http_client_settings *set); +struct http_client * +http_client_init(const struct http_client_settings *set); +struct http_client * +http_client_init_shared(struct http_client_context *cctx, + const struct http_client_settings *set) ATTR_NULL(1); void http_client_deinit(struct http_client **_client); /* switch this client to the current ioloop */ @@ -428,4 +433,13 @@ void http_client_wait(struct http_client *client); unsigned int http_client_get_pending_request_count(struct http_client *client); +/* + * Client shared context + */ + +struct http_client_context * +http_client_context_create(const struct http_client_settings *set); +void http_client_context_ref(struct http_client_context *cctx); +void http_client_context_unref(struct http_client_context **_cctx); + #endif