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; break;
} }
n = chunk_append(tail, buf, len); n = chunk_append(tail, buf, len);
DEBUGASSERT(n); if(!n)
break;
nwritten += n; nwritten += n;
buf += n; buf += n;
len -= n; len -= n;
@ -528,6 +529,14 @@ ssize_t Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
} }
break; break;
} }
if(!chunk_written) {
if(!nwritten) {
/* treat as blocked */
*err = CURLE_AGAIN;
nwritten = -1;
}
break;
}
Curl_bufq_skip(q, (size_t)chunk_written); Curl_bufq_skip(q, (size_t)chunk_written);
nwritten += chunk_written; nwritten += chunk_written;
} }
@ -551,7 +560,8 @@ ssize_t Curl_bufq_write_pass(struct bufq *q,
/* real error, fail */ /* real error, fail */
return -1; 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 */ /* real error, fail */
return -1; return -1;
} }
/* no room in bufq, bail out */ /* no room in bufq */
goto out; 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 */ /* Maybe only part of `data` has been added, continue to loop */
buf += (size_t)n; buf += (size_t)n;
len -= (size_t)n; len -= (size_t)n;
nwritten += (size_t)n; nwritten += (size_t)n;
} }
out: if(!nwritten && len) {
*err = CURLE_AGAIN;
return -1;
}
return nwritten; return nwritten;
} }