mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:31:41 +03:00
timeout handling: auto-detect effective timeout
When checking a transfer for being expired via `Curl_timeleft_ms()`, eleminate the `bool connecting` parameter and have the function check the `mstate` of the transfer instead. Advantages: * eleminate the caller needing awareness if the transfer is connecting or in a later state * fix pingpong timeout handling to check the correct timeout during "proto_connect" phases * avoid using "connecting" timeouts during establishing a secondary connection (e.g. FTP) since this would use the timestamp from the original, primary connect and thus be wrong Reported-by: Wyuer on github Fixes #20347 Closes #20354
This commit is contained in:
parent
3d354f55b7
commit
8ce16e7bf2
25 changed files with 73 additions and 79 deletions
|
|
@ -100,25 +100,27 @@ enum alpnid Curl_str2alpnid(const struct Curl_str *cstr)
|
|||
* transfer/connection. If the value is 0, there is no timeout (ie there is
|
||||
* infinite time left). If the value is negative, the timeout time has already
|
||||
* elapsed.
|
||||
* @param data the transfer to check on
|
||||
* @param duringconnect TRUE iff connect timeout is also taken into account.
|
||||
* @unittest: 1303
|
||||
*/
|
||||
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
|
||||
const struct curltime *pnow,
|
||||
bool duringconnect)
|
||||
const struct curltime *pnow)
|
||||
{
|
||||
timediff_t timeleft_ms = 0;
|
||||
timediff_t ctimeleft_ms = 0;
|
||||
timediff_t ctimeout_ms;
|
||||
|
||||
/* 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 || data->set.connect_only) && !duringconnect)
|
||||
if(Curl_shutdown_started(data, FIRSTSOCKET))
|
||||
return Curl_shutdown_timeleft(data, data->conn, FIRSTSOCKET);
|
||||
else if(Curl_is_connecting(data)) {
|
||||
timediff_t ctimeout_ms = (data->set.connecttimeout > 0) ?
|
||||
data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
|
||||
ctimeleft_ms = ctimeout_ms -
|
||||
curlx_ptimediff_ms(pnow, &data->progress.t_startsingle);
|
||||
if(!ctimeleft_ms)
|
||||
ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
}
|
||||
else if(!data->set.timeout || data->set.connect_only) {
|
||||
return 0; /* no timeout in place or checked, return "no limit" */
|
||||
}
|
||||
|
||||
if(data->set.timeout) {
|
||||
timeleft_ms = data->set.timeout -
|
||||
|
|
@ -127,25 +129,16 @@ timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
|
|||
timeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
}
|
||||
|
||||
if(!duringconnect)
|
||||
return timeleft_ms; /* no connect check, this is it */
|
||||
ctimeout_ms = (data->set.connecttimeout > 0) ?
|
||||
data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
|
||||
ctimeleft_ms = ctimeout_ms -
|
||||
curlx_ptimediff_ms(pnow, &data->progress.t_startsingle);
|
||||
if(!ctimeleft_ms)
|
||||
ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!timeleft_ms)
|
||||
return ctimeleft_ms; /* no general timeout, this is it */
|
||||
|
||||
/* return minimal time left or max amount already expired */
|
||||
return (ctimeleft_ms < timeleft_ms) ? ctimeleft_ms : timeleft_ms;
|
||||
return timeleft_ms;
|
||||
else if(!timeleft_ms)
|
||||
return ctimeleft_ms;
|
||||
return CURLMIN(ctimeleft_ms, timeleft_ms);
|
||||
}
|
||||
|
||||
timediff_t Curl_timeleft_ms(struct Curl_easy *data,
|
||||
bool duringconnect)
|
||||
timediff_t Curl_timeleft_ms(struct Curl_easy *data)
|
||||
{
|
||||
return Curl_timeleft_now_ms(data, Curl_pgrs_now(data), duringconnect);
|
||||
return Curl_timeleft_now_ms(data, Curl_pgrs_now(data));
|
||||
}
|
||||
|
||||
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
|
|
@ -162,6 +155,8 @@ void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
|||
/* Set a timer, unless we operate on the admin handle */
|
||||
if(data->mid)
|
||||
Curl_expire_ex(data, conn->shutdown.timeout_ms, EXPIRE_SHUTDOWN);
|
||||
CURL_TRC_M(data, "shutdown start on%s connection",
|
||||
sockindex ? " secondary" : "");
|
||||
}
|
||||
|
||||
timediff_t Curl_shutdown_timeleft(struct Curl_easy *data,
|
||||
|
|
@ -204,8 +199,11 @@ void Curl_shutdown_clear(struct Curl_easy *data, int sockindex)
|
|||
|
||||
bool Curl_shutdown_started(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
struct curltime *pt = &data->conn->shutdown.start[sockindex];
|
||||
return (pt->tv_sec > 0) || (pt->tv_usec > 0);
|
||||
if(data->conn) {
|
||||
struct curltime *pt = &data->conn->shutdown.start[sockindex];
|
||||
return (pt->tv_sec > 0) || (pt->tv_usec > 0);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* retrieves ip address and port from a sockaddr structure. note it calls
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue