mirror of
https://github.com/curl/curl.git
synced 2026-07-30 14:18:41 +03:00
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
This commit is contained in:
parent
7645c6bd5e
commit
d122df5972
4 changed files with 31 additions and 9 deletions
|
|
@ -1926,7 +1926,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
|||
char **url)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
bool retry = FALSE;
|
||||
*url = NULL;
|
||||
|
||||
/* if we're talking upload, we can't do the checks below, unless the protocol
|
||||
|
|
@ -1939,7 +1939,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
|||
conn->bits.reuse &&
|
||||
(!data->set.opt_no_body
|
||||
|| (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
|
||||
(data->set.rtspreq != RTSPREQ_RECEIVE)) {
|
||||
(data->set.rtspreq != RTSPREQ_RECEIVE))
|
||||
/* We got no data, we attempted to re-use a connection. For HTTP this
|
||||
can be a retry so we try again regardless if we expected a body.
|
||||
For other protocols we only try again only if we expected a body.
|
||||
|
|
@ -1947,6 +1947,19 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
|||
This might happen if the connection was left alive when we were
|
||||
done using it before, but that was closed when we wanted to read from
|
||||
it again. Bad luck. Retry the same request on a fresh connect! */
|
||||
retry = TRUE;
|
||||
else if(data->state.refused_stream &&
|
||||
(data->req.bytecount + data->req.headerbytecount == 0) ) {
|
||||
/* This was sent on a refused stream, safe to rerun. A refused stream
|
||||
error can typically only happen on HTTP/2 level if the stream is safe
|
||||
to issue again, but the nghttp2 API can deliver the message to other
|
||||
streams as well, which is why this adds the check the data counters
|
||||
too. */
|
||||
infof(conn->data, "REFUSED_STREAM, retrying a fresh connect\n");
|
||||
data->state.refused_stream = FALSE; /* clear again */
|
||||
retry = TRUE;
|
||||
}
|
||||
if(retry) {
|
||||
infof(conn->data, "Connection died, retrying a fresh connect\n");
|
||||
*url = strdup(conn->data->change.url);
|
||||
if(!*url)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue