Commit 92c2a4c0 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa Committed by Jay Satiro
Browse files

http2: Add handling stream level error

Previously, when a stream was closed with other than NGHTTP2_NO_ERROR
by RST_STREAM, underlying TCP connection was dropped.  This is
undesirable since there may be other streams multiplexed and they are
very much fine.  This change introduce new error code
CURLE_HTTP2_STREAM, which indicates stream error that only affects the
relevant stream, and connection should be kept open.  The existing
CURLE_HTTP2 means connection error in general.

Ref: https://github.com/curl/curl/issues/659
Ref: https://github.com/curl/curl/pull/663
parent b2a03763
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -251,6 +251,8 @@ available, the session will be queued. (added in 7.30.0)
Failed to match the pinned key specified with \fICURLOPT_PINNEDPUBLICKEY(3)\fP.
.IP "CURLE_SSL_INVALIDCERTSTATUS (91)"
Status returned failure when asked with \fICURLOPT_SSL_VERIFYSTATUS(3)\fP.
.IP "CURLE_HTTP2_STREAM (92)"
Stream error in the HTTP/2 framing layer.
.IP "CURLE_OBSOLETE*"
These error codes will never be returned. They were used in an old libcurl
version and are currently unused.
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ CURLE_FTP_WRITE_ERROR 7.1 7.17.0
CURLE_FUNCTION_NOT_FOUND        7.1
CURLE_GOT_NOTHING               7.9.1
CURLE_HTTP2                     7.38.0
CURLE_HTTP2_STREAM              7.49.0
CURLE_HTTP_NOT_FOUND            7.1
CURLE_HTTP_PORT_FAILED          7.3           7.12.0
CURLE_HTTP_POST_ERROR           7.1
+2 −0
Original line number Diff line number Diff line
@@ -537,6 +537,8 @@ typedef enum {
  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
                                     match */
  CURLE_SSL_INVALIDCERTSTATUS,   /* 91 - invalid certificate status */
  CURLE_HTTP2_STREAM,            /* 92 - stream error in HTTP/2 framing layer
                                    */
  CURL_LAST /* never use! */
} CURLcode;

+8 −1
Original line number Diff line number Diff line
@@ -1059,7 +1059,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
  if(stream->error_code != NGHTTP2_NO_ERROR) {
    failf(data, "HTTP/2 stream %u was not closed cleanly: error_code = %d",
          stream->stream_id, stream->error_code);
    *err = CURLE_HTTP2;
    *err = CURLE_HTTP2_STREAM;
    return -1;
  }

@@ -1231,6 +1231,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
    *err = CURLE_AGAIN;
    return -1;
  }
  else if(!nghttp2_session_want_read(httpc->h2) &&
          !nghttp2_session_want_write(httpc->h2)) {
    DEBUGF(infof(data,
                 "http2_recv: nothing to do in this session\n"));
    *err = CURLE_HTTP2;
    return -1;
  }
  else {
    char *inbuf;
    /* remember where to store incoming data for this stream and how big the
+2 −1
Original line number Diff line number Diff line
@@ -1880,7 +1880,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         * happened in the data connection.
         */

        if(!(data->easy_conn->handler->flags & PROTOPT_DUAL))
        if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
           result != CURLE_HTTP2_STREAM)
          connclose(data->easy_conn, "Transfer returned error");

        Curl_posttransfer(data);
Loading