diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index 7f6ce09d7..e928ba5d0 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -1715,18 +1715,34 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf, { struct cf_call_data save; ssize_t nread; + size_t ntotal = 0; CF_DATA_SAVE(save, cf, data); *err = CURLE_OK; - nread = Curl_ssl->recv_plain(cf, data, buf, len, err); - if(nread > 0) { - DEBUGASSERT((size_t)nread <= len); - } - else if(nread == 0) { - /* eof */ + /* Do receive until we fill the buffer somehwhat or EGAIN, error or EOF */ + while(!ntotal || (len - ntotal) > (4*1024)) { *err = CURLE_OK; + nread = Curl_ssl->recv_plain(cf, data, buf + ntotal, len - ntotal, err); + if(nread < 0) { + if(*err == CURLE_AGAIN && ntotal > 0) { + /* we EAGAINed after having reed data, return the success amount */ + *err = CURLE_OK; + break; + } + /* we have a an error to report */ + goto out; + } + else if(nread == 0) { + /* eof */ + break; + } + ntotal += (size_t)nread; + DEBUGASSERT((size_t)ntotal <= len); } - CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len, nread, *err); + nread = (ssize_t)ntotal; +out: + CURL_TRC_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len, + nread, *err); CF_DATA_RESTORE(cf, save); return nread; }