mirror of
https://github.com/curl/curl.git
synced 2026-08-08 18:02:59 +03:00
http2: remove stream dependency tracking
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
This commit is contained in:
parent
2056498625
commit
bfbff7852f
9 changed files with 34 additions and 130 deletions
|
|
@ -1165,11 +1165,12 @@ Redirect stderr to another stream. See CURLOPT_STDERR(3)
|
||||||
|
|
||||||
## CURLOPT_STREAM_DEPENDS
|
## 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
|
## 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_DEPENDS_E(3)
|
||||||
|
|
||||||
## CURLOPT_STREAM_WEIGHT
|
## CURLOPT_STREAM_WEIGHT
|
||||||
|
|
|
||||||
|
|
@ -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
|
a transfer that is about to be sent over the same HTTP/2 connection for this
|
||||||
option to have an actual effect.
|
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
|
# DEFAULT
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
|
|
@ -69,6 +73,10 @@ int main(void)
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
# DEPRECATED
|
||||||
|
|
||||||
|
Deprecated since 8.21.0.
|
||||||
|
|
||||||
# %AVAILABILITY%
|
# %AVAILABILITY%
|
||||||
|
|
||||||
# RETURN VALUE
|
# RETURN VALUE
|
||||||
|
|
|
||||||
|
|
@ -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
|
a transfer that is about to be sent over the same HTTP/2 connection for this
|
||||||
option to have an actual effect.
|
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
|
# DEFAULT
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
|
|
@ -72,6 +76,10 @@ int main(void)
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
# DEPRECATED
|
||||||
|
|
||||||
|
Deprecated since 8.21.0.
|
||||||
|
|
||||||
# %AVAILABILITY%
|
# %AVAILABILITY%
|
||||||
|
|
||||||
# RETURN VALUE
|
# RETURN VALUE
|
||||||
|
|
|
||||||
|
|
@ -882,8 +882,8 @@ CURLOPT_SSLKEYPASSWD 7.9.3 7.17.0
|
||||||
CURLOPT_SSLKEYTYPE 7.9.3
|
CURLOPT_SSLKEYTYPE 7.9.3
|
||||||
CURLOPT_SSLVERSION 7.1
|
CURLOPT_SSLVERSION 7.1
|
||||||
CURLOPT_STDERR 7.1
|
CURLOPT_STDERR 7.1
|
||||||
CURLOPT_STREAM_DEPENDS 7.46.0
|
CURLOPT_STREAM_DEPENDS 7.46.0 8.21.0
|
||||||
CURLOPT_STREAM_DEPENDS_E 7.46.0
|
CURLOPT_STREAM_DEPENDS_E 7.46.0 8.21.0
|
||||||
CURLOPT_STREAM_WEIGHT 7.46.0
|
CURLOPT_STREAM_WEIGHT 7.46.0
|
||||||
CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
|
CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
|
||||||
CURLOPT_TCP_FASTOPEN 7.49.0
|
CURLOPT_TCP_FASTOPEN 7.49.0
|
||||||
|
|
|
||||||
|
|
@ -1985,10 +1985,12 @@ typedef enum {
|
||||||
CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
|
CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
|
||||||
|
|
||||||
/* Set stream dependency on another curl handle */
|
/* 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 */
|
/* 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 */
|
/* Do not send any tftp option requests to the server */
|
||||||
CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
|
CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242),
|
||||||
|
|
|
||||||
18
lib/http2.c
18
lib/http2.c
|
|
@ -1778,16 +1778,12 @@ static int sweight_in_effect(const struct Curl_easy *data)
|
||||||
* struct.
|
* struct.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void h2_pri_spec(struct cf_h2_ctx *ctx,
|
static void h2_pri_spec(struct Curl_easy *data,
|
||||||
struct Curl_easy *data,
|
|
||||||
nghttp2_priority_spec *pri_spec)
|
nghttp2_priority_spec *pri_spec)
|
||||||
{
|
{
|
||||||
struct Curl_data_priority *prio = &data->set.priority;
|
struct Curl_data_priority *prio = &data->set.priority;
|
||||||
struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent);
|
nghttp2_priority_spec_init(pri_spec, 0,
|
||||||
int32_t depstream_id = depstream ? depstream->id : 0;
|
sweight_wanted(data), FALSE);
|
||||||
nghttp2_priority_spec_init(pri_spec, depstream_id,
|
|
||||||
sweight_wanted(data),
|
|
||||||
data->set.priority.exclusive);
|
|
||||||
data->state.priority = *prio;
|
data->state.priority = *prio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1805,13 +1801,11 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
if(stream && stream->id > 0 &&
|
if(stream && stream->id > 0 &&
|
||||||
((sweight_wanted(data) != sweight_in_effect(data)) ||
|
(sweight_wanted(data) != sweight_in_effect(data))) {
|
||||||
(data->set.priority.exclusive != data->state.priority.exclusive) ||
|
|
||||||
(data->set.priority.parent != data->state.priority.parent))) {
|
|
||||||
/* send new weight and/or dependency */
|
/* send new weight and/or dependency */
|
||||||
nghttp2_priority_spec pri_spec;
|
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);
|
CURL_TRC_CF(data, cf, "[%d] Queuing PRIORITY", stream->id);
|
||||||
DEBUGASSERT(stream->id != -1);
|
DEBUGASSERT(stream->id != -1);
|
||||||
rv = nghttp2_submit_priority(ctx->h2, NGHTTP2_FLAG_NONE,
|
rv = nghttp2_submit_priority(ctx->h2, NGHTTP2_FLAG_NONE,
|
||||||
|
|
@ -2123,7 +2117,7 @@ static CURLcode h2_submit(struct h2_stream_ctx **pstream,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2_pri_spec(ctx, data, &pri_spec);
|
h2_pri_spec(data, &pri_spec);
|
||||||
if(!nghttp2_session_check_request_allowed(ctx->h2))
|
if(!nghttp2_session_check_request_allowed(ctx->h2))
|
||||||
CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)");
|
CURL_TRC_CF(data, cf, "send request NOT allowed (via nghttp2)");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1527,13 +1527,10 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option,
|
||||||
|
|
||||||
#ifdef USE_HTTP2
|
#ifdef USE_HTTP2
|
||||||
case CURLOPT_STREAM_DEPENDS:
|
case CURLOPT_STREAM_DEPENDS:
|
||||||
case CURLOPT_STREAM_DEPENDS_E: {
|
case CURLOPT_STREAM_DEPENDS_E:
|
||||||
struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
|
/* not doing stream dependencies any longer, but accept options
|
||||||
if(!dep || GOOD_EASY_HANDLE(dep))
|
* for backward compatibility */
|
||||||
return Curl_data_priority_add_child(dep, data,
|
|
||||||
option == CURLOPT_STREAM_DEPENDS_E);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
98
lib/url.c
98
lib/url.c
|
|
@ -119,12 +119,6 @@
|
||||||
#include "smtp.h"
|
#include "smtp.h"
|
||||||
#include "ws.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
|
/* 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
|
* than a few bytes to play with. Do not let it become too small or bad things
|
||||||
* will happen.
|
* will happen.
|
||||||
|
|
@ -275,8 +269,6 @@ CURLcode Curl_close(struct Curl_easy **datap)
|
||||||
curlx_safefree(data->info.contenttype);
|
curlx_safefree(data->info.contenttype);
|
||||||
curlx_safefree(data->info.wouldredirect);
|
curlx_safefree(data->info.wouldredirect);
|
||||||
|
|
||||||
data_priority_cleanup(data);
|
|
||||||
|
|
||||||
/* No longer a dirty share, if it exists */
|
/* No longer a dirty share, if it exists */
|
||||||
if(Curl_share_easy_unlink(data))
|
if(Curl_share_easy_unlink(data))
|
||||||
DEBUGASSERT(0);
|
DEBUGASSERT(0);
|
||||||
|
|
@ -3009,96 +3001,6 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
|
||||||
|
|
||||||
#if defined(USE_HTTP2) || defined(USE_HTTP3)
|
#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)
|
void Curl_data_priority_clear_state(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
memset(&data->state.priority, 0, sizeof(data->state.priority));
|
memset(&data->state.priority, 0, sizeof(data->state.priority));
|
||||||
|
|
|
||||||
|
|
@ -592,15 +592,7 @@ struct Curl_data_prio_node {
|
||||||
* on the same connection.
|
* on the same connection.
|
||||||
*/
|
*/
|
||||||
struct Curl_data_priority {
|
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;
|
int weight;
|
||||||
#ifdef USE_NGHTTP2
|
|
||||||
BIT(exclusive);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Timers */
|
/* Timers */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue