bufq: make write/pass methods more robust

- related to #11242 where curl enters busy loop when
  sending http2 data to the server

Closes #11247
This commit is contained in:
Stefan Eissing 2023-06-04 12:43:14 +02:00 committed by Daniel Stenberg
parent b832cab112
commit 73022b52c1
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -418,7 +418,8 @@ ssize_t Curl_bufq_write(struct bufq *q,
break;
}
n = chunk_append(tail, buf, len);
DEBUGASSERT(n);
if(!n)
break;
nwritten += n;
buf += n;
len -= n;
@ -528,6 +529,14 @@ ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
}
break;
}
if(!chunk_written) {
if(!nwritten) {
/* treat as blocked */
*err = CURLE_AGAIN;
nwritten = -1;
}
break;
}
Curl_bufq_skip(q, (size_t)chunk_written);
nwritten += chunk_written;
}
@ -551,7 +560,8 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */
return -1;
}
/* would block */
/* would block, bufq is full, give up */
break;
}
}
@ -562,16 +572,24 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */
return -1;
}
/* no room in bufq, bail out */
goto out;
/* no room in bufq */
break;
}
/* edge case of writer returning 0 (and len is >0)
* break or we might enter an infinite loop here */
if(n == 0)
break;
/* Maybe only part of `data` has been added, continue to loop */
buf += (size_t)n;
len -= (size_t)n;
nwritten += (size_t)n;
}
out:
if(!nwritten && len) {
*err = CURLE_AGAIN;
return -1;
}
return nwritten;
}