From: Stephan Bosch Date: Wed, 24 May 2017 18:19:11 +0000 (+0200) Subject: lib-http: client: Only drop queued requests when a DNS lookup fails; not also the... X-Git-Tag: 2.3.0.rc1~1562 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5791d02c3672f6a525f1fcf0f4f375b4be0ccf4b;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: Only drop queued requests when a DNS lookup fails; not also the ones that are already in progress. --- diff --git a/src/lib-http/http-client-host.c b/src/lib-http/http-client-host.c index 6ec76c1973..02ec9edbf4 100644 --- a/src/lib-http/http-client-host.c +++ b/src/lib-http/http-client-host.c @@ -53,8 +53,7 @@ http_client_host_lookup_failure(struct http_client_host *host, error = t_strdup_printf("Failed to lookup host %s: %s", host->name, error); array_foreach_modifiable(&host->queues, queue_idx) { - http_client_queue_fail(*queue_idx, - HTTP_CLIENT_REQUEST_ERROR_HOST_LOOKUP_FAILED, error); + http_client_queue_host_lookup_failure(*queue_idx, error); } http_client_host_check_idle(host); diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index 37cdffbd41..615b088452 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -486,11 +486,11 @@ struct http_client_queue * http_client_queue_create(struct http_client_host *host, const struct http_client_peer_addr *addr); void http_client_queue_free(struct http_client_queue *queue); -void http_client_queue_fail(struct http_client_queue *queue, - unsigned int status, const char *error); void http_client_queue_connection_setup(struct http_client_queue *queue); unsigned int http_client_queue_host_lookup_done(struct http_client_queue *queue); +void http_client_queue_host_lookup_failure( + struct http_client_queue *queue, const char *error); void http_client_queue_submit_request(struct http_client_queue *queue, struct http_client_request *req); void diff --git a/src/lib-http/http-client-queue.c b/src/lib-http/http-client-queue.c index 16d74c8406..6884e4cd11 100644 --- a/src/lib-http/http-client-queue.c +++ b/src/lib-http/http-client-queue.c @@ -18,6 +18,9 @@ #define TIMEOUT_CMP_MARGIN_USECS 2000 +static void +http_client_queue_fail(struct http_client_queue *queue, + unsigned int status, const char *error); static void http_client_queue_set_delay_timer(struct http_client_queue *queue, struct timeval time); @@ -25,7 +28,6 @@ static void http_client_queue_set_request_timer(struct http_client_queue *queue, const struct timeval *time); - /* * Logging */ @@ -165,26 +167,43 @@ void http_client_queue_free(struct http_client_queue *queue) * Error handling */ -void http_client_queue_fail(struct http_client_queue *queue, - unsigned int status, const char *error) +static void +http_client_queue_fail_full(struct http_client_queue *queue, + unsigned int status, const char *error, bool queued_only) { ARRAY_TYPE(http_client_request) *req_arr, treqs; struct http_client_request **req_idx; + unsigned int retained = 0; - /* abort all pending requests */ + /* abort requests */ req_arr = &queue->requests; t_array_init(&treqs, array_count(req_arr)); array_copy(&treqs.arr, 0, &req_arr->arr, 0, array_count(req_arr)); array_foreach_modifiable(&treqs, req_idx) { - http_client_request_error(req_idx, status, error); + struct http_client_request *req = *req_idx; + + i_assert(req->state >= HTTP_REQUEST_STATE_QUEUED); + if (queued_only && + req->state != HTTP_REQUEST_STATE_QUEUED) + retained++; + else + http_client_request_error(&req, status, error); } - /* all queues should be empty now... unless new requests were submitted - from the callback. this invariant captures it all: */ - i_assert((array_count(&queue->delayed_requests) + + /* all queues should be empty now... unless new requests were submitted + from the callback. this invariant captures it all: */ + i_assert((retained + + array_count(&queue->delayed_requests) + array_count(&queue->queued_requests) + array_count(&queue->queued_urgent_requests)) == - array_count(&queue->requests)); + array_count(&queue->requests)); +} + +static void +http_client_queue_fail(struct http_client_queue *queue, + unsigned int status, const char *error) +{ + http_client_queue_fail_full(queue, status, error, FALSE); } /* @@ -423,6 +442,14 @@ http_client_queue_host_lookup_done(struct http_client_queue *queue) return reqs_pending; } +void http_client_queue_host_lookup_failure( + struct http_client_queue *queue, const char *error) +{ + http_client_queue_fail_full(queue, + HTTP_CLIENT_REQUEST_ERROR_HOST_LOOKUP_FAILED, + error, TRUE); +} + void http_client_queue_connection_success(struct http_client_queue *queue, const struct http_client_peer_addr *addr)