FILE: don't wait due to CURLOPT_MAX_RECV_SPEED_LARGE
authorDaniel Stenberg <daniel@haxx.se>
Sun, 22 Dec 2013 22:36:11 +0000 (23:36 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 22 Dec 2013 22:44:14 +0000 (23:44 +0100)
The FILE:// code doesn't support this option - and it doesn't make sense
to support it as long as it works as it does since then it'd only block
even longer.

But: setting CURLOPT_MAX_RECV_SPEED_LARGE would make the transfer first
get done and then libcurl would wait until the average speed would get
low enough. This happened because the transfer happens completely in the
DO state for FILE:// but then it would still unconditionally continue in
to the PERFORM state where the speed check is made.

Starting now, the code will skip from DO_DONE to DONE immediately if no
socket is set to be recv()ed or send()ed to.

Bug: http://curl.haxx.se/bug/view.cgi?id=1312
Reported-by: Mohammad AlSaleh
lib/multi.c

index ec45ecb17f4b0731bb0380c86cde39b49236693e..191c9b88a40e0345b5a79e53c513f519c5456f5b 100644 (file)
@@ -1381,7 +1381,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
       /* Check if we can move pending requests to send pipe */
       Curl_multi_process_pending_handles(multi);
-      multistate(data, CURLM_STATE_WAITPERFORM);
+
+      /* Only perform the transfer if there's a good socket to work with.
+         Having both BAD is a signal to skip immediately to DONE */
+      if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
+         (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
+        multistate(data, CURLM_STATE_WAITPERFORM);
+      else
+        multistate(data, CURLM_STATE_DONE);
       result = CURLM_CALL_MULTI_PERFORM;
       break;