Browse Source

src: add --http3-only

Warning: --http3 and --http3-only are subject to change again (or be
removed) before HTTP/3 support goes non-experimental.

Closes #10264
Daniel Stenberg 1 year ago
parent
commit
13991d60ee

+ 1 - 0
docs/cmdline-opts/Makefile.inc

@@ -107,6 +107,7 @@ DPAGES = \
   http2-prior-knowledge.d \
   http2.d \
   http3.d \
+  http3-only.d \
   ignore-content-length.d \
   include.d \
   insecure.d \

+ 25 - 0
docs/cmdline-opts/http3-only.d

@@ -0,0 +1,25 @@
+c: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+SPDX-License-Identifier: curl
+Long: http3-only
+Tags: Versions
+Protocols: HTTP
+Added: 7.88.0
+Mutexed: http1.1 http1.0 http2 http2-prior-knowledge http3
+Requires: HTTP/3
+Help: Use HTTP v3 only
+See-also: http1.1 http2 http3
+Category: http
+Example: --http3-only $URL
+Multi: mutex
+Experimental: yes
+---
+Instructs curl to use HTTP/3 to the host in the URL, with no fallback to
+earlier HTTP versions. HTTP/3 can only be used for HTTPS and not for HTTP
+URLs. For HTTP, this option will trigger an error.
+
+This option allows a user to avoid using the Alt-Svc method of upgrading to
+HTTP/3 when you know that the target speaks HTTP/3 on the given host and port.
+
+This option will make curl fail if a QUIC connection cannot be established, it
+will not attempt any other HTTP version on its own. Use --http3 for similar
+fuctionality *with* a fallback.

+ 12 - 7
docs/cmdline-opts/http3.d

@@ -4,7 +4,7 @@ Long: http3
 Tags: Versions
 Protocols: HTTP
 Added: 7.66.0
-Mutexed: http1.1 http1.0 http2 http2-prior-knowledge
+Mutexed: http1.1 http1.0 http2 http2-prior-knowledge http3-only
 Requires: HTTP/3
 Help: Use HTTP v3
 See-also: http1.1 http2
@@ -13,10 +13,15 @@ Example: --http3 $URL
 Multi: mutex
 Experimental: yes
 ---
-Tells curl to use HTTP version 3 directly to the host and port number used in
-the URL. A normal HTTP/3 transaction will be done to a host and then get
-redirected via Alt-Svc, but this option allows a user to circumvent that when
-you know that the target speaks HTTP/3 on the given host and port.
+Tells curl to try HTTP/3 to the host in the URL, but fallback to earlier
+HTTP versions if the HTTP/3 connection establishement fails. HTTP/3 is only
+available for HTTPS and not for HTTP URLs.
 
-This option will make curl fail if a QUIC connection cannot be established, it
-cannot fall back to a lower HTTP version on its own.
+This option allows a user to avoid using the Alt-Svc method of upgrading to
+HTTP/3 when you know that the target speaks HTTP/3 on the given host and port.
+
+When asked to use HTTP/3, curl will issue a separate attempt to use older HTTP
+versions with a slight delay, so if the HTTP/3 transfer fails or is very slow,
+curl will still try to proceed with an older HTTP version.
+
+Use --http3-only for similar fuctionality *without* a fallback.

+ 1 - 0
docs/options-in-versions

@@ -93,6 +93,7 @@
 --http2                              7.33.0
 --http2-prior-knowledge              7.49.0
 --http3                              7.66.0
+--http3-only                         7.88.0
 --ignore-content-length              7.14.1
 --include (-i)                       4.8
 --insecure (-k)                      7.10

+ 23 - 6
src/tool_getparam.c

@@ -208,6 +208,7 @@ static const struct LongShort aliases[]= {
   {"02",  "http2",                   ARG_NONE},
   {"03",  "http2-prior-knowledge",   ARG_NONE},
   {"04",  "http3",                   ARG_NONE},
+  {"05",  "http3-only",              ARG_NONE},
   {"09",  "http0.9",                 ARG_BOOL},
   {"1",  "tlsv1",                    ARG_NONE},
   {"10",  "tlsv1.0",                 ARG_NONE},
@@ -657,6 +658,16 @@ static ParameterError data_urlencode(struct GlobalConfig *global,
   return PARAM_OK;
 }
 
+static void sethttpver(struct GlobalConfig *global,
+                       struct OperationConfig *config,
+                       long httpversion)
+{
+  if(config->httpversion &&
+     (config->httpversion != httpversion))
+    warnf(global, "Overrides previous HTTP version option\n");
+
+  config->httpversion = httpversion;
+}
 
 ParameterError getparameter(const char *flag, /* f or -long-flag */
                             char *nextarg,    /* NULL if unset */
@@ -1418,25 +1429,31 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
       switch(subletter) {
       case '\0':
         /* HTTP version 1.0 */
-        config->httpversion = CURL_HTTP_VERSION_1_0;
+        sethttpver(global, config, CURL_HTTP_VERSION_1_0);
         break;
       case '1':
         /* HTTP version 1.1 */
-        config->httpversion = CURL_HTTP_VERSION_1_1;
+        sethttpver(global, config, CURL_HTTP_VERSION_1_1);
         break;
       case '2':
         /* HTTP version 2.0 */
-        config->httpversion = CURL_HTTP_VERSION_2_0;
+        sethttpver(global, config, CURL_HTTP_VERSION_2_0);
         break;
       case '3': /* --http2-prior-knowledge */
         /* HTTP version 2.0 over clean TCP */
-        config->httpversion = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE;
+        sethttpver(global, config, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
         break;
       case '4': /* --http3 */
-        /* HTTP version 3 go over QUIC - at once */
+        /* Try HTTP/3, allow fallback */
+        if(!feature_http3)
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        sethttpver(global, config, CURL_HTTP_VERSION_3);
+        break;
+      case '5': /* --http3-only */
+        /* Try HTTP/3 without fallback */
         if(!feature_http3)
           return PARAM_LIBCURL_DOESNT_SUPPORT;
-        config->httpversion = CURL_HTTP_VERSION_3;
+        sethttpver(global, config, CURL_HTTP_VERSION_3ONLY);
         break;
       case '9':
         /* Allow HTTP/0.9 responses! */

+ 3 - 0
src/tool_listhelp.c

@@ -282,6 +282,9 @@ const struct helptxt helptext[] = {
   {"    --http3",
    "Use HTTP v3",
    CURLHELP_HTTP},
+  {"    --http3-only",
+   "Use HTTP v3 only",
+   CURLHELP_HTTP},
   {"    --ignore-content-length",
    "Ignore the size of the remote resource",
    CURLHELP_HTTP | CURLHELP_FTP},

+ 1 - 0
src/tool_setopt.c

@@ -91,6 +91,7 @@ const struct NameValue setopt_nv_CURL_HTTP_VERSION[] = {
   NV(CURL_HTTP_VERSION_2_0),
   NV(CURL_HTTP_VERSION_2TLS),
   NV(CURL_HTTP_VERSION_3),
+  NV(CURL_HTTP_VERSION_3ONLY),
   NVEND,
 };