summaryrefslogtreecommitdiff
path: root/lib/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/connect.c')
-rw-r--r--lib/connect.c78
1 files changed, 38 insertions, 40 deletions
diff --git a/lib/connect.c b/lib/connect.c
index f9dd415ba..296fb6250 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -171,65 +171,63 @@ singleipconnect(struct Curl_easy *data,
* infinite time left). If the value is negative, the timeout time has already
* elapsed.
*
- * The start time is stored in progress.t_startsingle - as set with
- * Curl_pgrsTime(..., TIMER_STARTSINGLE);
- *
* If 'nowp' is non-NULL, it points to the current time.
* 'duringconnect' is FALSE if not during a connect, as then of course the
* connect timeout is not taken into account!
*
* @unittest: 1303
*/
+
+#define TIMEOUT_CONNECT 1
+#define TIMEOUT_MAXTIME 2
+
timediff_t Curl_timeleft(struct Curl_easy *data,
struct curltime *nowp,
bool duringconnect)
{
- int timeout_set = 0;
- timediff_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
+ unsigned int timeout_set = 0;
+ timediff_t connect_timeout_ms = 0;
+ timediff_t maxtime_timeout_ms = 0;
+ timediff_t timeout_ms = 0;
struct curltime now;
- /* if a timeout is set, use the most restrictive one */
-
- if(data->set.timeout > 0)
- timeout_set |= 1;
- if(duringconnect && (data->set.connecttimeout > 0))
- timeout_set |= 2;
-
- switch(timeout_set) {
- case 1:
- timeout_ms = data->set.timeout;
- break;
- case 2:
- timeout_ms = data->set.connecttimeout;
- break;
- case 3:
- if(data->set.timeout < data->set.connecttimeout)
- timeout_ms = data->set.timeout;
- else
- timeout_ms = data->set.connecttimeout;
- break;
- default:
- /* use the default */
- if(!duringconnect)
- /* if we're not during connect, there's no default timeout so if we're
- at zero we better just return zero and not make it a negative number
- by the math below */
- return 0;
- break;
+ /* The duration of a connect and the total transfer are calculated from two
+ different time-stamps. It can end up with the total timeout being reached
+ before the connect timeout expires and we must acknowledge whichever
+ timeout that is reached first. The total timeout is set per entire
+ operation, while the connect timeout is set per connect. */
+
+ if(data->set.timeout > 0) {
+ timeout_set = TIMEOUT_MAXTIME;
+ maxtime_timeout_ms = data->set.timeout;
+ }
+ if(duringconnect) {
+ timeout_set |= TIMEOUT_CONNECT;
+ connect_timeout_ms = (data->set.connecttimeout > 0) ?
+ data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
}
+ if(!timeout_set)
+ /* no timeout */
+ return 0;
if(!nowp) {
now = Curl_now();
nowp = &now;
}
- /* subtract elapsed time */
- if(duringconnect)
- /* since this most recent connect started */
- timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle);
- else
- /* since the entire operation started */
- timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop);
+ if(timeout_set & TIMEOUT_MAXTIME) {
+ maxtime_timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop);
+ timeout_ms = maxtime_timeout_ms;
+ }
+
+ if(timeout_set & TIMEOUT_CONNECT) {
+ connect_timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle);
+
+ if(!(timeout_set & TIMEOUT_MAXTIME) ||
+ (connect_timeout_ms < maxtime_timeout_ms))
+ timeout_ms = connect_timeout_ms;
+ }
+
if(!timeout_ms)
/* avoid returning 0 as that means no timeout! */
return -1;