From d122df5972fc01e39ae28e6bca705237d7e3318a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 19 Apr 2018 20:03:30 +0200 Subject: http2: handle GOAWAY properly When receiving REFUSED_STREAM, mark the connection for close and retry streams accordingly on another/fresh connection. Reported-by: Terry Wu Fixes #2416 Fixes #1618 Closes #2510 --- lib/http2.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'lib/http2.c') diff --git a/lib/http2.c b/lib/http2.c index 6ac69b9b5..fe5fdb1b8 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -1106,7 +1106,6 @@ void Curl_http2_done(struct connectdata *conn, bool premature) struct http_conn *httpc = &conn->proto.httpc; if(http->header_recvbuf) { - H2BUGF(infof(data, "free header_recvbuf!!\n")); Curl_add_buffer_free(http->header_recvbuf); http->header_recvbuf = NULL; /* clear the pointer */ Curl_add_buffer_free(http->trailer_recvbuf); @@ -1376,7 +1375,15 @@ 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(httpc->error_code != NGHTTP2_NO_ERROR) { + if(httpc->error_code == NGHTTP2_REFUSED_STREAM) { + H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n", + stream->stream_id)); + connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */ + data->state.refused_stream = TRUE; + *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ + return -1; + } + else 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(httpc->error_code), httpc->error_code); @@ -1604,9 +1611,9 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex, } if(nread == 0) { - failf(data, "Unexpected EOF"); - *err = CURLE_RECV_ERROR; - return -1; + H2BUGF(infof(data, "end of stream\n")); + *err = CURLE_OK; + return 0; } H2BUGF(infof(data, "nread=%zd\n", nread)); -- cgit v1.2.3