From 13991d60eeef7d1c6a7ac1e15a45c5210aa2a15d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 9 Jan 2023 15:00:34 +0100 Subject: [PATCH] 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 --- docs/cmdline-opts/Makefile.inc | 1 + docs/cmdline-opts/http3-only.d | 25 +++++++++++++++++++++++++ docs/cmdline-opts/http3.d | 19 ++++++++++++------- docs/options-in-versions | 1 + src/tool_getparam.c | 29 +++++++++++++++++++++++------ src/tool_listhelp.c | 3 +++ src/tool_setopt.c | 1 + 7 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 docs/cmdline-opts/http3-only.d diff --git a/docs/cmdline-opts/Makefile.inc b/docs/cmdline-opts/Makefile.inc index 0bfb51a94b..ffc9169d3f 100644 --- a/docs/cmdline-opts/Makefile.inc +++ b/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 \ diff --git a/docs/cmdline-opts/http3-only.d b/docs/cmdline-opts/http3-only.d new file mode 100644 index 0000000000..24a384e9a1 --- /dev/null +++ b/docs/cmdline-opts/http3-only.d @@ -0,0 +1,25 @@ +c: Copyright (C) Daniel Stenberg, , 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. diff --git a/docs/cmdline-opts/http3.d b/docs/cmdline-opts/http3.d index 5ca4d612ff..dbc15de05c 100644 --- a/docs/cmdline-opts/http3.d +++ b/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. diff --git a/docs/options-in-versions b/docs/options-in-versions index 8e64f2f3fe..0398373206 100644 --- a/docs/options-in-versions +++ b/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 diff --git a/src/tool_getparam.c b/src/tool_getparam.c index bb4303a8c4..cecaf4b8d5 100644 --- a/src/tool_getparam.c +++ b/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! */ diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index 505f3bb154..7611cf6a0a 100644 --- a/src/tool_listhelp.c +++ b/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}, diff --git a/src/tool_setopt.c b/src/tool_setopt.c index fafd2d432f..3279e85957 100644 --- a/src/tool_setopt.c +++ b/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, }; -- 2.47.2