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