url: alloc the download buffer at transfer start

... and free it as soon as the transfer is done. It removes the extra
alloc when a new size is set with setopt() and reduces memory for unused
easy handles.

In addition: the closure_handle now doesn't use an allocated buffer at
all but the smallest supported size as a stack based one.

Closes #5472
This commit is contained in:
Daniel Stenberg 2020-05-28 18:30:47 +02:00
parent 842f73de58
commit c4e6968127
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
10 changed files with 66 additions and 105 deletions

View file

@ -678,6 +678,7 @@ static CURLcode multi_done(struct Curl_easy *data,
data->state.lastconnect = NULL;
}
Curl_safefree(data->state.buffer);
Curl_free_request_state(data);
return result;
}
@ -1522,6 +1523,20 @@ static CURLcode protocol_connect(struct connectdata *conn,
return result; /* pass back status */
}
/*
* preconnect() is called immediately before a connect starts. When a redirect
* is followed, this is then called multiple times during a single transfer.
*/
static CURLcode preconnect(struct Curl_easy *data)
{
if(!data->state.buffer) {
data->state.buffer = malloc(data->set.buffer_size + 1);
if(!data->state.buffer)
return CURLE_OUT_OF_MEMORY;
}
return CURLE_OK;
}
static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct curltime now,
@ -1629,6 +1644,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
case CURLM_STATE_CONNECT:
/* Connect. We want to get a connection identifier filled in. */
/* init this transfer. */
result = preconnect(data);
if(result)
break;
Curl_pgrsTime(data, TIMER_STARTSINGLE);
if(data->set.timeout)
Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
@ -2058,7 +2078,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
char *newurl = NULL;
bool retry = FALSE;
bool comeback = FALSE;
DEBUGASSERT(data->state.buffer);
/* check if over send speed */
send_timeout_ms = 0;
if(data->set.max_send_speed > 0)