From 76013540c3a0d78f3723fede54465f35b00b41ea Mon Sep 17 00:00:00 2001 From: Basuke Suzuki Date: Fri, 5 Jan 2018 15:39:07 -0800 Subject: [PATCH 1/2] Fix connection ownership issue #2217 Before calling Curl_client_chop_write(), change the owner of connection to the current Curl_easy handle. This will fix the issue #2217. --- lib/easy.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/easy.c b/lib/easy.c index 75f332b07a00c6..248fd4d737447f 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1056,11 +1056,18 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) for(i = 0; i < count; i++) { /* even if one function returns error, this loops through and frees all buffers */ - if(!result) - result = Curl_client_chop_write(data->easy_conn, + if(!result) { + struct connectdata *conn = data->easy_conn; + if(conn && conn->data != data && data->mstate > CURLM_STATE_CONNECT && + data->mstate < CURLM_STATE_COMPLETED) + /* Make sure we set the connection's current owner */ + conn->data = data; + + result = Curl_client_chop_write(conn, writebuf[i].type, writebuf[i].buf, writebuf[i].len); + } free(writebuf[i].buf); } if(result) From 8fca099706432cdf0d205737938ab58ddc0733cc Mon Sep 17 00:00:00 2001 From: Basuke Suzuki Date: Mon, 8 Jan 2018 11:35:59 -0800 Subject: [PATCH 2/2] Recover old connection owner Also remove unnecessary state check. --- lib/easy.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/easy.c b/lib/easy.c index 248fd4d737447f..38517952e8f11a 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -1045,6 +1045,8 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) unsigned int i; unsigned int count = data->state.tempcount; struct tempbuf writebuf[3]; /* there can only be three */ + struct connectdata *conn = data->easy_conn; + struct Curl_easy *saved_data = NULL; /* copy the structs to allow for immediate re-pausing */ for(i = 0; i < data->state.tempcount; i++) { @@ -1053,23 +1055,26 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) } data->state.tempcount = 0; + if(conn && conn->data != data) { + /* Make sure we set the connection's current owner */ + saved_data = conn->data; + conn->data = data; + } + for(i = 0; i < count; i++) { /* even if one function returns error, this loops through and frees all buffers */ - if(!result) { - struct connectdata *conn = data->easy_conn; - if(conn && conn->data != data && data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_COMPLETED) - /* Make sure we set the connection's current owner */ - conn->data = data; - + if(!result) result = Curl_client_chop_write(conn, writebuf[i].type, writebuf[i].buf, writebuf[i].len); - } free(writebuf[i].buf); } + /* recover previous owner of the connection */ + if(saved_data) + conn->data = saved_data; + if(result) return result; }