curl-library
[PATCH] multi: when leaving for timeout, close accordingly
Date: Sun, 16 Nov 2014 21:53:56 +0100
Fixes the problem when a transfer in a pipeline times out.
diff --git a/lib/multi.c b/lib/multi.c
index fddb4c5..ea04e57 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1009,13 +1009,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
}
- /* Force the connection closed because the server could continue to
- send us stuff at any time. (The disconnect_conn logic used below
- doesn't work at this point). */
- connclose(data->easy_conn, "Disconnected with pending data");
+ /* Force connection closed if the connection has indeed been used */
+ if(data->mstate >= CURLM_STATE_DO) {
+ connclose(data->easy_conn, "Disconnected with pending data");
+ disconnect_conn = TRUE;
+ }
data->result = CURLE_OPERATION_TIMEDOUT;
- multistate(data, CURLM_STATE_COMPLETED);
- break;
+ /* Skip the statemachine and go directly to error handling section. */
+ goto statemachine_end;
}
}
@@ -1695,6 +1696,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
default:
return CURLM_INTERNAL_ERROR;
}
+statemachine_end:
if(data->mstate < CURLM_STATE_COMPLETED) {
if(CURLE_OK != data->result) {
@@ -1720,8 +1722,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
Curl_multi_process_pending_handles(multi);
if(disconnect_conn) {
+ /* Don't attempt to send data over a connection that timed out */
+ bool dead_connection = data->result == CURLE_OPERATION_TIMEDOUT;
/* disconnect properly */
- Curl_disconnect(data->easy_conn, /* dead_connection */ FALSE);
+ Curl_disconnect(data->easy_conn, dead_connection);
/* This is where we make sure that the easy_conn pointer is reset.
We don't have to do this in every case block above where a
diff --git a/lib/url.c b/lib/url.c
index 5b19f89..d68dfaf 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3064,6 +3064,11 @@ ConnectionExists(struct SessionHandle *data,
pipeLen = check->send_pipe->size + check->recv_pipe->size;
if(canPipeline) {
+ /* We can't use the connection if the connection can't be reused,
+ or is marked for closure due to an error (ie a timeout). */
+ if(check->bits.close)
+ continue;
+
/* Make sure the pipe has only GET requests */
struct SessionHandle* sh = gethandleathead(check->send_pipe);
struct SessionHandle* rh = gethandleathead(check->recv_pipe);
-- 2.1.3 --MP_/6tePfCNEbwe6BoX3W3IeMWd Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLQpMaXN0IGFkbWluOiBodHRwOi8vY29vbC5oYXh4LnNlL2xpc3QvbGlzdGluZm8v Y3VybC1saWJyYXJ5CkV0aXF1ZXR0ZTogIGh0dHA6Ly9jdXJsLmhheHguc2UvbWFpbC9ldGlxdWV0 dGUuaHRtbA== --MP_/6tePfCNEbwe6BoX3W3IeMWd--Received on 2001-09-17