Skip to content

Commit

Permalink
lib-http: client: When a request is destroyed prematurely during payl…
Browse files Browse the repository at this point in the history
…oad input, consider the payload stream destroyed and act accordingly.

The application may hold a reference to the payload stream still, and it may be difficult to prevent that.
This causes lib-http to keep waiting for the payload to be destroyed.
When nothing else is going on, the current ioloop may then become empty, which caused the familiar assert failure.
  • Loading branch information
stephanbosch authored and villesavolainen committed Jun 16, 2017
1 parent 9dc6c1c commit 4d14871
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/lib-http/http-client-connection.c
Expand Up @@ -646,7 +646,7 @@ static void http_client_payload_destroyed(struct http_client_request *req)
void http_client_connection_request_destroyed(
struct http_client_connection *conn, struct http_client_request *req)
{
struct istream *payload = conn->incoming_payload;
struct istream *payload;

i_assert(req->conn == conn);
if (conn->pending_request != req)
Expand All @@ -655,10 +655,28 @@ void http_client_connection_request_destroyed(
http_client_connection_debug(conn,
"Pending request destroyed prematurely");

if (payload == NULL)
payload = conn->incoming_payload;
if (payload == NULL) {
/* payload already gone */
return;
}

/* destroy the payload, so that the timeout istream is closed */
i_stream_ref(payload);
i_stream_destroy(&payload);

payload = conn->incoming_payload;
if (payload == NULL) {
/* not going to happen, but check for it anyway */
return;
}

/* the application still holds a reference to the payload stream, but it
is closed and we don't care about it anymore, so act as though it is
destroyed. */
i_stream_remove_destroy_callback(payload,
http_client_payload_destroyed);
http_client_payload_destroyed(req);
}

static bool
Expand Down

0 comments on commit 4d14871

Please sign in to comment.