vtls and h2 improvements

- eliminate receive loop in vtls to fill buffer. This may
  lead to partial reads of data which is counter productive
- let http2 instead loop smarter to process pending network
  data without transfer switches

scorecard improvements
- do not start caddy when only httpd is requested
- allow curl -v to stderr file on --curl-verbose

Closes #10891
This commit is contained in:
Stefan Eissing 2023-04-05 14:52:16 +02:00 committed by Daniel Stenberg
parent 3da642c4f0
commit 8f50e393ab
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
5 changed files with 241 additions and 214 deletions

View file

@ -76,12 +76,19 @@ static size_t chunk_read(struct buf_chunk *chunk,
unsigned char *p = &chunk->x.data[chunk->r_offset];
size_t n = chunk->w_offset - chunk->r_offset;
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
if(n) {
n = CURLMIN(n, len);
memcpy(buf, p, n);
chunk->r_offset += n;
if(!n) {
return 0;
}
else if(n <= len) {
memcpy(buf, p, n);
chunk->r_offset = chunk->w_offset = 0;
return n;
}
else {
memcpy(buf, p, len);
chunk->r_offset += len;
return len;
}
return n;
}
static ssize_t chunk_slurpn(struct buf_chunk *chunk, size_t max_len,

View file

@ -1643,6 +1643,7 @@ static ssize_t stream_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
ssize_t nread = -1;
*err = CURLE_AGAIN;
drained_transfer(cf, data);
if(!Curl_bufq_is_empty(&stream->h2_recvbuf)) {
nread = Curl_bufq_read(&stream->h2_recvbuf,
(unsigned char *)buf, len, err);
@ -1682,7 +1683,6 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
struct HTTP *stream = data->req.p.http;
CURLcode result = CURLE_OK;
ssize_t nread;
bool keep_reading = TRUE;
/* Process network input buffer fist */
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
@ -1694,12 +1694,11 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
/* Receive data from the "lower" filters, e.g. network until
* it is time to stop or we have enough data for this stream */
while(keep_reading &&
!ctx->conn_closed && /* not closed the connection */
while(!ctx->conn_closed && /* not closed the connection */
!stream->closed && /* nor the stream */
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
!Curl_bufq_is_full(&stream->h2_recvbuf) && /* enough? */
Curl_bufq_len(&stream->h2_recvbuf) < data->set.buffer_size) {
1 /* Curl_bufq_len(&stream->h2_recvbuf) < data->set.buffer_size */) {
nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
@ -1716,7 +1715,6 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
break;
}
keep_reading = Curl_bufq_is_full(&ctx->inbufq);
if(h2_process_pending_input(cf, data, &result))
return result;
}
@ -1755,9 +1753,6 @@ static ssize_t cf_h2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
goto out;
nread = stream_recv(cf, data, buf, len, err);
if(Curl_bufq_is_empty(&stream->h2_recvbuf)) {
drained_transfer(cf, data);
}
}
if(nread > 0) {

View file

@ -1578,45 +1578,20 @@ static ssize_t ssl_cf_recv(struct Curl_cfilter *cf,
CURLcode *err)
{
struct cf_call_data save;
ssize_t nread, n;
ssize_t nread;
CF_DATA_SAVE(save, cf, data);
/* SSL backends like OpenSSL/wolfSSL prefer to give us 1 TLS record content
* at a time when reading. But commonly, more data is available.
* So we try to fill the buffer we are called with until we
* are full or no more data is available. */
*err = CURLE_OK;
nread = 0;
while(len) {
n = Curl_ssl->recv_plain(cf, data, buf, len, err);
if(n < 0) {
if(*err != CURLE_AGAIN) {
/* serious err, fail */
nread = -1;
goto out;
}
/* would block, return this to caller if we have read nothing so far,
* otherwise return amount read without error. */
if(nread == 0)
nread = -1;
else
*err = CURLE_OK;
goto out;
}
else if(n == 0) {
/* eof */
break;
}
else {
DEBUGASSERT((size_t)n <= len);
nread += (size_t)n;
buf += (size_t)n;
len -= (size_t)n;
}
nread = Curl_ssl->recv_plain(cf, data, buf, len, err);
if(nread > 0) {
DEBUGASSERT((size_t)nread <= len);
}
out:
CF_DATA_RESTORE(cf, save);
return nread;
else if(nread == 0) {
/* eof */
*err = CURLE_OK;
}
DEBUGF(LOG_CF(data, cf, "cf_recv(len=%zu) -> %zd, %d", len, nread, *err));
CF_DATA_RESTORE(cf, save);
return nread;
}
static int ssl_cf_get_select_socks(struct Curl_cfilter *cf,