Skip to content

Commit

Permalink
lib-http: client: Only drop queued requests when a DNS lookup fails; …
Browse files Browse the repository at this point in the history
…not also the ones that are already in progress.
  • Loading branch information
stephanbosch authored and villesavolainen committed Jun 16, 2017
1 parent 4d14871 commit 6266ce1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 13 deletions.
3 changes: 1 addition & 2 deletions src/lib-http/http-client-host.c
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/lib-http/http-client-private.h
Expand Up @@ -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
Expand Down
45 changes: 36 additions & 9 deletions src/lib-http/http-client-queue.c
Expand Up @@ -18,14 +18,16 @@

#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
*/
Expand Down Expand Up @@ -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);
}

/*
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 6266ce1

Please sign in to comment.