mirror of
https://github.com/curl/curl.git
synced 2026-07-24 18:57:18 +03:00
http2: reset stream on response header error
We send a GOAWAY, but some servers ignore that and happily continue sending the stream response. RST the stream when response header errors are encountered. Fixes #16535 Reported-by: Peng-Yu Chen Closes #16544
This commit is contained in:
parent
ed15fce1fd
commit
e7de83aa29
1 changed files with 17 additions and 6 deletions
23
lib/http2.c
23
lib/http2.c
|
|
@ -1500,10 +1500,21 @@ static int on_begin_headers(nghttp2_session *session,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void report_header_error(struct Curl_easy *data, CURLcode result)
|
||||
static void cf_h2_header_error(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h2_stream_ctx *stream,
|
||||
CURLcode result)
|
||||
{
|
||||
struct cf_h2_ctx *ctx = cf->ctx;
|
||||
|
||||
failf(data, "Error receiving HTTP2 header: %d(%s)", result,
|
||||
curl_easy_strerror(result));
|
||||
if(stream) {
|
||||
nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE,
|
||||
stream->id, NGHTTP2_STREAM_CLOSED);
|
||||
stream->closed = TRUE;
|
||||
stream->reset = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
|
||||
|
|
@ -1606,7 +1617,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
(const char *)name, namelen,
|
||||
(const char *)value, valuelen);
|
||||
if(result) {
|
||||
report_header_error(data_s, result);
|
||||
cf_h2_header_error(cf, data_s, stream, result);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -1620,14 +1631,14 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
result = Curl_http_decode_status(&stream->status_code,
|
||||
(const char *)value, valuelen);
|
||||
if(result) {
|
||||
report_header_error(data_s, result);
|
||||
cf_h2_header_error(cf, data_s, stream, result);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
msnprintf(buffer, sizeof(buffer), HTTP_PSEUDO_STATUS ":%u\r",
|
||||
stream->status_code);
|
||||
result = Curl_headers_push(data_s, buffer, CURLH_PSEUDO);
|
||||
if(result) {
|
||||
report_header_error(data_s, result);
|
||||
cf_h2_header_error(cf, data_s, stream, result);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
Curl_dyn_reset(&ctx->scratch);
|
||||
|
|
@ -1640,7 +1651,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
h2_xfer_write_resp_hd(cf, data_s, stream, Curl_dyn_ptr(&ctx->scratch),
|
||||
Curl_dyn_len(&ctx->scratch), FALSE);
|
||||
if(result) {
|
||||
report_header_error(data_s, result);
|
||||
cf_h2_header_error(cf, data_s, stream, result);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
/* if we receive data for another handle, wake that up */
|
||||
|
|
@ -1667,7 +1678,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
h2_xfer_write_resp_hd(cf, data_s, stream, Curl_dyn_ptr(&ctx->scratch),
|
||||
Curl_dyn_len(&ctx->scratch), FALSE);
|
||||
if(result) {
|
||||
report_header_error(data_s, result);
|
||||
cf_h2_header_error(cf, data_s, stream, result);
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
/* if we receive data for another handle, wake that up */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue