mirror of
https://github.com/curl/curl.git
synced 2026-08-25 01:03:31 +03:00
cfilters: send flush
Since data can be held in connection filter buffers when sending gives EAGAIN, add methods to query this and perform flushing of those buffers. The transfer loop will continue sending until all upload data is processed and the connection is flushed. - add `CF_QUERY_SEND_PENDING` to query filters - add `CF_CTRL_DATA_SEND_FLUSH` to flush filters - change `Curl_req_want_send()` to query the connection if it needs flushing - use `Curl_req_want_send()` to determine the POLLOUT in the PERFORMING multi state - implement flush handling in the HTTP/2 connection filter Closes #14271
This commit is contained in:
parent
911c3166b6
commit
709a6a3965
10 changed files with 278 additions and 100 deletions
54
lib/http2.c
54
lib/http2.c
|
|
@ -2413,6 +2413,48 @@ out:
|
|||
return nwritten;
|
||||
}
|
||||
|
||||
static CURLcode cf_h2_flush(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_h2_ctx *ctx = cf->ctx;
|
||||
struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data);
|
||||
struct cf_call_data save;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
CF_DATA_SAVE(save, cf, data);
|
||||
if(stream && !Curl_bufq_is_empty(&stream->sendbuf)) {
|
||||
/* resume the potentially suspended stream */
|
||||
int rv = nghttp2_session_resume_data(ctx->h2, stream->id);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
result = CURLE_SEND_ERROR;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
result = h2_progress_egress(cf, data);
|
||||
|
||||
out:
|
||||
if(stream) {
|
||||
CURL_TRC_CF(data, cf, "[%d] flush -> %d, "
|
||||
"h2 windows %d-%d (stream-conn), "
|
||||
"buffers %zu-%zu (stream-conn)",
|
||||
stream->id, result,
|
||||
nghttp2_session_get_stream_remote_window_size(
|
||||
ctx->h2, stream->id),
|
||||
nghttp2_session_get_remote_window_size(ctx->h2),
|
||||
Curl_bufq_len(&stream->sendbuf),
|
||||
Curl_bufq_len(&ctx->outbufq));
|
||||
}
|
||||
else {
|
||||
CURL_TRC_CF(data, cf, "flush -> %d, "
|
||||
"connection-window=%d, nw_send_buffer(%zu)",
|
||||
result, nghttp2_session_get_remote_window_size(ctx->h2),
|
||||
Curl_bufq_len(&ctx->outbufq));
|
||||
}
|
||||
CF_DATA_RESTORE(cf, save);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cf_h2_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct easy_pollset *ps)
|
||||
|
|
@ -2622,6 +2664,9 @@ static CURLcode cf_h2_cntrl(struct Curl_cfilter *cf,
|
|||
case CF_CTRL_DATA_PAUSE:
|
||||
result = http2_data_pause(cf, data, (arg1 != 0));
|
||||
break;
|
||||
case CF_CTRL_FLUSH:
|
||||
result = cf_h2_flush(cf, data);
|
||||
break;
|
||||
case CF_CTRL_DATA_DONE_SEND:
|
||||
result = http2_data_done_send(cf, data);
|
||||
break;
|
||||
|
|
@ -2706,6 +2751,15 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf,
|
|||
*pres1 = stream? (int)stream->error : 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
case CF_QUERY_NEED_FLUSH: {
|
||||
struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data);
|
||||
if(!Curl_bufq_is_empty(&ctx->outbufq) ||
|
||||
(stream && !Curl_bufq_is_empty(&stream->sendbuf))) {
|
||||
*pres1 = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue