mirror of
https://github.com/curl/curl.git
synced 2026-08-26 20:23:32 +03:00
http2: mark the connection for close on GOAWAY
... don't consider it an error! Assisted-by: Jay Satiro Reported-by: Łukasz Domeradzki Fixes #2365 Closes #2375
This commit is contained in:
parent
7fe68c39b3
commit
8b498a875c
3 changed files with 26 additions and 21 deletions
33
lib/http2.c
33
lib/http2.c
|
|
@ -210,7 +210,6 @@ void Curl_http2_setup_req(struct Curl_easy *data)
|
|||
http->status_code = -1;
|
||||
http->pausedata = NULL;
|
||||
http->pauselen = 0;
|
||||
http->error_code = NGHTTP2_NO_ERROR;
|
||||
http->closed = FALSE;
|
||||
http->close_handled = FALSE;
|
||||
http->mem = data->state.buffer;
|
||||
|
|
@ -223,6 +222,7 @@ void Curl_http2_setup_conn(struct connectdata *conn)
|
|||
{
|
||||
conn->proto.httpc.settings.max_concurrent_streams =
|
||||
DEFAULT_MAX_CONCURRENT_STREAMS;
|
||||
conn->proto.httpc.error_code = NGHTTP2_NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -786,6 +786,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
|||
(void)stream_id;
|
||||
|
||||
if(stream_id) {
|
||||
struct http_conn *httpc;
|
||||
/* get the stream from the hash based on Stream ID, stream ID zero is for
|
||||
connection-oriented stuff */
|
||||
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
|
||||
|
|
@ -800,10 +801,11 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
|||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
stream->error_code = error_code;
|
||||
stream->closed = TRUE;
|
||||
data_s->state.drain++;
|
||||
conn->proto.httpc.drain_total++;
|
||||
httpc = &conn->proto.httpc;
|
||||
httpc->drain_total++;
|
||||
httpc->error_code = error_code;
|
||||
|
||||
/* remove the entry from the hash as the stream is now gone */
|
||||
nghttp2_session_set_stream_user_data(session, stream_id, 0);
|
||||
|
|
@ -1234,13 +1236,14 @@ static int h2_session_send(struct Curl_easy *data,
|
|||
* 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_easy *data,
|
||||
static int h2_process_pending_input(struct connectdata *conn,
|
||||
struct http_conn *httpc,
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
char *inbuf;
|
||||
ssize_t rv;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
nread = httpc->inbuflen - httpc->nread_inbuf;
|
||||
inbuf = httpc->inbuf + httpc->nread_inbuf;
|
||||
|
|
@ -1278,7 +1281,13 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
|||
if(should_close_session(httpc)) {
|
||||
H2BUGF(infof(data,
|
||||
"h2_process_pending_input: nothing to do in this session\n"));
|
||||
*err = CURLE_HTTP2;
|
||||
if(httpc->error_code)
|
||||
*err = CURLE_HTTP2;
|
||||
else {
|
||||
/* not an error per se, but should still close the connection */
|
||||
connclose(conn, "GOAWAY received");
|
||||
*err = CURLE_OK;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1309,7 +1318,7 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
|||
that it can signal EOF to nghttp2 */
|
||||
(void)nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
|
||||
(void)h2_process_pending_input(conn->data, httpc, &result);
|
||||
(void)h2_process_pending_input(conn, httpc, &result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
@ -1333,7 +1342,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
|||
data->state.drain = 0;
|
||||
|
||||
if(httpc->pause_stream_id == 0) {
|
||||
if(h2_process_pending_input(data, httpc, err) != 0) {
|
||||
if(h2_process_pending_input(conn, httpc, err) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1342,10 +1351,10 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
|||
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
|
||||
stream->closed = FALSE;
|
||||
if(stream->error_code != NGHTTP2_NO_ERROR) {
|
||||
if(httpc->error_code != NGHTTP2_NO_ERROR) {
|
||||
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
|
||||
stream->stream_id, Curl_http2_strerror(stream->error_code),
|
||||
stream->error_code);
|
||||
stream->stream_id, Curl_http2_strerror(httpc->error_code),
|
||||
httpc->error_code);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1493,7 +1502,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
|||
/* We have paused nghttp2, but we have no pause data (see
|
||||
on_data_chunk_recv). */
|
||||
httpc->pause_stream_id = 0;
|
||||
if(h2_process_pending_input(data, httpc, &result) != 0) {
|
||||
if(h2_process_pending_input(conn, httpc, &result) != 0) {
|
||||
*err = result;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1523,7 +1532,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
|||
frames, then we have to call it again with 0-length data.
|
||||
Without this, on_stream_close callback will not be called,
|
||||
and stream could be hanged. */
|
||||
if(h2_process_pending_input(data, httpc, &result) != 0) {
|
||||
if(h2_process_pending_input(conn, httpc, &result) != 0) {
|
||||
*err = result;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue