]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http2: remove stream dependency tracking
authorStefan Eissing <stefan@eissing.org>
Fri, 22 May 2026 07:11:41 +0000 (09:11 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 22 May 2026 07:44:08 +0000 (09:44 +0200)
The HTTP/2 feature is deprecated, few servers implement it and our
implementation is complicated by its state management. Make the two
CURLOPT_* involved a nop and deprecate them.

Closes #21723

docs/libcurl/curl_easy_setopt.md
docs/libcurl/opts/CURLOPT_STREAM_DEPENDS.md
docs/libcurl/opts/CURLOPT_STREAM_DEPENDS_E.md
docs/libcurl/symbols-in-versions
include/curl/curl.h
lib/http2.c
lib/setopt.c
lib/url.c
lib/urldata.h

index 37d028954e686bbcc7529da0620d61220d5011b4..5f75596cff601307419923e012d17881040ef780 100644 (file)
@@ -1165,11 +1165,12 @@ Redirect stderr to another stream. See CURLOPT_STDERR(3)
 
 ## CURLOPT_STREAM_DEPENDS
 
-This HTTP/2 stream depends on another. See CURLOPT_STREAM_DEPENDS(3)
+**Deprecated option** This HTTP/2 stream depends on another. See
+CURLOPT_STREAM_DEPENDS(3)
 
 ## CURLOPT_STREAM_DEPENDS_E
 
-This HTTP/2 stream depends on another exclusively. See
+**Deprecated option** This HTTP/2 stream depends on another exclusively. See
 CURLOPT_STREAM_DEPENDS_E(3)
 
 ## CURLOPT_STREAM_WEIGHT
index 5e3e177dce8f3635dfa2187e683f0f480ba9dcd0..e0e8ef0c53c3ef3996b266099a93b5832da407f1 100644 (file)
@@ -44,6 +44,10 @@ an error. It must be another easy handle, and it also needs to be a handle of
 a transfer that is about to be sent over the same HTTP/2 connection for this
 option to have an actual effect.
 
+Since version 8.21.0 setting this option no longer has an effect. HTTP/2
+stream dependencies were introduced in RFC 7540 and then later deprecated
+in RFC 9113.
+
 # DEFAULT
 
 NULL
@@ -69,6 +73,10 @@ int main(void)
 }
 ~~~
 
+# DEPRECATED
+
+Deprecated since 8.21.0.
+
 # %AVAILABILITY%
 
 # RETURN VALUE
index fe95ae8d71017138d5849782080d12139d4e2112..fe8f97f950d85c17d9f6d942b25680a9699745ad 100644 (file)
@@ -47,6 +47,10 @@ an error. It must be another easy handle, and it also needs to be a handle of
 a transfer that is about to be sent over the same HTTP/2 connection for this
 option to have an actual effect.
 
+Since version 8.21.0 setting this option no longer has an effect. HTTP/2
+stream dependencies were introduced in RFC 7540 and then later deprecated
+in RFC 9113.
+
 # DEFAULT
 
 NULL
@@ -72,6 +76,10 @@ int main(void)
 }
 ~~~
 
+# DEPRECATED
+
+Deprecated since 8.21.0.
+
 # %AVAILABILITY%
 
 # RETURN VALUE
index 6516f7823de87ae50644d21194b1e56020d2b576..4dc670da6eee59dd4abb1bf67165f756e55063e6 100644 (file)
@@ -882,8 +882,8 @@ CURLOPT_SSLKEYPASSWD            7.9.3         7.17.0
 CURLOPT_SSLKEYTYPE              7.9.3
 CURLOPT_SSLVERSION              7.1
 CURLOPT_STDERR                  7.1
-CURLOPT_STREAM_DEPENDS          7.46.0
-CURLOPT_STREAM_DEPENDS_E        7.46.0
+CURLOPT_STREAM_DEPENDS          7.46.0        8.21.0
+CURLOPT_STREAM_DEPENDS_E        7.46.0        8.21.0
 CURLOPT_STREAM_WEIGHT           7.46.0
 CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
 CURLOPT_TCP_FASTOPEN            7.49.0
index 8009df4051cade0a6ead2f1166ddf488041aa062..cb36eefad4639d4f12b8e1f4b6612e2b4787034f 100644 (file)
@@ -1985,10 +1985,12 @@ typedef enum {
   CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
 
   /* Set stream dependency on another curl handle */
-  CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
+  CURLOPTDEPRECATED(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240,
+                    8.21.0, "Has no function"),
 
   /* Set E-xclusive stream dependency on another curl handle */
-  CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
+  CURLOPTDEPRECATED(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241,
+                    8.21.0, "Has no function"),
 
   /* Do not send any tftp option requests to the server */
   CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
index c8ecb28b5a680c8c4dd847ca0eb21b20c223dde0..9eb1e0aeaa412e1faac711f2a12d76b287b6281a 100644 (file)
@@ -1778,16 +1778,12 @@ static int sweight_in_effect(const struct Curl_easy *data)
  * struct.
  */
 
-static void h2_pri_spec(struct cf_h2_ctx *ctx,
-                        struct Curl_easy *data,
+static void h2_pri_spec(struct Curl_easy *data,
                         nghttp2_priority_spec *pri_spec)
 {
   struct Curl_data_priority *prio = &data->set.priority;
-  struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent);
-  int32_t depstream_id = depstream ? depstream->id : 0;
-  nghttp2_priority_spec_init(pri_spec, depstream_id,
-                             sweight_wanted(data),
-                             data->set.priority.exclusive);
+  nghttp2_priority_spec_init(pri_spec, 0,
+                             sweight_wanted(data), FALSE);
   data->state.priority = *prio;
 }
 
@@ -1805,13 +1801,11 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
   int rv = 0;
 
   if(stream && stream->id > 0 &&
-     ((sweight_wanted(data) != sweight_in_effect(data)) ||
-      (data->set.priority.exclusive != data->state.priority.exclusive) ||
-      (data->set.priority.parent != data->state.priority.parent))) {
+     (sweight_wanted(data) != sweight_in_effect(data))) {
     /* send new weight and/or dependency */
     nghttp2_priority_spec pri_spec;
 
-    h2_pri_spec(ctx, data, &pri_spec);
+    h2_pri_spec(data, &pri_spec);
     CURL_TRC_CF(data, cf, "[%d] Queuing PRIORITY", stream->id);
     DEBUGASSERT(stream->id != -1);
     rv = nghttp2_submit_priority(ctx->h2, NGHTTP2_FLAG_NONE,
@@ -2123,7 +2117,7 @@ static CURLcode h2_submit(struct h2_stream_ctx **pstream,
     goto out;
   }
 
-  h2_pri_spec(ctx, data, &pri_spec);
+  h2_pri_spec(data, &pri_spec);
   if(!nghttp2_session_check_request_allowed(ctx->h2))
     CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)");
 
index 067a8450ded0bdca5079de70cfc4a3a3f80ca3a6..2e08a310ebdcfbec59ca223101f32a628eee9ed9 100644 (file)
@@ -1527,13 +1527,10 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option,
 
 #ifdef USE_HTTP2
   case CURLOPT_STREAM_DEPENDS:
-  case CURLOPT_STREAM_DEPENDS_E: {
-    struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
-    if(!dep || GOOD_EASY_HANDLE(dep))
-      return Curl_data_priority_add_child(dep, data,
-                                          option == CURLOPT_STREAM_DEPENDS_E);
+  case CURLOPT_STREAM_DEPENDS_E:
+    /* not doing stream dependencies any longer, but accept options
+     * for backward compatibility */
     break;
-  }
 #endif
 
   default:
index 354505ad6c95c8454cb56fc0ca8084d201095193..796d35e2296acda970e65087d8970c405d46bed2 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
 #include "smtp.h"
 #include "ws.h"
 
-#ifdef USE_NGHTTP2
-static void data_priority_cleanup(struct Curl_easy *data);
-#else
-#define data_priority_cleanup(x)
-#endif
-
 /* Some parts of the code (e.g. chunked encoding) assume this buffer has more
  * than a few bytes to play with. Do not let it become too small or bad things
  * will happen.
@@ -275,8 +269,6 @@ CURLcode Curl_close(struct Curl_easy **datap)
   curlx_safefree(data->info.contenttype);
   curlx_safefree(data->info.wouldredirect);
 
-  data_priority_cleanup(data);
-
   /* No longer a dirty share, if it exists */
   if(Curl_share_easy_unlink(data))
     DEBUGASSERT(0);
@@ -3009,96 +3001,6 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
 
 #if defined(USE_HTTP2) || defined(USE_HTTP3)
 
-#ifdef USE_NGHTTP2
-
-static void priority_remove_child(struct Curl_easy *parent,
-                                  struct Curl_easy *child)
-{
-  struct Curl_data_prio_node **pnext = &parent->set.priority.children;
-  struct Curl_data_prio_node *pnode = parent->set.priority.children;
-
-  DEBUGASSERT(child->set.priority.parent == parent);
-  while(pnode && pnode->data != child) {
-    pnext = &pnode->next;
-    pnode = pnode->next;
-  }
-
-  DEBUGASSERT(pnode);
-  if(pnode) {
-    *pnext = pnode->next;
-    curlx_free(pnode);
-  }
-
-  child->set.priority.parent = 0;
-  child->set.priority.exclusive = FALSE;
-}
-
-CURLcode Curl_data_priority_add_child(struct Curl_easy *parent,
-                                      struct Curl_easy *child,
-                                      bool exclusive)
-{
-  if(child->set.priority.parent) {
-    priority_remove_child(child->set.priority.parent, child);
-  }
-
-  if(parent) {
-    struct Curl_data_prio_node **tail;
-    struct Curl_data_prio_node *pnode;
-
-    pnode = curlx_calloc(1, sizeof(*pnode));
-    if(!pnode)
-      return CURLE_OUT_OF_MEMORY;
-    pnode->data = child;
-
-    if(parent->set.priority.children && exclusive) {
-      /* exclusive: move all existing children underneath the new child */
-      struct Curl_data_prio_node *node = parent->set.priority.children;
-      while(node) {
-        node->data->set.priority.parent = child;
-        node = node->next;
-      }
-
-      tail = &child->set.priority.children;
-      while(*tail)
-        tail = &(*tail)->next;
-
-      DEBUGASSERT(!*tail);
-      *tail = parent->set.priority.children;
-      parent->set.priority.children = 0;
-    }
-
-    tail = &parent->set.priority.children;
-    while(*tail) {
-      (*tail)->data->set.priority.exclusive = FALSE;
-      tail = &(*tail)->next;
-    }
-
-    DEBUGASSERT(!*tail);
-    *tail = pnode;
-  }
-
-  child->set.priority.parent = parent;
-  child->set.priority.exclusive = exclusive;
-  return CURLE_OK;
-}
-
-#endif /* USE_NGHTTP2 */
-
-#ifdef USE_NGHTTP2
-static void data_priority_cleanup(struct Curl_easy *data)
-{
-  while(data->set.priority.children) {
-    struct Curl_easy *tmp = data->set.priority.children->data;
-    priority_remove_child(data, tmp);
-    if(data->set.priority.parent)
-      Curl_data_priority_add_child(data->set.priority.parent, tmp, FALSE);
-  }
-
-  if(data->set.priority.parent)
-    priority_remove_child(data->set.priority.parent, data);
-}
-#endif
-
 void Curl_data_priority_clear_state(struct Curl_easy *data)
 {
   memset(&data->state.priority, 0, sizeof(data->state.priority));
index 63d231dc5cf39ea948d3949d197e64360e5c3a85..4ee5108b17508f7ea6e89fd20c3c7a736be851df 100644 (file)
@@ -592,15 +592,7 @@ struct Curl_data_prio_node {
  * on the same connection.
  */
 struct Curl_data_priority {
-#ifdef USE_NGHTTP2
-  /* tree like dependencies only implemented in nghttp2 */
-  struct Curl_easy *parent;
-  struct Curl_data_prio_node *children;
-#endif
   int weight;
-#ifdef USE_NGHTTP2
-  BIT(exclusive);
-#endif
 };
 
 /* Timers */