Mercurial > dovecot > core-2.2
changeset 22214:1b4a0735b158
lib-http: client: Only drop queued requests when a DNS lookup fails; not also the ones that are already in progress.
author | Stephan Bosch <stephan.bosch@dovecot.fi> |
---|---|
date | Wed, 24 May 2017 20:19:11 +0200 |
parents | f8d4ae988e7f |
children | 05aff1909f97 |
files | src/lib-http/http-client-host.c src/lib-http/http-client-private.h src/lib-http/http-client-queue.c |
diffstat | 3 files changed, 39 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-http/http-client-host.c Wed May 24 21:59:32 2017 +0200 +++ b/src/lib-http/http-client-host.c Wed May 24 20:19:11 2017 +0200 @@ -53,8 +53,7 @@ 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);
--- a/src/lib-http/http-client-private.h Wed May 24 21:59:32 2017 +0200 +++ b/src/lib-http/http-client-private.h Wed May 24 20:19:11 2017 +0200 @@ -486,11 +486,11 @@ 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
--- a/src/lib-http/http-client-queue.c Wed May 24 21:59:32 2017 +0200 +++ b/src/lib-http/http-client-queue.c Wed May 24 20:19:11 2017 +0200 @@ -19,13 +19,15 @@ #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); static void http_client_queue_set_request_timer(struct http_client_queue *queue, const struct timeval *time); - /* * Logging */ @@ -165,26 +167,43 @@ * 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 @@ 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)