]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: Only drop queued requests when a DNS lookup fails; not also the...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 24 May 2017 18:19:11 +0000 (20:19 +0200)
committerGitLab <gitlab@git.dovecot.net>
Fri, 26 May 2017 09:26:45 +0000 (12:26 +0300)
src/lib-http/http-client-host.c
src/lib-http/http-client-private.h
src/lib-http/http-client-queue.c

index 6ec76c1973e05cb84c4057c8973b250b1cac213e..02ec9edbf4c599363929de9b9d4d399cfed039bb 100644 (file)
@@ -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);
index 37cdffbd415e1442575115c625d7885f834186fb..615b088452c6e25a0ed1ad086ca5b09c1739d7c3 100644 (file)
@@ -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
index 16d74c840637ba27c441d2b387e778ffbabcac9e..6884e4cd110a46b7ec6db2f7824df686414624b2 100644 (file)
@@ -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)