]> granicus.if.org Git - curl/commitdiff
http2: Add handling stream level error
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Wed, 17 Feb 2016 12:36:59 +0000 (21:36 +0900)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 12 Apr 2016 01:43:24 +0000 (21:43 -0400)
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

docs/libcurl/libcurl-errors.3
docs/libcurl/symbols-in-versions
include/curl/curl.h
lib/http2.c
lib/multi.c
lib/strerror.c
packages/OS400/curl.inc.in

index 5d525382a967d3ec47a12364093af8c6b6648bb4..0a21a7589cec88922f87444ea9282c22c520fe03 100644 (file)
@@ -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.
index 3e64039a4dd7dd579b31ff4d23bee844f2407d97..524d4ff62b17e49c215b5ba43a6f868061417839 100644 (file)
@@ -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
index a8697bb2a7f3ed34abd00c25fa2c7eacaf3e2ab1..6d9710117e5c3ea54845faee5dd0e9b59ab8cf61 100644 (file)
@@ -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;
 
index 8f19ebaeec75ea2a795a5257c1baee768c02c28b..e15237e771a778f40ad365d25a8c99d2c4370a15 100644 (file)
@@ -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
index 8c69e37a52a6d28dd81e543d20c1ce15e2dae79a..b1c1f53961f722327dd59a855619531caf633961 100644 (file)
@@ -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);
index cf1a04781684d19abf5cb9fc974262d3b07f56a5..ac616f2c873198285c4021fbb30aebb5a96d7e15 100644 (file)
@@ -305,6 +305,9 @@ curl_easy_strerror(CURLcode error)
   case CURLE_SSL_INVALIDCERTSTATUS:
     return "SSL server certificate status verification FAILED";
 
+  case CURLE_HTTP2_STREAM:
+    return "Stream error in the HTTP/2 framing layer";
+
     /* error codes not used by current libcurl */
   case CURLE_OBSOLETE20:
   case CURLE_OBSOLETE24:
index 7c646868e07110621091f4a63c1db3a7166c8419..18d842993f821e92cf8bd4c4666f1e11713e3ec7 100644 (file)
      d                 c                   90
      d  CURLE_SSL_INVALIDCERTSTATUS...
      d                 c                   91
+     d  CURLE_HTTP2_STREAM...
+     d                 c                   92
       *
       /if not defined(CURL_NO_OLDIES)
      d  CURLE_URL_MALFORMAT_USER...