From ceb6d8d35e33f79007b7693edb4a216803c54bd2 Mon Sep 17 00:00:00 2001 From: User Date: Fri, 8 Aug 2025 18:43:34 +0300 Subject: [PATCH] moved into multi retry setup --- lib/altsvc.c | 19 ++++++++++ lib/altsvc.h | 4 ++- lib/multi.c | 62 ++++++++++++--------------------- lib/url.c | 3 +- tests/data/Makefile.am | 3 +- tests/data/test3302 | 2 +- tests/data/test3304 | 78 ++++++++++++++++++++++++++++++++++++++++++ tests/first-hsts.txt | 0 8 files changed, 124 insertions(+), 47 deletions(-) create mode 100644 tests/data/test3304 create mode 100644 tests/first-hsts.txt diff --git a/lib/altsvc.c b/lib/altsvc.c index a06f40bc2a..0ee25a2532 100644 --- a/lib/altsvc.c +++ b/lib/altsvc.c @@ -652,11 +652,14 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, altsvc_free(as); continue; } + if(as->used) + continue; if((as->src.alpnid == srcalpnid) && hostcompare(srchost, as->src.host) && (as->src.port == srcport) && (versions & (int)as->dst.alpnid)) { /* match */ + as->used = TRUE; *dstentry = as; return TRUE; } @@ -664,6 +667,22 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, return FALSE; } +bool Curl_is_altsvc_error(CURLcode rc) +{ + switch(rc) { + case CURLE_COULDNT_RESOLVE_PROXY: + case CURLE_COULDNT_RESOLVE_HOST: + case CURLE_COULDNT_CONNECT: + case CURLE_GOT_NOTHING: + case CURLE_SEND_ERROR: + case CURLE_RECV_ERROR: + return true; + + default: + return false; + } +} + #if defined(DEBUGBUILD) || defined(UNITTESTS) #undef time #endif diff --git a/lib/altsvc.h b/lib/altsvc.h index 597b954630..4d97d9e106 100644 --- a/lib/altsvc.h +++ b/lib/altsvc.h @@ -42,6 +42,7 @@ struct altsvc { struct Curl_llist_node node; unsigned int prio; BIT(persist); + BIT(used); }; struct altsvcinfo { @@ -49,7 +50,6 @@ struct altsvcinfo { struct Curl_llist list; /* list of entries */ long flags; /* the publicly set bitmask */ - BIT(errored); BIT(used); }; @@ -69,6 +69,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi, int srcport, struct altsvc **dstentry, const int versions); /* CURLALTSVC_H* bits */ +bool Curl_is_altsvc_error(CURLcode rc); + #else /* disabled */ #define Curl_altsvc_save(a,b,c) diff --git a/lib/multi.c b/lib/multi.c index ce4762c5b6..e7600069ed 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -2329,24 +2329,6 @@ static CURLMcode state_connect(struct Curl_multi *multi, return rc; } -#ifndef CURL_DISABLE_ALTSVC -static bool is_altsvc_error(CURLcode rc) -{ - switch(rc) { - case CURLE_COULDNT_RESOLVE_PROXY: - case CURLE_COULDNT_RESOLVE_HOST: - case CURLE_COULDNT_CONNECT: - case CURLE_GOT_NOTHING: - case CURLE_SEND_ERROR: - case CURLE_RECV_ERROR: - return true; - - default: - return false; - } -} -#endif - static CURLMcode multi_runsingle(struct Curl_multi *multi, struct curltime *nowp, struct Curl_easy *data) @@ -2677,32 +2659,30 @@ statemachine_end: /* maybe retry if altsvc is breaking */ #ifndef CURL_DISABLE_ALTSVC - if(data->asi && data->asi->used && !data->asi->errored) { - data->asi->errored = is_altsvc_error(result); + if(data->asi && data->asi->used && + Curl_is_altsvc_error(result) && + !(data->asi->flags & CURLALTSVC_NO_RETRY) && + data->mstate <= MSTATE_PROTOCONNECTING && + data->mstate >= MSTATE_CONNECT) { - if(data->asi->errored && - !(data->asi->flags & CURLALTSVC_NO_RETRY) && - data->mstate <= MSTATE_PROTOCONNECTING && - data->mstate >= MSTATE_CONNECT) { + infof(data, "Alt-Svc connection failed(%d). " + "Retrying with another target", result); + if(data->conn) { + struct connectdata *conn = data->conn; - infof(data, "Alt-Svc connection failed(%d). " - "Retrying with original target", result); - if(data->conn) { - struct connectdata *conn = data->conn; - - /* This is where we make sure that the conn pointer is reset. - We do not have to do this in every case block above where a - failure is detected */ - Curl_detach_connection(data); - Curl_conn_terminate(data, conn, FALSE); - } - - stream_error = FALSE; - multistate(data, MSTATE_CONNECT); - result = CURLE_OK; - rc = CURLM_CALL_MULTI_PERFORM; - continue; + /* This is where we make sure that the conn pointer is reset. + We do not have to do this in every case block above where a + failure is detected */ + Curl_detach_connection(data); + Curl_conn_terminate(data, conn, FALSE); } + + data->asi->used = FALSE; + stream_error = FALSE; + multistate(data, MSTATE_CONNECT); + result = CURLE_OK; + rc = CURLM_CALL_MULTI_PERFORM; + continue; } #endif if(data->conn) { diff --git a/lib/url.c b/lib/url.c index a96d23e7c2..4cf5185dbb 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3113,8 +3113,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, } #ifndef CURL_DISABLE_ALTSVC - /* only use altsvc if its the first time we tried it */ - if(data->asi && !host && (port == -1) && !data->asi->errored && + if(data->asi && !host && (port == -1) && ((conn->handler->protocol == CURLPROTO_HTTPS) || #ifdef DEBUGBUILD /* allow debug builds to circumvent the HTTPS restriction */ diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 1db144f3b1..017732bf45 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -279,9 +279,8 @@ test3100 test3101 test3102 test3103 test3104 test3105 \ \ test3200 test3201 test3202 test3203 test3204 test3205 test3207 test3208 \ test3209 test3210 test3211 test3212 test3213 test3214 test3215 \ -test3209 test3210 test3211 test3212 test3213 test3214 \ \ -test3300 test3301 test3302 test3303 \ +test3300 test3301 test3302 test3303 test3304 \ test4000 test4001 EXTRA_DIST = $(TESTCASES) DISABLED diff --git a/tests/data/test3302 b/tests/data/test3302 index 9b107c2a8b..b88a3c3073 100644 --- a/tests/data/test3302 +++ b/tests/data/test3302 @@ -46,7 +46,7 @@ alt-svc fail connection --alt-svc "%LOGDIR/altsvc-%TESTNUMBER" http://%HOSTIP:%HTTPPORT/%TESTNUMBER -h1 %HOSTIP %HTTPPORT h1 %HOSTIP %NOLISTENPORT "20290222 22:19:28" 0 0 +h1 %HOSTIP %HTTPPORT h1 %HOSTIP %NOLISTENPORT "20290222 22:19:28" 0 0 diff --git a/tests/data/test3304 b/tests/data/test3304 new file mode 100644 index 0000000000..e256c96249 --- /dev/null +++ b/tests/data/test3304 @@ -0,0 +1,78 @@ + + + +HTTP +HTTP GET +Alt-Svc +HTTP/2 + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-Head: yesyes + +-foo- + + + +# +# Client-side + + +alt-svc +Debug +IPv6 + + +http +http-ipv6 + + +failing alt svc retried into ipv6 + + +# make Debug-curl accept Alt-Svc over plain HTTP +CURL_ALTSVC_HTTP="yeah" + + +--alt-svc "%LOGDIR/altsvc-%TESTNUMBER" "http://%HOSTIP:%HTTPPORT/%TESTNUMBER" "http://%HOSTIP:%HTTPPORT/%TESTNUMBER" + + +h1 %HOSTIP %HTTPPORT h1 %HOST6IP %NOLISTENPORT "20290222 22:19:28" 0 0 +h2 %HOSTIP %HTTPPORT h2 %HOST6IP %HTTP6PORT "20290222 22:19:28" 0 0 +h3 %HOSTIP %HTTPPORT h3 %HOST6IP %NOLISTENPORT "20290222 22:19:28" 0 0 + + + + +# +# Verify data after the test has been "shot" + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-Head: yesyes + +-foo- +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-Head: yesyes + +-foo- + + + diff --git a/tests/first-hsts.txt b/tests/first-hsts.txt new file mode 100644 index 0000000000..e69de29bb2