Looks like curl_multi_remove_handle() doesn't fully remove the association between the easy handle and the connection object for long-pull request(or request with partial response). Somehow the "data" member in connection object still refer to the removed easy handle.

This comment has been minimized.

diff --git a/lib/multi.c b/lib/multi.c
index f16b594e0..6cdba393e 100644
--- a/lib/multi.c+++ b/lib/multi.c@@ -693,17 +693,17 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
}
if(data->easy_conn &&
data->mstate > CURLM_STATE_DO &&
data->mstate < CURLM_STATE_COMPLETED) {
+ /* Set connection owner so that the DONE function closes it. We can+ safely do this here since connection is killed. */+ data->easy_conn->data = easy;
/* If the handle is in a pipeline and has started sending off its
request but not received its response yet, we need to close
connection. */
streamclose(data->easy_conn, "Removed with partial response");
- /* Set connection owner so that the DONE function closes it. We can- safely do this here since connection is killed. */- data->easy_conn->data = easy;
easy_owns_conn = TRUE;
}
/* The timer must be shut down before data->multi is set to NULL,
else the timenode will remain in the splay tree after