mirror of
https://github.com/curl/curl.git
synced 2026-04-15 00:41:41 +03:00
http2: ingress handling edge cases
Fix some edge cases around the `data_max_bytes` handling when processing ingress. Reported-by: Joshua Rogers Closes #18933
This commit is contained in:
parent
44a79d4f7a
commit
f609b57389
1 changed files with 18 additions and 11 deletions
29
lib/http2.c
29
lib/http2.c
|
|
@ -623,9 +623,8 @@ static int should_close_session(struct cf_h2_ctx *ctx)
|
|||
* This function returns 0 if it succeeds, or -1 and error code will
|
||||
* be assigned to *err.
|
||||
*/
|
||||
static int h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
CURLcode *err)
|
||||
static CURLcode h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_h2_ctx *ctx = cf->ctx;
|
||||
const unsigned char *buf;
|
||||
|
|
@ -633,12 +632,10 @@ static int h2_process_pending_input(struct Curl_cfilter *cf,
|
|||
ssize_t rv;
|
||||
|
||||
while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) {
|
||||
|
||||
rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen);
|
||||
if(rv < 0) {
|
||||
failf(data, "nghttp2 recv error %zd: %s", rv, nghttp2_strerror((int)rv));
|
||||
*err = CURLE_HTTP2;
|
||||
return -1;
|
||||
return CURLE_HTTP2;
|
||||
}
|
||||
Curl_bufq_skip(&ctx->inbufq, (size_t)rv);
|
||||
if(Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
|
|
@ -658,7 +655,7 @@ static int h2_process_pending_input(struct Curl_cfilter *cf,
|
|||
connclose(cf->conn, "http/2: No new requests allowed");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -690,7 +687,8 @@ static bool http2_connisalive(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||
if(!result) {
|
||||
CURL_TRC_CF(data, cf, "%zu bytes stray data read before trying "
|
||||
"h2 connection", nread);
|
||||
if(h2_process_pending_input(cf, data, &result) < 0)
|
||||
result = h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
/* immediate error, considered dead */
|
||||
alive = FALSE;
|
||||
else {
|
||||
|
|
@ -2045,10 +2043,14 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
|||
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
CURL_TRC_CF(data, cf, "Process %zu bytes in connection buffer",
|
||||
Curl_bufq_len(&ctx->inbufq));
|
||||
if(h2_process_pending_input(cf, data, &result) < 0)
|
||||
result = h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!data_max_bytes)
|
||||
data_max_bytes = H2_CHUNK_SIZE;
|
||||
|
||||
/* Receive data from the "lower" filters, e.g. network until
|
||||
* it is time to stop due to connection close or us not processing
|
||||
* all network input */
|
||||
|
|
@ -2063,6 +2065,10 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
|||
Curl_multi_mark_dirty(data);
|
||||
break;
|
||||
}
|
||||
else if(!stream) {
|
||||
DEBUGASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread);
|
||||
if(result) {
|
||||
|
|
@ -2083,7 +2089,8 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
|||
data_max_bytes = (data_max_bytes > nread) ? (data_max_bytes - nread) : 0;
|
||||
}
|
||||
|
||||
if(h2_process_pending_input(cf, data, &result))
|
||||
result = h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
CURL_TRC_CF(data, cf, "[0] progress ingress: inbufg=%zu",
|
||||
Curl_bufq_len(&ctx->inbufq));
|
||||
|
|
@ -2546,7 +2553,7 @@ static CURLcode cf_h2_connect(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
if(!first_time) {
|
||||
result = h2_progress_ingress(cf, data, H2_CHUNK_SIZE);
|
||||
result = h2_progress_ingress(cf, data, 0);
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue