From 09d65829ae970930c6942a6c06058e584f24b770 Mon Sep 17 00:00:00 2001 From: dartraiden Date: Wed, 5 Jan 2022 22:24:16 +0300 Subject: libcurl: update to 7.81.0 --- libs/libcurl/docs/CHANGES | 10974 +++++++++++++++--------------- libs/libcurl/docs/THANKS | 25 + libs/libcurl/include/curl/curl.h | 6 + libs/libcurl/include/curl/curlver.h | 8 +- libs/libcurl/include/curl/multi.h | 5 +- libs/libcurl/include/curl/urlapi.h | 12 + libs/libcurl/src/CMakeLists.txt | 5 +- libs/libcurl/src/Makefile.m32 | 52 +- libs/libcurl/src/asyn-ares.c | 4 + libs/libcurl/src/checksrc.pl | 2 +- libs/libcurl/src/config-win32.h | 7 - libs/libcurl/src/conncache.c | 13 +- libs/libcurl/src/connect.c | 46 +- libs/libcurl/src/cookie.c | 2 +- libs/libcurl/src/curl_config.h.in | 6 - libs/libcurl/src/curl_hmac.h | 4 +- libs/libcurl/src/curl_md5.h | 8 +- libs/libcurl/src/curl_sha256.h | 4 +- libs/libcurl/src/curl_sspi.c | 4 +- libs/libcurl/src/easy.c | 10 +- libs/libcurl/src/easyoptions.c | 3 +- libs/libcurl/src/ftp.c | 13 +- libs/libcurl/src/hash.c | 82 +- libs/libcurl/src/hash.h | 12 +- libs/libcurl/src/hostcheck.c | 2 +- libs/libcurl/src/hostip.c | 25 +- libs/libcurl/src/hostip.h | 4 +- libs/libcurl/src/http.c | 13 +- libs/libcurl/src/http.h | 4 - libs/libcurl/src/http2.c | 5 +- libs/libcurl/src/http_aws_sigv4.c | 14 +- libs/libcurl/src/http_proxy.c | 21 +- libs/libcurl/src/http_proxy.h | 3 +- libs/libcurl/src/if2ip.c | 4 +- libs/libcurl/src/imap.c | 2 +- libs/libcurl/src/inet_pton.c | 6 +- libs/libcurl/src/krb5.c | 2 +- libs/libcurl/src/ldap.c | 7 +- libs/libcurl/src/libcurl.plist | 6 +- libs/libcurl/src/md4.c | 4 +- libs/libcurl/src/md5.c | 23 +- libs/libcurl/src/mime.c | 64 +- libs/libcurl/src/mprintf.c | 2 +- libs/libcurl/src/multi.c | 226 +- libs/libcurl/src/multihandle.h | 2 + libs/libcurl/src/multiif.h | 4 +- libs/libcurl/src/openldap.c | 833 ++- libs/libcurl/src/setopt.c | 13 + libs/libcurl/src/sha256.c | 41 +- libs/libcurl/src/share.c | 6 +- libs/libcurl/src/smtp.c | 2 +- libs/libcurl/src/socks.c | 33 +- libs/libcurl/src/splay.c | 2 +- libs/libcurl/src/strerror.c | 59 +- libs/libcurl/src/system_win32.c | 2 +- libs/libcurl/src/tftp.c | 2 +- libs/libcurl/src/transfer.c | 2 +- libs/libcurl/src/url.c | 40 +- libs/libcurl/src/urlapi-int.h | 4 +- libs/libcurl/src/urlapi.c | 212 +- libs/libcurl/src/urldata.h | 6 + libs/libcurl/src/vauth/digest.c | 11 +- libs/libcurl/src/vauth/ntlm.c | 4 +- libs/libcurl/src/version_win32.c | 82 +- libs/libcurl/src/version_win32.h | 3 +- libs/libcurl/src/vquic/ngtcp2.c | 57 +- libs/libcurl/src/vssh/libssh2.c | 13 +- libs/libcurl/src/vtls/gtls.c | 34 +- libs/libcurl/src/vtls/gtls.h | 8 +- libs/libcurl/src/vtls/mbedtls.c | 53 +- libs/libcurl/src/vtls/mesalink.c | 91 +- libs/libcurl/src/vtls/nss.c | 100 +- libs/libcurl/src/vtls/openssl.c | 180 +- libs/libcurl/src/vtls/openssl.h | 8 +- libs/libcurl/src/vtls/rustls.c | 61 +- libs/libcurl/src/vtls/schannel.c | 397 +- libs/libcurl/src/vtls/schannel_verify.c | 5 +- libs/libcurl/src/vtls/sectransp.c | 30 +- libs/libcurl/src/x509asn1.c | 127 +- 79 files changed, 7333 insertions(+), 6938 deletions(-) diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index f77f0a9e13..692f78f2bb 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,8295 +6,7935 @@ Changelog -Version 7.80.0 (10 Nov 2021) +Version 7.81.0 (5 Jan 2022) -Daniel Stenberg (10 Nov 2021) +Daniel Stenberg (5 Jan 2022) - RELEASE-NOTES: synced - for curl 7.80.0 + curl 7.81.0 release -- THANKS: add contributors from the 7.80.0 cycle +- THANKS: add names from 7.81.0 release -- [Tatsuhiro Tsujikawa brought this change] +- curl_multi_init.3: fix the copyright year range - ngtcp2: advertise h3 as well as h3-29 +- test719-721: require "proxy" feature present to run - Advertise h3 as well as h3-29 since some servers out there require h3 - for QUIC v1. + Bug: https://github.com/curl/curl/pull/8223#issuecomment-1005188696 + Reported-by: Marc Hörsken - Closes #7979 - -- [Tatsuhiro Tsujikawa brought this change] + Closes #8226 - ngtcp2: use QUIC v1 consistently +- test719: require ipv6 support to run - Since we switched to v1 quic_transport_parameters codepoint in #7960 - with quictls, lets use QUIC v1 consistently. + Follow-up to effd2bd7ba2a5fd244 + Reported-by: Marc Hörsken + Bug: https://github.com/curl/curl/pull/8217#issuecomment-1004681145 - Closes #7979 + Closes #8223 -- [Tatsuhiro Tsujikawa brought this change] +- test719-721: verify SOCKS details + + Using the new verify/socks details - ngtcp2: compile with the latest nghttp3 +- runtests: add verify/socks check - Closes #7978 + If used, this data is compared with the data in log/socksd-request.log + which the socksd server logs. + + Added to FILEFORMAT.md -Marc Hoersken (9 Nov 2021) -- tests: add Schannel-specific tests and disable unsupported ones +- server/socksd: log atyp + address in a separate log - Adds Schannel variants of SSLpinning tests that include the option - --ssl-revoke-best-effort to ignore certificate revocation check - failures which is required due to our custom test CA certificate. + To allow the test suite to verify that the right data arrived + +- socks5: use appropriate ATYP for numerical IP address host names - Disable the original variants if the Schannel backend is enabled. + When not resolving the address locallly (known as socks5h). - Also skip all IDN tests which are broken while using an msys shell. + Add test 719 and 720 to verify. - This is a step to simplify test exclusions for Windows and MinGW. + Reported-by: Peter Piekarski + Fixes #8216 + Closes #8217 + +Jay Satiro (3 Jan 2022) +- curl_multi_init.3: fix EXAMPLE formatting + +Daniel Stenberg (3 Jan 2022) +- RELEASE-NOTES: synced + +- libtest: avoid "assignment within conditional expression" - Reviewed-by: Jay Satiro - Reviewed-by: Marcel Raad - Reviewed-by: Daniel Stenberg - Closes #7968 + In lib530, lib540 and lib582 + + Closes #8218 -Daniel Stenberg (8 Nov 2021) -- docs: NAME fixes in easy option man pages +- ftp: disable warning 4706 in MSVC - Closes #7975 + Follow-up to 21248e052d + + Disabling "assignment within conditional expression" for MSVC needs to + be done before the function starts, for it to take effect. + + Closes #8218 -- [Roger Young brought this change] +- tool_operate: warn if too many output arguments were found + + More output instructions than URLs is likely a user error. + + Add test case 371 to verify + + Closes #8210 - ftp: make the MKD retry to retry once per directory +- .github/workflows/mbedtls.yml: bump to mbedtls 3.1.0 - Reported-by: Roger Young - Fixes #7967 - Closes #7976 + Closes #8215 -- tool_operate: reorder code to avoid compiler warning +- zuul: remove the mbedtls jobs - tool_operate.c(889) : warning C4701: potentially uninitialized local - variable 'per' use + Now running as github workflows - Follow-up to cc71d352651a0d95 - Reported-by: Marc Hörsken - Bug: https://github.com/curl/curl/pull/7922#issuecomment-963042676 - Closes #7971 + Closes #8215 -- curl_easy_perform.3: add a para about recv and send data +- github/workflows: add mbedtls and mbedtls-clang - Reported-by: Godwin Stewart - Fixes #7973 - Closes #7974 + Closes #8215 -- tool_operate: fclose stream only if fopened +- [Valentin Richter brought this change] + + mbedtls: fix private member designations for v3.1.0 - Fixes torture test failures - Follow-up to cc71d352651 + "As a last resort, you can access the field foo of a structure bar by + writing bar.MBEDTLS_PRIVATE(foo). Note that you do so at your own risk, + since such code is likely to break in a future minor version of Mbed + TLS." - + https://github.com/ARMmbed/mbedtls/blob/f2d1199edc5834df4297f247f213e614f7782d1d/docs/3.0-migration-guide.md - Closes #7972 + That future minor version is v3.1.0. I set the >= to == for the version + checks because v3.1.0 is a release, and I am not sure when the private + designation was reverted after v3.0.0. + + Closes #8214 -- libcurl-easy.3: language polish +- [Valentin Richter brought this change] -- limit-rate.d: this is average over several seconds + cmake: prevent dev warning due to mismatched arg - Closes #7970 + -- curl version=[7.81.0-DEV] + CMake Warning (dev) at /usr/share/cmake-3.22.1/Modules/FindPackageHandleStandardArgs.cmake:438 (message): + The package name passed to `find_package_handle_standard_args` (MBEDTLS) + does not match the name of the calling package (MbedTLS). This can lead to + problems in calling code that expects `find_package` result variables + (e.g., `_FOUND`) to follow a certain pattern. + Call Stack (most recent call first): + deps/curl/CMake/FindMbedTLS.cmake:31 (find_package_handle_standard_args) + deps/curl/CMakeLists.txt:473 (find_package) + This warning is for project developers. Use -Wno-dev to suppress it. + + Closes #8207 -- docs: reduce/avoid English contractions +- urlapi: if possible, shorten given numerical IPv6 addresses - You're => You are - Hasn't => Has not - Doesn't => Does not - Don't => Do not - You'll => You will - etc + Extended test 1560 to verify - Closes #7930 + Closes #8206 -- tool_operate: fix torture leaks with etags - - Spotted by torture testing 343 344 345 347. +- [Michał Antoniak brought this change] + + url: reduce ssl backend count for CURL_DISABLE_PROXY builds - Follow-up from cc71d352651a0 - Pointed-out-by: Dan Fandrich + Closes #8212 + +- KNOWN_BUGS: "Trying local ports fails on Windows" - Closes #7969 + Reported-by: gclinch on github + Closes #8112 -- [Amaury Denoyelle brought this change] +- misc: update copyright year range - ngtcp2: support latest QUIC TLS RFC9001 +- zuul: remove the wolfssl even more - QUIC Transport Parameters Extension has been changed between draft-29 - and latest RFC9001. Most notably, its identifier has been updated from - 0xffa5 to 0x0039. The version is selected through the QUIC TLS library - via the legacy codepoint. + Follow-up to 1914465cf180d32b3d + +- examples/multi-single.c: remove WAITMS() - Disable the usage of legacy codepoint in curl to switch to latest - RFC9001. This is required to be able to keep up with latest QUIC - implementations. + As it isn't used. - Acked-by: Tatsuhiro Tsujikawa - Closes #7960 + Reported-by: Melroy van den Berg + Fixes #8200 + Closes #8201 -- test1173: make manpage-syntax.pl spot \n errors in examples +- gtls: add gnutls include for the session type + + Follow-up to 8fbd6feddfa5 to make it build more universally -- man pages: fix backslash-n in examples +- m4/curl-compilers: tell clang -Wno-pointer-bool-conversion - ... to be proper backslash-backslash-n sequences to render nicely in man - and on website. + To hush compiler warnings we don't care for: error: address of function + 'X' will always evaluate to 'true' - Follow-up to 24155569d8a - Reported-by: Sergey Markelov + Fixes #8197 + Closes #8198 + +- http_proxy: don't close the socket (too early) - Fixes https://github.com/curl/curl-www/issues/163 - Closes #7962 + ... and double-check in the OpenSSL shutdown that the socket is actually + still there before it is used. + + Fixes #8193 + Closes #8195 + + Reported-by: Leszek Kubik -- scripts/release-notes.pl: use out of repo links verbatim in refs +- ngtcp2: verify the server certificate for the gnutls case + + Closes #8178 -- tool_operate: a failed etag save now only fails that transfer +- ngtcp2: verify the server cert on connect (quictls) - When failing to create the output file for saving an etag, only fail - that particular single transfer and allow others to follow. + Make ngtcp2+quictls correctly acknowledge `CURLOPT_SSL_VERIFYPEER` and + `CURLOPT_SSL_VERIFYHOST`. - In a serial transfer setup, if no transfer at all is done due to them - all being skipped because of this error, curl will output an error - message and return exit code 26. + The name check now uses a function from lib/vtls/openssl.c which will + need attention for when TLS is not done by OpenSSL or is disabled while + QUIC is enabled. - Added test 369 and 370 to verify. + Possibly the servercert() function in openssl.c should be adjusted to be + able to use for both regular TLS and QUIC. - Reported-by: Earnestly on github - Ref: #7942 - Closes #7945 + Ref: #8173 + Closes #8178 -- [Kevin Burke brought this change] +- zuul: remove the wolfssl build - .github: retry macos "brew install" command on failure - - Previously we saw errors attempting to run "brew install", see - https://github.com/curl/curl/runs/4095721123?check_suite_focus=true for - an example, since this command is idempotent, it is safe to run again. +- github workflow: add wolfssl - Closes #7955 + Closes #8196 -- CURLOPT_ALTSVC_CTRL.3: mention conn reuse is preferred +- [Nicolas Sterchele brought this change] + + zuul: fix quiche build pointing to wrong Cargo - Ref: https://github.com/curl/curl/discussions/7954 + Fixes #8184 + Closes #8189 + +- checksrc: detect more kinds of NULL comparisons we avoid - Closes #7957 + Co-authored-by: Jay Satiro + Closes #8180 - RELEASE-NOTES: synced -- zuul: pin the quiche build to use an older cmake-rs - - The latest cmake-rs assumes cmake's --parallel works. That was added in - cmake 3.12, but a lot of our CI builds run on Ubuntu Bionic which only - has cmake 3.10. +- mesalink: remove the BACKEND define kludge - Fixes #7927 - Closes #7952 - -- [Marc Hoersken brought this change] + Closes #8183 - Revert "src/tool_filetime: disable -Wformat on mingw for this file" - - This reverts commit 7c88fe375b15c44d77bccc9ab733b8069d228e6f. +- schannel: remove the BACKEND define kludge - Follow up to #6535 as the pragma is obsolete with warnf + Closes #8182 + +- gtls: check return code for gnutls_alpn_set_protocols - Closes #7941 + Closes #8181 -Jay Satiro (2 Nov 2021) -- schannel: fix memory leak due to failed SSL connection +- [Stefan Huber brought this change] + + README: label the link to the support document - - Call schannel_shutdown if the SSL connection fails. + Closes #8185 + +- docs/HTTP3: describe how to setup a h3 reverse-proxy for testing - Prior to this change schannel_shutdown (which shuts down the SSL - connection as well as memory cleanup) was not called when the SSL - connection failed (eg due to failed handshake). + Assisted-by: Matt Holt - Co-authored-by: Gisle Vanem + Closes #8177 + +- libcurl-multi.3: "SOCKS proxy handshakes" are not blocking - Fixes https://github.com/curl/curl/issues/7877 - Closes https://github.com/curl/curl/pull/7878 + Since 4a4b63daaa0 -Daniel Stenberg (2 Nov 2021) -- Curl_updateconninfo: store addresses for QUIC connections too +- [Vladimir Panteleev brought this change] + + tests: Add test for CURLOPT_HTTP200ALIASES + +- [Vladimir Panteleev brought this change] + + http: Fix CURLOPT_HTTP200ALIASES - So that CURLINFO_PRIMARY_IP etc work for HTTP/3 like for other HTTP - versions. + The httpcode < 100 check was also triggered when none of the fields were + parsed, thus making the if(!nc) block unreachable. - Reported-by: Jerome Mao - Fixes #7939 - Closes #7944 + Closes #8171 -- [Sergio Durigan Junior brought this change] +- RELEASE-NOTES: synced - curl.1: fix typos in the manpage +- language: "email" - s/transfering/transferring/ - s/transfered/transferred/ + Missed three occurrences. - Signed-off-by: Sergio Durigan Junior - Closes #7937 + Follow-up to 7a92f86 -Marc Hoersken (1 Nov 2021) -- tests/smbserver.py: fix compatibility with impacket 0.9.23+ - - impacket now performs sanity checks if the requested and to - be served file path actually is inside the real share path. +- nss:set_cipher don't clobber the cipher list - Ref: https://github.com/SecureAuthCorp/impacket/pull/1066 + The string is set by the user and needs to remain intact for proper + connection reuse etc. - Fixes #7924 - Closes #7935 + Reported-by: Eric Musser + Fixes #8160 + Closes #8161 -Daniel Stenberg (1 Nov 2021) -- docs: reduce use of "very" +- misc: s/e-mail/email - "Very" should be avoided in most texts. If intensifiers are needed, try - find better words instead. + Consistency is king. Following the lead in everything curl. - Closes #7936 + Closes #8159 -- [Tatsuhiro Tsujikawa brought this change] +- [Tobias Nießen brought this change] - ngtcp2: specify the missing required callback functions + docs: fix typo in OpenSSL 3 build instructions - Closes #7929 + Closes #8162 -- CURLOPT_[PROXY]_SSL_CIPHER_LIST.3: bold instead of quote +- linkcheck.yml: add CI job that checks markdown links - Bold the example ciphers instead of using single quotes, which then also - avoids the problem of how to use single quotes when first in a line. - - Also rephrased the pages a little. - - Reported-by: Sergio Durigan Junior - Ref: #7928 - Closes #7934 + Closes #8158 -- gen.pl: replace leading single quotes with \(aq +- RELEASE-PROCEDURE.md: remove ICAL link and old release dates + +- BINDINGS.md: "markdown-link-check-disable" - ... and allow single quotes to be used "normally" in the .d files. + It feels a bit unfortunate to litter an ugly tag for this functionality, + but if we get link scans of all markdown files, this might be worth the + price. + +- docs: fix dead links, remove ECH.md + +Jay Satiro (16 Dec 2021) +- openssl: define HAVE_OPENSSL_VERSION for OpenSSL 1.1.0+ - Makes the output curl.1 use better nroff. + Prior to this change OpenSSL_version was only detected in configure + builds. For other builds the old version parsing code was used which + would result in incorrect versioning for OpenSSL 3: - Reported-by: Sergio Durigan Junior - Ref: #7928 - Closes #7933 - -Marc Hoersken (1 Nov 2021) -- tests: kill some test servers afterwards to avoid locked logfiles + Before: - Reviewed-by: Daniel Stenberg - Closes #7925 - -Daniel Stenberg (1 Nov 2021) -- smooth-gtk-thread.c: enhance the mutex lock use + curl 7.80.0 (i386-pc-win32) libcurl/7.80.0 OpenSSL/3.0.0a zlib/1.2.11 + WinIDN libssh2/1.9.0 - Reported-by: ryancaicse on github - Fixes #7926 - Closes #7931 - -Marc Hoersken (31 Oct 2021) -- CI/runtests.pl: restore -u flag, but remove it from CI runs + After: - This makes it possible to use -u again for local testing, - but removes the flag from CI config files and make targets. + curl 7.80.0 (i386-pc-win32) libcurl/7.80.0 OpenSSL/3.0.1 zlib/1.2.11 + WinIDN libssh2/1.9.0 - Reviewed-by: Daniel Stenberg + Reported-by: lllaffer@users.noreply.github.com - Partially reverts #7841 - Closes #7921 + Fixes https://github.com/curl/curl/issues/8154 + Closes https://github.com/curl/curl/pull/8155 -Daniel Stenberg (29 Oct 2021) -- [Jonathan Cardoso Machado brought this change] +Daniel Stenberg (16 Dec 2021) +- [James Fuller brought this change] - CURLOPT_HSTSWRITEFUNCTION.3: using CURLOPT_HSTS_CTRL is required + docs: add known bugs list to HTTP3.md - Closes #7923 + Closes #8156 -- [Axel Morawietz brought this change] +Dan Fandrich (15 Dec 2021) +- BINDINGS: add one from Everything curl and update a link - imap: display quota information +- libcurl-security.3: mention address and URL mitigations - Show response to "GETQUOTAROOT INBOX" command. - - Closes #6973 + The new CURLOPT_PREREQFUNCTION callback is another way to sanitize + addresses. + Using the curl_url API is a way to mitigate against attacks relying on + URL parsing differences. +Daniel Stenberg (15 Dec 2021) - RELEASE-NOTES: synced -- [Boris Rasin brought this change] - - cmake: fix error getting LOCATION property on non-imported target +- x509asn1: return early on errors - Closes #7885 + Overhaul to make sure functions that detect errors bail out early with + error rather than trying to continue and risk hiding the problem. + + Closes #8147 -- [x2018 brought this change] +- [Patrick Monnerat brought this change] - url: check the return value of curl_url() + openldap: several minor improvements - Closes #7917 + - Early check proper LDAP URL syntax. Reject URLs with a userinfo part. + - Use dynamic memory for ldap_init_fd() URL rather than a + stack-allocated buffer. + - Never chase referrals: supporting it would require additional parallel + connections and alternate authentication credentials. + - Do not wait 1 microsecond while polling/reading query response data. + - Store last received server code for retrieval with CURLINFO_RESPONSE_CODE. + + Closes #8140 -- [Roy Li brought this change] +- [Michał Antoniak brought this change] - configure.ac: replace krb5-config with pkg-config + misc: remove unused doh flags when CURL_DISABLE_DOH is defined - The rationale is that custom *-config tools don't work well when - cross-compiling or using sysroots (such as when using Yocto project) and - require custom fixing for each of them; pkg-config on the other hand - works similarly everywhere. + Closes #8148 + +- mbedtls: fix CURLOPT_SSLCERT_BLOB - Signed-off-by: Roy Li - Signed-off-by: Alexander Kanavin + The memory passed to mbedTLS for this needs to be null terminated. - Closes #7916 + Reported-by: Florian Van Heghe + Closes #8146 -- test1160: edited to work with hyper +- asyn-ares: ares_getaddrinfo needs no happy eyeballs timer - Closes #7912 + Closes #8142 -- data/DISABLED: enable tests that now work with hyper +- mailmap: add Yongkang Huang - Closes #7911 + From #8141 -- test559: add 'HTTP' in keywords - - Makes it run fine with hyper - - Closes #7911 +- [Yongkang Huang brought this change] -- test552: updated to work with hyper - - Closes #7911 + check ssl_config when re-use proxy connection -Marc Hoersken (27 Oct 2021) -- github: fix incomplete permission to label PRs for Hacktoberfest +- mbedtls: do a separate malloc for ca_info_blob - Unfortunately the GitHub API requires a token with write permission - for both issues and pull-requests to edit labels on even just PRs. + Since the mbedTLS API requires the data to the null terminated. - Follow up to #7897 - -Daniel Stenberg (27 Oct 2021) -- opt-manpages: use 'Added in' instead of 'Since' + Follow-up to 456c53730d21b1fad0c7f72c1817 - Closes #7913 + Fixes #8139 + Closes #8145 -Marc Hoersken (27 Oct 2021) -- github: fix missing permission to label PRs for Hacktoberfest +Marc Hoersken (14 Dec 2021) +- CI: build examples for additional code verification - Follow up to #7897 + Some CIs already build them, let's do it on more of them. - Test references to see if permissions are now sufficient: + Reviewed-by: Daniel Stenberg - Closes #7832 - Closes #7897 + Follow up to #7690 and 77311f420a541a0de5b3014e0e40ff8b4205d4af + Replaces #7591 + Closes #7922 -- CI: more use of test-ci make target and verbose output +- docs/examples: workaround broken -Wno-pedantic-ms-format - Replace test-nonflaky with test-ci and enable verbose output - in all remaining CIs except Zuul which is customized a lot. + Avoid CURL_FORMAT_CURL_OFF_T by using unsigned long instead. + Improve size_t to long conversion in imap-append.c example. + Ref: https://github.com/curl/curl/issues/6079 + Ref: https://github.com/curl/curl/pull/6082 + Assisted-by: Jay Satiro Reviewed-by: Daniel Stenberg - Reviewed-by: Jay Satiro - Follow up to #7785 - Closes #7832 + Preparation of #7922 -- github: add support for Hacktoberfest using labels +- tests/data/test302[12]: fix MSYS2 path conversion of hostpubsha256 - Automatically add hacktoberfest-accepted label to PRs opened between - September 30th and November 1st once a commit with a close reference - to it is pushed onto the master branch. + Ref: https://www.msys2.org/wiki/Porting/#filesystem-namespaces - With this workflow we can participate in Hacktoberfest while not - relying on GitHub to identify PRs as merged due to our rebasing. + Reviewed-by: Marcel Raad + Reviewed-by: Jay Satiro - Requires hacktoberfest-accepted labels to exist for PRs on the - participating repository. Also requires hacktoberfest topic on - the participating repository to avoid applying to forked repos. + Fixes #8084 + Closes #8138 + +Daniel Stenberg (13 Dec 2021) +- [Patrick Monnerat brought this change] + + openldap: simplify ldif generation code - Reviewed-by: Daniel Stenberg + and take care of zero-length values, avoiding conversion to base64 + and/or trailing spaces. - Fixes #7865 - Closes #7897 + Closes #8136 -Daniel Stenberg (27 Oct 2021) -- http: reject HTTP response codes < 100 - - ... which then also includes negative ones as test 1430 uses. +- example/progressfunc: remove code for old libcurls - This makes native + hyper backend act identically on this and therefore - test 1430 can now be enabled when building with hyper. Adjust test 1431 - as well. + 7.61.0 is over three years old now, remove all #ifdefs for handling + ancient libcurl versions so that the example gets easier to read and + understand - Closes #7909 + Closes #8137 -- [Kerem Kat brought this change] +- [x2018 brought this change] - docs: fix typo in CURLOPT_TRAILERFUNCTION example + sha256/md5: return errors when init fails - Closes #7910 - -- docs/HYPER: remove some remaining issues, add HTTP/0.9 limitation + Closes #8133 -- configure: when hyper is selected, deselect nghttp2 +- TODO: 13.3 Defeat TLS fingerprinting - Closes #7908 + Closes #8119 + +- RELEASE-NOTES: synced - [Patrick Monnerat brought this change] - sendf: accept zero-length data in Curl_client_write() - - Historically, Curl_client_write() used a length value of 0 as a marker - for a null-terminated data string. This feature has been removed in - commit f4b85d2. To detect leftover uses of the feature, a DEBUGASSERT - statement rejecting a length with value 0 was introduced, effectively - precluding use of this function with zero-length data. + openldap: process search query response messages one by one - The current commit removes the DEBUGASSERT and makes the function to - return immediately if length is 0. + Upon receiving large result sets, this reduces memory consumption and + allows starting to output results while the transfer is still in + progress. - A direct effect is to fix trying to output a zero-length distinguished - name in openldap. + Closes #8101 + +- hash: lazy-alloc the table in Curl_hash_add() - Another DEBUGASSERT statement is also rephrased for better readability. + This makes Curl_hash_init() infallible which saves error paths. - Closes #7898 + Closes #8132 -- hyper: disable test 1294 since hyper doesn't allow such crazy headers +- multi: cleanup the socket hash when destroying it - Closes #7905 + Since each socket hash entry may themselves have a hash table in them, + the destroying of the socket hash needs to make sure all the subhashes + are also correctly destroyed to avoid leaking memory. + + Fixes #8129 + Closes #8131 -- c-hyper: make CURLOPT_SUPPRESS_CONNECT_HEADERS work +- test1156: fixup the stdout check for Windows - Verified by the enabled test 1288 + It is not text mode. - Closes #7905 + Follow-up to 6f73e68d182 + + Closes #8134 -- test1287: make work on hyper +- test1528: enable for hyper - Closes #7905 + Closes #8128 -- test1266/1267: disabled on hyper: no HTTP/0.9 support +- test1527: enable for hyper - Closes #7905 + Closes #8128 -Viktor Szakats (25 Oct 2021) -- Makefile.m32: fix to not require OpenSSL with -libssh2 or -rtmp options +- test1526: enable for hyper - Previously, -libssh2/-rtmp options assumed that OpenSSL is also enabled - (and then failed with an error when not finding expected OpenSSL headers), - but this isn't necessarly true, e.g. when building both libssh2 and curl - against Schannel. This patch makes sure to only enable the OpenSSL backend - with -libssh2/-rtmp, when there was no SSL option explicitly selected. + Closes #8128 + +- test1525: slightly tweaked for hyper - - Re-implement the logic as a single block of script. - - Also fix an indentation while there. + Closes #8128 + +- test1156: enable for hyper - Assisted-by: Jay Satiro + Minor reorg of the lib1156 code and it works fine for hyper. - Closes #7895 + Closes #8127 -Daniel Stenberg (25 Oct 2021) -- docs: consistent use of "Added in" +- test661: enable for hyper - Make them all say "Added in [version]" without using 'curl' or 'libcurl' - in that phrase. + Closes #8126 -- man pages: require all to use the same section header order - - This is the same order we already enforce among the options' man pages: - consistency is good. Add lots of previously missing examples. +- docs: fix proselint nits - Adjust the manpage-syntax script for this purpose, used in test 1173. + - remove a lot of exclamation marks + - use consistent spaces (1, not 2) + - use better words at some places - Closes #7904 + Closes #8123 -- [David Hu brought this change] +- [RekGRpth brought this change] - docs/HTTP3: improve build instructions - - 1. If writing to a system path if the command is not prefixed with - `sudo` it will cause a permission denied error + BINDINGS.md: add cURL client for PostgreSQL - 2. The patched OpenSSL branch has been updated to `openssl-3.0.0+quic` - to match upstream OpenSSL version. + Closes #8125 + +- [RekGRpth brought this change] + + CURLSHOPT_USERDATA.3: fix copy-paste mistake - 3. We should not disable GnuTLS docs. + Closes #8124 + +- docs: fix minor nroff format nits - Updated some commands about `make install` + Repairs test 1140 - Closes #7842 + Follow-up to 436cdf82041 -- [Ricardo Martins brought this change] +- docs/URL-SYNTAX.md: space is not fine in a given URL - CMake: restore support for SecureTransport on iOS +- curl_multi_perform/socket_action.3: clarify what errors mean - Restore support for building curl for iOS with SecureTransport enabled. + An error returned from one of these funtions mean that ALL still ongoing + transfers are to be considered failed. - Closes #7501 + Ref: #8114 + Closes #8120 -- tests: enable more tests with hyper +- libcurl-errors.3: add CURLM_ABORTED_BY_CALLBACK - Adjusted 1144, 1164 and 1176. + Follow-up to #8089 (2b3dd01) - Closes #7900 + Closes #8116 -- docs: provide "RETURN VALUE" section for more func manpages +- hash: add asserts to help detect bad usage - Three were missing, one used a non-standard name for the header. + For example trying to add entries after the hash has been "cleaned up" - Closes #7902 + Closes #8115 -Jay Satiro (25 Oct 2021) -- curl_multi_socket_action.3: add a "RETURN VALUE" section +- lib530: abort on curl_multi errors - .. because it may not be immediately clear to the user what - curl_multi_socket_action returns. + This makes torture tests run more proper. - Ref: https://curl.se/mail/lib-2021-10/0035.html + Also add an assert to trap situations where it would end up with no + sockets to wait for. - Closes https://github.com/curl/curl/pull/7901 + Closes #8121 -Daniel Stenberg (24 Oct 2021) -- RELEASE-NOTES: synced +- FAQ: we never pronounced it "see URL", we say "kurl" -- [Samuel Henrique brought this change] +- RELEASE-NOTES: synced - tests: use python3 in test 1451 +- CURLOPT_RESOLVE.3: minor polish - This is a continuation of commit ec91b5a69000bea0794bbb3 in which - changing this test was missed. There are no other python2 leftovers - now. + Minor rephrasing for some explanations. - Based on a Debian patch originally written by Alessandro Ghedini - + Put the format strings in stand-alone lines with .nf/.fi to be easier to spot. - Closes #7899 + Move "added in" to AVAILABILITY + + Closed #8110 -- [Eddie Lumpkin brought this change] +- test1556: adjust for hyper + + Closes #8105 - lib: fixing comment spelling typos in lib files +- test1554: adjust for hyper - Closes #7894 - Signed-off-by: ewlumpkin + Closes #8104 -- openssl: if verifypeer is not requested, skip the CA loading +- retry-all-errors.d: make the example complete - It was previously done mostly to show a match/non-match in the verbose - output even when verification was not asked for. This change skips the - loading of the CA certs unless verifypeer is set to save memory and CPU. + ... as it needs --retry too to work + +- TODO: 5.7 Require HTTP version X or higher - Closes #7892 + Closes #7980 -- curl-confopts.m4: remove --enable/disable-hidden-symbols +- CURLOPT_STDERR.3: does not work with libcurl as a win32 DLL - These configure options have been saying "deprecated" since 9e24b9c7af - (April 2012). It was about time we remove them. + This is the exact same limitation already documented for + CURLOPT_WRITEDATA but should be clarified here. It also has a different + work-around. - Closes #7891 + Reported-by: Stephane Pellegrino + Bug: https://github.com/curl/curl/issues/8102 + Closes #8103 -- c-hyper: don't abort CONNECT responses early when auth-in-progress +- multi: handle errors returned from socket/timer callbacks - ... and make sure to stop ignoring the body once the CONNECT is done. + The callbacks were partially documented to support this. Now the + behavior is documented and returning error from either of these + callbacks will effectively kill all currently ongoing transfers. - This should make test 206 work proper again and not be flaky. + Added test 530 to verify - Closes #7889 + Reported-by: Marcelo Juchem + Fixes #8083 + Closes #8089 -- hyper: does not support disabling CURLOPT_HTTP_TRANSFER_DECODING +- http2:set_transfer_url() return early on OOM - Simply because hyper doesn't have this ability. Mentioned in docs now. + If curl_url() returns NULL this should return early to avoid mistakes - + even if right now the subsequent function invokes are all OK. - Skip test 326 then + Coverity (wrongly) pointed out this as a NULL deref. - Closes #7889 + Closes #8100 -- test262: don't attempt with hyper +- tool_parsecfg: use correct free() call to free memory - This test verifies that curl works with binary zeroes in HTTP response - headers and hyper refuses such. They're not kosher http. + Detected by Coverity. CID 1494642. + Follow-up from 2be1aa619bca - Closes #7889 + Closes #8099 -- c-hyper: make test 217 run +- tool_operate: fix potential memory-leak - Closes #7889 + A 'CURLU *' would leak if url_proto() is called with no URL. + + Detected by Coverity. CID 1494643. + Follow-up to 18270893abdb19 + Closes #8098 -- DISABLED: enable test 209+213 for hyper +- [Patrick Monnerat brought this change] + + openldap: implement STARTTLS - Follow-up to 823d3ab855c + As this introduces use of CURLOPT_USE_SSL option for LDAP, also check + this option in ldap.c as it is not supported by this backend. - Closes #7889 + Closes #8065 -- test207: accept a different error code for hyper +- [Jun Tseng brought this change] + + curl_easy_unescape.3: call curl_easy_cleanup in example - It returns HYPERE_UNEXPECTED_EOF for this case which we convert to the - somewhat generic CURLE_RECV_ERROR. + Closes #8097 + +- [Jun Tseng brought this change] + + curl_easy_escape.3: call curl_easy_cleanup in example - Closes #7889 + Closes #8097 -- [Érico Nogueira brought this change] +- tool_listhelp: sync + + Follow-up to 172068b76f - INSTALL: update symbol hiding option +- [Damien Walsh brought this change] + + request.d: refer to 'method' rather than 'command' - --enable-hidden-symbols was deprecated in - 9e24b9c7afbcb81120af4cf3f6cdee49a06d8224. + Closes #8094 + +- RELEASE-NOTES: synced + +- writeout: fix %{http_version} for HTTP/3 - Closes #7890 + Output "3" properly when HTTP/3 was used. + + Reported-by: Bernat Mut + Fixes #8072 + Closes #8092 -- http_proxy: multiple CONNECT with hyper done better +- urlapi: accept port number zero - Enabled test 206 + This is a regression since 7.62.0 (fb30ac5a2d). - Closes #7888 + Updated test 1560 accordingly + + Reported-by: Brad Fitzpatrick + Fixes #8090 + Closes #8091 -- hyper: pass the CONNECT line to the debug callback +- [Mark Dodgson brought this change] + + lift: ignore is a deprecated config option, use ignoreRules - Closes #7887 + Closes #8082 -- mailmap: Malik Idrees Hasan Khan +- [Alessandro Ghedini brought this change] -Jay Satiro (21 Oct 2021) -- [Malik Idrees Hasan Khan brought this change] + HTTP3: update quiche build instructions + + The repo repo was re-organized a bit, so the build instructions need to + be updated. + + Closes #8076 - build: fix typos +- CURLMOPT_TIMERFUNCTION.3: call it expire time, not interval - Closes https://github.com/curl/curl/pull/7886 + Since we say it is a non-repating timer -- URL-SYNTAX: add IMAP UID SEARCH example +- [Florian Van Heghe brought this change] + + mbedTLS: include NULL byte in blob data length for CURLOPT_CAINFO_BLOB - - Explain the difference between IMAP search via URL (which returns - message sequence numbers) and IMAP search via custom request (which - can return UID numbers if prefixed with UID, eg "UID SEARCH ..."). + Fixes #8079 + Closes #8081 + +Jay Satiro (2 Dec 2021) +- [Wyatt O'Day brought this change] + + version_win32: Check build number and platform id - Bug: https://github.com/curl/curl/issues/7626 - Reported-by: orycho@users.noreply.github.com + Prior to this change the build number was not checked during version + comparison, and the platform id was supposed to be checked but wasn't. - Ref: https://github.com/curl/curl/issues/2789 + Checking the build number is required for enabling "evergreen" + Windows 10/11 features (like TLS 1.3). - Closes https://github.com/curl/curl/pull/7881 - -Daniel Stenberg (20 Oct 2021) -- manpage: adjust the asterisk in some SYNOPSIS sections + Ref: https://github.com/curl/curl/pull/7784 - Closes #7884 + Closes https://github.com/curl/curl/pull/7824 + Closes https://github.com/curl/curl/pull/7867 -- curl_multi_perform.3: polish wording +- libssh2: fix error message for sha256 mismatch - - simplify the example by using curl_multi_poll + - On mismatch error show sha256 fingerprint in base64 format. - - mention curl_multi_add_handle in the text + Prior to this change the fingerprint was mistakenly printed in binary. + +Daniel Stenberg (1 Dec 2021) +- [x2018 brought this change] + + openssl: check the return value of BIO_new() - - cut out the description of pre-7.20.0 return code behavior - that version - is now more than eleven years old and is basically no longer out there + Closes #8078 + +Dan Fandrich (30 Nov 2021) +- docs: Update the Reducing Size section - - adjust the "typical usage" to mention curl_multi_poll + Add many more options that can reduce the size of the binary that were + added since the last update. Update the sample minimal binary size for + version 7.80.0. + +- tests: Add some missing keywords to tests - Closes #7883 + These are needed to skip some tests when configure options have disabled + certain features. -- docs/THANKS: removed on request +Daniel Stenberg (30 Nov 2021) +- [Florian Van Heghe brought this change] -- FAQ: polish the explanation of libcurl + mbedTLS: add support for CURLOPT_CAINFO_BLOB + + Closes #8071 -- curl_easy_perform.3: minor wording tweak +- [Glenn Strauss brought this change] -- [Erik Stenlund brought this change] + digest: compute user:realm:pass digest w/o userhash + + https://datatracker.ietf.org/doc/html/rfc7616#section-3.4.4 + ... the client MUST calculate a hash of the username after + any other hash calculation ... + + Signed-off-by: Glenn Strauss + Closes #8066 - mime: mention CURL_DISABLE_MIME in comment +- config.d: update documentation to match the path search - CURL_DISABLE_MIME is not mentioned in the comment describing the if else - preprocessor directive. + Assisted-by: Jay Satiro + +- tool_findfile: search for a file in the homedir - Closes #7882 + The homedir() function is now renamed into findfile() and iterates over + all the environment variables trying to access the file in question + until it finds it. Last resort is then getpwuid() if + available. Previously it would first try to find a home directory and if + that was set, insist on checking only that directory for the file. This + now returns the full file name it finds. + + The Windows specific checks are now done differently too and in this + order: + + 1 - %USERPROFILE% + 2 - %APPDATA% + 3 - %USERPROFILE%\\Application Data + + The windows order is modified to match how the Windows 10 ssh tool works + when it searches for .ssh/known_hosts. + + Reported-by: jeffrson on github + Co-authored-by: Jay Satiro + Fixes #8033 + Closes #8035 -- tls: remove newline from three infof() calls +- docs: consistent manpage SYNOPSIS - Follow-up to e7416cf + Make all libcurl related options use .nf (no fill) for the SYNOPSIS + section - for consistent look. roffit then renders that section using +
 (monospace font) in html for the website.
   
-  Reported-by: billionai on github
-  Fixes #7879
-  Closes #7880
+  Extended manpage-syntax (test 1173) with a basic check for it.
+  
+  Closes #8062
 
 - RELEASE-NOTES: synced
 
-- curl_gssapi: fix build warnings by removing const
+- [Patrick Monnerat brought this change]
+
+  openldap: handle connect phase with a state machine
   
-  Follow-up to 20e980f85b0ea6
+  Closes #8054
+
+- docs: address proselint nits
   
-  In #7875 these inits were modified but I get two warnings that these new
-  typecasts are necessary for.
+  - avoid exclamation marks
+  - use consistent number of spaces after periods: one
+  - avoid clichés
+  - avoid using 'very'
   
-  Closes #7876
+  Closes #8060
 
-- [Bo Anderson brought this change]
+- [Bruno Baguette brought this change]
 
-  curl_gssapi: fix link error on macOS Monterey
+  FAQ: typo fix : "yout" ➤ "your"
   
-  Fixes #7657
-  Closes #7875
+  Closes #8059
 
-- test1185: verify checksrc
-  
-  Closes #7866
+- [Bruno Baguette brought this change]
 
-- checksrc: improve the SPACESEMICOLON error message
+  docs/INSTALL.md: typo fix : added missing "get" verb
   
-  and adjust the MULTISPACE one to use plural
+  Closes #8058
+
+- insecure.d: detail its use for SFTP and SCP as well
   
-  Closes #7866
+  Closes #8056
 
-- url: set "k->size" -1 at start of request
+Viktor Szakats (25 Nov 2021)
+- Makefile.m32: rename -winssl option to -schannel and tidy up
   
-  The size of the transfer is unknown at that point.
+  - accept `-schannel` as an alternative to `CFG` option `-winssl`
+    (latter still accepted, but deprecated)
+  - rename internal variable `WINSSL` to `SCHANNEL`
+  - make the `CFG` option evaluation shorter, without repeating the option
+    name
   
-  Fixes #7871
-  Closes #7872
+  Reviewed-by: Marcel Raad
+  Reviewed-by: Daniel Stenberg
+  Closes #8053
 
-Daniel Gustafsson (18 Oct 2021)
-- doh: remove experimental code for DoH with GET
-  
-  The code for sending DoH requests with GET was never enabled in a way
-  such that it could be used or tested. As there haven't been requests
-  for this feature, and since it at this is effectively dead, remove it
-  and favor reimplementing the feature in case anyone is interested.
+Daniel Stenberg (25 Nov 2021)
+- KNOWN_BUGS: 5.6 make distclean loops forever
   
-  Closes #7870
-  Reviewed-by: Daniel Stenberg 
+  Reported-by: David Bohman
+  Closes #7716
 
-Daniel Stenberg (18 Oct 2021)
-- cirrus: remove FreeBSD 11.4 from the matrix
+- KNOWN_BUGS: add one, remove one
   
-  It has reached End-Of-Life and causes some LDAP CI issues.
+  - 5.10 SMB tests fail with Python 2
   
-  Closes #7869
-
-- cirrus: switch to openldap24-client
+  Just use python 3.
   
-  ... as it seems openldap-client doesn't exist anymore.
+  + 5.10 curl hangs on SMB upload over stdin
   
-  Reported-by: Jay Satiro
-  Fixes #7868
-  Closes #7869
+  Closes #7896
 
-- checksrc: ignore preprocessor lines
+- urlapi: provide more detailed return codes
   
-  In order to check the actual code better, checksrc now ignores
-  everything that look like preprocessor instructions. It also means
-  that code in macros are now longer checked.
+  Previously, the return code CURLUE_MALFORMED_INPUT was used for almost
+  30 different URL format violations. This made it hard for users to
+  understand why a particular URL was not acceptable. Since the API cannot
+  point out a specific position within the URL for the problem, this now
+  instead introduces a number of additional and more fine-grained error
+  codes to allow the API to return more exactly in what "part" or section
+  of the URL a problem was detected.
   
-  Note that some rules then still don't need to be followed when code is
-  exactly below a cpp instruction.
+  Also bug-fixes curl_url_get() with CURLUPART_ZONEID, which previously
+  returned CURLUE_OK even if no zoneid existed.
   
-  Removes two checksrc exceptions we needed previously because of
-  preprocessor lines being checked.
+  Test cases in 1560 have been adjusted and extended. Tests 1538 and 1559
+  have been updated.
   
-  Reported-by: Marcel Raad
-  Fixes #7863
-  Closes #7864
+  Updated libcurl-errors.3 and curl_url_strerror() accordingly.
+  
+  Closes #8049
 
-- urlapi: skip a strlen(), pass in zero
+- urlapi: make Curl_is_absolute_url always use MAX_SCHEME_LEN
   
-  ... to let curl_easy_escape() itself do the strlen. This avoids a (false
-  positive) Coverity warning and it avoids us having to store the strlen()
-  return value in an int variable.
+  Instad of having all callers pass in the maximum length, always use
+  it. The passed in length is instead used only as the length of the
+  target buffer for to storing the scheme name in, if used.
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #7862
+  Added the scheme max length restriction to the curl_url_set.3 man page.
+  
+  Follow-up to 45bcb2eaa78c79
+  
+  Closes #8047
 
-- misc: update copyright years
+- [Jay Satiro brought this change]
 
-- examples/htmltidy: correct wrong printf() use
+  cmake: warn on use of the now deprecated symbols
   
-  ... and update the includes to match how current htmltidy wants them
-  used.
+  Follow-up to 9108da2c26d
   
-  Reported-by: Stathis Kapnidis
-  Fixes #7860
-  Closes #7861
+  Closes #8052
 
-Jay Satiro (15 Oct 2021)
-- http: set content length earlier
-  
-  - Make content length (ie download size) accessible to the user in the
-    header callback, but only after all headers have been processed (ie
-    only in the final call to the header callback).
+- [Kevin Burke brought this change]
+
+  tests/CI.md: add more information on CI environments
   
-  Background:
+  Fixes #8012
+  Closes #8022
+
+- cmake: private identifiers use CURL_ instead of CMAKE_ prefix
   
-  For a long time the content length could be retrieved in the header
-  callback via CURLINFO_CONTENT_LENGTH_DOWNLOAD_T as soon as it was parsed
-  by curl.
+  Since the 'CMAKE_' prefix is reserved for cmake's own private use.
+  Ref: https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html
   
-  Changes were made in 8a16e54 (precedes 7.79.0) to ignore content length
-  if any transfer encoding is used. A side effect of that was that
-  content length was not set by libcurl until after the header callback
-  was called the final time, because until all headers are processed it
-  cannot be determined if content length is valid.
+  Reported-by: Boris Rasin
+  Fixes #7988
+  Closes #8044
+
+- urlapi: reject short file URLs
   
-  This change keeps the same intention --all headers must be processed--
-  but now the content length is available before the final call to the
-  header function that indicates all headers have been processed (ie
-  a blank header).
+  file URLs that are 6 bytes or shorter are not complete. Return
+  CURLUE_MALFORMED_INPUT for those. Extended test 1560 to verify.
   
-  Bug: https://github.com/curl/curl/commit/8a16e54#r57374914
-  Reported-by: sergio-nsk@users.noreply.github.com
+  Triggered by #8041
+  Closes #8042
+
+- curl: improve error message for --head with -J
   
-  Co-authored-by: Daniel Stenberg
+  ... it now focuses on the "output of headers" combined with the
+  --remote-header-name option, as that is actually the problem. Both
+  --head and --include can output headers.
   
-  Fixes https://github.com/curl/curl/issues/7804
-  Closes https://github.com/curl/curl/pull/7803
+  Reported-by: nimaje on github
+  Fixes #7987
+  Closes #8045
 
-Daniel Stenberg (15 Oct 2021)
-- [Abhinav Singh brought this change]
+- RELEASE-NOTES: synced
 
-  aws-sigv4: make signature work when post data is binary
+- [Stefan Eissing brought this change]
+
+  urlapi: cleanup scheme parsing
   
-  User sets the post fields size for binary data.  Hence, we should not be
-  using strlen on it.
+  Makea Curl_is_absolute_url() always leave a defined 'buf' and avoids
+  copying on urls that do not start with a scheme.
   
-  Added test 1937 and 1938 to verify.
+  Closes #8043
+
+- tool_operate: only set SSH related libcurl options for SSH URLs
   
-  Closes #7844
+  For example, this avoids trying to find and set the known_hosts file (or
+  warn for its absence) if SFTP or SCP are not used.
+  
+  Closes #8040
 
-- [a1346054 brought this change]
+- [Jacob Hoffman-Andrews brought this change]
 
-  MacOSX-Framework: remove redundant ';'
+  rustls: remove comment about checking handshaking
   
-  Closes #7859
+  The comment is incorrect in two ways:
+   - It says the check needs to be last, but the check is actually first.
+   - is_handshaking actually starts out true.
+  
+  Closes #8038
 
-- RELEASE-NOTES: synced
+Marcel Raad (20 Nov 2021)
+- openssl: use non-deprecated API to read key parameters
+  
+  With OpenSSL 3.0, the parameters are read directly from the `EVP_PKEY`
+  using `EVP_PKEY_get_bn_param`.
+  
+  Closes https://github.com/curl/curl/pull/7893
 
-- openssl: with OpenSSL 1.1.0+ a failed RAND_status means goaway
+- openssl: reduce code duplication
   
-  One reason we know it can fail is if a provider is used that doesn't do
-  a proper job or is wrongly configured.
+  `BN_print`'s `BIGNUM` parameter has been `const` since OpenSSL 0.9.4.
   
-  Reported-by: Michael Baentsch
-  Fixes #7840
-  Closes #7856
+  Closes https://github.com/curl/curl/pull/7893
 
-Marcel Raad (14 Oct 2021)
-- [Ryan Mast brought this change]
+- openssl: remove `RSA_METHOD_FLAG_NO_CHECK` handling if unavailable
+  
+  The flag has been deprecated without replacement in OpenSSL 3.0.
+  
+  Closes https://github.com/curl/curl/pull/7893
 
-  cmake: add CURL_ENABLE_SSL option and make CMAKE_USE_* SSL backend options depend on it
+- openssl: remove usage of deprecated `SSL_get_peer_certificate`
   
-  Closes https://github.com/curl/curl/pull/7822
+  The function name was changed to `SSL_get1_peer_certificate` in OpenSSL
+  3.0.
+  
+  Closes https://github.com/curl/curl/pull/7893
 
-Daniel Stenberg (14 Oct 2021)
-- http: remove assert that breaks hyper
+Daniel Stenberg (19 Nov 2021)
+- page-footer: fix typo
   
-  Reported-by: Jay Satiro
-  Fixes #7852
-  Closes #7855
+  Closes #8036
 
-- http_proxy: fix one more result assign for hyper
+- http: enable haproxy support for hyper backend
   
-  and remove the bad assert again, since it was run even with no error!
+  This is done by having native code do the haproxy header output before
+  hyper issues its request. The little downside with this approach is that
+  we need the entire Curl_buffer_send() function built, which is otherwise
+  not used for hyper builds.
   
-  Closes #7854
+  If hyper ends up getting native support for the haproxy protocols we can
+  backpedal on this.
+  
+  Enables test 1455 and 1456
+  
+  Closes #8034
 
-Jay Satiro (14 Oct 2021)
-- sws: fix memory leak on exit
+- [Bernhard Walle brought this change]
+
+  configure: fix runtime-lib detection on macOS
   
-  - Free the allocated http request struct on cleanup.
+  With a non-standard installation of openssl we get this error:
   
-  Prior to this change if sws was built with leak sanitizer it would
-  report a memory leak error during testing.
+      checking run-time libs availability... failed
+      configure: error: one or more libs available at link-time are not available run-time. Libs used at link-time: -lnghttp2 -lssl -lcrypto -lssl -lcrypto -lz
   
-  Closes https://github.com/curl/curl/pull/7849
-
-Daniel Stenberg (14 Oct 2021)
-- c-hyper: make Curl_http propagate errors better
+  There's already code to set LD_LIBRARY_PATH on Linux, so set
+  DYLD_LIBRARY_PATH equivalent on macOS.
   
-  Pass on better return codes when errors occur within Curl_http instead
-  of insisting that CURLE_OUT_OF_MEMORY is the only possible one.
+  Closes #8028
+
+- [Don J Olmstead brought this change]
+
+  cmake: don't set _USRDLL on a static Windows build
   
-  Pointed-out-by: Jay Satiro
-  Closes #7851
+  Closes #8030
 
-- http_proxy: make hyper CONNECT() return the correct error code
+- page-footer: document more environment variables
   
-  For every 'goto error', make sure the result variable holds the error
-  code for what went wrong.
+  ... that curl might use.
   
-  Reported-by: Rafał Mikrut
-  Fixes #7825
-  Closes #7846
+  Closes #8027
 
-- docs/Makefile.am: repair 'make html'
+- netrc.d: edit the .netrc example to look nicer
   
-  by removing index.html which isn't around anymore
+  Works nicely thanks to d1828b470f43d
   
-  Closes #7853
+  Closes #8025
 
-- [Борис Верховский brought this change]
+- tftp: mark protocol as not possible to do over CONNECT
+  
+  ... and make connect_init() refusing trying to tunnel protocols marked
+  as not working. Avoids a double-free.
+  
+  Reported-by: Even Rouault
+  Fixes #8018
+  Closes #8020
 
-  curl: correct grammar in generated libcurl code
+- docs/cmdline-opts: do not say "protocols: all"
   
-  Closes #7802
+  Remove the lines saying "protocols: all". It makes the output in the
+  manpage look funny, and the expectation is probably by default that if
+  not anything is mentioned about protocols the option apply to them all.
+  
+  Closes #8021
 
-- tests: disable test 2043
+- curl.1: require "see also" for every documented option
   
-  It uses revoked.badssl.com which now is expired and therefor this now
-  permafails. We should not use external sites for tests, this test should
-  be converted to use our own infra.
+  gen.pl now generates a warning if the "See Also" field is not filled in for a
+  command line option
   
-  Closes #7845
+  All command line options now provide one or more related options. 167
+  "See alsos" added!
+  
+  Closes #8019
 
-- runtests: split out ignored tests
+- insecure.d: expand and clarify
   
-  Report ignore tests separately from the actual fails.
+  Closes #8017
+
+- gen.pl: improve example output format
   
-  Don't exit non-zero if test servers couldn't get killed.
+  Treat consecutive lines that start with a space to be "examples". They
+  are output enclosed by .nf and .fi
   
-  Assisted-by: Jay Satiro
+  Updated form.d to use this new fanciness
   
-  Fixes #7818
-  Closes #7841
+  Closes #8016
 
-- http2: make getsock not wait for write if there's no remote window
+- Revert "form-escape.d: double the back-slashes for proper man page output"
   
-  While uploading, check for remote window availability in the getsock
-  function so that we don't wait for a writable socket if no data can be
-  sent.
+  This reverts commit a2d8eac04a4eb1d5a98cf24b4e5cec5cec565d27.
   
-  Reported-by: Steini2000 on github
-  Fixes #7821
-  Closes #7839
+  silly me, it was intended to be one backslash!
 
-- test368: verify dash is appended for "-r [num]"
+- form-escape.d: double the back-slashes for proper man page output
+
+- page-footer: add a mention of how to report bugs to the man page
+
+- RELEASE-NOTES: synced
   
-  Follow-up to 8758a26f8878
+  and bump to 7.81.0-DEV
 
-- [Борис Верховский brought this change]
+- [Patrick Monnerat brought this change]
 
-  curl: actually append "-" to --range without number only
+  mime: use percent-escaping for multipart form field and file names
   
-  Closes #7837
+  Until now, form field and file names where escaped using the
+  backslash-escaping algorithm defined for multipart mails. This commit
+  replaces this with the percent-escaping method for URLs.
+  
+  As this may introduce incompatibilities with server-side applications, a
+  new libcurl option CURLOPT_MIME_OPTIONS with bitmask
+  CURLMIMEOPT_FORMESCAPE is introduced to revert to legacy use of
+  backslash-escaping. This is controlled by new cli tool option
+  --form-escape.
+  
+  New tests and documentation are provided for this feature.
+  
+  Reported by: Ryan Sleevi
+  Fixes #7789
+  Closes #7805
 
-- RELEASE-NOTES: synced
+- [Kevin Burke brought this change]
 
-- urlapi: URL decode percent-encoded host names
+  zuul.d: update rustls-ffi to version 0.8.2
   
-  The host name is stored decoded and can be encoded when used to extract
-  the full URL. By default when extracting the URL, the host name will not
-  be URL encoded to work as similar as possible as before. When not URL
-  encoding the host name, the '%' character will however still be encoded.
+  This version fixes errors with ALPN negotiation in rustls, which is
+  necessary for HTTP/2 support. For more information see the rustls-ffi
+  changelog.
   
-  Getting the URL with the CURLU_URLENCODE flag set will percent encode
-  the host name part.
+  Closes #8013
+
+- configure: better diagnostics if hyper is built wrong
   
-  As a bonus, setting the host name part with curl_url_set() no longer
-  accepts a name that contains space, CR or LF.
+  If hyper is indeed present in the specified directory but couldn't be
+  used to find the correct symbol, then offer a different error message to
+  better help the user understand the issue.
   
-  Test 1560 has been extended to verify percent encodings.
+  Suggested-by: Jacob Hoffman-Andrews
+  Fixes #8001
+  Closes #8005
+
+- test1939: require proxy support to run
   
-  Reported-by: Noam Moshe
-  Reported-by: Sharon Brizinov
-  Reported-by: Raul Onitza-Klugman
-  Reported-by: Kirill Efimov
-  Fixes #7830
-  Closes #7834
+  Follow-up to f0b7099a10d1a
+  
+  Closes #8011
 
-Marc Hoersken (8 Oct 2021)
-- CI/makefiles: introduce dedicated test target
+- test302[12]: run only with the libssh2 backend
   
-  Make it easy to use the same set of test flags
-  throughout all current and future CI builds.
+  ... as the others don't support --hostpubsha256
   
-  Reviewed-by: Jay Satiro
+  Reported-by: Paul Howarth
+  Fixes #8009
+  Closes #8010
+
+- runtests: make the SSH library a testable feature
   
-  Follow up to #7690
-  Closes #7785
+  libssh2, libssh and wolfssh
 
-Daniel Stenberg (8 Oct 2021)
-- maketgz: redirect updatemanpages.pl output to /dev/null
+- [Jacob Hoffman-Andrews brought this change]
 
-- CURLOPT_HTTPHEADER.3: add descripion for specific headers
-  
-  Settting Host: or Transfer-Encoding: chunked actually have special
-  meanings to libcurl. This change tries to document them
+  rustls: read of zero bytes might be okay
   
-  Closes #7829
-
-- c-hyper: use hyper_request_set_uri_parts to make h2 better
+  When we're reading out plaintext from rustls' internal buffers, we might
+  get a read of zero bytes (meaning a clean TCP close, including
+  close_notify). However, we shouldn't return immediately when that
+  happens, since we may have already copied out some plaintext bytes.
+  Break out of the loop when we get a read of zero bytes, and figure out
+  which path we're dealing with.
   
-  and make sure to not send Host: over h2.
+  Acked-by: Kevin Burke
   
-  Fixes #7679
-  Reported-by: David Cook
-  Closes #7827
+  Closes #8003
 
-- [Michael Afanasiev brought this change]
+- [Jacob Hoffman-Andrews brought this change]
 
-  curl-openssl.m4: modify library order for openssl linking
+  rustls: remove incorrect EOF check
   
-  lcrypto may depend on lz, and configure corrently fails with when
-  statically linking as the order is "-lz -lcrypto". This commit switches
-  the order to "-lcrypto -lz".
+  The update to rustls-ffi 0.8.0 changed handling of EOF and close_notify.
+  From the CHANGELOG:
   
-  Closes #7826
-
-Marcel Raad (7 Oct 2021)
-- sha256: use high-level EVP interface for OpenSSL
+  > Handling of unclean close and the close_notify TLS alert. Mirroring
+  > upstream changes, a rustls_connection now tracks TCP closed state like
+  > so: rustls_connection_read_tls considers a 0-length read from its
+  > callback to mean "TCP stream was closed by peer."  If that happens
+  > before the peer sent close_notify, rustls_connection_read will return
+  > RUSTLS_RESULT_UNEXPECTED_EOF once the available plaintext bytes are
+  > exhausted. This is useful to protect against truncation attacks. Note:
+  > some TLS implementations don't send close_notify. If you are already
+  > getting length information from your protocol (e.g. Content-Length in
+  > HTTP) you may choose to ignore UNEXPECTED_EOF so long as the number of
+  > plaintext bytes was as expected.
   
-  Available since OpenSSL 0.9.7. The low-level SHA256 interface is
-  deprecated in OpenSSL v3, and its usage was discouraged even before.
+  That means we don't need to check for unclean EOF in `cr_recv()`,
+  because `process_new_packets()` will give us an error if appropriate.
   
-  Closes https://github.com/curl/curl/pull/7808
+  Closes #8003
 
-- curl_ntlm_core: use OpenSSL only if DES is available
+- lib1939: make it endure torture tests
   
-  This selects another SSL backend then if available, or otherwise at
-  least gives a meaningful error message.
+  Follow-up to f0b7099a10d1a
   
-  Closes https://github.com/curl/curl/pull/7808
+  Closes #8007
 
-- md5: fix compilation with OpenSSL 3.0 API
+- azure: make the "w/o HTTP/SMTP/IMAP" build disable SSL proper
   
-  Only use OpenSSL's MD5 code if it's available.
+  The configure line would previously depend on a configure mistake using
+  --without-openssl that is fixed and now this configure line needs
+  adjusting to use --without-ssl.
   
-  Also fix wolfSSL build with `NO_MD5`, in which case neither the
-  wolfSSL/OpenSSL implementation nor the fallback implementation was
-  used.
+  Follow-up to b589696f0312d
   
-  Closes https://github.com/curl/curl/pull/7808
+  Closes #8006
 
-Daniel Stenberg (7 Oct 2021)
-- print_category: printf %*s needs an int argument
+- [Jacob Hoffman-Andrews brought this change]
+
+  configure: add -lm to configure for rustls build.
   
-  ... not a size_t!
+  Note: The list of libraries that rustc tells us we need to include is
+  longer, but also includes some more platform-specific libraries that I
+  am not sure how to effectively incorporate. Adding just -lm seems to
+  solve an immediate problem, so I'm adding just that.
   
-  Detected by Coverity: CID 1492331.
-  Closes #7823
+  Closes #8002
 
-Jay Satiro (7 Oct 2021)
-- version_win32: use actual version instead of manifested version
-  
-  - Use RtlVerifyVersionInfo instead of VerifyVersionInfo, when possible.
+- curl_share_setopt.3: refer to CURLSHOPT_USERDATA(3) properly
+
+- curl_share_setopt.3: split out options into their own manpages
   
-  Later versions of Windows have normal version functions that compare and
-  return versions based on the way the application is manifested, instead
-  of the actual version of Windows the application is running on. We
-  prefer the actual version of Windows so we'll now call the Rtl variant
-  of version functions (RtlVerifyVersionInfo) which does a proper
-  comparison of the actual version.
+  CURLSHOPT_LOCKFUNC.3
+  CURLSHOPT_SHARE.3
+  CURLSHOPT_UNLOCKFUNC.3
+  CURLSHOPT_UNSHARE.3
+  CURLSHOPT_USERDATA.3
   
-  Reported-by: Wyatt O'Day
+  Closes #7998
+
+- http_proxy: make Curl_connect_done() work for proxy disabled builds
   
-  Ref: https://github.com/curl/curl/pull/7727
+  ... by making it an empty macro then.
   
-  Fixes https://github.com/curl/curl/issues/7742
-  Closes https://github.com/curl/curl/pull/7810
-
-Daniel Stenberg (6 Oct 2021)
-- RELEASE-NOTES: synced
+  Follow-up to f0b7099a10d1a
+  Reported-by: Vincent Grande
+  Fixes #7995
+  Closes #7996
 
-- http: fix Basic auth with empty name field in URL
+- Curl_connect_done: handle being called twice
   
-  Add test 367 to verify.
+  Follow-up to f0b7099a10d1a7c
   
-  Reported-by: Rick Lane
-  Fixes #7819
-  Closes #7820
+  When torture testing 1021, it turns out the Curl_connect_done function
+  might be called twice and that previously then wrongly cleared the HTTP
+  pointer in the second invoke.
+  
+  Closes #7999
 
-- [Jeffrey Tolar brought this change]
+- [Stan Hu brought this change]
 
-  CURLOPT_MAXLIFETIME_CONN: maximum allowed lifetime for conn reuse
-  
-  ... and close connections that are too old instead of reusing them.
+  configure: don't enable TLS when --without-* flags are used
   
-  By default, this behavior is disabled.
+  Previously specifying `--without-gnutls` would unexpectedly attempt to
+  compile with GnuTLS, effectively interpreting this as
+  `--with-gnutls`. This caused a significant amount of confusion when
+  `libcurl` was built with SSL disabled since GnuTLS wasn't present.
   
-  Bug: https://curl.se/mail/lib-2021-09/0058.html
-  Closes #7751
-
-Daniel Gustafsson (6 Oct 2021)
-- docs/examples: add missing binaries to gitignore
+  68d89f24 dropped the `--without-*` options from the configure help, but
+  `AC_ARG_WITH` still defines these flags automatically. As
+  https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/External-Software.html
+  describes, the `action-if-given` is called when the user specifies
+  `--with-*` or `--without-*` options.
   
-  Commit f65d7889b added getreferrer, and commit ae8e11ed5 multi-legacy,
-  both of which missed adding .gitignore clauses for the built binaries.
+  To prevent this confusion, we make the `--without` flag do the right
+  thing by ignoring the value if it set to "no".
   
-  Closes #7817
-  Reviewed-by: Daniel Stenberg 
+  Closes #7994
 
-Daniel Stenberg (5 Oct 2021)
-- [Josip Medved brought this change]
+- [Rikard Falkeborn brought this change]
 
-  HTTP3: fix the HTTP/3 Explained book link
+  docs/checksrc: Add documentation for STRERROR
   
-  Closes #7813
-
-- [Lucas Holt brought this change]
+  Closes #7991
 
-  misc: fix a few issues on MidnightBSD
+- vtls/rustls: adapt to the updated rustls_version proto
   
-  Closes #7812
+  Closes #7956
 
-Daniel Gustafsson (4 Oct 2021)
-- [8U61ife brought this change]
+- [Kevin Burke brought this change]
 
-  tool_main: fix typo in comment
+  vtls/rustls: handle RUSTLS_RESULT_PLAINTEXT_EMPTY
   
-  Closes: #7811
-  Reviewed-by: Daniel Gustafsson 
+  Previously we'd return CURLE_READ_ERROR if we received this, instead
+  of triggering the error handling logic that's present in the next if
+  block down.
+  
+  After this change, curl requests to https://go.googlesource.com using
+  HTTP/2 complete successfully.
+  
+  Fixes #7949
+  Closes #7948
 
-Daniel Stenberg (4 Oct 2021)
-- [Ryan Mast brought this change]
+- [Kevin Burke brought this change]
 
-  BINDINGS: URL updates
+  zuul: update build environment for rustls-ffi 0.8.0
+
+- [Kevin Burke brought this change]
+
+  vtls/rustls: update to compile with rustls-ffi v0.8.0
   
-  For cpr, BBHTTP, Eiffel, Harbour, Haskell, Mono, and Rust
+  Some method names, as well as the generated library name, were changed
+  in a recent refactoring.
   
-  Closes #7809
-
-- scripts/delta: hide a git error message we don't care about
+  Further, change the default configuration instructions to check for
+  Hyper in either "target/debug" or "target/release" - the latter
+  contains an optimized build configuration.
   
-  fatal: path 'src/tool_listhelp.c' exists on disk, but not in [tag]
+  Fixes #7947
+  Closes #7948
 
-- [Patrick Monnerat brought this change]
+- RELEASE-NOTES: synced
+  
+  and bump the version to 7.80.1
 
-  sasl: binary messages
+- multi: shut down CONNECT in Curl_detach_connnection
   
-  Capabilities of sasl module are extended to exchange messages in binary
-  as an alternative to base64.
+  ... to prevent a lingering pointer that would lead to a double-free.
   
-  If http authentication flags have been set, those are used as sasl
-  default preferred mechanisms.
+  Added test 1939 to verify.
   
-  Closes #6930
+  Reported-by: Stephen M. Coakley
+  Fixes #7982
+  Closes #7986
 
-- [Hayden Roche brought this change]
-
-  wolfssl: use for SHA256, MD4, MD5, and setting DES odd parity
+- curl_easy_cleanup.3: remove from multi handle first
   
-  Prior to this commit, OpenSSL could be used for all these functions, but
-  not wolfSSL. This commit makes it so wolfSSL will be used if USE_WOLFSSL
-  is defined.
+  Easy handles that are used by the multi interface should be removed from
+  the multi handle before they are cleaned up.
   
-  Closes #7806
+  Reported-by: Stephen M. Coakley
+  Ref: #7982
+  Closes #7983
 
-- scripts/delta: count command line options in the new file
+- url.c: fix the SIGPIPE comment for Curl_close
   
-  ... which makes the shown delta number wrong until next release.
+  Closes #7984
+
+Version 7.80.0 (10 Nov 2021)
 
+Daniel Stenberg (10 Nov 2021)
 - RELEASE-NOTES: synced
+  
+  for curl 7.80.0
 
-- print_category: print help descriptions aligned
+- THANKS: add contributors from the 7.80.0 cycle
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: advertise h3 as well as h3-29
   
-  Adjust the description position to make an aligned column when doing
-  help listings, which is more pleasing to the eye.
+  Advertise h3 as well as h3-29 since some servers out there require h3
+  for QUIC v1.
   
-  Suggested-by: Gisle Vanem
-  Closes #7792
+  Closes #7979
 
-- lib/mk-ca-bundle.pl: skip certs passed Not Valid After date
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: use QUIC v1 consistently
   
-  With this change applied, the now expired 'DST Root CA X3' cert will no
-  longer be included in the output.
+  Since we switched to v1 quic_transport_parameters codepoint in #7960
+  with quictls, lets use QUIC v1 consistently.
   
-  Details: https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/
+  Closes #7979
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: compile with the latest nghttp3
   
-  Closes #7801
+  Closes #7978
 
-- tool_listhelp: easier to generate with gen.pl
+Marc Hoersken (9 Nov 2021)
+- tests: add Schannel-specific tests and disable unsupported ones
   
-  tool_listhelp.c is now a separate file with only the command line --help
-  output, exactly as generated by gen.pl. This makes it easier to generate
-  updates according to what's in the docs/cmdline-opts docs.
+  Adds Schannel variants of SSLpinning tests that include the option
+  --ssl-revoke-best-effort to ignore certificate revocation check
+  failures which is required due to our custom test CA certificate.
   
-    cd $srcroot/docs/cmdline-opts
-    ./gen.pl listhelp *.d > $srcroot/src/tool_listhelp.c
+  Disable the original variants if the Schannel backend is enabled.
   
-  With a configure build, this also works:
+  Also skip all IDN tests which are broken while using an msys shell.
   
-    make -C src listhelp
+  This is a step to simplify test exclusions for Windows and MinGW.
   
-  Closes #7787
-
-- [Anthony Hu brought this change]
+  Reviewed-by: Jay Satiro
+  Reviewed-by: Marcel Raad
+  Reviewed-by: Daniel Stenberg
+  Closes #7968
 
-  wolfssl: allow setting of groups/curves
-  
-  In particular, the quantum safe KEM and hybrid curves if wolfSSL is
-  built to support them.
+Daniel Stenberg (8 Nov 2021)
+- docs: NAME fixes in easy option man pages
   
-  Closes #7728
+  Closes #7975
 
-- [Jan Mazur brought this change]
+- [Roger Young brought this change]
 
-  connnect: use sysaddr_un fron sys/un.h or custom-defined for windows
+  ftp: make the MKD retry to retry once per directory
   
-  Closes #7737
-
-Jay Satiro (30 Sep 2021)
-- [Rikard Falkeborn brought this change]
+  Reported-by: Roger Young
+  Fixes #7967
+  Closes #7976
 
-  hostip: Move allocation to clarify there is no memleak
+- tool_operate: reorder code to avoid compiler warning
   
-  By just glancing at the code, it looks like there is a memleak if the
-  call to Curl_inet_pton() fails. Looking closer, it is clear that the
-  call to Curl_inet_pton() can not fail, so the code will never leak
-  memory. However, we can make this obvious by moving the allocation
-  after the if-statement.
+  tool_operate.c(889) : warning C4701: potentially uninitialized local
+  variable 'per' use
   
-  Closes https://github.com/curl/curl/pull/7796
+  Follow-up to cc71d352651a0d95
+  Reported-by: Marc Hörsken
+  Bug: https://github.com/curl/curl/pull/7922#issuecomment-963042676
+  Closes #7971
 
-Daniel Stenberg (30 Sep 2021)
-- gen.pl: make the output date format work better
+- curl_easy_perform.3: add a para about recv and send data
   
-  Follow-up to 15910dfd143dd
+  Reported-by: Godwin Stewart
+  Fixes #7973
+  Closes #7974
+
+- tool_operate: fclose stream only if fopened
   
-  The previous strftime format used didn't work correctly on Windows, so
-  change to %B %d %Y which today looks like "September 29 2021".
+  Fixes torture test failures
+  Follow-up to cc71d352651
   
-  Reported-by: Gisle Vanem
-  Bug: #7782
-  Closes #7793
+  Closes #7972
 
-- typecheck-gcc.h: add CURLOPT_PREREQDATA awareness
+- libcurl-easy.3: language polish
+
+- limit-rate.d: this is average over several seconds
   
-  Follow-up to a517378de58358a
-  
-  To make test 1912 happy again
-  
-  Closes #7799
+  Closes #7970
 
-Marcel Raad (29 Sep 2021)
-- configure: remove `HAVE_WINSOCK_H` definition
+- docs: reduce/avoid English contractions
   
-  It's not used anymore.
+  You're => You are
+  Hasn't => Has not
+  Doesn't => Does not
+  Don't => Do not
+  You'll => You will
+  etc
   
-  Closes https://github.com/curl/curl/pull/7795
+  Closes #7930
 
-- CMake: remove `HAVE_WINSOCK_H` definition
-  
-  It's not used anymore.
+- tool_operate: fix torture leaks with etags
   
-  Closes https://github.com/curl/curl/pull/7795
-
-- config: remove `HAVE_WINSOCK_H` definition
+  Spotted by torture testing 343 344 345 347.
   
-  It's not used anymore.
+  Follow-up from cc71d352651a0
+  Pointed-out-by: Dan Fandrich
   
-  Closes https://github.com/curl/curl/pull/7795
+  Closes #7969
 
-- lib: remove `HAVE_WINSOCK_H` usage
-  
-  WinSock v1 is not supported anymore. Exclusively use `HAVE_WINSOCK2_H`
-  instead.
-  
-  Closes https://github.com/curl/curl/pull/7795
+- [Amaury Denoyelle brought this change]
 
-Daniel Stenberg (29 Sep 2021)
-- easyoptions: add the two new PRE* options
+  ngtcp2: support latest QUIC TLS RFC9001
   
-  Follow-up to a517378de58358a
+  QUIC Transport Parameters Extension has been changed between draft-29
+  and latest RFC9001. Most notably, its identifier has been updated from
+  0xffa5 to 0x0039. The version is selected through the QUIC TLS library
+  via the legacy codepoint.
   
-  Also fix optiontable.pl to do the correct remainder on the entry.
+  Disable the usage of legacy codepoint in curl to switch to latest
+  RFC9001. This is required to be able to keep up with latest QUIC
+  implementations.
   
-  Reported-by: Gisle Vanem
-  Bug: https://github.com/curl/curl/commit/a517378de58358a85b7cfe9efecb56051268f629#commitcomment-57224830
-  Closes #7791
+  Acked-by: Tatsuhiro Tsujikawa
+  Closes #7960
 
-- Revert "build: remove checks for WinSock 1"
+- test1173: make manpage-syntax.pl spot \n errors in examples
+
+- man pages: fix backslash-n in examples
   
-  Due to CI issues
+  ... to be proper backslash-backslash-n sequences to render nicely in man
+  and on website.
   
-  This reverts commit c2ea04f92b00b6271627cb218647527b5a50f2fc.
+  Follow-up to 24155569d8a
+  Reported-by: Sergey Markelov
   
-  Closes #7790
+  Fixes https://github.com/curl/curl-www/issues/163
+  Closes #7962
 
-Daniel Gustafsson (29 Sep 2021)
-- lib: avoid fallthrough cases in switch statements
+- scripts/release-notes.pl: use out of repo links verbatim in refs
+
+- tool_operate: a failed etag save now only fails that transfer
   
-  Commit b5a434f7f0ee4d64857f8592eced5b9007d83620 inhibits the warning
-  on implicit fallthrough cases, since the current coding of indicating
-  fallthrough with comments is falling out of fashion with new compilers.
-  This attempts to make the issue smaller by rewriting fallthroughs to no
-  longer fallthrough, via either breaking the cases or turning switch
-  statements into if statements.
+  When failing to create the output file for saving an etag, only fail
+  that particular single transfer and allow others to follow.
   
-    lib/content_encoding.c: the fallthrough codepath is simply copied
-      into the case as it's a single line.
-    lib/http_ntlm.c: the fallthrough case skips a state in the state-
-      machine and fast-forwards to NTLMSTATE_LAST. Do this before the
-      switch statement instead to set up the states that we actually
-      want.
-    lib/http_proxy.c: the fallthrough is just falling into exiting the
-      switch statement which can be done easily enough in the case.
-    lib/mime.c: switch statement rewritten as if statement.
-    lib/pop3.c: the fallthrough case skips to the next state in the
-      statemachine, do this explicitly instead.
-    lib/urlapi.c: switch statement rewritten as if statement.
-    lib/vssh/wolfssh.c: the fallthrough cases fast-forwards the state
-      machine, do this by running another iteration of the switch
-      statement instead.
-    lib/vtls/gtls.c: switch statement rewritten as if statement.
-    lib/vtls/nss.c: the fallthrough codepath is simply copied into the
-      case as it's a single line. Also twiddle a comment to not be
-      inside a non-brace if statement.
+  In a serial transfer setup, if no transfer at all is done due to them
+  all being skipped because of this error, curl will output an error
+  message and return exit code 26.
   
-  Closes: #7322
-  See-also: #7295
-  Reviewed-by: Daniel Stenberg 
-
-Marcel Raad (28 Sep 2021)
-- config-win32ce: enable WinSock 2
+  Added test 369 and 370 to verify.
   
-  WinSock 2.2 is supported by Windows CE .NET 4.1 (from 2002, out of
-  support since 2013).
+  Reported-by: Earnestly on github
+  Ref: #7942
+  Closes #7945
+
+- [Kevin Burke brought this change]
+
+  .github: retry macos "brew install" command on failure
   
-  Ref: https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms899586(v=msdn.10)
+  Previously we saw errors attempting to run "brew install", see
+  https://github.com/curl/curl/runs/4095721123?check_suite_focus=true for
+  an example, since this command is idempotent, it is safe to run again.
   
-  Closes https://github.com/curl/curl/pull/7778
+  Closes #7955
 
-- externalsocket: use WinSock 2.2
+- CURLOPT_ALTSVC_CTRL.3: mention conn reuse is preferred
   
-  That's the only version we support.
+  Ref: https://github.com/curl/curl/discussions/7954
   
-  Closes https://github.com/curl/curl/pull/7778
+  Closes #7957
 
-- build: remove checks for WinSock 1
+- RELEASE-NOTES: synced
+
+- zuul: pin the quiche build to use an older cmake-rs
   
-  It's not supported anymore.
+  The latest cmake-rs assumes cmake's --parallel works. That was added in
+  cmake 3.12, but a lot of our CI builds run on Ubuntu Bionic which only
+  has cmake 3.10.
   
-  Closes https://github.com/curl/curl/pull/7778
+  Fixes #7927
+  Closes #7952
 
-Daniel Stenberg (28 Sep 2021)
-- scripts/copyright: .muse is .lift now
-  
-  And update 5 files with old copyright year range
+- [Marc Hoersken brought this change]
 
-- cmdline-opts: made the 'Added:' field mandatory
+  Revert "src/tool_filetime: disable -Wformat on mingw for this file"
   
-  Since "too old" versions are no longer included in the generated man
-  page, this field is now mandatory so that it won't be forgotten and then
-  not included in the documentation.
+  This reverts commit 7c88fe375b15c44d77bccc9ab733b8069d228e6f.
   
-  Closes #7786
+  Follow up to #6535 as the pragma is obsolete with warnf
+  
+  Closes #7941
 
-- curl.1: remove mentions of really old version changes
+Jay Satiro (2 Nov 2021)
+- schannel: fix memory leak due to failed SSL connection
   
-  To make the man page more readable, this change removes all references
-  to changes in support/versions etc that happened before 7.30.0 from the
-  curl.1 output file. 7.30.0 was released on Apr 12 2013. This particular
-  limit is a bit arbitrary but was fairly easy to grep for.
+  - Call schannel_shutdown if the SSL connection fails.
   
-  It is handled like this: the 'Added' keyword is only used in output if
-  it refers to 7.30.0 or later. All occurances of "(Added in $VERSION)" in
-  description will be stripped out if the mentioned $VERSION is from
-  before 7.30.0. It is therefore important that the "Added in..."
-  references are always written exactly like that - and on a single line,
-  not split over two.
+  Prior to this change schannel_shutdown (which shuts down the SSL
+  connection as well as memory cleanup) was not called when the SSL
+  connection failed (eg due to failed handshake).
   
-  This change removes about 80 version number references from curl.1, down
-  to 138 from 218.
+  Co-authored-by: Gisle Vanem
   
-  Closes #7786
-
-- RELEASE-NOTES: synced
+  Fixes https://github.com/curl/curl/issues/7877
+  Closes https://github.com/curl/curl/pull/7878
 
-- tool_cb_prg: make resumed upload progress bar show better
+Daniel Stenberg (2 Nov 2021)
+- Curl_updateconninfo: store addresses for QUIC connections too
   
-  This is a regression that was *probably* injected in the larger progress
-  bar overhaul in 2018.
+  So that CURLINFO_PRIMARY_IP etc work for HTTP/3 like for other HTTP
+  versions.
   
-  Reported-by: beslick5 on github
-  Fixes #7760
-  Closes #7777
+  Reported-by: Jerome Mao
+  Fixes #7939
+  Closes #7944
 
-- gen.pl: insert the current date and version in generated man page
-  
-  Reported-by: Gisle Vanem
-  Ref: #7780
-  Closes #7782
+- [Sergio Durigan Junior brought this change]
 
-- NTLM: use DES_set_key_unchecked with OpenSSL
+  curl.1: fix typos in the manpage
   
-  ... as the previously used function DES_set_key() will in some cases
-  reject using a key that it deems "weak" which will cause curl to
-  continue using the unitialized buffer content as key instead.
+  s/transfering/transferring/
+  s/transfered/transferred/
   
-  Assisted-by: Harry Sintonen
-  Fixes #7779
-  Closes #7781
+  Signed-off-by: Sergio Durigan Junior 
+  Closes #7937
 
-Marc Hoersken (27 Sep 2021)
-- CI: align make and test flags in various config files
+Marc Hoersken (1 Nov 2021)
+- tests/smbserver.py: fix compatibility with impacket 0.9.23+
   
-  1. Use Makefile target to run tests in autotools builds on AppVeyor.
-  2. Disable testing of SCP protocol on native Windows environments.
-  3. Remove redundant parameters -a -p from target test-nonflaky.
-  4. Don't use -vc parameter which is reserved for debugging.
+  impacket now performs sanity checks if the requested and to
+  be served file path actually is inside the real share path.
   
-  Replaces #7591
-  Closes #7690
+  Ref: https://github.com/SecureAuthCorp/impacket/pull/1066
+  
+  Fixes #7924
+  Closes #7935
 
-Daniel Stenberg (27 Sep 2021)
-- mailmap: unify Max!
+Daniel Stenberg (1 Nov 2021)
+- docs: reduce use of "very"
+  
+  "Very" should be avoided in most texts. If intensifiers are needed, try
+  find better words instead.
+  
+  Closes #7936
 
-- [Max Dymond brought this change]
+- [Tatsuhiro Tsujikawa brought this change]
 
-  CURLOPT_PREREQFUNCTION: add new callback
+  ngtcp2: specify the missing required callback functions
   
-  Triggered before a request is made but after a connection is set up
+  Closes #7929
+
+- CURLOPT_[PROXY]_SSL_CIPHER_LIST.3: bold instead of quote
   
-  Changes:
+  Bold the example ciphers instead of using single quotes, which then also
+  avoids the problem of how to use single quotes when first in a line.
   
-  - callback: Update docs and callback for pre-request callback
-  - Add documentation for CURLOPT_PREREQDATA and CURLOPT_PREREQFUNCTION,
-  - Add redirect test and callback failure test
-  - Note that the function may be called multiple times on a redirection
-  - Disable new 2086 test due to Windows weirdness
+  Also rephrased the pages a little.
   
-  Closes #7477
+  Reported-by: Sergio Durigan Junior
+  Ref: #7928
+  Closes #7934
 
-- KNOWN_BUGS: HTTP/2 connections through HTTPS proxy frequently stall
+- gen.pl: replace leading single quotes with \(aq
   
-  Closes #6936
+  ... and allow single quotes to be used "normally" in the .d files.
+  
+  Makes the output curl.1 use better nroff.
+  
+  Reported-by: Sergio Durigan Junior
+  Ref: #7928
+  Closes #7933
 
-- TODO: make configure use --cache-file more and better
+Marc Hoersken (1 Nov 2021)
+- tests: kill some test servers afterwards to avoid locked logfiles
   
-  Closes #7753
+  Reviewed-by: Daniel Stenberg
+  Closes #7925
 
-- [Sergey Markelov brought this change]
+Daniel Stenberg (1 Nov 2021)
+- smooth-gtk-thread.c: enhance the mutex lock use
+  
+  Reported-by: ryancaicse on github
+  Fixes #7926
+  Closes #7931
 
-  urlapi: support UNC paths in file: URLs on Windows
+Marc Hoersken (31 Oct 2021)
+- CI/runtests.pl: restore -u flag, but remove it from CI runs
   
-  - file://host.name/path/file.txt is a valid UNC path
-    \\host.name\path\files.txt to a non-local file transformed into URI
-    (RFC 8089 Appendix E.3)
+  This makes it possible to use -u again for local testing,
+  but removes the flag from CI config files and make targets.
   
-  - UNC paths on other OSs must be smb: URLs
+  Reviewed-by: Daniel Stenberg
   
-  Closes #7366
+  Partially reverts #7841
+  Closes #7921
 
-- [Gleb Ivanovsky brought this change]
+Daniel Stenberg (29 Oct 2021)
+- [Jonathan Cardoso Machado brought this change]
 
-  urlapi: add curl_url_strerror()
+  CURLOPT_HSTSWRITEFUNCTION.3: using CURLOPT_HSTS_CTRL is required
   
-  Add curl_url_strerror() to convert CURLUcode into readable string and
-  facilitate easier troubleshooting in programs using URL API.
-  Extend CURLUcode with CURLU_LAST for iteration in unit tests.
-  Update man pages with a mention of new function.
-  Update example code and tests with new functionality where it fits.
+  Closes #7923
+
+- [Axel Morawietz brought this change]
+
+  imap: display quota information
   
-  Closes #7605
+  Show response to "GETQUOTAROOT INBOX" command.
+  
+  Closes #6973
 
 - RELEASE-NOTES: synced
 
-- [Mats Lindestam brought this change]
+- [Boris Rasin brought this change]
 
-  libssh2: add SHA256 fingerprint support
-  
-  Added support for SHA256 fingerprint in command line curl and in
-  libcurl.
+  cmake: fix error getting LOCATION property on non-imported target
   
-  Closes #7646
+  Closes #7885
 
-- libcurl.rc: switch out the copyright symbol for plain ASCII
+- [x2018 brought this change]
+
+  url: check the return value of curl_url()
   
-  Reported-by: Vitaly Varyvdin
-  Assisted-by: Viktor Szakats
-  Fixes #7765
-  Closes #7776
+  Closes #7917
 
-- [Jun-ya Kato brought this change]
+- [Roy Li brought this change]
 
-  ngtcp2: fix QUIC transport parameter version
+  configure.ac: replace krb5-config with pkg-config
   
-  fix inappropriate version setting for QUIC transport parameters.
-  this patch keeps curl with ngtcp2 uses QUIC draft version (h3-29).
+  The rationale is that custom *-config tools don't work well when
+  cross-compiling or using sysroots (such as when using Yocto project) and
+  require custom fixing for each of them; pkg-config on the other hand
+  works similarly everywhere.
   
-  Closes #7771
+  Signed-off-by: Roy Li 
+  Signed-off-by: Alexander Kanavin 
+  
+  Closes #7916
 
-- examples/imap-append: fix end-of-data check
+- test1160: edited to work with hyper
   
-  Reported-by: Alexander Chuykov
-  Fixes #7774
-  Closes #7775
+  Closes #7912
 
-Michael Kaufmann (24 Sep 2021)
-- vtls: Fix a memory leak if an SSL session cannot be added to the cache
+- data/DISABLED: enable tests that now work with hyper
   
-  On connection shutdown, a new TLS session ticket may arrive after the
-  SSL session cache has already been destructed. In this case, the new
-  SSL session cannot be added to the SSL session cache.
+  Closes #7911
+
+- test559: add 'HTTP' in keywords
   
-  The callers of Curl_ssl_addsessionid() need to know whether the SSL
-  session has been added to the cache. If it has not been added, the
-  reference counter of the SSL session must not be incremented, or memory
-  used by the SSL session must be freed. This is now possible with the new
-  output parameter "added" of Curl_ssl_addsessionid().
+  Makes it run fine with hyper
   
-  Fixes #7683
-  Closes #7752
+  Closes #7911
 
-Daniel Stenberg (24 Sep 2021)
-- [Momoka Yamamoto brought this change]
+- test552: updated to work with hyper
+  
+  Closes #7911
 
-  HTTP3.md: use 'autoreconf -fi' instead of buildconf
+Marc Hoersken (27 Oct 2021)
+- github: fix incomplete permission to label PRs for Hacktoberfest
   
-  buildconf is not used since #5853
+  Unfortunately the GitHub API requires a token with write permission
+  for both issues and pull-requests to edit labels on even just PRs.
   
-  Closes #7746
-
-- GIT-INFO: rephrase to adapt to s/buildconf/autoreconf
-
-- [h1zzz brought this change]
+  Follow up to #7897
 
-  llist: remove redundant code, branch will not be executed
+Daniel Stenberg (27 Oct 2021)
+- opt-manpages: use 'Added in' instead of 'Since'
   
-  Closes #7770
-
-- [tlahn brought this change]
+  Closes #7913
 
-  HTTP-COOKIES.md: remove duplicate 'each'
+Marc Hoersken (27 Oct 2021)
+- github: fix missing permission to label PRs for Hacktoberfest
   
-  Closes #7772
-
-Jay Satiro (24 Sep 2021)
-- [Joel Depooter brought this change]
-
-  libssh2: Get the version at runtime if possible
+  Follow up to #7897
   
-  Previously this code used a compile time constant, meaning that libcurl
-  always reported the libssh2 version that libcurl was built with. This
-  could differ from the libssh2 version actually being used. The new code
-  uses the CURL_LIBSSH2_VERSION macro, which is defined in ssh.h. The
-  macro calls the libssh2_version function if it is available, otherwise
-  it falls back to the compile time version.
+  Test references to see if permissions are now sufficient:
   
-  Closes https://github.com/curl/curl/pull/7768
-
-- [Joel Depooter brought this change]
+  Closes #7832
+  Closes #7897
 
-  schannel: fix typo
+- CI: more use of test-ci make target and verbose output
   
-  Closes https://github.com/curl/curl/pull/7769
-
-Daniel Stenberg (23 Sep 2021)
-- cmake: with OpenSSL, define OPENSSL_SUPPRESS_DEPRECATED
+  Replace test-nonflaky with test-ci and enable verbose output
+  in all remaining CIs except Zuul which is customized a lot.
   
-  To avoid the "... is deprecated" warnings brought by OpenSSL v3.
-  (We need to address the underlying code at some point of course.)
+  Reviewed-by: Daniel Stenberg
+  Reviewed-by: Jay Satiro
   
-  Assisted-by: Jakub Zakrzewski
-  Closes #7767
+  Follow up to #7785
+  Closes #7832
 
-- curl-openssl: pass argument to sed single-quoted
+- github: add support for Hacktoberfest using labels
   
-  ... instead of using an escaped double-quote. This is an attempt to make
-  this work better with ksh that otherwise would insist on a double
-  escape!
+  Automatically add hacktoberfest-accepted label to PRs opened between
+  September 30th and November 1st once a commit with a close reference
+  to it is pushed onto the master branch.
   
-  Reported-by: Randall S. Becker
-  Fixes #7758
-  Closes #7764
-
-- RELEASE-NOTES: synced
+  With this workflow we can participate in Hacktoberfest while not
+  relying on GitHub to identify PRs as merged due to our rebasing.
   
-  Bumped curlver to 7.80.0-dev
-
-- [a1346054 brought this change]
-
-  misc: fix typos in docs and comments
+  Requires hacktoberfest-accepted labels to exist for PRs on the
+  participating repository. Also requires hacktoberfest topic on
+  the participating repository to avoid applying to forked repos.
   
-  No user facing output from curl/libcurl is changed by this, just
-  comments.
+  Reviewed-by: Daniel Stenberg
   
-  Closes #7747
-
-- [Thomas M. DuBuisson brought this change]
+  Fixes #7865
+  Closes #7897
 
-  ci: update Lift config to match requirements of curl build
+Daniel Stenberg (27 Oct 2021)
+- http: reject HTTP response codes < 100
   
-  Also renamed Muse -> Lift, the new tool name.
+  ... which then also includes negative ones as test 1430 uses.
   
-  Closes #7761
+  This makes native + hyper backend act identically on this and therefore
+  test 1430 can now be enabled when building with hyper. Adjust test 1431
+  as well.
+  
+  Closes #7909
 
-- [Rikard Falkeborn brought this change]
+- [Kerem Kat brought this change]
 
-  cleanup: constify unmodified static structs
-  
-  Constify a number of static structs that are never modified. Make them
-  const to show this.
+  docs: fix typo in CURLOPT_TRAILERFUNCTION example
   
-  Closes #7759
+  Closes #7910
 
-Version 7.79.1 (22 Sep 2021)
+- docs/HYPER: remove some remaining issues, add HTTP/0.9 limitation
 
-Daniel Stenberg (22 Sep 2021)
-- RELEASE-NOTES: synced
+- configure: when hyper is selected, deselect nghttp2
   
-  curl 7.79.1 release
+  Closes #7908
 
-- THANKS: added names from the 7.79.1 release
+- [Patrick Monnerat brought this change]
 
-- test897: verify delivery of IMAP post-body header content
+  sendf: accept zero-length data in Curl_client_write()
   
-  The "content" is delivered as "body" by curl, but the envelope continues
-  after the body and the rest of it should be delivered as header.
+  Historically, Curl_client_write() used a length value of 0 as a marker
+  for a null-terminated data string. This feature has been removed in
+  commit f4b85d2. To detect leftover uses of the feature, a DEBUGASSERT
+  statement rejecting a length with value 0 was introduced, effectively
+  precluding use of this function with zero-length data.
   
-  The IMAP server can now get 'POSTFETCH' set to include more data to
-  include after the body and test 897 is done to verify that such "extra"
-  header data is in fact delivered by curl as header.
+  The current commit removes the DEBUGASSERT and makes the function to
+  return immediately if length is 0.
   
-  Ref: #7284 but fails to reproduce the issue
+  A direct effect is to fix trying to output a zero-length distinguished
+  name in openldap.
   
-  Closes #7748
-
-- KNOWN_BUGS: connection migration doesn't work
+  Another DEBUGASSERT statement is also rephrased for better readability.
   
-  Closes #7695
-
-- RELEASE-NOTES: synced
+  Closes #7898
 
-- http: fix the broken >3 digit response code detection
+- hyper: disable test 1294 since hyper doesn't allow such crazy headers
   
-  When the "reason phrase" in the HTTP status line starts with a digit,
-  that was treated as the forth response code digit and curl would claim
-  the response to be non-compliant.
+  Closes #7905
+
+- c-hyper: make CURLOPT_SUPPRESS_CONNECT_HEADERS work
   
-  Added test 1466 to verify this case.
+  Verified by the enabled test 1288
   
-  Regression brought by 5dc594e44f73b17
-  Reported-by: Glenn de boer
-  Fixes #7738
-  Closes #7739
+  Closes #7905
 
-Jay Satiro (17 Sep 2021)
-- strerror: use sys_errlist instead of strerror on Windows
-  
-  - Change Curl_strerror to use sys_errlist[errnum] instead of strerror to
-    retrieve the error message on Windows.
+- test1287: make work on hyper
   
-  Windows' strerror writes to a static buffer and is not thread-safe.
+  Closes #7905
+
+- test1266/1267: disabled on hyper: no HTTP/0.9 support
   
-  Follow-up to 2f0bb86 which removed most instances of strerror in favor
-  of calling Curl_strerror (which calls strerror_r for other platforms).
+  Closes #7905
+
+Viktor Szakats (25 Oct 2021)
+- Makefile.m32: fix to not require OpenSSL with -libssh2 or -rtmp options
   
-  Ref: https://github.com/curl/curl/pull/7685
-  Ref: https://github.com/curl/curl/commit/2f0bb86
+  Previously, -libssh2/-rtmp options assumed that OpenSSL is also enabled
+  (and then failed with an error when not finding expected OpenSSL headers),
+  but this isn't necessarly true, e.g. when building both libssh2 and curl
+  against Schannel. This patch makes sure to only enable the OpenSSL backend
+  with -libssh2/-rtmp, when there was no SSL option explicitly selected.
   
-  Closes https://github.com/curl/curl/pull/7735
-
-Daniel Stenberg (16 Sep 2021)
-- dist: provide lib/.checksrc in the tarball
+  - Re-implement the logic as a single block of script.
+  - Also fix an indentation while there.
   
-  So that debug builds work (checksrc really)
+  Assisted-by: Jay Satiro
   
-  Reported-by: Marcel Raad
-  Reported-by: tawmoto on github
-  Fixes #7733
-  Closes #7734
+  Closes #7895
 
-- TODO: Improve documentation about fork safety
+Daniel Stenberg (25 Oct 2021)
+- docs: consistent use of "Added in"
   
-  Closes #6968
+  Make them all say "Added in [version]" without using 'curl' or 'libcurl'
+  in that phrase.
 
-- hsts: CURLSTS_FAIL from hsts read callback should fail transfer
+- man pages: require all to use the same section header order
   
-  ... and have CURLE_ABORTED_BY_CALLBACK returned.
+  This is the same order we already enforce among the options' man pages:
+  consistency is good. Add lots of previously missing examples.
   
-  Extended test 1915 to verify.
+  Adjust the manpage-syntax script for this purpose, used in test 1173.
   
-  Reported-by: Jonathan Cardoso
-  Fixes #7726
-  Closes #7729
+  Closes #7904
 
-- test1184: disable
-  
-  The test should be fine and it works for me repeated when run manually,
-  but clearly it causes CI failures and it needs more research.
-  
-  Reported-by: RiderALT on github
-  Fixes #7725
-  Closes #7732
+- [David Hu brought this change]
 
-- Curl_http2_setup: don't change connection data on repeat invokes
+  docs/HTTP3: improve build instructions
   
-  Regression from 3cb8a748670ab88c (releasde in 7.79.0). That change moved
-  transfer oriented inits to before the check but also erroneously moved a
-  few connection oriented ones, which causes problems.
+  1. If writing to a system path if the command is not prefixed with
+  `sudo` it will cause a permission denied error
   
-  Reported-by: Evangelos Foutras
-  Fixes #7730
-  Closes #7731
-
-- RELEASE-NOTES: synced
+  2. The patched OpenSSL branch has been updated to `openssl-3.0.0+quic`
+  to match upstream OpenSSL version.
   
-  and bump to 7.79.1
-
-Kamil Dudka (16 Sep 2021)
-- tests/sshserver.pl: make it work with openssh-8.7p1
+  3. We should not disable GnuTLS docs.
   
-  ... by not using options with no argument where an argument is required:
+  Updated some commands about `make install`
   
-  === Start of file tests/log/ssh_server.log
-  curl_sshd_config line 6: no argument after keyword "DenyGroups"
-  curl_sshd_config line 7: no argument after keyword "AllowGroups"
-  curl_sshd_config line 10: Deprecated option AuthorizedKeysFile2
-  curl_sshd_config line 29: Deprecated option KeyRegenerationInterval
-  curl_sshd_config line 39: Deprecated option RhostsRSAAuthentication
-  curl_sshd_config line 40: Deprecated option RSAAuthentication
-  curl_sshd_config line 41: Deprecated option ServerKeyBits
-  curl_sshd_config line 45: Deprecated option UseLogin
-  curl_sshd_config line 56: no argument after keyword "AcceptEnv"
-  curl_sshd_config: terminating, 3 bad configuration options
-  === End of file tests/log/ssh_server.log
+  Closes #7842
+
+- [Ricardo Martins brought this change]
+
+  CMake: restore support for SecureTransport on iOS
   
-  === Start of file log/sftp_server.log
-  curl_sftp_config line 33: Unsupported option "rhostsrsaauthentication"
-  curl_sftp_config line 34: Unsupported option "rsaauthentication"
-  curl_sftp_config line 52: no argument after keyword "sendenv"
-  curl_sftp_config: terminating, 1 bad configuration options
-  Connection closed.
-  Connection closed
-  === End of file log/sftp_server.log
+  Restore support for building curl for iOS with SecureTransport enabled.
   
-  Closes #7724
+  Closes #7501
 
-Daniel Stenberg (15 Sep 2021)
-- hsts: handle unlimited expiry
+- tests: enable more tests with hyper
   
-  When setting a blank expire string, meaning unlimited, curl would pass
-  TIME_T_MAX to getime_r() when creating the output, while on 64 bit
-  systems such a large value cannot be convetered to a tm struct making
-  curl to exit the loop with an error instead. It can't be converted
-  because the year it would represent doesn't fit in the 'int tm_year'
-  field!
+  Adjusted 1144, 1164 and 1176.
   
-  Starting now, unlimited expiry is instead handled differently by using a
-  human readable expiry date spelled out as "unlimited" instead of trying
-  to use a distant actual date.
+  Closes #7900
+
+- docs: provide "RETURN VALUE" section for more func manpages
   
-  Test 1660 and 1915 have been updated to help verify this change.
+  Three were missing, one used a non-standard name for the header.
   
-  Reported-by: Jonathan Cardoso
-  Fixes #7720
-  Closes #7721
+  Closes #7902
 
-- curl_multi_fdset: make FD_SET() not operate on sockets out of range
+Jay Satiro (25 Oct 2021)
+- curl_multi_socket_action.3: add a "RETURN VALUE" section
   
-  The VALID_SOCK() macro was made to only check for FD_SETSIZE if curl was
-  built to use select(), even though the curl_multi_fdset() function
-  always and unconditionally uses FD_SET and needs the check.
+  .. because it may not be immediately clear to the user what
+  curl_multi_socket_action returns.
   
-  Reported-by: 0xee on github
-  Fixes #7718
-  Closes #7719
+  Ref: https://curl.se/mail/lib-2021-10/0035.html
+  
+  Closes https://github.com/curl/curl/pull/7901
 
-- FAQ: add GOPHERS + curl works on data, not files
+Daniel Stenberg (24 Oct 2021)
+- RELEASE-NOTES: synced
 
-Version 7.79.0 (14 Sep 2021)
+- [Samuel Henrique brought this change]
 
-Daniel Stenberg (14 Sep 2021)
-- RELEASE-NOTES: synced
+  tests: use python3 in test 1451
   
-  For the 7.79.0 release
+  This is a continuation of commit ec91b5a69000bea0794bbb3 in which
+  changing this test was missed.  There are no other python2 leftovers
+  now.
+  
+  Based on a Debian patch originally written by Alessandro Ghedini
+  
+  
+  Closes #7899
 
-- THANKS: add contributors from 7.79.0 release cycle
+- [Eddie Lumpkin brought this change]
 
-- FAQ: add two dev related questions
-  
-    8.1 Why does curl use C89?
-    8.2 Will curl be rewritten?
+  lib: fixing comment spelling typos in lib files
   
-  Spell-checked-by: Paul Johnson
-  Closes #7715
+  Closes #7894
+  Signed-off-by: ewlumpkin 
 
-- zuul.d/jobs: disable three tests for *-openssl-disable-proxy
+- openssl: if verifypeer is not requested, skip the CA loading
   
-  ... as they mysteriously seem to permfail without being related to
-  proxy.
+  It was previously done mostly to show a match/non-match in the verbose
+  output even when verification was not asked for. This change skips the
+  loading of the CA certs unless verifypeer is set to save memory and CPU.
   
-  Closes #7714
-
-- [Patrick Monnerat brought this change]
+  Closes #7892
 
-  ftp,imap,pop3,smtp: reject STARTTLS server response pipelining
+- curl-confopts.m4:  remove --enable/disable-hidden-symbols
   
-  If a server pipelines future responses within the STARTTLS response, the
-  former are preserved in the pingpong cache across TLS negotiation and
-  used as responses to the encrypted commands.
+  These configure options have been saying "deprecated" since 9e24b9c7af
+  (April 2012). It was about time we remove them.
   
-  This fix detects pipelined STARTTLS responses and rejects them with an
-  error.
+  Closes #7891
+
+- c-hyper: don't abort CONNECT responses early when auth-in-progress
   
-  CVE-2021-22947
+  ... and make sure to stop ignoring the body once the CONNECT is done.
   
-  Bug: https://curl.se/docs/CVE-2021-22947.html
-
-- [Patrick Monnerat brought this change]
+  This should make test 206 work proper again and not be flaky.
+  
+  Closes #7889
 
-  ftp,imap,pop3: do not ignore --ssl-reqd
+- hyper: does not support disabling CURLOPT_HTTP_TRANSFER_DECODING
   
-  In imap and pop3, check if TLS is required even when capabilities
-  request has failed.
+  Simply because hyper doesn't have this ability. Mentioned in docs now.
   
-  In ftp, ignore preauthentication (230 status of server greeting) if TLS
-  is required.
+  Skip test 326 then
   
-  Bug: https://curl.se/docs/CVE-2021-22946.html
+  Closes #7889
+
+- test262: don't attempt with hyper
   
-  CVE-2021-22946
+  This test verifies that curl works with binary zeroes in HTTP response
+  headers and hyper refuses such. They're not kosher http.
+  
+  Closes #7889
 
-- [z2_ on hackerone brought this change]
+- c-hyper: make test 217 run
+  
+  Closes #7889
 
-  mqtt: clear the leftovers pointer when sending succeeds
+- DISABLED: enable test 209+213 for hyper
   
-  CVE-2021-22945
+  Follow-up to 823d3ab855c
   
-  Bug: https://curl.se/docs/CVE-2021-22945.html
+  Closes #7889
 
-- zuul: bump the rustls job to use v0.7.2
+- test207: accept a different error code for hyper
   
-  ... and add -lm when using a rust library.
+  It returns HYPERE_UNEXPECTED_EOF for this case which we convert to the
+  somewhat generic CURLE_RECV_ERROR.
   
-  Closes #7701
+  Closes #7889
 
-- RELEASE-PROCEDURE: add release dates from now to 8.0.0 in 2023
+- [Érico Nogueira brought this change]
 
-- SECURITY-PROCESS: tweak a little to match current practices
+  INSTALL: update symbol hiding option
   
-  Closes #7713
-
-- http_proxy: fix the User-Agent inclusion in CONNECT
+  --enable-hidden-symbols was deprecated in
+  9e24b9c7afbcb81120af4cf3f6cdee49a06d8224.
   
-  It should not refer to the uagent string that is allocated and created
-  for the end server http request, as that pointer may be cleared on
-  subsequent CONNECT requests.
+  Closes #7890
+
+- http_proxy: multiple CONNECT with hyper done better
   
-  Added test case 1184 to verify.
+  Enabled test 206
   
-  Reported-by: T200proX7 on github
-  Fixes #7705
-  Closes #7707
+  Closes #7888
 
-- Curl_hsts_loadcb: don't attempt to load if hsts wasn't inited
+- hyper: pass the CONNECT line to the debug callback
   
-  Reported-by: Jonathan Cardoso
-  Fixes #7710
-  Closes #7711
+  Closes #7887
 
-- [Tatsuhiro Tsujikawa brought this change]
+- mailmap: Malik Idrees Hasan Khan
 
-  ngtcp2: fix build with ngtcp2 and nghttp3
-  
-  ngtcp2_conn_client_new and nghttp3_conn_client_new are now macros.
-  Check the wrapped functions instead.
-  
-  ngtcp2_stream_close callback now takes flags parameter.
-  
-  Closes #7709
+Jay Satiro (21 Oct 2021)
+- [Malik Idrees Hasan Khan brought this change]
 
-- write-out.d: clarify size_download/upload
+  build: fix typos
   
-  They show the number of "body" bytes transfered.
-  Fixes #7702
-  Closes #7706
+  Closes https://github.com/curl/curl/pull/7886
 
-- http2: Curl_http2_setup needs to init stream data in all invokes
+- URL-SYNTAX: add IMAP UID SEARCH example
   
-  Thus function was written to avoid doing multiple connection data
-  initializations, which is fine, but since it also initiates stream
-  related data it is crucial that it doesn't skip those even if called
-  again for the same connection. Solved by moving the stream
-  initializations before the "doing-it-again" check.
+  - Explain the difference between IMAP search via URL (which returns
+    message sequence numbers) and IMAP search via custom request (which
+    can return UID numbers if prefixed with UID, eg "UID SEARCH ...").
   
-  Reported-by: Inho Oh
-  Fixes #7630
-  Closes #7692
-
-- url: fix compiler warning in no-verbose builds
+  Bug: https://github.com/curl/curl/issues/7626
+  Reported-by: orycho@users.noreply.github.com
   
-  Follow-up from 2f0bb864c12
+  Ref: https://github.com/curl/curl/issues/2789
   
-  Closes #7700
+  Closes https://github.com/curl/curl/pull/7881
 
-- non-ascii: fix build errors from strerror fix
-  
-  Follow-up to 2f0bb864c12
+Daniel Stenberg (20 Oct 2021)
+- manpage: adjust the asterisk in some SYNOPSIS sections
   
-  Closes #7697
+  Closes #7884
 
-- parse_args: redo the warnings for --remote-header-name combos
+- curl_multi_perform.3: polish wording
   
-  ... to avoid the memory leak risk pointed out by scan-build.
+   - simplify the example by using curl_multi_poll
   
-  Follow-up from 7a3e981781d6c18a
+   - mention curl_multi_add_handle in the text
   
-  Closes #7698
-
-- ngtcp2: adapt to new size defintions upstream
+   - cut out the description of pre-7.20.0 return code behavior - that version
+     is now more than eleven years old and is basically no longer out there
   
-  Reviewed-by: Tatsuhiro Tsujikawa
-  Closes #7699
-
-- rustls: add strerror.h include
+   - adjust the "typical usage" to mention curl_multi_poll
   
-  Follow-up to 2f0bb864c12
+  Closes #7883
 
-- docs: the security list is reached at security at curl.se now
-  
-  Also update the FAQ section a bit to encourage users to rather submit
-  security issues on hackerone than sending email.
-  
-  Closes #7689
+- docs/THANKS: removed on request
 
-Marc Hoersken (9 Sep 2021)
-- runtests: add option -u to error on server unexpectedly alive
-  
-  Let's try to actually handle the server unexpectedly alive
-  case by first making them visible on CI builds as failures.
-  
-  This is needed to detect issues with killing of the test
-  servers completely including nested process chains with
-  multiple PIDs per test server (including bash and perl).
-  
-  On Windows/cygwin platforms this is especially helpful with
-  debugging PID mixups due to cygwin using its own PID space.
-  
-  Reviewed-by: Daniel Stenberg
-  Closes #7180
+- FAQ: polish the explanation of libcurl
 
-Daniel Stenberg (9 Sep 2021)
-- opts docs: unify phrasing in NAME header
-  
-  - avoid writing "set ..." or "enable/disable ..." or "specify ..."
-    *All* options for curl_easy_setopt() are about setting or enabling
-    things and most of the existing options didn't use that way of
-    description.
-  
-  - start with lowercase letter, unless abbreviation. For consistency.
-  
-  - Some additional touch-ups
-  
-  Closes #7688
+- curl_easy_perform.3: minor wording tweak
 
-- strerror.h: remove the #include from files not using it
+- [Erik Stenlund brought this change]
 
-- lib: don't use strerror()
-  
-  We have and provide Curl_strerror() internally for a reason: strerror()
-  is not necessarily thread-safe so we should always try to avoid it.
+  mime: mention CURL_DISABLE_MIME in comment
   
-  Extended checksrc to warn for this, but feature the check disabled by
-  default and only enable it in lib/
+  CURL_DISABLE_MIME is not mentioned in the comment describing the if else
+  preprocessor directive.
   
-  Closes #7685
+  Closes #7882
 
-Daniel Gustafsson (8 Sep 2021)
-- cirrus: Add FreeBSD 13.0 job and disable sanitizer build
-  
-  As alluded to the in the now removed comment, a 13.0 image became
-  available and is now ready to be used.
+- tls: remove newline from three infof() calls
   
-  The sanitizer builds were running on the 12.1 image which since has
-  been removed from the config, leaving the builds not running at all.
-  When enabled it turns out that they don't actually work due to very
-  long timeouts in executing the tests, so keep the disabled for now
-  but a bit more controlled.
+  Follow-up to e7416cf
   
-  Closes #7592
-
-Daniel Stenberg (8 Sep 2021)
-- copyrights: update copyright year ranges
+  Reported-by: billionai on github
+  Fixes #7879
+  Closes #7880
 
 - RELEASE-NOTES: synced
 
-- INTERNALS: c-ares has a new home: c-ares.org
-
-- docs: remove experimental mentions from HSTS and MQTT
+- curl_gssapi: fix build warnings by removing const
   
-  Reported-by: Jonathan Cardoso
-  Bug: https://github.com/curl/curl/pull/6700#issuecomment-913792863
-  Closes #7681
-
-- [Cao ZhenXiang brought this change]
-
-  curl: add warning for incompatible parameters usage
+  Follow-up to 20e980f85b0ea6
   
-  --continue-at - and --remote-header-name are known incompatible parameters
+  In #7875 these inits were modified but I get two warnings that these new
+  typecasts are necessary for.
   
-  Closes #7674
+  Closes #7876
 
-- [git-bruh brought this change]
+- [Bo Anderson brought this change]
 
-  examples/*hiperfifo.c: fix calloc arguments to match function proto
+  curl_gssapi: fix link error on macOS Monterey
   
-  Closes #7678
+  Fixes #7657
+  Closes #7875
 
-- INTERNALS: bump c-ares requirement to 1.16.0
+- test1185: verify checksrc
   
-  Since ba904db0705c93 we use ares_getaddrinfo, added in c-ares 1.16.0
+  Closes #7866
 
-- curl: stop retry if Retry-After: is longer than allowed
-  
-  If Retry-After: specifies a period that is longer than what fits within
-  --retry-max-time, then stop retrying immediately.
+- checksrc: improve the SPACESEMICOLON error message
   
-  Added test 366 to verify.
+  and adjust the MULTISPACE one to use plural
   
-  Reported-by: Kari Pahula
-  Fixes #7675
-  Closes #7676
-
-- [Michał Antoniak brought this change]
+  Closes #7866
 
-  mbedtls: avoid using a large buffer on the stack
+- url: set "k->size" -1 at start of request
   
-  Use dynamic memory allocation for the buffer used in checking "pinned
-  public key". The PUB_DER_MAX_BYTES parameter with default settings is
-  set to a value greater than 2kB.
+  The size of the transfer is unknown at that point.
   
-  Co-authored-by: Daniel Stenberg
-  Closes #7586
+  Fixes #7871
+  Closes #7872
 
-- configure: make --disable-hsts work
+Daniel Gustafsson (18 Oct 2021)
+- doh: remove experimental code for DoH with GET
   
-  The AC_ARG_ENABLE() macro itself uses a variable called
-  'enable_[option]', so when our script also used a variable with that
-  name for the purpose of storing what the user wants, it also
-  accidentally made it impossible to switch off the feature with
-  --disable-hsts. Fix this by renaming our variable.
+  The code for sending DoH requests with GET was never enabled in a way
+  such that it could be used or tested. As there haven't been requests
+  for this feature, and since it at this is effectively dead, remove it
+  and favor reimplementing the feature in case anyone is interested.
   
-  Reported-by: Michał Antoniak
-  Fixes #7669
-  Closes #7672
+  Closes #7870
+  Reviewed-by: Daniel Stenberg 
 
-Jay Satiro (5 Sep 2021)
-- config.d: note that curlrc is used even when --config
+Daniel Stenberg (18 Oct 2021)
+- cirrus: remove FreeBSD 11.4 from the matrix
   
-  Bug: https://github.com/curl/curl/pull/7666#issuecomment-912214751
-  Reported-by: Viktor Szakats
+  It has reached End-Of-Life and causes some LDAP CI issues.
   
-  Closes https://github.com/curl/curl/pull/7667
-
-Daniel Stenberg (4 Sep 2021)
-- RELEASE-NOTES: synced
+  Closes #7869
 
-- test1173: check references to libcurl options
+- cirrus: switch to openldap24-client
   
-  ... that they refer to actual existing libcurl options.
+  ... as it seems openldap-client doesn't exist anymore.
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #7656
+  Reported-by: Jay Satiro
+  Fixes #7868
+  Closes #7869
 
-- CURLOPT_UNIX_SOCKET_PATH.3: remove nginx reference, add see also
+- checksrc: ignore preprocessor lines
   
-  Closes #7656
-
-- opt-docs: verify man page sections + order
-  
-  In every libcurl option man page there are now 8 mandatory sections that
-  must use the right name in the correct order and test 1173 verifies
-  this. Only 14 man pages needed adjustments.
+  In order to check the actual code better, checksrc now ignores
+  everything that look like preprocessor instructions. It also means
+  that code in macros are now longer checked.
   
-  The sections and the order is as follows:
+  Note that some rules then still don't need to be followed when code is
+  exactly below a cpp instruction.
   
-   - NAME
-   - SYNOPSIS
-   - DESCRIPTION
-   - PROTOCOLS
-   - EXAMPLE
-   - AVAILABILITY
-   - RETURN VALUE
-   - SEE ALSO
+  Removes two checksrc exceptions we needed previously because of
+  preprocessor lines being checked.
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #7656
+  Reported-by: Marcel Raad
+  Fixes #7863
+  Closes #7864
 
-- opt-docs: make sure all man pages have examples
+- urlapi: skip a strlen(), pass in zero
   
-  Extended manpage-syntax.pl (run by test 1173) to check that every man
-  page for a libcurl option has an EXAMPLE section that is more than two
-  lines. Then fixed all errors it found and added examples.
+  ... to let curl_easy_escape() itself do the strlen. This avoids a (false
+  positive) Coverity warning and it avoids us having to store the strlen()
+  return value in an int variable.
   
   Reviewed-by: Daniel Gustafsson
-  Closes #7656
-
-- get.d: provide more useful examples
-  
-  Closes #7668
-
-- page-header: add GOPHERS, simplify wording in the 1st para
-  
-  Closes #7665
+  Closes #7862
 
-- connect: get local port + ip also when reusing connections
-  
-  Regression. In d6a37c23a3c (7.75.0) we removed the duplicated storage
-  (connection + easy handle), so this info needs be extracted again even
-  for re-used connections.
-  
-  Add test 435 to verify
-  
-  Reported-by: Max Dymond
-  Fixes #7660
-  Closes #7662
+- misc: update copyright years
 
-Marcel Raad (2 Sep 2021)
-- multi: fix compiler warning with `CURL_DISABLE_WAKEUP`
+- examples/htmltidy: correct wrong printf() use
   
-  `use_wakeup` is unused in this case.
+  ... and update the includes to match how current htmltidy wants them
+  used.
   
-  Closes https://github.com/curl/curl/pull/7661
+  Reported-by: Stathis Kapnidis
+  Fixes #7860
+  Closes #7861
 
-Daniel Stenberg (1 Sep 2021)
-- tests: adjust the tftpd output to work with hyper mode
+Jay Satiro (15 Oct 2021)
+- http: set content length earlier
   
-  By making them look less like http headers, the hyper mode "tweak"
-  doesn't interfere.
+  - Make content length (ie download size) accessible to the user in the
+    header callback, but only after all headers have been processed (ie
+    only in the final call to the header callback).
   
-  Enable test 2002 and 2003 in hyper builds (and 1280 which is unrelated
-  but should be enabled).
+  Background:
   
-  Closes #7658
-
-Daniel Gustafsson (1 Sep 2021)
-- [Gisle Vanem brought this change]
-
-  openssl: annotate SSL3_MT_SUPPLEMENTAL_DATA
+  For a long time the content length could be retrieved in the header
+  callback via CURLINFO_CONTENT_LENGTH_DOWNLOAD_T as soon as it was parsed
+  by curl.
   
-  This adds support for the previously unhandled supplemental data which
-  in -v output was printed like:
+  Changes were made in 8a16e54 (precedes 7.79.0) to ignore content length
+  if any transfer encoding is used. A side effect of that was that
+  content length was not set by libcurl until after the header callback
+  was called the final time, because until all headers are processed it
+  cannot be determined if content length is valid.
   
-      TLSv1.2 (IN), TLS header, Unknown (23):
+  This change keeps the same intention --all headers must be processed--
+  but now the content length is available before the final call to the
+  header function that indicates all headers have been processed (ie
+  a blank header).
   
-  These will now be printed with proper annotation:
+  Bug: https://github.com/curl/curl/commit/8a16e54#r57374914
+  Reported-by: sergio-nsk@users.noreply.github.com
   
-      TLSv1.2 (OUT), TLS header, Supplemental data (23):
+  Co-authored-by: Daniel Stenberg
   
-  Closes #7652
-  Reviewed-by: Daniel Stenberg 
+  Fixes https://github.com/curl/curl/issues/7804
+  Closes https://github.com/curl/curl/pull/7803
 
-Daniel Stenberg (1 Sep 2021)
-- curl.1: provide examples for each option
-  
-  The file format for each option now features a "Example:" header that
-  can provide one or more examples that get rendered appropriately in the
-  output. All options MUST have at least one example or gen.pl complains
-  at build-time.
-  
-  This fix also does a few other minor format and consistency cleanups.
-  
-  Closes #7654
+Daniel Stenberg (15 Oct 2021)
+- [Abhinav Singh brought this change]
 
-- progress: make trspeed avoid floats
+  aws-sigv4: make signature work when post data is binary
   
-  and compiler warnings for data conversions.
+  User sets the post fields size for binary data.  Hence, we should not be
+  using strlen on it.
   
-  Reported-by: Michał Antoniak
-  Fixes #7645
-  Closes #7653
+  Added test 1937 and 1938 to verify.
+  
+  Closes #7844
 
-- test365: verify response with chunked AND Content-Length headers
+- [a1346054 brought this change]
 
-- http: ignore content-length if any transfer-encoding is used
+  MacOSX-Framework: remove redundant ';'
   
-  Fixes #7643
-  Closes #7649
+  Closes #7859
 
 - RELEASE-NOTES: synced
 
-- Revert "http2: skip immediate parsing of payload following protocol switch"
+- openssl: with OpenSSL 1.1.0+ a failed RAND_status means goaway
   
-  This reverts commit 455a63c66f188598275e87d32de2c4e8e26b80cb.
+  One reason we know it can fail is if a provider is used that doesn't do
+  a proper job or is wrongly configured.
   
-  Reported-by: Tk Xiong
-  Fixes #7633
-  Closes #7648
+  Reported-by: Michael Baentsch
+  Fixes #7840
+  Closes #7856
 
-- KNOWN_BUGS: HTTP/3 doesn't support client certs
-  
-  Closes #7625
+Marcel Raad (14 Oct 2021)
+- [Ryan Mast brought this change]
 
-- mailing lists: move from cool.haxx.se to lists.haxx.se
+  cmake: add CURL_ENABLE_SSL option and make CMAKE_USE_* SSL backend options depend on it
+  
+  Closes https://github.com/curl/curl/pull/7822
 
-- http_proxy: only wait for writable socket while sending request
+Daniel Stenberg (14 Oct 2021)
+- http: remove assert that breaks hyper
   
-  Otherwise it would wait socket writability even after the entire CONNECT
-  request has sent and make curl basically busy-loop while waiting for a
-  response to come back.
+  Reported-by: Jay Satiro
+  Fixes #7852
+  Closes #7855
+
+- http_proxy: fix one more result assign for hyper
   
-  The previous fix attempt in #7484 (c27a70a591a4) was inadequate.
+  and remove the bad assert again, since it was run even with no error!
   
-  Reported-by: zloi-user on github
-  Reported-by: Oleguer Llopart
-  Fixes #7589
-  Closes #7647
+  Closes #7854
 
-- http: disallow >3-digit response codes
+Jay Satiro (14 Oct 2021)
+- sws: fix memory leak on exit
   
-  Make the built-in HTTP parser behave similar to hyper and reject any
-  HTTP response using more than 3 digits for the response code.
+  - Free the allocated http request struct on cleanup.
   
-  Updated test 1432 accordingly.
-  Enabled test 1432 in the hyper builds.
+  Prior to this change if sws was built with leak sanitizer it would
+  report a memory leak error during testing.
   
-  Closes #7641
-
-- [Tatsuhiro Tsujikawa brought this change]
+  Closes https://github.com/curl/curl/pull/7849
 
-  ngtcp2: stop buffering crypto data
+Daniel Stenberg (14 Oct 2021)
+- c-hyper: make Curl_http propagate errors better
   
-  Stop buffering crypto data because libngtcp2 now buffers submitted
-  crypto data.
+  Pass on better return codes when errors occur within Curl_http instead
+  of insisting that CURLE_OUT_OF_MEMORY is the only possible one.
   
-  Closes #7637
+  Pointed-out-by: Jay Satiro
+  Closes #7851
 
-- test1280: CRLFify the response to please hyper
+- http_proxy: make hyper CONNECT() return the correct error code
   
-  Closes #7639
-
-- tests: enable test 1129 for hyper builds
+  For every 'goto error', make sure the result variable holds the error
+  code for what went wrong.
   
-  Closes #7638
+  Reported-by: Rafał Mikrut
+  Fixes #7825
+  Closes #7846
 
-- curl: better error message when -O fails to get a good name
-  
-  Due to how this currently works internally, it needs a working initial
-  file name to store contents in, so it may still fail even with -J is
-  used (and thus accepting a name from content-disposition:) if the file
-  name part of the URL isn't "good enough".
+- docs/Makefile.am: repair 'make html'
   
-  Fixes #7628
-  Closes #7635
-
-- curl_easy_setopt: tweak the string copy wording
+  by removing index.html which isn't around anymore
   
-  Reported-by: Yaobin Wen
-  Fixes #7632
-  Closes #7634
-
-- RELEASE-NOTES: synced
+  Closes #7853
 
-- [Don J Olmstead brought this change]
+- [Борис Верховский brought this change]
 
-  cmake: sync CURL_DISABLE options
+  curl: correct grammar in generated libcurl code
   
-  Adds the full listing of CURL_DISABLE options to the CMake build. Moves
-  all option code, except for CURL_DISABLE_OPENSSL_AUTO_LOA_CONFIG which
-  resides near OpenSSL configuration, to the same block of code. Also
-  sorts the options here and in the cmake config header.
+  Closes #7802
+
+- tests: disable test 2043
   
-  Additionally sorted the CURL-DISABLE listing and fixed the
-  CURL_DISABLE_POP3 option.
+  It uses revoked.badssl.com which now is expired and therefor this now
+  permafails. We should not use external sites for tests, this test should
+  be converted to use our own infra.
   
-  Closes #7624
+  Closes #7845
 
-Jay Satiro (25 Aug 2021)
-- KNOWN_BUGS: FTPS upload data loss with TLS 1.3
+- runtests: split out ignored tests
   
-  Bug: https://github.com/curl/curl/issues/6149
-  Reported-by: Bylon2@users.noreply.github.com
+  Report ignore tests separately from the actual fails.
   
-  Closes https://github.com/curl/curl/pull/7623
-
-Daniel Stenberg (24 Aug 2021)
-- cmake: avoid poll() on macOS
+  Don't exit non-zero if test servers couldn't get killed.
   
-  ... like we do in configure builds. Since poll() on macOS is not
-  reliable enough.
+  Assisted-by: Jay Satiro
   
-  Reported-by: marc-groundctl
-  Fixes #7595
-  Closes #7619
+  Fixes #7818
+  Closes #7841
 
-- c-hyper: handle HTTP/1.1 => HTTP/1.0 downgrade on reused connection
+- http2: make getsock not wait for write if there's no remote window
   
-  Enable test 1074
+  While uploading, check for remote window availability in the getsock
+  function so that we don't wait for a writable socket if no data can be
+  sent.
   
-  Closes #7617
+  Reported-by: Steini2000 on github
+  Fixes #7821
+  Closes #7839
 
-- c-hyper: deal with Expect: 100-continue combined with POSTFIELDS
-  
-  Enable test 1130 and 1131
+- test368: verify dash is appended for "-r [num]"
   
-  Closes #7616
+  Follow-up to 8758a26f8878
 
-- [a1346054 brought this change]
+- [Борис Верховский brought this change]
 
-  tests: be explicit about using 'python3' instead of 'python'
-  
-  This fixes running tests in virtualenvs (or on distros) that no longer
-  have a symlink from python to python2 or python3.
+  curl: actually append "-" to --range without number only
   
-  Closes #7602
-
-- [a1346054 brought this change]
+  Closes #7837
 
-  scripts: invoke interpreters through /usr/bin/env
-  
-  Closes #7602
+- RELEASE-NOTES: synced
 
-- DISABLED: enable 11 more tests for hyper builds
+- urlapi: URL decode percent-encoded host names
   
-  Closes #7612
-
-- setopt: enable CURLOPT_IGNORE_CONTENT_LENGTH for hyper
+  The host name is stored decoded and can be encoded when used to extract
+  the full URL. By default when extracting the URL, the host name will not
+  be URL encoded to work as similar as possible as before. When not URL
+  encoding the host name, the '%' character will however still be encoded.
   
-  Since this option is also used for FTP, it needs to work to set for
-  applications even if hyper doesn't support it for HTTP. Verified by test
-  1137.
+  Getting the URL with the CURLU_URLENCODE flag set will percent encode
+  the host name part.
   
-  Updated docs to specify that the option doesn't work for HTTP when using
-  the hyper backend.
+  As a bonus, setting the host name part with curl_url_set() no longer
+  accepts a name that contains space, CR or LF.
   
-  Closes #7614
-
-- test1138: remove trailing space to make work with hyper
+  Test 1560 has been extended to verify percent encodings.
   
-  Closes #7613
+  Reported-by: Noam Moshe
+  Reported-by: Sharon Brizinov
+  Reported-by: Raul Onitza-Klugman
+  Reported-by: Kirill Efimov
+  Fixes #7830
+  Closes #7834
 
-- libcurl-errors.3: clarify two CURLUcode errors
+Marc Hoersken (8 Oct 2021)
+- CI/makefiles: introduce dedicated test target
   
-  CURLUE_BAD_HANDLE and CURLUE_BAD_PARTPOINTER should be for "bad" or
-  wrong pointers in a generic sense, not just for NULL pointers.
+  Make it easy to use the same set of test flags
+  throughout all current and future CI builds.
   
   Reviewed-by: Jay Satiro
   
-  Ref: #7605
-  Closes #7611
+  Follow up to #7690
+  Closes #7785
 
-Jay Satiro (23 Aug 2021)
-- symbols-in-versions: fix CURLSSLBACKEND_QSOSSL last used version
-  
-  ... and also change the 'Removed' column name to 'Last' since that
-  column is for the last version to contain the symbol.
-  
-  Closes https://github.com/curl/curl/pull/7609
+Daniel Stenberg (8 Oct 2021)
+- maketgz: redirect updatemanpages.pl output to /dev/null
 
-Daniel Stenberg (23 Aug 2021)
-- urlapi.c:seturl: assert URL instead of using if-check
+- CURLOPT_HTTPHEADER.3: add descripion for specific headers
   
-  There's no code flow possible where this can happen. The assert makes
-  sure it also won't be introduced undetected in the future.
+  Settting Host: or Transfer-Encoding: chunked actually have special
+  meanings to libcurl. This change tries to document them
   
-  Closes #7610
+  Closes #7829
 
-- curl-openssl.m4: show correct output for OpenSSL v3
+- c-hyper: use hyper_request_set_uri_parts to make h2 better
   
-  Using 3.0.0 versions configure should now show this:
+  and make sure to not send Host: over h2.
   
-  checking for OpenSSL headers version... 3.0.0 - 0x300
-  checking for OpenSSL library version... 3.0.0
-  checking for OpenSSL headers and library versions matching... yes
+  Fixes #7679
+  Reported-by: David Cook
+  Closes #7827
+
+- [Michael Afanasiev brought this change]
+
+  curl-openssl.m4: modify library order for openssl linking
   
-  This output doesn't actually change what configure generates but is only
-  "cosmetic".
+  lcrypto may depend on lz, and configure corrently fails with when
+  statically linking as the order is "-lz -lcrypto". This commit switches
+  the order to "-lcrypto -lz".
   
-  Reported-by: Randall S. Becker
-  Fixes #7606
-  Closes #7608
+  Closes #7826
 
-Jay Satiro (22 Aug 2021)
-- mksymbolsmanpage.pl: Fix showing symbol's last used version
+Marcel Raad (7 Oct 2021)
+- sha256: use high-level EVP interface for OpenSSL
   
-  Prior to this change the symbol's deprecated version was erroneously
-  shown as its last used version.
+  Available since OpenSSL 0.9.7. The low-level SHA256 interface is
+  deprecated in OpenSSL v3, and its usage was discouraged even before.
   
-  Bug: https://github.com/curl/curl/commit/4e53b94#commitcomment-55239509
-  Reported-by: i-ky@users.noreply.github.com
+  Closes https://github.com/curl/curl/pull/7808
 
-Daniel Stenberg (21 Aug 2021)
-- mksymbolsmanpage.pl: match symbols case insenitively
+- curl_ntlm_core: use OpenSSL only if DES is available
   
-  Follow-up to 4e53b9430c750 which made this bug show.
+  This selects another SSL backend then if available, or otherwise at
+  least gives a meaningful error message.
   
-  Reported-by: i-ky
-  Bug: https://github.com/curl/curl/commit/4e53b9430c7504de8984796e2a2091ec16f27136#commitcomment-55239253
-  Closes #7607
+  Closes https://github.com/curl/curl/pull/7808
 
-- asyn-ares: call ares_freeaddrinfo() to clean up addrinfo results
+- md5: fix compilation with OpenSSL 3.0 API
   
-  As this leaks memory otherwise
+  Only use OpenSSL's MD5 code if it's available.
   
-  Follow-up to ba904db0705c931
+  Also fix wolfSSL build with `NO_MD5`, in which case neither the
+  wolfSSL/OpenSSL implementation nor the fallback implementation was
+  used.
   
-  Closes #7599
-
-- [Ehren Bendler brought this change]
+  Closes https://github.com/curl/curl/pull/7808
 
-  wolfssl: clean up wolfcrypt error queue
+Daniel Stenberg (7 Oct 2021)
+- print_category: printf %*s needs an int argument
   
-  If wolfSSL is built in certain ways (OPENSSL_EXTRA or Debug), the error
-  queue gets added on to for each session and never freed. Fix it by
-  calling ERR_clear_error() like in vtls/openssl when needed. This func is
-  a no-op in wolfcrypt if the error queue is not enabled.
+  ... not a size_t!
   
-  Closes #7594
+  Detected by Coverity: CID 1492331.
+  Closes #7823
 
-- man pages: remove trailing whitespaces
+Jay Satiro (7 Oct 2021)
+- version_win32: use actual version instead of manifested version
   
-  Extended test 1173 (via the manpage-syntax.pl script) to detect and warn
-  for them.
+  - Use RtlVerifyVersionInfo instead of VerifyVersionInfo, when possible.
   
-  Ref: #7602
-  Reported-by: a1346054 on github
-  Closes #7604
-
-- mailmap: add Gleb Ivanovsky
-
-- config.d: escape the backslash properly
+  Later versions of Windows have normal version functions that compare and
+  return versions based on the way the application is manifested, instead
+  of the actual version of Windows the application is running on. We
+  prefer the actual version of Windows so we'll now call the Rtl variant
+  of version functions (RtlVerifyVersionInfo) which does a proper
+  comparison of the actual version.
   
-  Closes #7603
+  Reported-by: Wyatt O'Day
+  
+  Ref: https://github.com/curl/curl/pull/7727
+  
+  Fixes https://github.com/curl/curl/issues/7742
+  Closes https://github.com/curl/curl/pull/7810
 
-- [Don J Olmstead brought this change]
+Daniel Stenberg (6 Oct 2021)
+- RELEASE-NOTES: synced
 
-  curl_setup.h: sync values for HTTP_ONLY
+- http: fix Basic auth with empty name field in URL
   
-  The values for HTTP_ONLY differed between CMakeLists.txt and
-  curl_setup.h. Sync them and sort the values in curl_setup.h to make it
-  easier to spot differences.
+  Add test 367 to verify.
   
-  Closes #7601
+  Reported-by: Rick Lane
+  Fixes #7819
+  Closes #7820
 
-Jay Satiro (21 Aug 2021)
-- configure: set classic mingw minimum OS version to XP
-  
-  - If the user has not specified a minimum OS version (via WINVER or
-    _WIN32_WINNT macros) then set it to Windows XP.
+- [Jeffrey Tolar brought this change]
+
+  CURLOPT_MAXLIFETIME_CONN: maximum allowed lifetime for conn reuse
   
-  Prior to this change classic MinGW defaulted the minimum OS version
-  to Windows NT 4.0 which is way too old. At least Windows XP is needed
-  for getaddrinfo (which resolves hostnames to IPv6 addresses).
+  ... and close connections that are too old instead of reusing them.
   
-  Ref: https://github.com/curl/curl/issues/7483#issuecomment-891597034
+  By default, this behavior is disabled.
   
-  Closes https://github.com/curl/curl/pull/7581
+  Bug: https://curl.se/mail/lib-2021-09/0058.html
+  Closes #7751
 
-- schannel: Work around typo in classic mingw macro
-  
-  - Define ALG_CLASS_DHASH (the typo from the include) to ALG_CLASS_HASH.
-  
-  Prior to this change there was an incomplete fix to ignore the
-  CALG_TLS1PRF macro on those versions of MinGW where it uses the
-  ALG_CLASS_DHASH typoed macro.
+Daniel Gustafsson (6 Oct 2021)
+- docs/examples: add missing binaries to gitignore
   
-  Ref: 48cf45c
-  Ref: https://osdn.net/projects/mingw/ticket/38391
-  Ref: https://github.com/curl/curl/issues/2924
+  Commit f65d7889b added getreferrer, and commit ae8e11ed5 multi-legacy,
+  both of which missed adding .gitignore clauses for the built binaries.
   
-  Closes https://github.com/curl/curl/pull/7580
+  Closes #7817
+  Reviewed-by: Daniel Stenberg 
 
-Daniel Stenberg (20 Aug 2021)
-- RELEASE-NOTES: synced
+Daniel Stenberg (5 Oct 2021)
+- [Josip Medved brought this change]
 
-- http_proxy: fix user-agent and custom headers for CONNECT with hyper
-  
-  Enable test 287
+  HTTP3: fix the HTTP/3 Explained book link
   
-  Closes #7598
+  Closes #7813
 
-- c-hyper: initial support for "dumping" 1xx HTTP responses
+- [Lucas Holt brought this change]
+
+  misc: fix a few issues on MidnightBSD
   
-  With the use hyper_request_on_informational()
-  
-  Enable test 155 and 158
-  
-  Closes #7597
+  Closes #7812
 
-Marc Hoersken (18 Aug 2021)
-- tests/*server.pl: flush output before executing subprocess
-  
-  Also avoid shell processes staying around by using exec.
-  This is necessary to avoid output data being buffering
-  inside the process chain of Perl, Bash/Shell and our
-  test server binaries. On non-Windows systems the exec
-  will also make the subprocess replace the intermediate
-  shell, but on Windows it will at least bind the processes
-  together since there is no real fork or exec available.
-  
-  See: https://cygwin.com/cygwin-ug-net/highlights.html
-  and: https://docs.microsoft.com/cpp/c-runtime-library/exec-wexec-functions
-  Ref: https://github.com/curl/curl/pull/7530#issuecomment-900949010
-  
-  Reviewed-by: Daniel Stenberg
-  Reviewed-by: Jay Satiro
-  Closes #7530
+Daniel Gustafsson (4 Oct 2021)
+- [8U61ife brought this change]
 
-- CI: use GitHub Container Registry instead of Docker Hub
-  
-  Avoid limits on Docker Hub and improve image pull/download speed.
+  tool_main: fix typo in comment
   
-  Closes #7587
+  Closes: #7811
+  Reviewed-by: Daniel Gustafsson 
 
-Daniel Stenberg (18 Aug 2021)
-- openssl: when creating a new context, there cannot be an old one
+Daniel Stenberg (4 Oct 2021)
+- [Ryan Mast brought this change]
+
+  BINDINGS: URL updates
   
-  Remove the previous handling that would call SSL_CTX_free(), and instead
-  add an assert that halts a debug build if there ever is a context
-  already set at this point.
+  For cpr, BBHTTP, Eiffel, Harbour, Haskell, Mono, and Rust
   
-  Closes #7585
+  Closes #7809
 
-Jay Satiro (18 Aug 2021)
-- KNOWN_BUGS: Renegotiate from server may cause hang for OpenSSL backend
+- scripts/delta: hide a git error message we don't care about
   
-  Closes https://github.com/curl/curl/issues/6785
+  fatal: path 'src/tool_listhelp.c' exists on disk, but not in [tag]
 
-Viktor Szakats (17 Aug 2021)
-- docs/BINDINGS: URL update
+- [Patrick Monnerat brought this change]
 
-Marc Hoersken (17 Aug 2021)
-- tests/server/*.c: align handling of portfile argument and file
+  sasl: binary messages
   
-  1. Call the internal variable portname (like pidname) everywhere.
-  2. Have a variable wroteportfile (like wrotepidfile) everywhere.
-  3. Make sure the file is cleaned up on exit (like pidfile).
-  4. Add parameter --portfile to usage outputs everywhere.
+  Capabilities of sasl module are extended to exchange messages in binary
+  as an alternative to base64.
   
-  Reviewed-by: Daniel Stenberg
+  If http authentication flags have been set, those are used as sasl
+  default preferred mechanisms.
   
-  Replaces #7523
-  Closes #7574
+  Closes #6930
 
-Daniel Gustafsson (17 Aug 2021)
-- KNOWN_BUGS: Fix a number of typos in KNOWN_BUGS
-  
-  Fixes a set of typos found in section 11.3.
+- [Hayden Roche brought this change]
 
-Daniel Stenberg (17 Aug 2021)
-- getparameter: fix the --local-port number parser
+  wolfssl: use for SHA256, MD4, MD5, and setting DES odd parity
   
-  It could previously get tricked into parsing the uninitialized stack
-  based buffer.
+  Prior to this commit, OpenSSL could be used for all these functions, but
+  not wolfSSL. This commit makes it so wolfSSL will be used if USE_WOLFSSL
+  is defined.
   
-  Reported-by: Brian Carpenter
-  Closes #7582
+  Closes #7806
 
-- KNOWN_BUGS: Can't use Secure Transport with Crypto Token Kit
+- scripts/delta: count command line options in the new file
   
-  Closes #7048
+  ... which makes the shown delta number wrong until next release.
 
-- [Jan Verbeek brought this change]
+- RELEASE-NOTES: synced
 
-  curl: add warning for ignored data after quoted form parameter
+- print_category: print help descriptions aligned
   
-  In an argument like `-F 'x=@/etc/hostname;filename="foo"abc'` the `abc`
-  is ignored. This adds a warning if the ignored data isn't all
-  whitespace.
+  Adjust the description position to make an aligned column when doing
+  help listings, which is more pleasing to the eye.
   
-  Closes #7394
+  Suggested-by: Gisle Vanem
+  Closes #7792
 
-Jay Satiro (17 Aug 2021)
-- codeql: fix error "Resource not accessible by integration"
-  
-  - Enable codeql writing security-events.
+- lib/mk-ca-bundle.pl: skip certs passed Not Valid After date
   
-  GitHub set the default permissions to read, apparently since earlier
-  this year.
+  With this change applied, the now expired 'DST Root CA X3' cert will no
+  longer be included in the output.
   
-  Ref: https://github.com/github/codeql-action/issues/464
-  Ref: https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/
+  Details: https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/
   
-  Fixes https://github.com/curl/curl/issues/7575
-  Closes https://github.com/curl/curl/pull/7576
+  Closes #7801
 
-- tool_operate: Fix --fail-early with parallel transfers
+- tool_listhelp: easier to generate with gen.pl
   
-  - Abort via progress callback to fail early during parallel transfers.
+  tool_listhelp.c is now a separate file with only the command line --help
+  output, exactly as generated by gen.pl. This makes it easier to generate
+  updates according to what's in the docs/cmdline-opts docs.
   
-  When a critical error occurs during a transfer (eg --fail-early
-  constraint) then other running transfers will be aborted via progress
-  callback and finish with error CURLE_ABORTED_BY_CALLBACK (42). In this
-  case, the callback error does not become the most recent error and a
-  custom error message is used for those transfers:
+    cd $srcroot/docs/cmdline-opts
+    ./gen.pl listhelp *.d > $srcroot/src/tool_listhelp.c
   
-  curld --fail --fail-early --parallel
-  https://httpbin.org/status/404 https://httpbin.org/delay/10
+  With a configure build, this also works:
   
-  curl: (22) The requested URL returned error: 404
-  curl: (42) Transfer aborted due to critical error in another transfer
+    make -C src listhelp
   
-  > echo %ERRORLEVEL%
-  22
+  Closes #7787
+
+- [Anthony Hu brought this change]
+
+  wolfssl: allow setting of groups/curves
   
-  Fixes https://github.com/curl/curl/issues/6939
-  Closes https://github.com/curl/curl/pull/6984
+  In particular, the quantum safe KEM and hybrid curves if wolfSSL is
+  built to support them.
+  
+  Closes #7728
 
-Daniel Stenberg (17 Aug 2021)
-- [Sergey Markelov brought this change]
+- [Jan Mazur brought this change]
 
-  sectransp: support CURLINFO_CERTINFO
+  connnect: use sysaddr_un fron sys/un.h or custom-defined for windows
   
-  Fixes #4130
-  Closes #7372
+  Closes #7737
 
-- ngtcp2: remove the acked_crypto_offset struct field init
+Jay Satiro (30 Sep 2021)
+- [Rikard Falkeborn brought this change]
+
+  hostip: Move allocation to clarify there is no memleak
   
-  ... as it is gone from the API upstream.
+  By just glancing at the code, it looks like there is a memleak if the
+  call to Curl_inet_pton() fails. Looking closer, it is clear that the
+  call to Curl_inet_pton() can not fail, so the code will never leak
+  memory. However, we can make this obvious by moving the allocation
+  after the if-statement.
   
-  Closes #7578
+  Closes https://github.com/curl/curl/pull/7796
 
-- misc: update incorrect copyright year ranges
+Daniel Stenberg (30 Sep 2021)
+- gen.pl: make the output date format work better
   
-  Closes #7577
-
-- KNOWN_BUGS: HTTP/3 quiche upload large file fails
+  Follow-up to 15910dfd143dd
   
-  Closes #7532
-
-- KNOWN_BUGS: CMake build with MIT Kerberos does not work
+  The previous strftime format used didn't work correctly on Windows, so
+  change to %B %d %Y which today looks like "September 29 2021".
   
-  Closes #6904
+  Reported-by: Gisle Vanem
+  Bug: #7782
+  Closes #7793
 
-- TODO: add asynch getaddrinfo support
+- typecheck-gcc.h: add CURLOPT_PREREQDATA awareness
   
-  Closes #6746
-
-- RELEASE-NOTES: synced
-
-- [Artur Sinila brought this change]
-
-  http2: revert call the handle-closed function correctly on closed stream
+  Follow-up to a517378de58358a
   
-  Reverts 252790c5335a221
+  To make test 1912 happy again
   
-  Assisted-by: Gergely Nagy
-  Fixes #7400
-  Closes #7525
-
-- [Patrick Monnerat brought this change]
+  Closes #7799
 
-  auth: do not append zero-terminator to authorisation id in kerberos
+Marcel Raad (29 Sep 2021)
+- configure: remove `HAVE_WINSOCK_H` definition
   
-  RFC4752 Section 3.1 states "The authorization identity is not terminated
-  with a zero-valued (%x00) octet". Although a comment in code said it may
-  be needed anyway, nothing confirms it. In addition, servers may consider
-  it as part of the identity, causing a failure.
+  It's not used anymore.
   
-  Closes #7008
-
-- [Patrick Monnerat brought this change]
+  Closes https://github.com/curl/curl/pull/7795
 
-  auth: use sasl authzid option in kerberos
+- CMake: remove `HAVE_WINSOCK_H` definition
   
-  ... instead of deriving it from active ticket.
-  Closes #7008
-
-- [Patrick Monnerat brought this change]
-
-  auth: we do not support a security layer after kerberos authentication
+  It's not used anymore.
   
-  Closes #7008
-
-- [Patrick Monnerat brought this change]
+  Closes https://github.com/curl/curl/pull/7795
 
-  auth: properly handle byte order in kerberos security message
+- config: remove `HAVE_WINSOCK_H` definition
   
-  Closes #7008
-
-- [z2_ brought this change]
-
-  x509asn1: fix heap over-read when parsing x509 certificates
+  It's not used anymore.
   
-  Assisted-by: Patrick Monnerat
-  Closes #7536
+  Closes https://github.com/curl/curl/pull/7795
 
-- KNOWN_BUGS: Disconnects don't do verbose
+- lib: remove `HAVE_WINSOCK_H` usage
   
-  Closes #6995
-
-- mailmap: fixup Michał Antoniak
-
-- [Michał Antoniak brought this change]
+  WinSock v1 is not supported anymore. Exclusively use `HAVE_WINSOCK2_H`
+  instead.
+  
+  Closes https://github.com/curl/curl/pull/7795
 
-  build: fix compiler warnings
+Daniel Stenberg (29 Sep 2021)
+- easyoptions: add the two new PRE* options
   
-  For when CURL_DISABLE_VERBOSE_STRINGS and DEBUGBUILD flags are both
-  active.
+  Follow-up to a517378de58358a
   
-  - socks.c : warning C4100: 'lineno': unreferenced formal parameter
-    (co-authored by Daniel Stenberg)
+  Also fix optiontable.pl to do the correct remainder on the entry.
   
-  - mbedtls.c: warning C4189: 'port': local variable is initialized but
-    not referenced
+  Reported-by: Gisle Vanem
+  Bug: https://github.com/curl/curl/commit/a517378de58358a85b7cfe9efecb56051268f629#commitcomment-57224830
+  Closes #7791
+
+- Revert "build: remove checks for WinSock 1"
   
-  - schannel.c: warning C4189: 'hostname': local variable is initialized
-    but not referenced
+  Due to CI issues
   
-  Cloes #7528
-
-- [Gleb Ivanovsky brought this change]
+  This reverts commit c2ea04f92b00b6271627cb218647527b5a50f2fc.
+  
+  Closes #7790
 
-  CODE_STYLE-md: fix bold font style
+Daniel Gustafsson (29 Sep 2021)
+- lib: avoid fallthrough cases in switch statements
   
-  Markdown gets confused with abundance of asterisks, so use underscores
-  instead.
+  Commit b5a434f7f0ee4d64857f8592eced5b9007d83620 inhibits the warning
+  on implicit fallthrough cases, since the current coding of indicating
+  fallthrough with comments is falling out of fashion with new compilers.
+  This attempts to make the issue smaller by rewriting fallthroughs to no
+  longer fallthrough, via either breaking the cases or turning switch
+  statements into if statements.
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #7569
-
-- [Gleb Ivanovsky brought this change]
-
-  CODE_STYLE-md: add missing comma
+    lib/content_encoding.c: the fallthrough codepath is simply copied
+      into the case as it's a single line.
+    lib/http_ntlm.c: the fallthrough case skips a state in the state-
+      machine and fast-forwards to NTLMSTATE_LAST. Do this before the
+      switch statement instead to set up the states that we actually
+      want.
+    lib/http_proxy.c: the fallthrough is just falling into exiting the
+      switch statement which can be done easily enough in the case.
+    lib/mime.c: switch statement rewritten as if statement.
+    lib/pop3.c: the fallthrough case skips to the next state in the
+      statemachine, do this explicitly instead.
+    lib/urlapi.c: switch statement rewritten as if statement.
+    lib/vssh/wolfssh.c: the fallthrough cases fast-forwards the state
+      machine, do this by running another iteration of the switch
+      statement instead.
+    lib/vtls/gtls.c: switch statement rewritten as if statement.
+    lib/vtls/nss.c: the fallthrough codepath is simply copied into the
+      case as it's a single line. Also twiddle a comment to not be
+      inside a non-brace if statement.
   
-  Reviewed-by: Daniel Gustafsson
-  Closes #7570
-
-- [Daniel Gustafsson brought this change]
+  Closes: #7322
+  See-also: #7295
+  Reviewed-by: Daniel Stenberg 
 
-  examples/ephiperfifo.c: simplify signal handler
+Marcel Raad (28 Sep 2021)
+- config-win32ce: enable WinSock 2
   
-  The signal handler registered for SIGINT is only handling SIGINT
-  so there isn't much need for inspecting the signo.  While there,
-  rename the handler to be more specific.
+  WinSock 2.2 is supported by Windows CE .NET 4.1 (from 2002, out of
+  support since 2013).
   
-  g_should_exit should really be of sig_atomic_t type, but relying
-  on autoconf in the examples seems like a bad idea so keep that
-  for now.
+  Ref: https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms899586(v=msdn.10)
   
-  Reviewed-by: Daniel Stenberg
-  Closes #7310
+  Closes https://github.com/curl/curl/pull/7778
 
-- c-hyper: initial step for 100-continue support
+- externalsocket: use WinSock 2.2
   
-  Enabled test 154
+  That's the only version we support.
   
-  Closes #7568
-
-- [Ikko Ashimine brought this change]
+  Closes https://github.com/curl/curl/pull/7778
 
-  vtls: fix typo in schannel_verify.c
+- build: remove checks for WinSock 1
   
-  occurence -> occurrence
+  It's not supported anymore.
   
-  Closes #7566
+  Closes https://github.com/curl/curl/pull/7778
 
-- [Emil Engler brought this change]
+Daniel Stenberg (28 Sep 2021)
+- scripts/copyright: .muse is .lift now
+  
+  And update 5 files with old copyright year range
 
-  curl_url_get.3: clarify about path and query
+- cmdline-opts: made the 'Added:' field mandatory
   
-  The current man-page lacks some details regarding the obtained path and
-  query.
+  Since "too old" versions are no longer included in the generated man
+  page, this field is now mandatory so that it won't be forgotten and then
+  not included in the documentation.
   
-  Closes #7563
+  Closes #7786
 
-- c-hyper: fix header value passed to debug callback
+- curl.1: remove mentions of really old version changes
   
-  Closes #7567
-
-Viktor Szakats (12 Aug 2021)
-- cleanup: URL updates
+  To make the man page more readable, this change removes all references
+  to changes in support/versions etc that happened before 7.30.0 from the
+  curl.1 output file. 7.30.0 was released on Apr 12 2013. This particular
+  limit is a bit arbitrary but was fairly easy to grep for.
   
-  - replace broken URL with the one it was most probably pointing to
-    when added (lib/tftp.c)
-  - replace broken URL with archive.org link (lib/curl_ntlm_wb.c)
-  - delete unnecessary protocol designator from archive.org URL
-    (docs/BINDINGS.md)
+  It is handled like this: the 'Added' keyword is only used in output if
+  it refers to 7.30.0 or later. All occurances of "(Added in $VERSION)" in
+  description will be stripped out if the mentioned $VERSION is from
+  before 7.30.0. It is therefore important that the "Added in..."
+  references are always written exactly like that - and on a single line,
+  not split over two.
   
-  Closes #7562
+  This change removes about 80 version number references from curl.1, down
+  to 138 from 218.
+  
+  Closes #7786
 
-Daniel Stenberg (12 Aug 2021)
-- [April King brought this change]
+- RELEASE-NOTES: synced
 
-  DEPRECATE.md: linkify curl-library mailing list
+- tool_cb_prg: make resumed upload progress bar show better
   
-  Closes #7561
+  This is a regression that was *probably* injected in the larger progress
+  bar overhaul in 2018.
+  
+  Reported-by: beslick5 on github
+  Fixes #7760
+  Closes #7777
 
-- [Barry Pollard brought this change]
+- gen.pl: insert the current date and version in generated man page
+  
+  Reported-by: Gisle Vanem
+  Ref: #7780
+  Closes #7782
 
-  output.d: add method to suppress response bodies
+- NTLM: use DES_set_key_unchecked with OpenSSL
   
-  Closes #7560
+  ... as the previously used function DES_set_key() will in some cases
+  reject using a key that it deems "weak" which will cause curl to
+  continue using the unitialized buffer content as key instead.
+  
+  Assisted-by: Harry Sintonen
+  Fixes #7779
+  Closes #7781
 
-- TODO: remove 'c-ares deviates on http://1346569778'
+Marc Hoersken (27 Sep 2021)
+- CI: align make and test flags in various config files
   
-  Fixed since 56a037cc0ad1b2 (7.77.0)
+  1. Use Makefile target to run tests in autotools builds on AppVeyor.
+  2. Disable testing of SCP protocol on native Windows environments.
+  3. Remove redundant parameters -a -p from target test-nonflaky.
+  4. Don't use -vc parameter which is reserved for debugging.
+  
+  Replaces #7591
+  Closes #7690
 
-- [Colin O'Dell brought this change]
+Daniel Stenberg (27 Sep 2021)
+- mailmap: unify Max!
 
-  BINDINGS.md: update links to use https where available
-  
-  Closes #7558
+- [Max Dymond brought this change]
 
-- asyn-ares.c: move all version number checks to the top
+  CURLOPT_PREREQFUNCTION: add new callback
   
-  ... and use #ifdef [feature] in the code as per our guidelines.
-
-- ares: use ares_getaddrinfo()
+  Triggered before a request is made but after a connection is set up
   
-  ares_getaddrinfo() is the getaddrinfo() cloned provided by c-ares, introduced
-  in version 1.16.0.
+  Changes:
   
-  With older c-ares versions, curl invokes ares_gethostbyname() twice - once for
-  IPv4 and once for IPv6 to resolve both addresses, and then combines the
-  returned results.
+  - callback: Update docs and callback for pre-request callback
+  - Add documentation for CURLOPT_PREREQDATA and CURLOPT_PREREQFUNCTION,
+  - Add redirect test and callback failure test
+  - Note that the function may be called multiple times on a redirection
+  - Disable new 2086 test due to Windows weirdness
   
-  Reported-by: jjandesmet
-  Fixes #7364
-  Closes #7552
+  Closes #7477
 
-- [Tatsuhiro Tsujikawa brought this change]
+- KNOWN_BUGS: HTTP/2 connections through HTTPS proxy frequently stall
+  
+  Closes #6936
 
-  ngtcp2: utilize crypto API functions to simplify
+- TODO: make configure use --cache-file more and better
   
-  Closes #7551
+  Closes #7753
 
-- [megatronking brought this change]
+- [Sergey Markelov brought this change]
 
-  ngtcp2: reset the oustanding send buffer again when drained
+  urlapi: support UNC paths in file: URLs on Windows
   
-  Closes #7538
+  - file://host.name/path/file.txt is a valid UNC path
+    \\host.name\path\files.txt to a non-local file transformed into URI
+    (RFC 8089 Appendix E.3)
+  
+  - UNC paths on other OSs must be smb: URLs
+  
+  Closes #7366
 
-Michael Kaufmann (10 Aug 2021)
-- progress: fix a compile warning on some systems
+- [Gleb Ivanovsky brought this change]
+
+  urlapi: add curl_url_strerror()
   
-  lib/progress.c:380:40: warning: conversion to 'long double' from
-  'curl_off_t {aka long long int}' may alter its value [-Wconversion]
+  Add curl_url_strerror() to convert CURLUcode into readable string and
+  facilitate easier troubleshooting in programs using URL API.
+  Extend CURLUcode with CURLU_LAST for iteration in unit tests.
+  Update man pages with a mention of new function.
+  Update example code and tests with new functionality where it fits.
   
-  Closes #7549
+  Closes #7605
 
-Daniel Stenberg (10 Aug 2021)
 - RELEASE-NOTES: synced
 
-- http: consider cookies over localhost to be secure
+- [Mats Lindestam brought this change]
+
+  libssh2: add SHA256 fingerprint support
   
-  Updated test31.
-  Added test 392 to verify secure cookies used for http://localhost
+  Added support for SHA256 fingerprint in command line curl and in
+  libcurl.
   
-  Reviewed-by: Daniel Gustafsson
-  Fixes #6733
-  Closes #7263
+  Closes #7646
 
-- TODO: erase secrets from heap/stack after use
+- libcurl.rc: switch out the copyright symbol for plain ASCII
   
-  Closes #7268
+  Reported-by: Vitaly Varyvdin
+  Assisted-by: Viktor Szakats
+  Fixes #7765
+  Closes #7776
 
-Jay Satiro (10 Aug 2021)
-- hostip: Make Curl_ipv6works function independent of getaddrinfo
+- [Jun-ya Kato brought this change]
+
+  ngtcp2: fix QUIC transport parameter version
   
-  - Do not assume IPv6 is not working when getaddrinfo is not present.
+  fix inappropriate version setting for QUIC transport parameters.
+  this patch keeps curl with ngtcp2 uses QUIC draft version (h3-29).
   
-  The check to see if IPv6 actually works is now independent of whether
-  there is any resolver that can potentially resolve a hostname to IPv6.
+  Closes #7771
+
+- examples/imap-append: fix end-of-data check
   
-  Prior to this change if getaddrinfo() was not found at compile time then
-  Curl_ipv6works() would be defined as a macro that returns FALSE.
+  Reported-by: Alexander Chuykov
+  Fixes #7774
+  Closes #7775
+
+Michael Kaufmann (24 Sep 2021)
+- vtls: Fix a memory leak if an SSL session cannot be added to the cache
   
-  When getaddrinfo is not found then libcurl is built with CURLRES_IPV4
-  defined instead of CURLRES_IPV6, meaning that it cannot do IPv6 lookups
-  in the traditional way. With this commit if libcurl is built with IPv6
-  support (ENABLE_IPV6) but without getaddrinfo (CURLRES_IPV6), and the
-  IPv6 stack is actually working, then it is possible for libcurl to
-  resolve IPv6 addresses by using DoH.
+  On connection shutdown, a new TLS session ticket may arrive after the
+  SSL session cache has already been destructed. In this case, the new
+  SSL session cannot be added to the SSL session cache.
   
-  Ref: https://github.com/curl/curl/issues/7483#issuecomment-890765378
+  The callers of Curl_ssl_addsessionid() need to know whether the SSL
+  session has been added to the cache. If it has not been added, the
+  reference counter of the SSL session must not be incremented, or memory
+  used by the SSL session must be freed. This is now possible with the new
+  output parameter "added" of Curl_ssl_addsessionid().
   
-  Closes https://github.com/curl/curl/pull/7529
+  Fixes #7683
+  Closes #7752
 
-- test1565: fix windows build errors
-  
-  - Use our wait_ms() instead of sleep() since Windows doesn't have the
-    latter.
-  
-  - Use a separate variable to keep track of whether the pthread_t thread
-    id is valid.
+Daniel Stenberg (24 Sep 2021)
+- [Momoka Yamamoto brought this change]
+
+  HTTP3.md: use 'autoreconf -fi' instead of buildconf
   
-  On Windows pthread_t is not an integer type. pthread offers no macro for
-  invalid pthread_t thread id, so validity is kept track of separately.
+  buildconf is not used since #5853
   
-  Closes https://github.com/curl/curl/pull/7527
+  Closes #7746
 
-- [Jeremy Falcon brought this change]
+- GIT-INFO: rephrase to adapt to s/buildconf/autoreconf
 
-  winbuild/README.md: clarify GEN_PDB option
-  
-  - Document that GEN_PDB option creates an external database.
+- [h1zzz brought this change]
+
+  llist: remove redundant code, branch will not be executed
   
-  Ref: https://github.com/curl/curl/issues/7502
+  Closes #7770
 
-Daniel Stenberg (9 Aug 2021)
-- [Tatsuhiro Tsujikawa brought this change]
+- [tlahn brought this change]
 
-  ngtcp2: replace deprecated functions with nghttp3_conn_shutdown_stream_read
+  HTTP-COOKIES.md: remove duplicate 'each'
   
-  Closes #7546
+  Closes #7772
 
-- [Tatsuhiro Tsujikawa brought this change]
+Jay Satiro (24 Sep 2021)
+- [Joel Depooter brought this change]
 
-  ngtcp2: rework the return value handling of ngtcp2_conn_writev_stream
+  libssh2: Get the version at runtime if possible
   
-  Rework the return value handling of ngtcp2_conn_writev_stream and treat
-  NGTCP2_ERR_STREAM_SHUT_WR separately.
+  Previously this code used a compile time constant, meaning that libcurl
+  always reported the libssh2 version that libcurl was built with. This
+  could differ from the libssh2 version actually being used. The new code
+  uses the CURL_LIBSSH2_VERSION macro, which is defined in ssh.h. The
+  macro calls the libssh2_version function if it is available, otherwise
+  it falls back to the compile time version.
   
-  Closes #7546
+  Closes https://github.com/curl/curl/pull/7768
 
-- configure: error out if both ngtcp2 and quiche are specified
+- [Joel Depooter brought this change]
+
+  schannel: fix typo
   
-  Reported-by: Vincent Grande
-  See #7539
-  Closes #7545
+  Closes https://github.com/curl/curl/pull/7769
 
-- [Jeff Mears brought this change]
+Daniel Stenberg (23 Sep 2021)
+- cmake: with OpenSSL, define OPENSSL_SUPPRESS_DEPRECATED
+  
+  To avoid the "... is deprecated" warnings brought by OpenSSL v3.
+  (We need to address the underlying code at some point of course.)
+  
+  Assisted-by: Jakub Zakrzewski
+  Closes #7767
 
-  easy: use a custom implementation of wcsdup on Windows
+- curl-openssl: pass argument to sed single-quoted
   
-  ... so that malloc/free overrides from curl_global_init are used for
-  wcsdup correctly.
+  ... instead of using an escaped double-quote. This is an attempt to make
+  this work better with ksh that otherwise would insist on a double
+  escape!
   
-  Closes #7540
+  Reported-by: Randall S. Becker
+  Fixes #7758
+  Closes #7764
 
-- zuul: add an mbedtls3 CI job
+- RELEASE-NOTES: synced
   
-  Closes #7544
+  Bumped curlver to 7.80.0-dev
 
-- [Benau brought this change]
+- [a1346054 brought this change]
 
-  mbedTLS: initial 3.0.0 support
+  misc: fix typos in docs and comments
   
-  Closes #7428
+  No user facing output from curl/libcurl is changed by this, just
+  comments.
+  
+  Closes #7747
 
-- RELEASE-NOTES: synced
+- [Thomas M. DuBuisson brought this change]
 
-- configure.ac: revert bad nghttp2 library detection improvements
-  
-  This reverts commit b4b34db65f9f8, 673753344c5f and 29c7cf79e8b.
+  ci: update Lift config to match requirements of curl build
   
-  The logic is now back to assuming that the nghttp2 lib is called nghttp2 and
-  nothing else.
+  Also renamed Muse -> Lift, the new tool name.
   
-  Reported-by: Rui Pinheiro
-  Reported-by: Alex Crichton
-  Fixes #7514
-  Closes #7515
+  Closes #7761
 
-- happy-eyeballs-timeout-ms.d: polish the wording
+- [Rikard Falkeborn brought this change]
+
+  cleanup: constify unmodified static structs
   
-  Reported-by: Josh Soref
-  Fixes #7433
-  Closes #7542
+  Constify a number of static structs that are never modified. Make them
+  const to show this.
+  
+  Closes #7759
 
-- [modbw brought this change]
+Version 7.79.1 (22 Sep 2021)
 
-  mbedtls_threadlock: fix unused variable warning
+Daniel Stenberg (22 Sep 2021)
+- RELEASE-NOTES: synced
   
-  Closes #7393
+  curl 7.79.1 release
 
-- [Tatsuhiro Tsujikawa brought this change]
+- THANKS: added names from the 7.79.1 release
 
-  ngtcp2: compile with the latest ngtcp2 and nghttp3
+- test897: verify delivery of IMAP post-body header content
   
-  Closes #7541
-
-Marc Hoersken (31 Jul 2021)
-- CI/cirrus: reduce compile time with increased parallism
+  The "content" is delivered as "body" by curl, but the envelope continues
+  after the body and the rest of it should be delivered as header.
   
-  Cirrus CI VMs have 2 CPUs, let's use them also for Windows builds.
+  The IMAP server can now get 'POSTFETCH' set to include more data to
+  include after the body and test 897 is done to verify that such "extra"
+  header data is in fact delivered by curl as header.
   
-  Reviewed-by: Daniel Stenberg
-  Closes #7505
+  Ref: #7284 but fails to reproduce the issue
+  
+  Closes #7748
 
-Daniel Stenberg (30 Jul 2021)
-- [Bin Lan brought this change]
+- KNOWN_BUGS: connection migration doesn't work
+  
+  Closes #7695
 
-  tool/tests: fix potential year 2038 issues
+- RELEASE-NOTES: synced
+
+- http: fix the broken >3 digit response code detection
   
-  The length of 'long' in a 32-bit system is 32 bits, which cannot be used
-  to save timestamps after 2038. Most operating systems have extended
-  time_t to 64 bits.
+  When the "reason phrase" in the HTTP status line starts with a digit,
+  that was treated as the forth response code digit and curl would claim
+  the response to be non-compliant.
   
-  Remove the castings to long.
+  Added test 1466 to verify this case.
   
-  Closes #7466
+  Regression brought by 5dc594e44f73b17
+  Reported-by: Glenn de boer
+  Fixes #7738
+  Closes #7739
 
-- compressed.d: it's a request, not an order
+Jay Satiro (17 Sep 2021)
+- strerror: use sys_errlist instead of strerror on Windows
   
-  Clarified
+  - Change Curl_strerror to use sys_errlist[errnum] instead of strerror to
+    retrieve the error message on Windows.
   
-  Reported-by: Dan Jacobson
-  Reviewed-by: Daniel Gustafsson
-  Fixes #7516
-  Closes #7517
-
-- [Bernhard M. Wiedemann brought this change]
-
-  tests: make three tests pass until 2037
+  Windows' strerror writes to a static buffer and is not thread-safe.
   
-  after 2038 something in test1915 fails on 32-bit OSes
+  Follow-up to 2f0bb86 which removed most instances of strerror in favor
+  of calling Curl_strerror (which calls strerror_r for other platforms).
   
-  Closes #7512
+  Ref: https://github.com/curl/curl/pull/7685
+  Ref: https://github.com/curl/curl/commit/2f0bb86
+  
+  Closes https://github.com/curl/curl/pull/7735
 
-Daniel Gustafsson (30 Jul 2021)
-- connect: remove superfluous conditional
+Daniel Stenberg (16 Sep 2021)
+- dist: provide lib/.checksrc in the tarball
   
-  Commit dbd16c3e2 cleaned up the logic for traversing the addrinfos,
-  but the move left a conditional on ai which no longer is needed as
-  the while loop reevaluation will cover it.
+  So that debug builds work (checksrc really)
   
-  Closes #7511
-  Reviewed-by: Carlo Marcelo Arenas Belón
-  Reviewed-by: Daniel Stenberg 
+  Reported-by: Marcel Raad
+  Reported-by: tawmoto on github
+  Fixes #7733
+  Closes #7734
 
-Daniel Stenberg (29 Jul 2021)
-- RELEASE-NOTES: synced
+- TODO: Improve documentation about fork safety
   
-  and bump curlver to 7.79.0 for next release
+  Closes #6968
 
-Marc Hoersken (29 Jul 2021)
-- tests/*server.py: remove pidfile on server termination
+- hsts: CURLSTS_FAIL from hsts read callback should fail transfer
   
-  Avoid pidfile leaking/laying around after server already exited.
+  ... and have CURLE_ABORTED_BY_CALLBACK returned.
   
-  Reviewed-by: Daniel Stenberg
-  Closes #7506
-
-Daniel Gustafsson (27 Jul 2021)
-- tool_main: fix typo in comment
+  Extended test 1915 to verify.
   
-  The referred to library is NSPR, so fix the switched around characters.
+  Reported-by: Jonathan Cardoso
+  Fixes #7726
+  Closes #7729
 
-Daniel Stenberg (28 Jul 2021)
-- [Aleksandr Krotov brought this change]
-
-  bearssl: support CURLOPT_CAINFO_BLOB
+- test1184: disable
   
-  Closes #7468
+  The test should be fine and it works for me repeated when run manually,
+  but clearly it causes CI failures and it needs more research.
+  
+  Reported-by: RiderALT on github
+  Fixes #7725
+  Closes #7732
 
-- curl.1: mention "global" flags
+- Curl_http2_setup: don't change connection data on repeat invokes
   
-  Mention options that are "global". A global command line option is one
-  that doesn't get reset at --next uses and therefore don't need to be
-  used again.
+  Regression from 3cb8a748670ab88c (releasde in 7.79.0). That change moved
+  transfer oriented inits to before the check but also erroneously moved a
+  few connection oriented ones, which causes problems.
   
-  Reported-by: Josh Soref
+  Reported-by: Evangelos Foutras
+  Fixes #7730
+  Closes #7731
+
+- RELEASE-NOTES: synced
   
-  Fixes #7457
-  Closes #7510
+  and bump to 7.79.1
 
-- CURLOPT_DOH_URL.3: CURLOPT_OPENSOCKETFUNCTION is not inherited
+Kamil Dudka (16 Sep 2021)
+- tests/sshserver.pl: make it work with openssh-8.7p1
   
-  Reported-by: Daniel Woelfel
-  Fixes #7441
-  Closes #7509
+  ... by not using options with no argument where an argument is required:
+  
+  === Start of file tests/log/ssh_server.log
+  curl_sshd_config line 6: no argument after keyword "DenyGroups"
+  curl_sshd_config line 7: no argument after keyword "AllowGroups"
+  curl_sshd_config line 10: Deprecated option AuthorizedKeysFile2
+  curl_sshd_config line 29: Deprecated option KeyRegenerationInterval
+  curl_sshd_config line 39: Deprecated option RhostsRSAAuthentication
+  curl_sshd_config line 40: Deprecated option RSAAuthentication
+  curl_sshd_config line 41: Deprecated option ServerKeyBits
+  curl_sshd_config line 45: Deprecated option UseLogin
+  curl_sshd_config line 56: no argument after keyword "AcceptEnv"
+  curl_sshd_config: terminating, 3 bad configuration options
+  === End of file tests/log/ssh_server.log
+  
+  === Start of file log/sftp_server.log
+  curl_sftp_config line 33: Unsupported option "rhostsrsaauthentication"
+  curl_sftp_config line 34: Unsupported option "rsaauthentication"
+  curl_sftp_config line 52: no argument after keyword "sendenv"
+  curl_sftp_config: terminating, 1 bad configuration options
+  Connection closed.
+  Connection closed
+  === End of file log/sftp_server.log
+  
+  Closes #7724
 
-- KNOWN_BUGS: add more HTTP/3 problems
+Daniel Stenberg (15 Sep 2021)
+- hsts: handle unlimited expiry
   
-  Closes #7351
-  Closes #7339
-  Closes #7125
+  When setting a blank expire string, meaning unlimited, curl would pass
+  TIME_T_MAX to getime_r() when creating the output, while on 64 bit
+  systems such a large value cannot be convetered to a tm struct making
+  curl to exit the loop with an error instead. It can't be converted
+  because the year it would represent doesn't fit in the 'int tm_year'
+  field!
+  
+  Starting now, unlimited expiry is instead handled differently by using a
+  human readable expiry date spelled out as "unlimited" instead of trying
+  to use a distant actual date.
+  
+  Test 1660 and 1915 have been updated to help verify this change.
+  
+  Reported-by: Jonathan Cardoso
+  Fixes #7720
+  Closes #7721
 
-Marc Hoersken (27 Jul 2021)
-- CI/azure: reduce compile time with increased parallism
+- curl_multi_fdset: make FD_SET() not operate on sockets out of range
   
-  Azure Pipelines CI VMs have 2 CPUs, let's use them.
+  The VALID_SOCK() macro was made to only check for FD_SETSIZE if curl was
+  built to use select(), even though the curl_multi_fdset() function
+  always and unconditionally uses FD_SET and needs the check.
   
-  Closes #7489
+  Reported-by: 0xee on github
+  Fixes #7718
+  Closes #7719
 
-Jay Satiro (27 Jul 2021)
-- [Josh Soref brought this change]
+- FAQ: add GOPHERS + curl works on data, not files
 
-  docs: fix grammar
+Version 7.79.0 (14 Sep 2021)
+
+Daniel Stenberg (14 Sep 2021)
+- RELEASE-NOTES: synced
   
-  Fixes https://github.com/curl/curl/issues/7444
-  Fixes https://github.com/curl/curl/issues/7451
-  Fixes https://github.com/curl/curl/issues/7465
-  Closes https://github.com/curl/curl/pull/7495
+  For the 7.79.0 release
 
-- mail-rcpt.d: fix grammar
+- THANKS: add contributors from 7.79.0 release cycle
+
+- FAQ: add two dev related questions
   
-  Remove confusing sentence that says to specify an e-mail address for
-  mail transfer, since that's implied.
+    8.1 Why does curl use C89?
+    8.2 Will curl be rewritten?
   
-  Reported-by: Josh Soref
+  Spell-checked-by: Paul Johnson
+  Closes #7715
+
+- zuul.d/jobs: disable three tests for *-openssl-disable-proxy
   
-  Fixes https://github.com/curl/curl/issues/7452
-  Closes https://github.com/curl/curl/pull/7495
+  ... as they mysteriously seem to permfail without being related to
+  proxy.
+  
+  Closes #7714
 
-Daniel Stenberg (27 Jul 2021)
-- c-hyper: remove the hyper_executor_poll() loop from Curl_http
+- [Patrick Monnerat brought this change]
+
+  ftp,imap,pop3,smtp: reject STARTTLS server response pipelining
   
-  1. it's superfluous
-  2. it didn't work identically to the Curl_hyper_stream one which could
-     cause problems like #7486
+  If a server pipelines future responses within the STARTTLS response, the
+  former are preserved in the pingpong cache across TLS negotiation and
+  used as responses to the encrypted commands.
   
-  Pointed-out-by: David Cook
-  Closes #7499
+  This fix detects pipelined STARTTLS responses and rejects them with an
+  error.
+  
+  CVE-2021-22947
+  
+  Bug: https://curl.se/docs/CVE-2021-22947.html
 
-- curl-openssl.m4: check lib64 for the pkg-config file
+- [Patrick Monnerat brought this change]
+
+  ftp,imap,pop3: do not ignore --ssl-reqd
   
-  OpenSSL recently started putting the libs in $prefix/lib64 on 'make
-  install', so we check that directory for pkg-config data if the 'lib'
-  check fails.
+  In imap and pop3, check if TLS is required even when capabilities
+  request has failed.
   
-  Closes #7503
+  In ftp, ignore preauthentication (230 status of server greeting) if TLS
+  is required.
+  
+  Bug: https://curl.se/docs/CVE-2021-22946.html
+  
+  CVE-2021-22946
 
-- CURLOPT_SSL_CTX_*.3: tidy up the example
+- [z2_ on hackerone brought this change]
+
+  mqtt: clear the leftovers pointer when sending succeeds
   
-  Use the proper code style. Don't store return codes that aren't read.
-  Copy the same example into CURLOPT_SSL_CTX_FUNCTION.3 as well.
+  CVE-2021-22945
   
-  Closes #7500
+  Bug: https://curl.se/docs/CVE-2021-22945.html
 
-- example/cookie_interface: fix scan-build printf warning
+- zuul: bump the rustls job to use v0.7.2
   
-  Follow-up to 4b79c4fb565
+  ... and add -lm when using a rust library.
   
-  Fixes #7497
-  Closes #7498
+  Closes #7701
 
-- [Josh Soref brought this change]
+- RELEASE-PROCEDURE: add release dates from now to 8.0.0 in 2023
 
-  limit-rate.d: clarify base unit
+- SECURITY-PROCESS: tweak a little to match current practices
   
-  Fixes #7439
-  Closes #7494
-
-- [Carlo Marcelo Arenas Belón brought this change]
+  Closes #7713
 
-  examples/cookie_interface: avoid printfing time_t directly
+- http_proxy: fix the User-Agent inclusion in CONNECT
   
-  time_t representation is undefined and varies on bitsize and signedness,
-  and as of C11 could be even non integer.
+  It should not refer to the uagent string that is allocated and created
+  for the end server http request, as that pointer may be cleared on
+  subsequent CONNECT requests.
   
-  instead of casting to unsigned long (which would truncate in systems
-  with a 32bit long after 2106) use difftime to get the elapsed time as a
-  double and print that (without decimals) instead.
+  Added test case 1184 to verify.
   
-  alternatively a cast to curl_off_t and its corresponding print
-  formatting could have been used (at least in POSIX) but portability and
-  curl agnostic code was prioritized.
+  Reported-by: T200proX7 on github
+  Fixes #7705
+  Closes #7707
+
+- Curl_hsts_loadcb: don't attempt to load if hsts wasn't inited
   
-  Closes #7490
+  Reported-by: Jonathan Cardoso
+  Fixes #7710
+  Closes #7711
 
-Marc Hoersken (25 Jul 2021)
-- tests/servers: remove obsolete pid variable
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: fix build with ngtcp2 and nghttp3
   
-  Variable is not used since pidfile handling moved to util.[ch]
+  ngtcp2_conn_client_new and nghttp3_conn_client_new are now macros.
+  Check the wrapped functions instead.
   
-  Reviewed-by: Jay Satiro
-  Closes #7482
+  ngtcp2_stream_close callback now takes flags parameter.
+  
+  Closes #7709
 
-- tests/servers: use our platform-aware pid for server verification
+- write-out.d: clarify size_download/upload
   
-  The pid used for server verification is later stored as pid2 in
-  the hash of running test servers and therefore used for shutdown.
+  They show the number of "body" bytes transfered.
+  Fixes #7702
+  Closes #7706
+
+- http2: Curl_http2_setup needs to init stream data in all invokes
   
-  The pid used for shutdown must be the platform-aware (Win32) pid
-  to avoid leaking test servers while running them using Cygwin/msys.
+  Thus function was written to avoid doing multiple connection data
+  initializations, which is fine, but since it also initiates stream
+  related data it is crucial that it doesn't skip those even if called
+  again for the same connection. Solved by moving the stream
+  initializations before the "doing-it-again" check.
   
-  Reviewed-by: Jay Satiro
-  Closes #7481
+  Reported-by: Inho Oh
+  Fixes #7630
+  Closes #7692
 
-- tests/runtests.pl: cleanup copy&paste mistakes and unused code
+- url: fix compiler warning in no-verbose builds
   
-  Reviewed-by: Jay Satiro
-  Part of #7481
+  Follow-up from 2f0bb864c12
+  
+  Closes #7700
 
-Daniel Stenberg (25 Jul 2021)
-- RELEASE-NOTES: synced
+- non-ascii: fix build errors from strerror fix
   
-  bumped to 7.78.1 for next release
+  Follow-up to 2f0bb864c12
+  
+  Closes #7697
 
-- http_proxy: clear 'sending' when the outgoing request is sent
+- parse_args: redo the warnings for --remote-header-name combos
   
-  ... so that Curl_connect_getsock() will know how to wait for the socket
-  to become readable and not writable after the entire CONNECT request has
-  been issued.
+  ... to avoid the memory leak risk pointed out by scan-build.
   
-  Regression added in 7.77.0
+  Follow-up from 7a3e981781d6c18a
   
-  Reported-by: zloi-user on github
-  Assisted-by: Jay Satiro
-  Fixes #7155
-  Closes #7484
-
-Jay Satiro (25 Jul 2021)
-- [Josh Soref brought this change]
+  Closes #7698
 
-  openssl: fix grammar
+- ngtcp2: adapt to new size defintions upstream
   
-  Closes https://github.com/curl/curl/pull/7480
+  Reviewed-by: Tatsuhiro Tsujikawa
+  Closes #7699
 
-- configure.ac: tweak nghttp2 library name fix again
+- rustls: add strerror.h include
   
-  - Change extraction to handle multiple library names returned by
-    pkg-config (eg a possible scenario with pkg-config --static).
+  Follow-up to 2f0bb864c12
+
+- docs: the security list is reached at security at curl.se now
   
-  Ref: https://github.com/curl/curl/pull/7472
+  Also update the FAQ section a bit to encourage users to rather submit
+  security issues on hackerone than sending email.
   
-  Closes https://github.com/curl/curl/pull/7485
+  Closes #7689
 
-Dan Fandrich (23 Jul 2021)
-- Get rid of the unused HAVE_SIG_ATOMIC_T et. al.
+Marc Hoersken (9 Sep 2021)
+- runtests: add option -u to error on server unexpectedly alive
   
-  It was added in 2006 but I see no evidence it was ever used.
-
-Jay Satiro (23 Jul 2021)
-- docs: change max-filesize caveat again
+  Let's try to actually handle the server unexpectedly alive
+  case by first making them visible on CI builds as failures.
   
-  - Add protocols field to max-filesize.d.
+  This is needed to detect issues with killing of the test
+  servers completely including nested process chains with
+  multiple PIDs per test server (including bash and perl).
   
-  - Revert wording on unknown file size caveat and do not discuss specific
-    protocols in that section.
+  On Windows/cygwin platforms this is especially helpful with
+  debugging PID mixups due to cygwin using its own PID space.
   
-  Partial revert of ecf0225. All max-filesize options now have the list of
-  protocols and it's clearer just to have that list without discussing
-  specific protocols in the caveat.
+  Reviewed-by: Daniel Stenberg
+  Closes #7180
+
+Daniel Stenberg (9 Sep 2021)
+- opts docs: unify phrasing in NAME header
   
-  Reported-by: Josh Soref
+  - avoid writing "set ..." or "enable/disable ..." or "specify ..."
+    *All* options for curl_easy_setopt() are about setting or enabling
+    things and most of the existing options didn't use that way of
+    description.
   
-  Ref: https://github.com/curl/curl/issues/7453#issuecomment-884128762
+  - start with lowercase letter, unless abbreviation. For consistency.
+  
+  - Some additional touch-ups
+  
+  Closes #7688
 
-Daniel Stenberg (22 Jul 2021)
-- [Christian Weisgerber brought this change]
+- strerror.h: remove the #include from files not using it
 
-  configure: tweak nghttp2 library name fix
+- lib: don't use strerror()
   
-  commit 29c7cf79e8b44cf (shipped in 7.78.0) introduced a problem by
-  assuming that LIB_H2 does not have any leading whitespace.  At least
-  OpenBSD's native pkg-config can produce such whitespace, though:
+  We have and provide Curl_strerror() internally for a reason: strerror()
+  is not necessarily thread-safe so we should always try to avoid it.
   
-      $ pkg-config --libs-only-l libnghttp2
-       -lnghttp2
+  Extended checksrc to warn for this, but feature the check disabled by
+  default and only enable it in lib/
   
-  As a result, the configure check for libnghttp2 will erroneously fail.
+  Closes #7685
+
+Daniel Gustafsson (8 Sep 2021)
+- cirrus: Add FreeBSD 13.0 job and disable sanitizer build
   
-  Bug: https://curl.se/mail/lib-2021-07/0050.html
-  Closes #7472
+  As alluded to the in the now removed comment, a 13.0 image became
+  available and is now ready to be used.
+  
+  The sanitizer builds were running on the 12.1 image which since has
+  been removed from the config, leaving the builds not running at all.
+  When enabled it turns out that they don't actually work due to very
+  long timeouts in executing the tests, so keep the disabled for now
+  but a bit more controlled.
+  
+  Closes #7592
 
-- [Bastian Krause brought this change]
+Daniel Stenberg (8 Sep 2021)
+- copyrights: update copyright year ranges
 
-  docs/MQTT: update state of username/password support
+- RELEASE-NOTES: synced
+
+- INTERNALS: c-ares has a new home: c-ares.org
+
+- docs: remove experimental mentions from HSTS and MQTT
   
-  PR #7243 implemented username/password support for MQTT, so let's drop
-  these items from the caveats.
+  Reported-by: Jonathan Cardoso
+  Bug: https://github.com/curl/curl/pull/6700#issuecomment-913792863
+  Closes #7681
+
+- [Cao ZhenXiang brought this change]
+
+  curl: add warning for incompatible parameters usage
   
-  Signed-off-by: Bastian Krause 
+  --continue-at - and --remote-header-name are known incompatible parameters
   
-  Closes #7474
+  Closes #7674
 
-- [Oleg Pudeyev brought this change]
+- [git-bruh brought this change]
 
-  CURLMOPT_TIMERFUNCTION.3: remove misplaced "time"
+  examples/*hiperfifo.c: fix calloc arguments to match function proto
   
-  Closes #7470
+  Closes #7678
 
-Version 7.78.0 (21 Jul 2021)
+- INTERNALS: bump c-ares requirement to 1.16.0
+  
+  Since ba904db0705c93 we use ares_getaddrinfo, added in c-ares 1.16.0
 
-Daniel Stenberg (21 Jul 2021)
-- RELEASE-NOTES: synced
+- curl: stop retry if Retry-After: is longer than allowed
   
-  curl 7.78.0 release
+  If Retry-After: specifies a period that is longer than what fits within
+  --retry-max-time, then stop retrying immediately.
+  
+  Added test 366 to verify.
+  
+  Reported-by: Kari Pahula
+  Fixes #7675
+  Closes #7676
 
-- winbuild/MakefileBuild.vc: bump copyright year
+- [Michał Antoniak brought this change]
 
-Jay Satiro (21 Jul 2021)
-- docs: mention max-filesize options also apply to MQTT transfers
+  mbedtls: avoid using a large buffer on the stack
   
-  Also make it clearer that the caveat 'if the file size is unknown it
-  the option will have no effect' may apply to protocols other than FTP
-  and HTTP.
+  Use dynamic memory allocation for the buffer used in checking "pinned
+  public key". The PUB_DER_MAX_BYTES parameter with default settings is
+  set to a value greater than 2kB.
   
-  Reported-by: Josh Soref
+  Co-authored-by: Daniel Stenberg
+  Closes #7586
+
+- configure: make --disable-hsts work
   
-  Fixes https://github.com/curl/curl/issues/7453
+  The AC_ARG_ENABLE() macro itself uses a variable called
+  'enable_[option]', so when our script also used a variable with that
+  name for the purpose of storing what the user wants, it also
+  accidentally made it impossible to switch off the feature with
+  --disable-hsts. Fix this by renaming our variable.
+  
+  Reported-by: Michał Antoniak
+  Fixes #7669
+  Closes #7672
 
-- [Josh Soref brought this change]
+Jay Satiro (5 Sep 2021)
+- config.d: note that curlrc is used even when --config
+  
+  Bug: https://github.com/curl/curl/pull/7666#issuecomment-912214751
+  Reported-by: Viktor Szakats
+  
+  Closes https://github.com/curl/curl/pull/7667
 
-  docs/cmdline: fix grammar and typos
+Daniel Stenberg (4 Sep 2021)
+- RELEASE-NOTES: synced
 
-- [Josh Soref brought this change]
+- test1173: check references to libcurl options
+  
+  ... that they refer to actual existing libcurl options.
+  
+  Reviewed-by: Daniel Gustafsson
+  Closes #7656
 
-  dump-header.d: Drop suggestion to use for cookie storage
+- CURLOPT_UNIX_SOCKET_PATH.3: remove nginx reference, add see also
   
-  Since --cookie-jar is the preferred way to store cookies, no longer
-  suggest using --dump-header to do so.
+  Closes #7656
+
+- opt-docs: verify man page sections + order
   
-  Co-authored-by: Daniel Stenberg
+  In every libcurl option man page there are now 8 mandatory sections that
+  must use the right name in the correct order and test 1173 verifies
+  this. Only 14 man pages needed adjustments.
   
-  Closes https://github.com/curl/curl/issues/7414
+  The sections and the order is as follows:
+  
+   - NAME
+   - SYNOPSIS
+   - DESCRIPTION
+   - PROTOCOLS
+   - EXAMPLE
+   - AVAILABILITY
+   - RETURN VALUE
+   - SEE ALSO
+  
+  Reviewed-by: Daniel Gustafsson
+  Closes #7656
 
-- [Josh Soref brought this change]
+- opt-docs: make sure all man pages have examples
+  
+  Extended manpage-syntax.pl (run by test 1173) to check that every man
+  page for a libcurl option has an EXAMPLE section that is more than two
+  lines. Then fixed all errors it found and added examples.
+  
+  Reviewed-by: Daniel Gustafsson
+  Closes #7656
 
-  doc/cmdline: fix grammar and typos
+- get.d: provide more useful examples
   
-  Closes https://github.com/curl/curl/pull/7454
-  Closes https://github.com/curl/curl/pull/7455
-  Closes https://github.com/curl/curl/pull/7456
-  Closes https://github.com/curl/curl/pull/7459
-  Closes https://github.com/curl/curl/pull/7460
-  Closes https://github.com/curl/curl/pull/7461
-  Closes https://github.com/curl/curl/pull/7462
-  Closes https://github.com/curl/curl/pull/7463
+  Closes #7668
+
+- page-header: add GOPHERS, simplify wording in the 1st para
+  
+  Closes #7665
+
+- connect: get local port + ip also when reusing connections
+  
+  Regression. In d6a37c23a3c (7.75.0) we removed the duplicated storage
+  (connection + easy handle), so this info needs be extracted again even
+  for re-used connections.
+  
+  Add test 435 to verify
+  
+  Reported-by: Max Dymond
+  Fixes #7660
+  Closes #7662
 
-Daniel Stenberg (20 Jul 2021)
-- vtls: fix connection reuse checks for issuer cert and case sensitivity
+Marcel Raad (2 Sep 2021)
+- multi: fix compiler warning with `CURL_DISABLE_WAKEUP`
   
-  CVE-2021-22924
+  `use_wakeup` is unused in this case.
   
-  Reported-by: Harry Sintonen
-  Bug: https://curl.se/docs/CVE-2021-22924.html
+  Closes https://github.com/curl/curl/pull/7661
 
-- sectransp: check for client certs by name first, then file
+Daniel Stenberg (1 Sep 2021)
+- tests: adjust the tftpd output to work with hyper mode
   
-  CVE-2021-22926
+  By making them look less like http headers, the hyper mode "tweak"
+  doesn't interfere.
   
-  Bug: https://curl.se/docs/CVE-2021-22926.html
+  Enable test 2002 and 2003 in hyper builds (and 1280 which is unrelated
+  but should be enabled).
   
-  Assisted-by: Daniel Gustafsson
-  Reported-by: Harry Sintonen
+  Closes #7658
 
-- telnet: fix option parser to not send uninitialized contents
-  
-  CVS-2021-22925
-  
-  Reported-by: Red Hat Product Security
-  Bug: https://curl.se/docs/CVE-2021-22925.html
+Daniel Gustafsson (1 Sep 2021)
+- [Gisle Vanem brought this change]
 
-Jay Satiro (20 Jul 2021)
-- connect: fix wrong format specifier in connect error string
+  openssl: annotate SSL3_MT_SUPPLEMENTAL_DATA
   
-  0842175 (not in any release) used the wrong format specifier (long int)
-  for timediff_t. On an OS such as Windows libcurl's timediff_t (usually
-  64-bit) is bigger than long int (32-bit). In 32-bit Windows builds the
-  upper 32-bits of the timediff_t were erroneously then used by the next
-  format specifier. Usually since the timeout isn't larger than 32-bits
-  this would result in null as a pointer to the string with the reason for
-  the connection failing. On other OSes or maybe other compilers it could
-  probably result in garbage values (ie crash on deref).
+  This adds support for the previously unhandled supplemental data which
+  in -v output was printed like:
   
-  Before:
-  Failed to connect to localhost port 12345 after 1201 ms: (nil)
+      TLSv1.2 (IN), TLS header, Unknown (23):
   
-  After:
-  Failed to connect to localhost port 12345 after 1203 ms: Connection refused
+  These will now be printed with proper annotation:
   
-  Closes https://github.com/curl/curl/pull/7449
+      TLSv1.2 (OUT), TLS header, Supplemental data (23):
+  
+  Closes #7652
+  Reviewed-by: Daniel Stenberg 
 
-- winbuild: support alternate nghttp2 static lib name
+Daniel Stenberg (1 Sep 2021)
+- curl.1: provide examples for each option
   
-  - Support both nghttp2.lib and nghttp2_static.lib for static nghttp2.
+  The file format for each option now features a "Example:" header that
+  can provide one or more examples that get rendered appropriately in the
+  output. All options MUST have at least one example or gen.pl complains
+  at build-time.
   
-  nghttp2 briefly changed its static lib name to nghttp2_static, but then
-  made the _static suffix optional.
+  This fix also does a few other minor format and consistency cleanups.
   
-  Ref: https://github.com/nghttp2/nghttp2/pull/1394
-  Ref: https://github.com/nghttp2/nghttp2/pull/1418
-  Ref: https://github.com/nghttp2/nghttp2/issues/1466
+  Closes #7654
+
+- progress: make trspeed avoid floats
   
-  Reported-by: Pierre Yager
+  and compiler warnings for data conversions.
   
-  Fixes https://github.com/curl/curl/issues/7446
-  Closes https://github.com/curl/curl/pull/7447
+  Reported-by: Michał Antoniak
+  Fixes #7645
+  Closes #7653
 
-- [Josh Soref brought this change]
+- test365: verify response with chunked AND Content-Length headers
 
-  docs/cmdline: fix grammar and typos
+- http: ignore content-length if any transfer-encoding is used
   
-  Closes https://github.com/curl/curl/pull/7432
-  Closes https://github.com/curl/curl/pull/7436
-  Closes https://github.com/curl/curl/pull/7438
-  Closes https://github.com/curl/curl/pull/7440
-  Closes https://github.com/curl/curl/pull/7445
+  Fixes #7643
+  Closes #7649
 
-- [Josh Soref brought this change]
+- RELEASE-NOTES: synced
 
-  delegation.d: mention what happens when used multiple times
+- Revert "http2: skip immediate parsing of payload following protocol switch"
   
-  Closes https://github.com/curl/curl/pull/7408
-
-- [Josh Soref brought this change]
-
-  create-file-mode.d: mention what happens when used multiple times
+  This reverts commit 455a63c66f188598275e87d32de2c4e8e26b80cb.
   
-  Closes https://github.com/curl/curl/pull/7407
-
-- [Josh Soref brought this change]
+  Reported-by: Tk Xiong
+  Fixes #7633
+  Closes #7648
 
-  config.d: split comments and option-per line
+- KNOWN_BUGS: HTTP/3 doesn't support client certs
   
-  Closes https://github.com/curl/curl/pull/7405
-
-Daniel Stenberg (19 Jul 2021)
-- misc: copyright year range updates
-
-- mailmap: add Tobias and Timur
+  Closes #7625
 
-Daniel Gustafsson (18 Jul 2021)
-- [Josh Soref brought this change]
+- mailing lists: move from cool.haxx.se to lists.haxx.se
 
-  docs: spell out directories instead of dirs in create-dirs
-  
-  Write out directories rather than using the dirs abbrevation. Also
-  use plural form consistently, even if the code in the end might just
-  create a single directory.
+- http_proxy: only wait for writable socket while sending request
   
-  Closes #7406
-  Reviewed-by: Daniel Stenberg 
-  Reviewed-by: Daniel Gustafsson 
-
-- [Tobias Nyholm brought this change]
-
-  docs: correct spelling errors and a broken link
+  Otherwise it would wait socket writability even after the entire CONNECT
+  request has sent and make curl basically busy-loop while waiting for a
+  response to come back.
   
-  Update grammar and spelling in docs and source code comments.
+  The previous fix attempt in #7484 (c27a70a591a4) was inadequate.
   
-  Closes: #7427
-  Reviewed-by: Daniel Stenberg 
+  Reported-by: zloi-user on github
+  Reported-by: Oleguer Llopart
+  Fixes #7589
+  Closes #7647
 
-Marc Hoersken (18 Jul 2021)
-- CI/cirrus: install impacket from PyPI instead of FreeBSD packages
-  
-  Availability of impacket as FreeBSD package is too flaky.
+- http: disallow >3-digit response codes
   
-  Stick to legacy version of cryptography which still
-  supports OpenSSL version 1.0.2 due to FreeBSD 11.
+  Make the built-in HTTP parser behave similar to hyper and reject any
+  HTTP response using more than 3 digits for the response code.
   
-  Reviewed-by: Daniel Stenberg
+  Updated test 1432 accordingly.
+  Enabled test 1432 in the hyper builds.
   
-  Closes #7418
+  Closes #7641
 
-Daniel Stenberg (18 Jul 2021)
-- [Josh Soref brought this change]
+- [Tatsuhiro Tsujikawa brought this change]
 
-  docs/cmdline: mention what happens when used multiple times
+  ngtcp2: stop buffering crypto data
   
-  For --dns-ipv4-addr, --dns-ipv6-addr and --dns-servers
+  Stop buffering crypto data because libngtcp2 now buffers submitted
+  crypto data.
   
-  Closes #7410
-  Closes #7411
-  Closes #7412
+  Closes #7637
 
-- [Michał Antoniak brought this change]
+- test1280: CRLFify the response to please hyper
+  
+  Closes #7639
 
-  lib: fix compiler warnings with CURL_DISABLE_NETRC
+- tests: enable test 1129 for hyper builds
   
-  warning C4189: 'netrc_user_changed': local variable is initialized but
-  not referenced
+  Closes #7638
+
+- curl: better error message when -O fails to get a good name
   
-  warning C4189: 'netrc_passwd_changed': local variable is initialized but
-  not referenced
+  Due to how this currently works internally, it needs a working initial
+  file name to store contents in, so it may still fail even with -J is
+  used (and thus accepting a name from content-disposition:) if the file
+  name part of the URL isn't "good enough".
   
-  Closes #7423
+  Fixes #7628
+  Closes #7635
 
-- disable-epsv.d: remove duplicate "(FTP)"
+- curl_easy_setopt: tweak the string copy wording
   
-  ... since the tooling adds that to the output based on the "Protocols:"
-  tag.
+  Reported-by: Yaobin Wen
+  Fixes #7632
+  Closes #7634
 
-- [Max Zettlmeißl brought this change]
+- RELEASE-NOTES: synced
 
-  docs: make the documentation for --etag-save match the program behaviour
-  
-  When using curl with the option `--etag-save` I expected it to save the
-  ETag without its surrounding quotes, as stated by the documentation in
-  the repository and by the generated man pages.
+- [Don J Olmstead brought this change]
+
+  cmake: sync CURL_DISABLE options
   
-  My first endeavour was to fix the program, but while investigating the
-  history of the relevant parts, I discovered that curl once saved the
-  ETag without the quotes.  This was undone by Daniel Stenberg in commit
-  `98c94596f5928840177b6bd3c7b0f0dd03a431af`, therefore I decided that in
-  this case the documentation should be adjusted to match the behaviour of
-  curl.
+  Adds the full listing of CURL_DISABLE options to the CMake build. Moves
+  all option code, except for CURL_DISABLE_OPENSSL_AUTO_LOA_CONFIG which
+  resides near OpenSSL configuration, to the same block of code. Also
+  sorts the options here and in the cmake config header.
   
-  The changed save behaviour also made parts of the `--etag-compare`
-  documentation wrong or superfluous, so I adjusted those accordingly.
+  Additionally sorted the CURL-DISABLE listing and fixed the
+  CURL_DISABLE_POP3 option.
   
-  Closes #7429
-
-- [Josh Soref brought this change]
+  Closes #7624
 
-  write-out.d: add missing periods
+Jay Satiro (25 Aug 2021)
+- KNOWN_BUGS: FTPS upload data loss with TLS 1.3
   
-  Closes #7404
-
-- [Josie Huddleston brought this change]
-
-  easy: during upkeep, attach Curl_easy to connections in the cache
+  Bug: https://github.com/curl/curl/issues/6149
+  Reported-by: Bylon2@users.noreply.github.com
   
-  During the protocol-specific parts of connection upkeep, some code
-  assumes that the data->conn pointer already is set correctly.  However,
-  there's currently no guarantee of that in the code.
+  Closes https://github.com/curl/curl/pull/7623
+
+Daniel Stenberg (24 Aug 2021)
+- cmake: avoid poll() on macOS
   
-  This fix temporarily attaches each connection to the Curl_easy object
-  before performing the protocol-specific connection check on it, in a
-  similar manner to the connection checking in extract_if_dead().
+  ... like we do in configure builds. Since poll() on macOS is not
+  reliable enough.
   
-  Fixes #7386
-  Closes #7387
-  Reported-by: Josie Huddleston
+  Reported-by: marc-groundctl
+  Fixes #7595
+  Closes #7619
 
-- [Josh Soref brought this change]
+- c-hyper: handle HTTP/1.1 => HTTP/1.0 downgrade on reused connection
+  
+  Enable test 1074
+  
+  Closes #7617
 
-  cleanup: spell DoH with a lowercase o
+- c-hyper: deal with Expect: 100-continue combined with POSTFIELDS
   
-  Signed-off-by: Josh Soref 
+  Enable test 1130 and 1131
   
-  Closes #7413
+  Closes #7616
 
-- [Josh Soref brought this change]
+- [a1346054 brought this change]
 
-  TheArtOfHttpScripting: polish
-  
-  - add missing backticks and comma
-  
-  - fix proxy description:
+  tests: be explicit about using 'python3' instead of 'python'
   
-  * example proxy isn't local
-  * locally doesn't really make sense
+  This fixes running tests in virtualenvs (or on distros) that no longer
+  have a symlink from python to python2 or python3.
   
-  Closes #7416
+  Closes #7602
 
-- [Josh Soref brought this change]
+- [a1346054 brought this change]
 
-  form.d: add examples of `,`/`;` for file[name]
+  scripts: invoke interpreters through /usr/bin/env
   
-  Fixes #7415
-  Closes #7417
+  Closes #7602
 
-- [Michał Antoniak brought this change]
+- DISABLED: enable 11 more tests for hyper builds
+  
+  Closes #7612
 
-  mbedtls: Remove unnecessary include
+- setopt: enable CURLOPT_IGNORE_CONTENT_LENGTH for hyper
   
-  - curl_setup.h: all references to mbedtls_md4* functions and structures
-    are in the md4.c. This file already includes the  file
-    along with the file existence control (defined (MBEDTLS_MD4_C))
+  Since this option is also used for FTP, it needs to work to set for
+  applications even if hyper doesn't support it for HTTP. Verified by test
+  1137.
   
-  - curl_ntlm_core.c: unnecessary include - repeated below
+  Updated docs to specify that the option doesn't work for HTTP when using
+  the hyper backend.
   
-  Closes #7419
-
-- RELEASE-NOTES: synced
+  Closes #7614
 
-Jay Satiro (16 Jul 2021)
-- [User Sg brought this change]
+- test1138: remove trailing space to make work with hyper
+  
+  Closes #7613
 
-  multi: fix crash in curl_multi_wait / curl_multi_poll
+- libcurl-errors.3: clarify two CURLUcode errors
   
-  Appears to have been caused by 51c0ebc (precedes 7.77.0) which added a
-  VALID_SOCK check to one of the loops through the sockets but not the
-  other.
+  CURLUE_BAD_HANDLE and CURLUE_BAD_PARTPOINTER should be for "bad" or
+  wrong pointers in a generic sense, not just for NULL pointers.
   
-  Reported-by: sylgal@users.noreply.github.com
-  Authored-by: sylgal@users.noreply.github.com
+  Reviewed-by: Jay Satiro
   
-  Fixes https://github.com/curl/curl/issues/7379
-  Closes https://github.com/curl/curl/pull/7389
-
-- [Daniel Gustafsson brought this change]
+  Ref: #7605
+  Closes #7611
 
-  tool_help: remove unused define
+Jay Satiro (23 Aug 2021)
+- symbols-in-versions: fix CURLSSLBACKEND_QSOSSL last used version
   
-  The PRINT_LINES_PAUSE macro is no longer used, and has been mostly
-  cleaned out but one occurrence remained.
+  ... and also change the 'Removed' column name to 'Last' since that
+  column is for the last version to contain the symbol.
   
-  Closes https://github.com/curl/curl/pull/7380
-
-- [Sergey Markelov brought this change]
+  Closes https://github.com/curl/curl/pull/7609
 
-  build: fix compiler warnings when CURL_DISABLE_VERBOSE_STRINGS
+Daniel Stenberg (23 Aug 2021)
+- urlapi.c:seturl: assert URL instead of using if-check
   
-  fix compiler warnings about unused variables and parameters when
-  built with --disable-verbose.
+  There's no code flow possible where this can happen. The assert makes
+  sure it also won't be introduced undetected in the future.
   
-  Closes https://github.com/curl/curl/pull/7377
-
-- [Andrea Pappacoda brought this change]
+  Closes #7610
 
-  build: fix IoctlSocket FIONBIO check
+- curl-openssl.m4: show correct output for OpenSSL v3
   
-  Prior to this change HAVE_IOCTLSOCKET_CAMEL_FIONBIO mistakenly checked
-  for (lowercase) ioctlsocket when it should have checked for IoctlSocket.
+  Using 3.0.0 versions configure should now show this:
   
-  Closes https://github.com/curl/curl/pull/7375
-
-- [Timur Artikov brought this change]
-
-  configure: fix nghttp2 library name for static builds
+  checking for OpenSSL headers version... 3.0.0 - 0x300
+  checking for OpenSSL library version... 3.0.0
+  checking for OpenSSL headers and library versions matching... yes
   
-  Don't hardcode the nghttp2 library name,
-  because it can vary, be "nghttp2_static" for example.
+  This output doesn't actually change what configure generates but is only
+  "cosmetic".
   
-  Fixes https://github.com/curl/curl/issues/7367
-  Closes https://github.com/curl/curl/pull/7368
-
-Gisle Vanem (16 Jul 2021)
-- [PellesC] fix _lseeki64() macro
+  Reported-by: Randall S. Becker
+  Fixes #7606
+  Closes #7608
 
-- [SChannel] Use '_tcsncmp()' instead
-  
-  Revert previous change for PellesC.
+Jay Satiro (22 Aug 2021)
+- mksymbolsmanpage.pl: Fix showing symbol's last used version
   
-  Instead replace all use of `_tcsnccmp()` with `_tcsncmp()`.
-
-- [PellesC] missing '_tcsnccmp'
+  Prior to this change the symbol's deprecated version was erroneously
+  shown as its last used version.
   
-  PellesC compiler does not have this macro in it's ``
+  Bug: https://github.com/curl/curl/commit/4e53b94#commitcomment-55239509
+  Reported-by: i-ky@users.noreply.github.com
 
-Daniel Gustafsson (14 Jul 2021)
-- TODO: add mention of mbedTLS 3 incompatibilities
+Daniel Stenberg (21 Aug 2021)
+- mksymbolsmanpage.pl: match symbols case insenitively
   
-  Wyatt OʼDay reported in #7385 that mbedTLS isn't backwards compatible
-  and curl no longer builds with it. Document the need to fix our support
-  until so has been done.
+  Follow-up to 4e53b9430c750 which made this bug show.
   
-  Closes #7390
-  Fixes #7385
-  Reported-by: Wyatt OʼDay
-  Reviewed-by: Jay Satiro 
+  Reported-by: i-ky
+  Bug: https://github.com/curl/curl/commit/4e53b9430c7504de8984796e2a2091ec16f27136#commitcomment-55239253
+  Closes #7607
 
-- docs: fix inconsistencies in EGDSOCKET documentation
+- asyn-ares: call ares_freeaddrinfo() to clean up addrinfo results
   
-  Only the OpenSSL backend actually use the EGDSOCKET, and also use
-  TLS consistently rather than mixing SSL and TLS. While there, also
-  fix a minor spelling nit.
+  As this leaks memory otherwise
   
-  Closes: #7391
-  Reviewed-by: Jay Satiro 
+  Follow-up to ba904db0705c931
+  
+  Closes #7599
 
-- [Борис Верховский brought this change]
+- [Ehren Bendler brought this change]
 
-  docs: document missing arguments to commands
+  wolfssl: clean up wolfcrypt error queue
   
-  This is a followup to commit f410b9e538129e77607fef1 fixing a few
-  more commands which takes arguments.
+  If wolfSSL is built in certain ways (OPENSSL_EXTRA or Debug), the error
+  queue gets added on to for each session and never freed. Fix it by
+  calling ERR_clear_error() like in vtls/openssl when needed. This func is
+  a no-op in wolfcrypt if the error queue is not enabled.
   
-  Closes #7382
-  Reviewed-by: Daniel Gustafsson 
-
-- [Randolf J brought this change]
+  Closes #7594
 
-  docs: fix incorrect argument name reference
+- man pages: remove trailing whitespaces
   
-  The documentation for the read callback was erroneously referencing
-  the nitems argument by nmemb.  The error was introduced in commit
-  ce0881edee3c7.
+  Extended test 1173 (via the manpage-syntax.pl script) to detect and warn
+  for them.
   
-  Closes #7383
-  Reviewed-by: Daniel Gustafsson 
-
-- [Борис Верховский brought this change]
+  Ref: #7602
+  Reported-by: a1346054 on github
+  Closes #7604
 
-  tool_help: Document that --tlspassword takes a password
-  
-  Closes #7378
-  Reviewed-by: Daniel Stenberg 
+- mailmap: add Gleb Ivanovsky
 
-- scripts: Fix typo in release-notes instructions
+- config.d: escape the backslash properly
   
-  The command to run had a typo in the pathname which prevented copy
-  pasting it to work, which has annoyed me enough to fix this now.
+  Closes #7603
 
-- RELEASE-NOTES: synced
+- [Don J Olmstead brought this change]
 
-Jay Satiro (10 Jul 2021)
-- write-out.d: Clarify urlnum is not unique for de-globbed URLs
+  curl_setup.h: sync values for HTTP_ONLY
   
-  Reported-by: Коваленко Анатолий Викторович
+  The values for HTTP_ONLY differed between CMakeLists.txt and
+  curl_setup.h. Sync them and sort the values in curl_setup.h to make it
+  easier to spot differences.
   
-  Fixes https://github.com/curl/curl/issues/7342
-  Closes https://github.com/curl/curl/pull/7369
-
-Daniel Gustafsson (3 Jul 2021)
-- [William Desportes brought this change]
+  Closes #7601
 
-  docs: Fix typos
+Jay Satiro (21 Aug 2021)
+- configure: set classic mingw minimum OS version to XP
   
-  Closes: #7370
-  Reviewed-by: Daniel Gustafsson 
-
-Daniel Stenberg (8 Jul 2021)
-- [Jonathan Wernberg brought this change]
-
-  Revert "ftp: Expression 'ftpc->wait_data_conn' is always false"
+  - If the user has not specified a minimum OS version (via WINVER or
+    _WIN32_WINNT macros) then set it to Windows XP.
   
-  The reverted commit introduced a logic error in code that was
-  correct.
+  Prior to this change classic MinGW defaulted the minimum OS version
+  to Windows NT 4.0 which is way too old. At least Windows XP is needed
+  for getaddrinfo (which resolves hostnames to IPv6 addresses).
   
-  The client using libcurl would notice the error since FTP file
-  uploads in active transfer mode would somtimes complete with
-  success despite no transfer having been performed and the
-  "uploaded" file thus not being on the remote server afterwards.
+  Ref: https://github.com/curl/curl/issues/7483#issuecomment-891597034
   
-  The FTP server would notice the error because it receives a
-  RST on the data connection it has established with the client
-  before any data was transferred at all.
+  Closes https://github.com/curl/curl/pull/7581
+
+- schannel: Work around typo in classic mingw macro
   
-  The logic error happens if the STOR response from the server have
-  arrived by the time ftp_multi_statemach() in the affected code path
-  is called, but the incoming data connection have not arrived yet.
-  In that case, the processing of the STOR response will cause
-  'ftpc->wait_data_conn' to be set to TRUE, contradicting the comment
-  in the code. Since 'complete' will also be set, later logic would
-  believe the transfer was done.
+  - Define ALG_CLASS_DHASH (the typo from the include) to ALG_CLASS_HASH.
   
-  In most cases, the STOR response will not have arrived yet when
-  the affected code path is executed, or the incoming connection will
-  also have arrived, and thus the error would not express itself.
-  But if the speed difference of the device using libcurl and the
-  FTP server is exactly right, the error may happen as often as in
-  one out of hundred file transfers.
+  Prior to this change there was an incomplete fix to ignore the
+  CALG_TLS1PRF macro on those versions of MinGW where it uses the
+  ALG_CLASS_DHASH typoed macro.
+  
+  Ref: 48cf45c
+  Ref: https://osdn.net/projects/mingw/ticket/38391
+  Ref: https://github.com/curl/curl/issues/2924
   
-  This reverts commit 49f3117a238b6eac0e22a32f50699a9eddcb66ab.
+  Closes https://github.com/curl/curl/pull/7580
+
+Daniel Stenberg (20 Aug 2021)
+- RELEASE-NOTES: synced
+
+- http_proxy: fix user-agent and custom headers for CONNECT with hyper
   
-  Bug: https://curl.se/mail/lib-2021-07/0025.html
-  Closes #7362
+  Enable test 287
+  
+  Closes #7598
 
-- msnprintf: return number of printed characters excluding null byte
+- c-hyper: initial support for "dumping" 1xx HTTP responses
   
-  ... even when the output is "capped" by the maximum length argument.
+  With the use hyper_request_on_informational()
   
-  Clarified in the docs.
+  Enable test 155 and 158
   
-  Closes #7361
+  Closes #7597
 
-- infof: remove newline from format strings, always append it
-  
-  - the data needs to be "line-based" anyway since it's also passed to the
-    debug callback/application
+Marc Hoersken (18 Aug 2021)
+- tests/*server.pl: flush output before executing subprocess
   
-  - it makes infof() work like failf() and consistency is good
+  Also avoid shell processes staying around by using exec.
+  This is necessary to avoid output data being buffering
+  inside the process chain of Perl, Bash/Shell and our
+  test server binaries. On non-Windows systems the exec
+  will also make the subprocess replace the intermediate
+  shell, but on Windows it will at least bind the processes
+  together since there is no real fork or exec available.
   
-  - there's an assert that triggers on newlines in the format string
+  See: https://cygwin.com/cygwin-ug-net/highlights.html
+  and: https://docs.microsoft.com/cpp/c-runtime-library/exec-wexec-functions
+  Ref: https://github.com/curl/curl/pull/7530#issuecomment-900949010
   
-  - Also removes a few instances of "..."
+  Reviewed-by: Daniel Stenberg
+  Reviewed-by: Jay Satiro
+  Closes #7530
+
+- CI: use GitHub Container Registry instead of Docker Hub
   
-  - Removes the code that would append "..." to the end of the data *iff*
-    it was truncated in infof()
+  Avoid limits on Docker Hub and improve image pull/download speed.
   
-  Closes #7357
+  Closes #7587
 
-- examples/multi-single: fix scan-build warning
+Daniel Stenberg (18 Aug 2021)
+- openssl: when creating a new context, there cannot be an old one
   
-  warning: Value stored to 'mc' during its initialization is never read
+  Remove the previous handling that would call SSL_CTX_free(), and instead
+  add an assert that halts a debug build if there ever is a context
+  already set at this point.
   
-  Follow-up to ae8e11ed5fd2ce
+  Closes #7585
+
+Jay Satiro (18 Aug 2021)
+- KNOWN_BUGS: Renegotiate from server may cause hang for OpenSSL backend
   
-  Closes #7360
+  Closes https://github.com/curl/curl/issues/6785
 
-- wolfssl: failing to set a session id is not reason to error out
+Viktor Szakats (17 Aug 2021)
+- docs/BINDINGS: URL update
+
+Marc Hoersken (17 Aug 2021)
+- tests/server/*.c: align handling of portfile argument and file
   
-  ... as it is *probably* just timed out.
+  1. Call the internal variable portname (like pidname) everywhere.
+  2. Have a variable wroteportfile (like wrotepidfile) everywhere.
+  3. Make sure the file is cleaned up on exit (like pidfile).
+  4. Add parameter --portfile to usage outputs everywhere.
   
-  Reported-by: Francisco Munoz
+  Reviewed-by: Daniel Stenberg
   
-  Closes #7358
+  Replaces #7523
+  Closes #7574
 
-- docs/examples: use curl_multi_poll() in multi examples
-  
-  The API is soon two years old and deserves being shown as the primary
-  way to drive multi code as it makes it much easier to write code.
+Daniel Gustafsson (17 Aug 2021)
+- KNOWN_BUGS: Fix a number of typos in KNOWN_BUGS
   
-  multi-poll: removed
+  Fixes a set of typos found in section 11.3.
+
+Daniel Stenberg (17 Aug 2021)
+- getparameter: fix the --local-port number parser
   
-  multi-legacy: add to show how we did multi API use before
-  curl_multi_wait/poll.
+  It could previously get tricked into parsing the uninitialized stack
+  based buffer.
   
-  Closes #7352
+  Reported-by: Brian Carpenter
+  Closes #7582
 
-- KNOWN_BUGS: flaky Windows CI builds
+- KNOWN_BUGS: Can't use Secure Transport with Crypto Token Kit
   
-  Closes #6972
+  Closes #7048
 
-- RELEASE-NOTES: synced
+- [Jan Verbeek brought this change]
 
-- test1147: hyper doesn't allow "crazy" request headers like built-in
+  curl: add warning for ignored data after quoted form parameter
   
-  ... so strip that from the test.
+  In an argument like `-F 'x=@/etc/hostname;filename="foo"abc'` the `abc`
+  is ignored. This adds a warning if the ignored data isn't all
+  whitespace.
   
-  Closes #7349
+  Closes #7394
 
-- c-hyper: bail on too long response headers
+Jay Satiro (17 Aug 2021)
+- codeql: fix error "Resource not accessible by integration"
   
-  To match with built-in behaviors. Makes test 1154 work.
+  - Enable codeql writing security-events.
   
-  Closes #7350
-
-- test1151: added missing CRLF to work with hyper
+  GitHub set the default permissions to read, apparently since earlier
+  this year.
   
-  Closes #7350
-
-- c-hyper: add support for transfer-encoding in the request
+  Ref: https://github.com/github/codeql-action/issues/464
+  Ref: https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/
   
-  Closes #7348
-
-- [Andrea Pappacoda brought this change]
+  Fixes https://github.com/curl/curl/issues/7575
+  Closes https://github.com/curl/curl/pull/7576
 
-  cmake: remove libssh2 feature checks
+- tool_operate: Fix --fail-early with parallel transfers
   
-  libssh2 features are detected based on version since commit
-  9dbbba997608f7c3c5de1c627c77c8cd2aa85b73
+  - Abort via progress callback to fail early during parallel transfers.
   
-  Closes #7343
+  When a critical error occurs during a transfer (eg --fail-early
+  constraint) then other running transfers will be aborted via progress
+  callback and finish with error CURLE_ABORTED_BY_CALLBACK (42). In this
+  case, the callback error does not become the most recent error and a
+  custom error message is used for those transfers:
+  
+  curld --fail --fail-early --parallel
+  https://httpbin.org/status/404 https://httpbin.org/delay/10
+  
+  curl: (22) The requested URL returned error: 404
+  curl: (42) Transfer aborted due to critical error in another transfer
+  
+  > echo %ERRORLEVEL%
+  22
+  
+  Fixes https://github.com/curl/curl/issues/6939
+  Closes https://github.com/curl/curl/pull/6984
 
-- test1116: hyper doesn't pass through "surprise-trailers"
+Daniel Stenberg (17 Aug 2021)
+- [Sergey Markelov brought this change]
+
+  sectransp: support CURLINFO_CERTINFO
   
-  Closes #7344
+  Fixes #4130
+  Closes #7372
 
-- socks4: scan for the IPv4 address in resolve results
+- ngtcp2: remove the acked_crypto_offset struct field init
   
-  Follow-up to 84d2839740 which changed the resolving to always resolve
-  both address families, but since SOCKS4 only supports IPv4 it should
-  scan for and use the first available IPv4 address.
+  ... as it is gone from the API upstream.
   
-  Reported-by: shithappens2016 on github
-  Fixes #7345
-  Closes #7346
+  Closes #7578
 
-Jay Satiro (5 Jul 2021)
-- proto.d: fix formatting for paragraphs after margin changes
+- misc: update incorrect copyright year ranges
   
-  Closes https://github.com/curl/curl/pull/7341
+  Closes #7577
 
-- pinnedpubkey.d: fix formatting for version support lists
+- KNOWN_BUGS: HTTP/3 quiche upload large file fails
   
-  Closes https://github.com/curl/curl/pull/7340
+  Closes #7532
 
-Daniel Stenberg (2 Jul 2021)
-- TODO: "Support in-memory certs/ca certs/keys" done
+- KNOWN_BUGS: CMake build with MIT Kerberos does not work
   
-  Has been suppored for a while now with the *BLOB options.
+  Closes #6904
 
-- examples: safer and more proper read callback logic
+- TODO: add asynch getaddrinfo support
   
-  The same callback code is used in:
+  Closes #6746
+
+- RELEASE-NOTES: synced
+
+- [Artur Sinila brought this change]
+
+  http2: revert call the handle-closed function correctly on closed stream
   
-   imap-append.c
-   smtp-authzid.c
-   smtp-mail.c
-   smtp-multi.c
-   smtp-ssl.c
-   smtp-tls.c
+  Reverts 252790c5335a221
   
-  It should not assume that it can copy full lines into the buffer as it
-  will encourage sloppy coding practices. Instead use byte-wise logic and
-  check/acknowledge the buffer size appropriately.
+  Assisted-by: Gergely Nagy
+  Fixes #7400
+  Closes #7525
+
+- [Patrick Monnerat brought this change]
+
+  auth: do not append zero-terminator to authorisation id in kerberos
   
-  Reported-by: Harry Sintonen
-  Fixes #7330
-  Closes #7331
+  RFC4752 Section 3.1 states "The authorization identity is not terminated
+  with a zero-valued (%x00) octet". Although a comment in code said it may
+  be needed anyway, nothing confirms it. In addition, servers may consider
+  it as part of the identity, causing a failure.
+  
+  Closes #7008
 
-- test1519: adjusted to work with hyper
+- [Patrick Monnerat brought this change]
+
+  auth: use sasl authzid option in kerberos
   
-  Closes #7333
+  ... instead of deriving it from active ticket.
+  Closes #7008
 
-- test1518: adjusted to work with hyper
+- [Patrick Monnerat brought this change]
+
+  auth: we do not support a security layer after kerberos authentication
   
-  ... by making sure the stdout output doesn't look like HTTP headers.
+  Closes #7008
+
+- [Patrick Monnerat brought this change]
+
+  auth: properly handle byte order in kerberos security message
   
-  Closes #7333
+  Closes #7008
 
-- test1514: add a CRLF to the response to make it correct
+- [z2_ brought this change]
+
+  x509asn1: fix heap over-read when parsing x509 certificates
   
-  Makes hyper accept it fine instead returning HYPERE_UNEXPECTED_EOF on
-  us.
+  Assisted-by: Patrick Monnerat
+  Closes #7536
+
+- KNOWN_BUGS: Disconnects don't do verbose
   
-  Closes #7334
+  Closes #6995
+
+- mailmap: fixup Michał Antoniak
+
+- [Michał Antoniak brought this change]
 
-- formdata: avoid "Argument cannot be negative" warning
+  build: fix compiler warnings
   
-  ... when converting a curl_off_t to size_t, by using
-  CURL_ZERO_TERMINATED before passing the argument to the function.
+  For when CURL_DISABLE_VERBOSE_STRINGS and DEBUGBUILD flags are both
+  active.
   
-  Detected by Coverity CID 1486590.
+  - socks.c : warning C4100: 'lineno': unreferenced formal parameter
+    (co-authored by Daniel Stenberg)
   
-  Closes #7328
-  Assisted-by: Daniel Gustafsson
-
-- lib: more %u for port and int for %*s fixes
+  - mbedtls.c: warning C4189: 'port': local variable is initialized but
+    not referenced
   
-  Detected by Coverity
+  - schannel.c: warning C4189: 'hostname': local variable is initialized
+    but not referenced
   
-  Closes #7329
+  Cloes #7528
 
-- doh: (void)-prefix call to curl_easy_setopt
+- [Gleb Ivanovsky brought this change]
 
-- lib: fix type of len passed to *printf's %*s
+  CODE_STYLE-md: fix bold font style
   
-  ... it needs to be 'int'. Detected by Coverity CID 1486611 (etc)
+  Markdown gets confused with abundance of asterisks, so use underscores
+  instead.
   
-  Closes #7326
+  Reviewed-by: Daniel Gustafsson
+  Closes #7569
 
-- lib: use %u instead of %ld for port number printf
-  
-  Follow-up to 764c6bd3bf which changed the type of some port number
-  fields. Detected by Coverity (CID 1486624) etc.
-  
-  Closes #7325
+- [Gleb Ivanovsky brought this change]
 
-- version: turn version number functions into returning void
-  
-  ... as we never use the return codes from them.
+  CODE_STYLE-md: add missing comma
   
   Reviewed-by: Daniel Gustafsson
-  Closes #7319
+  Closes #7570
 
-- mqtt: extend the error message for no topic
-  
-  ... and mention that it needs URL encoding.
-  
-  Reported-by: Peter Körner
-  Fixes #7316
-  Closes #7317
+- [Daniel Gustafsson brought this change]
 
-- formdata: correct typecast in curl_mime_data call
-  
-  Coverity pointed out it the mismatch. CID 1486590
+  examples/ephiperfifo.c: simplify signal handler
   
-  Closes #7327
-
-- url: (void)-prefix a curl_url_get() call
+  The signal handler registered for SIGINT is only handling SIGINT
+  so there isn't much need for inspecting the signo.  While there,
+  rename the handler to be more specific.
   
-  Coverity (CID 1486645) pointed out a use of curl_url_get() in the
-  parse_proxy function where the return code wasn't checked. A
-  (void)-prefix makes the intention obvious.
+  g_should_exit should really be of sig_atomic_t type, but relying
+  on autoconf in the examples seems like a bad idea so keep that
+  for now.
   
-  Closes #7320
+  Reviewed-by: Daniel Stenberg
+  Closes #7310
 
-- glob: pass an 'int' as len when using printf's %*s
+- c-hyper: initial step for 100-continue support
   
-  Detected by Coverity CID 1486629.
+  Enabled test 154
   
-  Closes #7324
+  Closes #7568
 
-- vtls: use free() not curl_free()
-  
-  curl_free() is provided for users of the API to free returned data,
-  there's no need to use it internally.
-  
-  Closes #7318
+- [Ikko Ashimine brought this change]
 
-- zuul: use the new rustls directory name
-  
-  Follow-up to 6d972c8b1cbb3 which missed updating this directory name.
+  vtls: fix typo in schannel_verify.c
   
-  Also no longer call it crustls in the docs and bump to rusttls-ffi 0.7.1
+  occurence -> occurrence
   
-  Closes #7311
+  Closes #7566
 
-Jay Satiro (29 Jun 2021)
-- http: fix crash in rate-limited upload
-  
-  - Don't set the size of the piece of data to send to the rate limit if
-    that limit is larger than the buffer size that will hold the piece.
-  
-  Prior to this change if CURLOPT_MAX_SEND_SPEED_LARGE
-  (curl tool: --limit-rate) was set then it was possible that a temporary
-  buffer used for uploading could be written to out of bounds. A likely
-  scenario for this would be a non-trivial amount of post data combined
-  with a rate limit larger than CURLOPT_UPLOAD_BUFFERSIZE (default 64k).
-  
-  The bug was introduced in 24e469f which is in releases since 7.76.0.
-  
-  perl -e "print '0' x 200000" > tmp
-  curl --limit-rate 128k -d @tmp httpbin.org/post
+- [Emil Engler brought this change]
+
+  curl_url_get.3: clarify about path and query
   
-  Reported-by: Richard Marion
+  The current man-page lacks some details regarding the obtained path and
+  query.
   
-  Fixes https://github.com/curl/curl/issues/7308
-  Closes https://github.com/curl/curl/pull/7315
+  Closes #7563
 
-Daniel Stenberg (29 Jun 2021)
-- copyright: add boiler-plate headers to CI config files
-  
-  And whitelist .zuul.ignore
+- c-hyper: fix header value passed to debug callback
   
-  Closes #7314
+  Closes #7567
 
-- CI: remove travis details
+Viktor Szakats (12 Aug 2021)
+- cleanup: URL updates
   
-  Rename still used leftovers to "zuul" as that's now the CI using them.
+  - replace broken URL with the one it was most probably pointing to
+    when added (lib/tftp.c)
+  - replace broken URL with archive.org link (lib/curl_ntlm_wb.c)
+  - delete unnecessary protocol designator from archive.org URL
+    (docs/BINDINGS.md)
   
-  Closes #7313
+  Closes #7562
 
-- RELEASE-NOTES: synced
+Daniel Stenberg (12 Aug 2021)
+- [April King brought this change]
 
-- openssl: avoid static variable for seed flag
-  
-  Avoid the race condition risk by instead storing the "seeded" flag in
-  the multi handle. Modern OpenSSL versions handle the seeding itself so
-  doing the seeding once per multi-handle instead of once per process is
-  less of an issue.
+  DEPRECATE.md: linkify curl-library mailing list
   
-  Reported-by: Gerrit Renker
-  Fixes #7296
-  Closes #7306
+  Closes #7561
 
-- configure: inhibit the implicit-fallthrough warning on gcc-12
+- [Barry Pollard brought this change]
+
+  output.d: add method to suppress response bodies
   
-  ... since it no longer acknowledges the comment markup we use for that
-  purpose.
+  Closes #7560
+
+- TODO: remove 'c-ares deviates on http://1346569778'
   
-  Reported-by: Younes El-karama
-  Fixes #7295
-  Closes #7307
+  Fixed since 56a037cc0ad1b2 (7.77.0)
 
-Daniel Gustafsson (28 Jun 2021)
-- [Andrei Rybak brought this change]
+- [Colin O'Dell brought this change]
 
-  misc: fix typos in comments which repeat a word
+  BINDINGS.md: update links to use https where available
   
-  Fix typos in code comments which repeat various words.  In trivial
-  cases, just delete the repeated word.  Reword the affected sentence in
-  "lib/url.c" for it to make sense.
+  Closes #7558
+
+- asyn-ares.c: move all version number checks to the top
   
-  Closes #7303
-  Reviewed-by: Daniel Gustafsson 
+  ... and use #ifdef [feature] in the code as per our guidelines.
 
-Daniel Stenberg (27 Jun 2021)
-- lib677: make it survive torture testing
+- ares: use ares_getaddrinfo()
   
-  Follow-up to a5ab72d5edd7
+  ares_getaddrinfo() is the getaddrinfo() cloned provided by c-ares, introduced
+  in version 1.16.0.
   
-  Closes #7300
+  With older c-ares versions, curl invokes ares_gethostbyname() twice - once for
+  IPv4 and once for IPv6 to resolve both addresses, and then combines the
+  returned results.
+  
+  Reported-by: jjandesmet
+  Fixes #7364
+  Closes #7552
 
-- [Tommy Chiang brought this change]
+- [Tatsuhiro Tsujikawa brought this change]
 
-  docs/BINDINGS: fix outdated links
-  
-  * luacurl page is now not accessible, fix it with wayback machine page
-  * Scheme one seems not providing https now, change it back to http one
+  ngtcp2: utilize crypto API functions to simplify
   
-  Closes #7301
+  Closes #7551
 
-- [Jacob Hoffman-Andrews brought this change]
+- [megatronking brought this change]
 
-  curstls: bump crustls version and use new URL
+  ngtcp2: reset the oustanding send buffer again when drained
   
-  crustls moved to https://github.com/rustls/rustls-ffi. This also bumps
-  the expected version to 0.7.0.
+  Closes #7538
+
+Michael Kaufmann (10 Aug 2021)
+- progress: fix a compile warning on some systems
   
-  Closes #7297
+  lib/progress.c:380:40: warning: conversion to 'long double' from
+  'curl_off_t {aka long long int}' may alter its value [-Wconversion]
+  
+  Closes #7549
 
+Daniel Stenberg (10 Aug 2021)
 - RELEASE-NOTES: synced
 
-- examples: length-limit two sscanf() uses of %s
+- http: consider cookies over localhost to be secure
   
-  Reported-by: Jishan Shaikh
-  Fixes #7293
-  Closes #7294
+  Updated test31.
+  Added test 392 to verify secure cookies used for http://localhost
+  
+  Reviewed-by: Daniel Gustafsson
+  Fixes #6733
+  Closes #7263
 
-- [Richard Whitehouse brought this change]
+- TODO: erase secrets from heap/stack after use
+  
+  Closes #7268
 
-  multi: alter transfer timeout ordering
+Jay Satiro (10 Aug 2021)
+- hostip: Make Curl_ipv6works function independent of getaddrinfo
   
-  - Check whether a connection has succeded before checking whether it's
-    timed out.
+  - Do not assume IPv6 is not working when getaddrinfo is not present.
   
-    This means if we've connected quickly, but subsequently been
-    descheduled, we allow the connection to succeed. Note, if we timeout,
-    but between checking the timeout, and connecting to the server the
-    connection succeeds, we will allow it to go ahead. This is viewed as
-    an acceptable trade off.
+  The check to see if IPv6 actually works is now independent of whether
+  there is any resolver that can potentially resolve a hostname to IPv6.
   
-  - Add additional failf logging around failed connection attempts to
-    propogate the cause up to the caller.
+  Prior to this change if getaddrinfo() was not found at compile time then
+  Curl_ipv6works() would be defined as a macro that returns FALSE.
+  
+  When getaddrinfo is not found then libcurl is built with CURLRES_IPV4
+  defined instead of CURLRES_IPV6, meaning that it cannot do IPv6 lookups
+  in the traditional way. With this commit if libcurl is built with IPv6
+  support (ENABLE_IPV6) but without getaddrinfo (CURLRES_IPV6), and the
+  IPv6 stack is actually working, then it is possible for libcurl to
+  resolve IPv6 addresses by using DoH.
+  
+  Ref: https://github.com/curl/curl/issues/7483#issuecomment-890765378
   
-  Co-Authored-by: Martin Howarth
-  Closes #7178
+  Closes https://github.com/curl/curl/pull/7529
 
-- test677: IMAP CONNECT_ONLY, custom command and then exit
+- test1565: fix windows build errors
   
-  Adjusted ftpserver.pl to add support for the IMAP IDLE command
+  - Use our wait_ms() instead of sleep() since Windows doesn't have the
+    latter.
   
-  Adjusted test 660 to sync with the fix
-
-- multi: do not switch off connect_only flag when closing
+  - Use a separate variable to keep track of whether the pthread_t thread
+    id is valid.
   
-  ... as it made protocol specific disconnect commands wrongly get used.
+  On Windows pthread_t is not an integer type. pthread offers no macro for
+  invalid pthread_t thread id, so validity is kept track of separately.
   
-  Bug: https://curl.se/mail/lib-2021-06/0024.html
-  Reported-by: Aleksander Mazur
-  Closes #7288
+  Closes https://github.com/curl/curl/pull/7527
 
-- http: make the haproxy support work with unix domain sockets
+- [Jeremy Falcon brought this change]
+
+  winbuild/README.md: clarify GEN_PDB option
   
-  ... it should then pass on "PROXY UNKNOWN" since it doesn't know the
-  involved IP addresses.
+  - Document that GEN_PDB option creates an external database.
   
-  Reported-by: Valentín Gutiérrez
-  Fixes #7290
-  Closes #7291
+  Ref: https://github.com/curl/curl/issues/7502
 
-- [Xiang Xiao brought this change]
+Daniel Stenberg (9 Aug 2021)
+- [Tatsuhiro Tsujikawa brought this change]
 
-  curl.h: include sys/select.h for NuttX RTOS
+  ngtcp2: replace deprecated functions with nghttp3_conn_shutdown_stream_read
   
-  Closes #7287
+  Closes #7546
 
-- [Bin Meng brought this change]
+- [Tatsuhiro Tsujikawa brought this change]
 
-  curl.h: remove the execution bit
-  
-  The execution bit of curl.h file was wrongly added:
-  
-    commit 2621025d6f96 ("curl.h:  is supported by VxWorks7")
+  ngtcp2: rework the return value handling of ngtcp2_conn_writev_stream
   
-  and should be removed.
+  Rework the return value handling of ngtcp2_conn_writev_stream and treat
+  NGTCP2_ERR_STREAM_SHUT_WR separately.
   
-  Follow-up to 2621025d6f96 ("curl.h:  is supported by VxWorks7")
-  Signed-off-by: Bin Meng 
-  Closes #7286
-
-- [Bin Lan brought this change]
+  Closes #7546
 
-  curl.h:  is supported by VxWorks7
+- configure: error out if both ngtcp2 and quiche are specified
   
-  Closes #7285
+  Reported-by: Vincent Grande
+  See #7539
+  Closes #7545
 
-- [Bachue Zhou brought this change]
+- [Jeff Mears brought this change]
 
-  quiche: use send() instead of sendto() to avoid macOS issue
+  easy: use a custom implementation of wcsdup on Windows
   
-  sendto() always returns "Socket is already connected" error on macos
+  ... so that malloc/free overrides from curl_global_init are used for
+  wcsdup correctly.
   
-  Closes #7260
-
-- [Li Xinwei brought this change]
+  Closes #7540
 
-  cmake: fix support for UnixSockets feature on Win32
-  
-  Move the definition of sockaddr_un struct from config-win32.h to
-  curl_setup.h, so that it could be shared by all build systems.
-  
-  Add ADDRESS_FAMILY typedef for old mingw, now old mingw can also use
-  unix sockets.
-  
-  Also fix the build of tests/server/sws.c on Win32 when USE_UNIX_SOCKETS
-  is defined.
+- zuul: add an mbedtls3 CI job
   
-  Closes #7034
+  Closes #7544
 
-- [Gregory Muchka brought this change]
+- [Benau brought this change]
 
-  hostip: (macOS) free returned memory of SCDynamicStoreCopyProxies
-  
-  From Apples documentation on SCDynamicStoreCopyProxies, "Return Value: A
-  dictionary of key-value pairs that represent the current internet proxy
-  settings, or NULL if no proxy settings have been defined or if an error
-  occurred. You must release the returned value."
-  
-  Failure to release the returned value of SCDynamicStoreCopyProxies can
-  result in a memory leak.
-  
-  Source: https://developer.apple.com/documentation/systemconfiguration/1517088-scdynamicstorecopyproxies
+  mbedTLS: initial 3.0.0 support
   
-  Closes #7265
+  Closes #7428
 
 - RELEASE-NOTES: synced
 
-Jay Satiro (21 Jun 2021)
-- vtls: fix warning due to function prototype mismatch
-  
-  b09c8ee changed the function prototype. Caught by Visual Studio.
-
-- curl_multibyte: Remove local encoding fallbacks
-  
-  - If the UTF-8 to UTF-16 conversion fails in Windows Unicode builds then
-    no longer fall back to assuming the string is in a local encoding.
+- configure.ac: revert bad nghttp2 library detection improvements
   
-  Background:
+  This reverts commit b4b34db65f9f8, 673753344c5f and 29c7cf79e8b.
   
-  Some functions in Windows Unicode builds must convert UTF-8 to UTF-16 to
-  pass to the Windows CRT API wide-character functions since in Windows
-  UTF-8 is not a valid locale (or at least 99% of the time right now).
+  The logic is now back to assuming that the nghttp2 lib is called nghttp2 and
+  nothing else.
   
-  Prior to this change if the Unicode encoding conversion failed then
-  libcurl would assume, for backwards compatibility with applications that
-  may have written their code for non-Unicode builds, attempt to convert
-  the string from local encoding to UTF-16.
+  Reported-by: Rui Pinheiro
+  Reported-by: Alex Crichton
+  Fixes #7514
+  Closes #7515
+
+- happy-eyeballs-timeout-ms.d: polish the wording
   
-  That type of "best effort" could theoretically cause some type of
-  security or other problem if a string that was locally encoded was also
-  valid UTF-8, and therefore an unexpected UTF-8 to UTF-16 conversion
-  could occur.
+  Reported-by: Josh Soref
+  Fixes #7433
+  Closes #7542
+
+- [modbw brought this change]
+
+  mbedtls_threadlock: fix unused variable warning
   
-  Ref: https://github.com/curl/curl/pull/7246
+  Closes #7393
+
+- [Tatsuhiro Tsujikawa brought this change]
+
+  ngtcp2: compile with the latest ngtcp2 and nghttp3
   
-  Closes https://github.com/curl/curl/pull/7257
+  Closes #7541
 
-Daniel Stenberg (20 Jun 2021)
-- curl_endian: remove the unused Curl_write64_le function
+Marc Hoersken (31 Jul 2021)
+- CI/cirrus: reduce compile time with increased parallism
   
-  The last usage was removed in cca455a36
+  Cirrus CI VMs have 2 CPUs, let's use them also for Windows builds.
   
-  Closes #7280
+  Reviewed-by: Daniel Stenberg
+  Closes #7505
 
-- vtls: only store TIMER_APPCONNECT for non-proxy connect
+Daniel Stenberg (30 Jul 2021)
+- [Bin Lan brought this change]
+
+  tool/tests: fix potential year 2038 issues
   
-  Introducing a 'isproxy' argument to the connect function so that it
-  knows wether to store the time stamp or not.
+  The length of 'long' in a 32-bit system is 32 bits, which cannot be used
+  to save timestamps after 2038. Most operating systems have extended
+  time_t to 64 bits.
   
-  Reported-by: Yongkang Huang
-  Fixes #7274
-  Closes #7274
+  Remove the castings to long.
+  
+  Closes #7466
 
-- gnutls: set the preferred TLS versions in correct order
+- compressed.d: it's a request, not an order
   
-  Regression since 781864bedbc57 (curl 7.77.0)
+  Clarified
   
-  Reported-by: civodul on github
-  Assisted-by: Nikos Mavrogiannopoulos
-  Fixes #7277
-  Closes #7278
+  Reported-by: Dan Jacobson
+  Reviewed-by: Daniel Gustafsson
+  Fixes #7516
+  Closes #7517
 
-- [Gergely Nagy brought this change]
+- [Bernhard M. Wiedemann brought this change]
 
-  configure/cmake: remove checks for unused gethostbyaddr and gethostbyaddr_r
+  tests: make three tests pass until 2037
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
-
-  configure/cmake: remove checks for unused inet_ntoa and inet_ntoa_r
+  after 2038 something in test1915 fails on 32-bit OSes
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
+  Closes #7512
 
-  configure/cmake: remove unused define HAVE_PERROR
+Daniel Gustafsson (30 Jul 2021)
+- connect: remove superfluous conditional
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
-
-  configure: remove unused check for gai_strerror
+  Commit dbd16c3e2 cleaned up the logic for traversing the addrinfos,
+  but the move left a conditional on ai which no longer is needed as
+  the while loop reevaluation will cover it.
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
+  Closes #7511
+  Reviewed-by: Carlo Marcelo Arenas Belón
+  Reviewed-by: Daniel Stenberg 
 
-  configure/cmake: remove unused define HAVE_FREEIFADDRS
+Daniel Stenberg (29 Jul 2021)
+- RELEASE-NOTES: synced
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
+  and bump curlver to 7.79.0 for next release
 
-  configure/cmake: remove unused define HAVE_FORK
+Marc Hoersken (29 Jul 2021)
+- tests/*server.py: remove pidfile on server termination
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
-
-  configure/cmake: remove unused define HAVE_FDOPEN
+  Avoid pidfile leaking/laying around after server already exited.
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
+  Reviewed-by: Daniel Stenberg
+  Closes #7506
 
-  configure/cmake: remove checks for unused sgtty.h
+Daniel Gustafsson (27 Jul 2021)
+- tool_main: fix typo in comment
   
-  Closes #7276
+  The referred to library is NSPR, so fix the switched around characters.
 
-- [Gergely Nagy brought this change]
+Daniel Stenberg (28 Jul 2021)
+- [Aleksandr Krotov brought this change]
 
-  configure/cmake: remove remaining checks for rsa.h
+  bearssl: support CURLOPT_CAINFO_BLOB
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
+  Closes #7468
 
-  configure/cmake: remove remaining checks for err.h
+- curl.1: mention "global" flags
+  
+  Mention options that are "global". A global command line option is one
+  that doesn't get reset at --next uses and therefore don't need to be
+  used again.
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
-
-  configure/cmake: remove remaining checks for crypto.h
+  Reported-by: Josh Soref
   
-  Closes #7276
-
-- [Gergely Nagy brought this change]
+  Fixes #7457
+  Closes #7510
 
-  configure/cmake: remove checks for unused getservbyport_r
+- CURLOPT_DOH_URL.3: CURLOPT_OPENSOCKETFUNCTION is not inherited
   
-  Closes #7276
+  Reported-by: Daniel Woelfel
+  Fixes #7441
+  Closes #7509
 
-- --socks4[a]: clarify where the host name is resolved
+- KNOWN_BUGS: add more HTTP/3 problems
   
-  Closes #7273
+  Closes #7351
+  Closes #7339
+  Closes #7125
 
-- libcurl-security.3: mention file descriptors and forks
+Marc Hoersken (27 Jul 2021)
+- CI/azure: reduce compile time with increased parallism
   
-  ... and move the security report section last.
+  Azure Pipelines CI VMs have 2 CPUs, let's use them.
   
-  Reported-by: Harry Sintonen
-  Closes #7270
+  Closes #7489
 
-- [Alex Xu (Hello71) brought this change]
+Jay Satiro (27 Jul 2021)
+- [Josh Soref brought this change]
 
-  configure.ac: make non-executable
-  
-  it needs to be processed by autoconf or autoreconf, and doesn't have a
-  suitable shebang to be directly executed. other projects normally set
-  configure.ac -x.
+  docs: fix grammar
   
-  Closes #7272
+  Fixes https://github.com/curl/curl/issues/7444
+  Fixes https://github.com/curl/curl/issues/7451
+  Fixes https://github.com/curl/curl/issues/7465
+  Closes https://github.com/curl/curl/pull/7495
 
-- configure: do not strip out debug flags
+- mail-rcpt.d: fix grammar
   
-  To allow users to set them when invoking configure without using
-  --with-debug.
+  Remove confusing sentence that says to specify an e-mail address for
+  mail transfer, since that's implied.
   
-  Reported-by: Alex Xu
-  Fixes #7216
-  Closes #7267
-
-- libssh2: limit time a disconnect can take to 1 second
+  Reported-by: Josh Soref
   
-  Closes #7271
+  Fixes https://github.com/curl/curl/issues/7452
+  Closes https://github.com/curl/curl/pull/7495
 
-- TLS: prevent shutdown loops to get stuck
+Daniel Stenberg (27 Jul 2021)
+- c-hyper: remove the hyper_executor_poll() loop from Curl_http
   
-  ... by making sure the loops are only allowed to read the shutdown
-  traffic a limited number of times.
+  1. it's superfluous
+  2. it didn't work identically to the Curl_hyper_stream one which could
+     cause problems like #7486
   
-  Reported-by: Harry Sintonen
-  Closes #7271
+  Pointed-out-by: David Cook
+  Closes #7499
 
-- hyper: propagate errors back up from read callbacks
+- curl-openssl.m4: check lib64 for the pkg-config file
   
-  Makes test 513 work with hyper
+  OpenSSL recently started putting the libs in $prefix/lib64 on 'make
+  install', so we check that directory for pkg-config data if the 'lib'
+  check fails.
   
-  Closes #7266
+  Closes #7503
 
-- KNOWN_BUGS: Negotiate on Windows fails
+- CURLOPT_SSL_CTX_*.3: tidy up the example
   
-  Closes #5881
-
-- KNOWN_BUGS: renames instead of locking for atomic operations
+  Use the proper code style. Don't store return codes that aren't read.
+  Copy the same example into CURLOPT_SSL_CTX_FUNCTION.3 as well.
   
-  Closes #6882
-  Closes #6884
+  Closes #7500
 
-- zuul: add two missing CI jobs
+- example/cookie_interface: fix scan-build printf warning
   
-  ... that were configured, just not run
+  Follow-up to 4b79c4fb565
   
-  Closes #7261
+  Fixes #7497
+  Closes #7498
 
-Viktor Szakats (15 Jun 2021)
-- idn: fix libidn2 with windows unicode builds
-  
-  Unicode Windows builds use UTF-8 strings internally in libcurl,
-  so make sure to call the UTF-8 flavour of the libidn2 API. Also
-  document that Windows builds with libidn2 and UNICODE do expect
-  CURLOPT_URL as an UTF-8 string.
+- [Josh Soref brought this change]
+
+  limit-rate.d: clarify base unit
   
-  Reported-by: dEajL3kA on github
-  Assisted-by: Jay Satiro
-  Reviewed-by: Marcel Raad
-  Closes #7246
-  Fixes #7228
+  Fixes #7439
+  Closes #7494
 
-Daniel Stenberg (15 Jun 2021)
-- curl_url_set: reject spaces in URLs w/o CURLU_ALLOW_SPACE
+- [Carlo Marcelo Arenas Belón brought this change]
+
+  examples/cookie_interface: avoid printfing time_t directly
   
-  They were never officially allowed and slipped in only due to sloppy
-  parsing. Spaces (ascii 32) should be correctly encoded (to %20) before
-  being part of a URL.
+  time_t representation is undefined and varies on bitsize and signedness,
+  and as of C11 could be even non integer.
   
-  The new flag bit CURLU_ALLOW_SPACE when a full URL is set, makes libcurl
-  allow spaces.
+  instead of casting to unsigned long (which would truncate in systems
+  with a 32bit long after 2106) use difftime to get the elapsed time as a
+  double and print that (without decimals) instead.
   
-  Updated test 1560 to verify.
+  alternatively a cast to curl_off_t and its corresponding print
+  formatting could have been used (at least in POSIX) but portability and
+  curl agnostic code was prioritized.
   
-  Closes #7073
+  Closes #7490
 
-- RELEASE-NOTES: synced
+Marc Hoersken (25 Jul 2021)
+- tests/servers: remove obsolete pid variable
   
-  ... and bump to version 7.78.0 for the next planned release.
+  Variable is not used since pidfile handling moved to util.[ch]
+  
+  Reviewed-by: Jay Satiro
+  Closes #7482
 
-Jay Satiro (15 Jun 2021)
-- docs: Remove outdated curl tool limitation
+- tests/servers: use our platform-aware pid for server verification
   
-  - Document that HTTP/2 multiplexing is supported by the curl tool when
-    parallel transfers are used.
+  The pid used for server verification is later stored as pid2 in
+  the hash of running test servers and therefore used for shutdown.
   
-  Supported since 7.66.0 via --parallel, but the doc wasn't updated.
+  The pid used for shutdown must be the platform-aware (Win32) pid
+  to avoid leaking test servers while running them using Cygwin/msys.
   
-  Closes https://github.com/curl/curl/pull/7259
+  Reviewed-by: Jay Satiro
+  Closes #7481
 
-- http2: Clarify 'Using HTTP2' verbose message
+- tests/runtests.pl: cleanup copy&paste mistakes and unused code
   
-  - Change phrasing from multi-use to multiplexing since the former may
-    not be as well understood.
+  Reviewed-by: Jay Satiro
+  Part of #7481
+
+Daniel Stenberg (25 Jul 2021)
+- RELEASE-NOTES: synced
   
-  Before: * Using HTTP2, server supports multi-use
+  bumped to 7.78.1 for next release
+
+- http_proxy: clear 'sending' when the outgoing request is sent
   
-  After: * Using HTTP2, server supports multiplexing
+  ... so that Curl_connect_getsock() will know how to wait for the socket
+  to become readable and not writable after the entire CONNECT request has
+  been issued.
   
-  Bug: https://github.com/curl/curl/discussions/7255
-  Reported-by: David Hu
+  Regression added in 7.77.0
   
-  Closes https://github.com/curl/curl/pull/7258
+  Reported-by: zloi-user on github
+  Assisted-by: Jay Satiro
+  Fixes #7155
+  Closes #7484
 
-Daniel Stenberg (14 Jun 2021)
-- winbuild/README: VC should be set to 6 'or larger'
-  
-  Previously it listed all versions up to 15 (missing 16) but this new
-  phrasing is more open ended.
-  
-  Reported-by: Hugh Macdonald
-  Fixes #7253
-  Closes #7254
+Jay Satiro (25 Jul 2021)
+- [Josh Soref brought this change]
 
-- [Jacob Hoffman-Andrews brought this change]
+  openssl: fix grammar
+  
+  Closes https://github.com/curl/curl/pull/7480
 
-  rustls: remove native_roots fallback
+- configure.ac: tweak nghttp2 library name fix again
   
-  For the commandline tool, we expect to be passed
-  SSL_CONN_CONFIG(CAfile); for library use, the use should pass a set of
-  trusted roots (like in other TLS backends).
+  - Change extraction to handle multiple library names returned by
+    pkg-config (eg a possible scenario with pkg-config --static).
   
-  This also removes a dependency on Security.framework when building on
-  macOS.
+  Ref: https://github.com/curl/curl/pull/7472
   
-  Closes #7250
-
-- [Albin Vass brought this change]
+  Closes https://github.com/curl/curl/pull/7485
 
-  travis: remove jobs that have migrated to zuul
+Dan Fandrich (23 Jul 2021)
+- Get rid of the unused HAVE_SIG_ATOMIC_T et. al.
   
-  Closes #7245
-
-- [Mohammed Naser brought this change]
+  It was added in 2006 but I see no evidence it was ever used.
 
-  CI: add jobs using Zuul
+Jay Satiro (23 Jul 2021)
+- docs: change max-filesize caveat again
   
-  It also includes a few changes to get the builds going:
-  - Added autoconf to common dependencies
-  - Added automake to common dependencies
-  - Added libtool to common dependencies
-  - Added libssl-dev to common dependencies
+  - Add protocols field to max-filesize.d.
   
-  Co-authored-by: Albin Vass
+  - Revert wording on unknown file size caveat and do not discuss specific
+    protocols in that section.
   
-  Closes #7245
-
-- netrc: skip 'macdef' definitions
+  Partial revert of ecf0225. All max-filesize options now have the list of
+  protocols and it's clearer just to have that list without discussing
+  specific protocols in the caveat.
   
-  Add test 494 to verify
+  Reported-by: Josh Soref
   
-  Reported-by: Harry Sintonen
-  Fixes #7238
-  Closes #7244
+  Ref: https://github.com/curl/curl/issues/7453#issuecomment-884128762
 
-- multi: add scan-build-6 work-around in curl_multi_fdset
+Daniel Stenberg (22 Jul 2021)
+- [Christian Weisgerber brought this change]
+
+  configure: tweak nghttp2 library name fix
   
-  scan-build-6 otherwise warns, saying: warning: The left operand of '>='
-  is a garbage value otherwise, which is false.
+  commit 29c7cf79e8b44cf (shipped in 7.78.0) introduced a problem by
+  assuming that LIB_H2 does not have any leading whitespace.  At least
+  OpenBSD's native pkg-config can produce such whitespace, though:
   
-  Later scan-builds don't claim this on the same code.
+      $ pkg-config --libs-only-l libnghttp2
+       -lnghttp2
+  
+  As a result, the configure check for libnghttp2 will erroneously fail.
   
-  Closes #7248
+  Bug: https://curl.se/mail/lib-2021-07/0050.html
+  Closes #7472
 
-- asyn-ares: remove check for 'data' in Curl_resolver_cancel
+- [Bastian Krause brought this change]
+
+  docs/MQTT: update state of username/password support
   
-  It implied it would survive a NULL in there which it won't. Instead do
-  an assert.
+  PR #7243 implemented username/password support for MQTT, so let's drop
+  these items from the caveats.
   
-  Pointed out by scan-build.
+  Signed-off-by: Bastian Krause 
   
-  Closes #7248
+  Closes #7474
 
-- url.c: remove two variable assigns that are never read
-  
-  Pointed out by scan-build
+- [Oleg Pudeyev brought this change]
+
+  CURLMOPT_TIMERFUNCTION.3: remove misplaced "time"
   
-  Closes #7248
+  Closes #7470
 
-- [Gealber Morales brought this change]
+Version 7.78.0 (21 Jul 2021)
 
-  mqtt: add support for username and password
-  
-  Minor-edits-by: Daniel Stenberg
-  Added test 2200 to 2205
+Daniel Stenberg (21 Jul 2021)
+- RELEASE-NOTES: synced
   
-  Closes #7243
+  curl 7.78.0 release
 
-- travis: remove the arm job
-  
-  We do it on circle CI instead
+- winbuild/MakefileBuild.vc: bump copyright year
 
-- CI: add .circleci/config.yml
+Jay Satiro (21 Jul 2021)
+- docs: mention max-filesize options also apply to MQTT transfers
   
-  Assisted-by: Gabriel Simmer
+  Also make it clearer that the caveat 'if the file size is unknown it
+  the option will have no effect' may apply to protocols other than FTP
+  and HTTP.
   
-  Closes #7239
+  Reported-by: Josh Soref
+  
+  Fixes https://github.com/curl/curl/issues/7453
 
-- RELEASE-NOTES: synced
+- [Josh Soref brought this change]
 
-- runtests: init $VERSION to avoid warnings when using -l
+  docs/cmdline: fix grammar and typos
 
-- openssl: don't remove session id entry in disassociate
+- [Josh Soref brought this change]
+
+  dump-header.d: Drop suggestion to use for cookie storage
   
-  When a connection is disassociated from a transfer, the Session ID entry
-  should remain.
+  Since --cookie-jar is the preferred way to store cookies, no longer
+  suggest using --dump-header to do so.
   
-  Regression since 7f4a9a9 (shipped in libcurl 7.77.0)
-  Reported-by: Gergely Nagy
-  Reported-by: Paul Groke
+  Co-authored-by: Daniel Stenberg
   
-  Fixes #7222
-  Closes #7230
+  Closes https://github.com/curl/curl/issues/7414
 
-- single_transfer: ignore blank --output-dir
-  
-  ... as otherwise it creates a rather unexpected target directory with a
-  leading slash.
-  
-  Reported-by: Harry Sintonen
-  Fixes #7218
-  Closes #7233
+- [Josh Soref brought this change]
 
-- tests: update README about servers and port numbers
+  doc/cmdline: fix grammar and typos
   
-  Closes #7242
+  Closes https://github.com/curl/curl/pull/7454
+  Closes https://github.com/curl/curl/pull/7455
+  Closes https://github.com/curl/curl/pull/7456
+  Closes https://github.com/curl/curl/pull/7459
+  Closes https://github.com/curl/curl/pull/7460
+  Closes https://github.com/curl/curl/pull/7461
+  Closes https://github.com/curl/curl/pull/7462
+  Closes https://github.com/curl/curl/pull/7463
 
-- conn_shutdown: if closed during CONNECT cleanup properly
+Daniel Stenberg (20 Jul 2021)
+- vtls: fix connection reuse checks for issuer cert and case sensitivity
   
-  Reported-by: Alex Xu
-  Reported-by: Phil E. Taylor
+  CVE-2021-22924
   
-  Fixes #7236
-  Closes #7237
-
-- [Christian Weisgerber brought this change]
+  Reported-by: Harry Sintonen
+  Bug: https://curl.se/docs/CVE-2021-22924.html
 
-  sws: malloc request struct instead of using stack
-  
-  ... 2MB requests is otherwise just too big for some systems.
+- sectransp: check for client certs by name first, then file
   
-  (The allocations are not freed properly.)
+  CVE-2021-22926
   
-  Bug: https://curl.se/mail/lib-2021-06/0018.html
+  Bug: https://curl.se/docs/CVE-2021-22926.html
   
-  Closes #7235
-
-- [Mark Swaanenburg brought this change]
+  Assisted-by: Daniel Gustafsson
+  Reported-by: Harry Sintonen
 
-  lib: don't compare fd to FD_SETSIZE when using poll
+- telnet: fix option parser to not send uninitialized contents
   
-  FD_SETSIZE is irrelevant when using poll. So ensuring that the file
-  descriptor is smaller than FD_SETSIZE in VALID_SOCK, can cause
-  multi_wait to ignore perfectly valid file descriptors and simply wait
-  for 1s to avoid hammering the CPU in a busy loop.
+  CVS-2021-22925
   
-  Fixes #7240
-  Closes #7241
-
-- [zhangxiuhua brought this change]
+  Reported-by: Red Hat Product Security
+  Bug: https://curl.se/docs/CVE-2021-22925.html
 
-  doh: fix wrong DEBUGASSERT for doh private_data
+Jay Satiro (20 Jul 2021)
+- connect: fix wrong format specifier in connect error string
   
-  Closes #7227
-
-- [yb999 brought this change]
-
-  tests: update README.md with a missing single quote
+  0842175 (not in any release) used the wrong format specifier (long int)
+  for timediff_t. On an OS such as Windows libcurl's timediff_t (usually
+  64-bit) is bigger than long int (32-bit). In 32-bit Windows builds the
+  upper 32-bits of the timediff_t were erroneously then used by the next
+  format specifier. Usually since the timeout isn't larger than 32-bits
+  this would result in null as a pointer to the string with the reason for
+  the connection failing. On other OSes or maybe other compilers it could
+  probably result in garbage values (ie crash on deref).
   
-  Closes #7231
-
-- GHA: run all tests for hyper too
+  Before:
+  Failed to connect to localhost port 12345 after 1201 ms: (nil)
   
-  As it lists disabled ones in DISABLED now
+  After:
+  Failed to connect to localhost port 12345 after 1203 ms: Connection refused
   
-  Closes #7209
+  Closes https://github.com/curl/curl/pull/7449
 
-- tests/data/DISABLED: add tests not working with hyper
-  
-  The goal is to remove them all from here over time.
+- winbuild: support alternate nghttp2 static lib name
   
-  Closes #7209
-
-- runtests: also find the last test in Makefile.inc
+  - Support both nghttp2.lib and nghttp2_static.lib for static nghttp2.
   
-  Closes #7209
-
-- test3010: work with hyper mode
+  nghttp2 briefly changed its static lib name to nghttp2_static, but then
+  made the _static suffix optional.
   
-  Closes #7209
-
-- configure: disable RTSP when hyper is selected
+  Ref: https://github.com/nghttp2/nghttp2/pull/1394
+  Ref: https://github.com/nghttp2/nghttp2/pull/1418
+  Ref: https://github.com/nghttp2/nghttp2/issues/1466
   
-  Makes test 1013 work
+  Reported-by: Pierre Yager
   
-  Closes #7209
+  Fixes https://github.com/curl/curl/issues/7446
+  Closes https://github.com/curl/curl/pull/7447
 
-- test1594/1595/1596: fix to work in hyper mode
-  
-  Closes #7209
+- [Josh Soref brought this change]
 
-- test1438/1457: add HTTP keyword to make hyper mode work
+  docs/cmdline: fix grammar and typos
   
-  Closes #7209
+  Closes https://github.com/curl/curl/pull/7432
+  Closes https://github.com/curl/curl/pull/7436
+  Closes https://github.com/curl/curl/pull/7438
+  Closes https://github.com/curl/curl/pull/7440
+  Closes https://github.com/curl/curl/pull/7445
 
-- test1340/1341: adjusted for hyper mode
-  
-  Closes #7209
+- [Josh Soref brought this change]
 
-- test1218: adjusted for hyper mode
+  delegation.d: mention what happens when used multiple times
   
-  Closes #7209
+  Closes https://github.com/curl/curl/pull/7408
 
-- test1216: adjusted for hyper mode
-  
-  Closes #7209
+- [Josh Soref brought this change]
 
-- test1230: adjust to work in hyper mode
+  create-file-mode.d: mention what happens when used multiple times
   
-  Closes #7209
+  Closes https://github.com/curl/curl/pull/7407
 
-- c-hyper: abort CONNECT response reading early on non 2xx responses
-  
-  Fixes test 493
-  
-  Closes #7209
+- [Josh Soref brought this change]
 
-- test434: add HTTP keyword
+  config.d: split comments and option-per line
   
-  Closes #7209
+  Closes https://github.com/curl/curl/pull/7405
 
-- test599: adjusted to work in hyper mode
-  
-  Closes #7209
+Daniel Stenberg (19 Jul 2021)
+- misc: copyright year range updates
 
-- c-hyper: fix the uploaded field in progress callbacks
-  
-  Makes test 578 work
-  
-  Closes #7209
+- mailmap: add Tobias and Timur
 
-- test566: adjust to work with hyper mode
+Daniel Gustafsson (18 Jul 2021)
+- [Josh Soref brought this change]
+
+  docs: spell out directories instead of dirs in create-dirs
   
-  Closes #7209
+  Write out directories rather than using the dirs abbrevation. Also
+  use plural form consistently, even if the code in the end might just
+  create a single directory.
+  
+  Closes #7406
+  Reviewed-by: Daniel Stenberg 
+  Reviewed-by: Daniel Gustafsson 
 
-- [Fawad Mirza brought this change]
+- [Tobias Nyholm brought this change]
 
-  CURLOPT_WRITEFUNCTION.3: minor update of the example
+  docs: correct spelling errors and a broken link
   
-  Safely avoid chunk.size garbage value if declared non globally.
+  Update grammar and spelling in docs and source code comments.
   
-  Closes #7219
-
-- [Bastian Krause brought this change]
+  Closes: #7427
+  Reviewed-by: Daniel Stenberg 
 
-  configure: rename get-easy-option configure option to get-easy-options
+Marc Hoersken (18 Jul 2021)
+- CI/cirrus: install impacket from PyPI instead of FreeBSD packages
   
-  "get-easy-options" is the configure option advertised by the help text
-  anyway, so use that.
+  Availability of impacket as FreeBSD package is too flaky.
+  
+  Stick to legacy version of cryptography which still
+  supports OpenSSL version 1.0.2 due to FreeBSD 11.
   
-  Fixes #7211
-  Closes #7213
+  Reviewed-by: Daniel Stenberg
   
-  Follow-up to ad691b191 ("configure: added --disable-get-easy-options")
-  Suggested-by: Daniel Stenberg 
-  Signed-off-by: Bastian Krause 
+  Closes #7418
 
-- runtests: skip disabled tests unless -f is used
-  
-  To make it easier to write ranges like '115 to 229' without that
-  explicitly enabling tests that are listed in DISABLED, this makes
-  runtests always skip disabled tests unless the -f command line option is
-  used.
+Daniel Stenberg (18 Jul 2021)
+- [Josh Soref brought this change]
+
+  docs/cmdline: mention what happens when used multiple times
   
-  Previously the code attempted to not run such tests, but didn't do it
-  correctly.
+  For --dns-ipv4-addr, --dns-ipv6-addr and --dns-servers
   
-  Closes #7212
+  Closes #7410
+  Closes #7411
+  Closes #7412
 
-- [Jun-ya Kato brought this change]
+- [Michał Antoniak brought this change]
 
-  ngtcp2: disable TLSv1.3 compatible mode when using GnuTLS
+  lib: fix compiler warnings with CURL_DISABLE_NETRC
   
-  The latest GnuTLS-3.7.2 implements disable switch for TLSv1.3 compatible
-  mode for middle box but it is enabled by default, which is unnecessary
-  for QUIC.
+  warning C4189: 'netrc_user_changed': local variable is initialized but
+  not referenced
   
-  Fixes #6896
-  Closes #7202
+  warning C4189: 'netrc_passwd_changed': local variable is initialized but
+  not referenced
+  
+  Closes #7423
 
-- test644: remove as duplicate of test 587
+- disable-epsv.d: remove duplicate "(FTP)"
   
-  Closes #7208
+  ... since the tooling adds that to the output based on the "Protocols:"
+  tag.
 
-Daniel Gustafsson (8 Jun 2021)
-- RELEASE-NOTES: synced
+- [Max Zettlmeißl brought this change]
 
-- cookies: track expiration in jar to optimize removals
+  docs: make the documentation for --etag-save match the program behaviour
   
-  Removing expired cookies needs to be a fast operation since we want to
-  be able to perform it often and speculatively. By tracking the timestamp
-  of the next known expiration we can exit early in case the timestamp is
-  in the future.
+  When using curl with the option `--etag-save` I expected it to save the
+  ETag without its surrounding quotes, as stated by the documentation in
+  the repository and by the generated man pages.
   
-  Closes: #7172
-  Reviewed-by: Daniel Stenberg 
-
-Daniel Stenberg (7 Jun 2021)
-- GHA: add several libcurl tests to the hyper job
+  My first endeavour was to fix the program, but while investigating the
+  history of the relevant parts, I discovered that curl once saved the
+  ETag without the quotes.  This was undone by Daniel Stenberg in commit
+  `98c94596f5928840177b6bd3c7b0f0dd03a431af`, therefore I decided that in
+  this case the documentation should be adjusted to match the behaviour of
+  curl.
   
-  500 to 512
+  The changed save behaviour also made parts of the `--etag-compare`
+  documentation wrong or superfluous, so I adjusted those accordingly.
+  
+  Closes #7429
 
-- test500: adjust to work with hyper mode
+- [Josh Soref brought this change]
 
-- c-hyper: support CURLINFO_STARTTRANSFER_TIME
+  write-out.d: add missing periods
   
-  Closes #7204
+  Closes #7404
 
-- c-hyper: support CURLOPT_HEADER
+- [Josie Huddleston brought this change]
+
+  easy: during upkeep, attach Curl_easy to connections in the cache
   
-  When enabled, the headers are passed to the body write callback as well.
+  During the protocol-specific parts of connection upkeep, some code
+  assumes that the data->conn pointer already is set correctly.  However,
+  there's currently no guarantee of that in the code.
   
-  Like in test 500
+  This fix temporarily attaches each connection to the Curl_easy object
+  before performing the protocol-specific connection check on it, in a
+  similar manner to the connection checking in extract_if_dead().
   
-  Closes #7204
+  Fixes #7386
+  Closes #7387
+  Reported-by: Josie Huddleston
 
-- GHA: run the newly fixed tests with hyper
-  
-  Closes #7205
+- [Josh Soref brought this change]
 
-- test433: adjust for hyper mode
+  cleanup: spell DoH with a lowercase o
   
-  Closes #7205
-
-- test395: hyper cannot work around > 64 bit content-lengths like built-in
+  Signed-off-by: Josh Soref 
   
-  Closes #7205
+  Closes #7413
 
-- test394: hyper returns a different error
-  
-  Closes #7205
+- [Josh Soref brought this change]
 
-- test393: make Content-Length fit within 64 bit for hyper
+  TheArtOfHttpScripting: polish
   
-  Closes #7205
-
-- test347: CRLFify to work in hyper mode
+  - add missing backticks and comma
   
-  Closes #7205
-
-- test339: CRLFify better to work in hyper mode
+  - fix proxy description:
   
-  Closes #7205
+  * example proxy isn't local
+  * locally doesn't really make sense
+  
+  Closes #7416
 
-- travis: remove the hyper build
+- [Josh Soref brought this change]
 
-- GHA: add a linux-hyper job
+  form.d: add examples of `,`/`;` for file[name]
   
-  Closes #7206
+  Fixes #7415
+  Closes #7417
 
-- test328: avoid a header-looking body to make hyper mode work
+- [Michał Antoniak brought this change]
+
+  mbedtls: Remove unnecessary include
   
-  The test still works the same, just modified two bytes in the content.
+  - curl_setup.h: all references to mbedtls_md4* functions and structures
+    are in the md4.c. This file already includes the  file
+    along with the file existence control (defined (MBEDTLS_MD4_C))
   
-  Closes #7203
+  - curl_ntlm_core.c: unnecessary include - repeated below
+  
+  Closes #7419
 
-- release-notes.pl: also spot common 'closes' typo
+- RELEASE-NOTES: synced
 
-- metalink: remove
+Jay Satiro (16 Jul 2021)
+- [User Sg brought this change]
+
+  multi: fix crash in curl_multi_wait / curl_multi_poll
   
-  Warning: this will make existing curl command lines that use metalink to
-  stop working.
+  Appears to have been caused by 51c0ebc (precedes 7.77.0) which added a
+  VALID_SOCK check to one of the loops through the sockets but not the
+  other.
   
-  Reasons for removal:
+  Reported-by: sylgal@users.noreply.github.com
+  Authored-by: sylgal@users.noreply.github.com
   
-  1. We've found several security problems and issues involving the
-     metalink support in curl. The issues are not detailed here. When
-     working on those, it become apparent to the team that several of the
-     problems are due to the system design, metalink library API and what
-     the metalink RFC says. They are very hard to fix on the curl side
-     only.
+  Fixes https://github.com/curl/curl/issues/7379
+  Closes https://github.com/curl/curl/pull/7389
+
+- [Daniel Gustafsson brought this change]
+
+  tool_help: remove unused define
   
-  2. The metalink usage with curl was only very briefly documented and was
-     not following the "normal" curl usage pattern in several ways, making
-     it surprising and non-intuitive which could lead to further security
-     issues.
+  The PRINT_LINES_PAUSE macro is no longer used, and has been mostly
+  cleaned out but one occurrence remained.
   
-  3. The metalink library was last updated 6 years ago and wasn't so
-     active the years before that either. An unmaintained library means
-     there's a security problem waiting to happen. This is probably reason
-     enough.
+  Closes https://github.com/curl/curl/pull/7380
+
+- [Sergey Markelov brought this change]
+
+  build: fix compiler warnings when CURL_DISABLE_VERBOSE_STRINGS
   
-  4. Metalink requires an XML parsing library, which is complex code (even
-     the smaller alternatives) and to this day often gets security
-     updates.
+  fix compiler warnings about unused variables and parameters when
+  built with --disable-verbose.
   
-  5. Metalink is not a widely used curl feature. In the 2020 curl user
-     survey, only 1.4% of the responders said that they'd are using it. In
-     2021 that number was 1.2%. Searching the web also show very few
-     traces of it being used, even with other tools.
+  Closes https://github.com/curl/curl/pull/7377
+
+- [Andrea Pappacoda brought this change]
+
+  build: fix IoctlSocket FIONBIO check
   
-  6. The torrent format and associated technology clearly won for
-     downloading large files from multiple sources in parallel.
+  Prior to this change HAVE_IOCTLSOCKET_CAMEL_FIONBIO mistakenly checked
+  for (lowercase) ioctlsocket when it should have checked for IoctlSocket.
   
-  Cloes #7176
+  Closes https://github.com/curl/curl/pull/7375
 
-- docs/INSTALL: remove mentions of configure --with-darwin-ssl
-  
-  ... as it isn't supported since a while back.
+- [Timur Artikov brought this change]
+
+  configure: fix nghttp2 library name for static builds
   
-  Make configure fail with a warning if used.
+  Don't hardcode the nghttp2 library name,
+  because it can vary, be "nghttp2_static" for example.
   
-  Reported-by: Vadim Grinshpun
-  Bug: https://curl.se/mail/lib-2021-06/0008.html
-  Closes #7200
-
-- RELEASE-NOTES: synced
+  Fixes https://github.com/curl/curl/issues/7367
+  Closes https://github.com/curl/curl/pull/7368
 
-- [Gregor Jasny brought this change]
+Gisle Vanem (16 Jul 2021)
+- [PellesC] fix _lseeki64() macro
 
-  cmake: Avoid leaking absolute paths into exported config
+- [SChannel] Use '_tcsncmp()' instead
   
-  The `find_libarary` command resolves the library or framework
-  into an absolute path. In case of system frameworks which are
-  located within an Xcode-provided SDK this results in the Xcode
-  path and SDK version being part of the library path.
+  Revert previous change for PellesC.
   
-  Because those library paths end up in the exported CMake config
-  importing curl will fail once the Xcode location or SDK version
-  changes:
+  Instead replace all use of `_tcsnccmp()` with `_tcsncmp()`.
+
+- [PellesC] missing '_tcsnccmp'
   
-  ```cmake
-  set_target_properties(CURL::libcurl PROPERTIES
-    INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
-    INTERFACE_LINK_LIBRARIES "lber;ldap;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/System/Library/Frameworks/SystemConfiguration.framework;OpenSSL::SSL;OpenSSL::Crypto;ZLIB::ZLIB"
-  )
-  ```
+  PellesC compiler does not have this macro in it's ``
+
+Daniel Gustafsson (14 Jul 2021)
+- TODO: add mention of mbedTLS 3 incompatibilities
   
-  A work-around is to link against system-level frameworks with
-  `-framework XYZ`. In case of `SystemConfiguration` we might be able
-  to omit the lookup-check because we could assume the framework is
-  always present.
+  Wyatt OʼDay reported in #7385 that mbedTLS isn't backwards compatible
+  and curl no longer builds with it. Document the need to fix our support
+  until so has been done.
   
-  Closes #7152
-
-- [Shikha Sharma brought this change]
+  Closes #7390
+  Fixes #7385
+  Reported-by: Wyatt OʼDay
+  Reviewed-by: Jay Satiro 
 
-  http2_connisdead: handle trailing GOAWAY better
+- docs: fix inconsistencies in EGDSOCKET documentation
   
-  When checking the connection the input processing returns error
-  immediately, we now consider that a dead connnection.
+  Only the OpenSSL backend actually use the EGDSOCKET, and also use
+  TLS consistently rather than mixing SSL and TLS. While there, also
+  fix a minor spelling nit.
   
-  Bug: https://curl.se/mail/lib-2021-06/0001.html
-  Closes #7192
+  Closes: #7391
+  Reviewed-by: Jay Satiro 
 
-- [Dmitry Karpov brought this change]
+- [Борис Верховский brought this change]
 
-  ares: always store IPv6 addresses first
-  
-  Trying dual-stack on some embedded platform, I noticed that quite
-  frequently (20%) libCurl starts from IPv4 regardless the Happy Eyeballs
-  timeout value.  After debugging this issue, I noticed that this happens
-  if c-ares resolver response for IPv6 family comes before IPv4 (which was
-  randomly happening in my tests).
-  
-  In such cases, because libCurl puts the last resolver response on top of
-  the address list, when IPv4 resolver response comes after IPv6 one - the
-  IPv4 family starts the connection phase instead of IPv6 family.
-  
-  The solution for this issue is to always put IPv6 addresses on top of
-  the address list, regardless the order of resolver responses.
+  docs: document missing arguments to commands
   
-  Bug: https://curl.se/mail/lib-2021-06/0003.html
+  This is a followup to commit f410b9e538129e77607fef1 fixing a few
+  more commands which takes arguments.
   
-  Closes #7188
+  Closes #7382
+  Reviewed-by: Daniel Gustafsson 
 
-- Revert "Revert "socketpair: fix potential hangs""
-  
-  This reverts commit 3e70c3430a370a31eff2c1d8fea29edaca8f1127.
+- [Randolf J brought this change]
+
+  docs: fix incorrect argument name reference
   
-  Thus brings back the change from #7144 as was originally landed in
-  c769d1eab4de8b
+  The documentation for the read callback was erroneously referencing
+  the nitems argument by nmemb.  The error was introduced in commit
+  ce0881edee3c7.
   
-  Closes #7144 (again)
+  Closes #7383
+  Reviewed-by: Daniel Gustafsson 
 
-- [Ebe Janchivdorj brought this change]
+- [Борис Верховский brought this change]
 
-  schannel: move code out of SChannel_connect_step1
+  tool_help: Document that --tlspassword takes a password
   
-  Reviewed-by: Marc Hoersken
-  Closes #7168
+  Closes #7378
+  Reviewed-by: Daniel Stenberg 
 
-- tests/data/Makefile.inc: error: trailing backslash on last line
+- scripts: Fix typo in release-notes instructions
   
-  Follow-up to d8dcb399b8009d
-
-- TODO: Support rate-limiting for MQTT
+  The command to run had a typo in the pathname which prevented copy
+  pasting it to work, which has annoyed me enough to fix this now.
 
-- [Dmitry Kostjuchenko brought this change]
+- RELEASE-NOTES: synced
 
-  warnless: simplify type size handling
+Jay Satiro (10 Jul 2021)
+- write-out.d: Clarify urlnum is not unique for de-globbed URLs
   
-  By using sizeof(T), existing defines and relying on the compiler to
-  define the required signed/unsigned mask.
+  Reported-by: Коваленко Анатолий Викторович
   
-  Closes #7181
+  Fixes https://github.com/curl/curl/issues/7342
+  Closes https://github.com/curl/curl/pull/7369
 
-Gisle Vanem (4 Jun 2021)
-- [Win32] Fix for USE_WATT32
+Daniel Gustafsson (3 Jul 2021)
+- [William Desportes brought this change]
+
+  docs: Fix typos
   
-  My Watt-32 tcp/ip stack works on Windows but it does not have `WSAIoctl()`
+  Closes: #7370
+  Reviewed-by: Daniel Gustafsson 
 
-Daniel Stenberg (4 Jun 2021)
-- [Alexis Vachette brought this change]
+Daniel Stenberg (8 Jul 2021)
+- [Jonathan Wernberg brought this change]
 
-  url: bad CURLOPT_CONNECT_TO syntax now returns error
+  Revert "ftp: Expression 'ftpc->wait_data_conn' is always false"
   
-  Added test 3020 to verify
+  The reverted commit introduced a logic error in code that was
+  correct.
   
-  Closes #7183
-
-- github: remove the cmake macOS gcc-8 jobs
+  The client using libcurl would notice the error since FTP file
+  uploads in active transfer mode would somtimes complete with
+  success despite no transfer having been performed and the
+  "uploaded" file thus not being on the remote server afterwards.
   
-  They're too similar to the gcc-9 ones to be useful (and seems to not
-  work anymore).
+  The FTP server would notice the error because it receives a
+  RST on the data connection it has established with the client
+  before any data was transferred at all.
   
-  Closes #7187
-
-- test269: disable for hyper
+  The logic error happens if the STOR response from the server have
+  arrived by the time ftp_multi_statemach() in the affected code path
+  is called, but the incoming data connection have not arrived yet.
+  In that case, the processing of the STOR response will cause
+  'ftpc->wait_data_conn' to be set to TRUE, contradicting the comment
+  in the code. Since 'complete' will also be set, later logic would
+  believe the transfer was done.
   
-  --ignore-content-length / CURLOPT_IGNORE_CONTENT_LENGTH doesn't work
-  with hyper.
+  In most cases, the STOR response will not have arrived yet when
+  the affected code path is executed, or the incoming connection will
+  also have arrived, and thus the error would not express itself.
+  But if the speed difference of the device using libcurl and the
+  FTP server is exactly right, the error may happen as often as in
+  one out of hundred file transfers.
   
-  Closes #7184
+  This reverts commit 49f3117a238b6eac0e22a32f50699a9eddcb66ab.
+  
+  Bug: https://curl.se/mail/lib-2021-07/0025.html
+  Closes #7362
 
-- runtests: enable 'hyper mode' only for HTTP tests
+- msnprintf: return number of printed characters excluding null byte
   
-  The 'hyper mode' makes line-ending checks work in the test suite for
-  when hyper is used. Now it also requires that HTTP or HTTPS are
-  mentioned as keywords to be enabled so that it doesn't wrongly adjusts
-  tests for other protocols.
+  ... even when the output is "capped" by the maximum length argument.
   
-  This makes test 271 (TFTP) work again in hyper enabled builds.
+  Clarified in the docs.
   
-  Closes #7185
-
-- [Alexis Vachette brought this change]
+  Closes #7361
 
-  hostip: bad CURLOPT_RESOLVE syntax now returns error
+- infof: remove newline from format strings, always append it
   
-  Added test 3019
-  Fixes #7170
-  Closes #7174
-
-Daniel Gustafsson (3 Jun 2021)
-- cookies: fix typo and expand comment
+  - the data needs to be "line-based" anyway since it's also passed to the
+    debug callback/application
   
-  Fix a typo in the sorting comment, and while in there elaborate slightly
-  on why creationtime can be used as a tiebreaker.
-
-- cookies: remove unused header
+  - it makes infof() work like failf() and consistency is good
   
-  Commit 1c1d9f1affbd3367bcb24062e261d0ea5d185e3a removed the last use
-  for the inet_pton.h headerfile, this removes the inclusion of the
-  header.
+  - there's an assert that triggers on newlines in the format string
   
-  Closes: #7182
-  Reviewed-by: Daniel Stenberg 
-
-Daniel Stenberg (3 Jun 2021)
-- Revert "socketpair: fix potential hangs"
+  - Also removes a few instances of "..."
   
-  This reverts commit c769d1eab4de8b9f1bd84d992c63692fdc43c5be.
+  - Removes the code that would append "..." to the end of the data *iff*
+    it was truncated in infof()
   
-  See #7144 for details
-
-- [Paul Groke brought this change]
+  Closes #7357
 
-  socketpair: fix potential hangs
-  
-  Fixes potential hang in accept by using select + non-blocking accept.
+- examples/multi-single: fix scan-build warning
   
-  Fixes potential hang in peer check by replacing the send/recv check with
-  a getsockname/getpeername check.
+  warning: Value stored to 'mc' during its initialization is never read
   
-  Adds length check for returned sockaddr data.
+  Follow-up to ae8e11ed5fd2ce
   
-  Closes #7144
+  Closes #7360
 
-- runtests: parse data/Makefile.inc instead of using make
+- wolfssl: failing to set a session id is not reason to error out
   
-  The warning about missing entries in that file then doesn't require that
-  the Makefile has been regenerated which was confusing.
+  ... as it is *probably* just timed out.
   
-  The scan for the test num is a little more error prone than before
-  (since now it doesn't actually verify that it is legitimate Makefile
-  syntax), but I think it is good enough.
+  Reported-by: Francisco Munoz
   
-  Closes #7177
-
-- [Harry Sintonen brought this change]
+  Closes #7358
 
-  filecheck: quietly remove test-place/*~
+- docs/examples: use curl_multi_poll() in multi examples
   
-  Closes #7179
-
-- CURLE_SETOPT_OPTION_SYNTAX: new error name for wrong setopt syntax
+  The API is soon two years old and deserves being shown as the primary
+  way to drive multi code as it makes it much easier to write code.
   
-  For options that pass in lists or strings that are subsequently parsed
-  and must be correct. This broadens the scope for the option previously
-  known as CURLE_TELNET_OPTION_SYNTAX but the old name is of course still
-  provided as a #define for existing applications.
+  multi-poll: removed
   
-  Closes #7175
+  multi-legacy: add to show how we did multi API use before
+  curl_multi_wait/poll.
+  
+  Closes #7352
 
-- tests: fix Accept-Encoding strips to work with Hyper builds
+- KNOWN_BUGS: flaky Windows CI builds
   
-  The previous strip also removed the CR which turned problematic.
+  Closes #6972
+
+- RELEASE-NOTES: synced
+
+- test1147: hyper doesn't allow "crazy" request headers like built-in
   
-  valgrind.supp: add zstd suppression using hyper
+  ... so strip that from the test.
   
-  Reported-and-analyzed-by: Kevin Burke
-  Fixes #7169
-  Closes #7171
+  Closes #7349
 
-- github: timeout jobs on macOS after 90 minutes
+- c-hyper: bail on too long response headers
   
-  Assisted-by: Marc Hoersken
-  Closes #7173
-
-- [Harry Sintonen brought this change]
-
-  mqtt: detect illegal and too large file size
+  To match with built-in behaviors. Makes test 1154 work.
   
-  Add test 3017 and 3018 to verify.
-  Closes #7166
+  Closes #7350
 
-- [Abhinav Singh brought this change]
+- test1151: added missing CRLF to work with hyper
+  
+  Closes #7350
 
-  cmake: add CURL_DISABLE_NTLM option
+- c-hyper: add support for transfer-encoding in the request
   
-  Closes #7028
+  Closes #7348
 
-- [Abhinav Singh brought this change]
+- [Andrea Pappacoda brought this change]
 
-  configure: add --disable-ntlm option
+  cmake: remove libssh2 feature checks
   
-  Closes #7028
+  libssh2 features are detected based on version since commit
+  9dbbba997608f7c3c5de1c627c77c8cd2aa85b73
+  
+  Closes #7343
 
-- [Abhinav Singh brought this change]
+- test1116: hyper doesn't pass through "surprise-trailers"
+  
+  Closes #7344
 
-  define: re-add CURL_DISABLE_NTLM and corresponding ifdefs
+- socks4: scan for the IPv4 address in resolve results
   
-  This flag will be further exposed by adding build options.
+  Follow-up to 84d2839740 which changed the resolving to always resolve
+  both address families, but since SOCKS4 only supports IPv4 it should
+  scan for and use the first available IPv4 address.
   
-  Reverts #6809
-  Closes #7028
+  Reported-by: shithappens2016 on github
+  Fixes #7345
+  Closes #7346
 
-- RELEASE-NOTES: synced
+Jay Satiro (5 Jul 2021)
+- proto.d: fix formatting for paragraphs after margin changes
+  
+  Closes https://github.com/curl/curl/pull/7341
 
-Viktor Szakats (1 Jun 2021)
-- travis: delete --enable-hsts option (it is the default now) [ci skip]
+- pinnedpubkey.d: fix formatting for version support lists
   
-  Reviewed-by: Daniel Stenberg
-  Closes #7167
+  Closes https://github.com/curl/curl/pull/7340
 
-Daniel Stenberg (1 Jun 2021)
-- hostip: fix 3 coverity complaints
+Daniel Stenberg (2 Jul 2021)
+- TODO: "Support in-memory certs/ca certs/keys" done
   
-  Follow-up to 1a0ebf6632f889eed
+  Has been suppored for a while now with the *BLOB options.
+
+- examples: safer and more proper read callback logic
   
-  - Check the return code to Curl_inet_pton() in two instances, even
-    though we know the input is valid so the functions won't fail.
+  The same callback code is used in:
   
-  - Clear the 'struct sockaddr_in' struct before use so that the
-    'sin_zero' field isn't left uninitialized.
+   imap-append.c
+   smtp-authzid.c
+   smtp-mail.c
+   smtp-multi.c
+   smtp-ssl.c
+   smtp-tls.c
   
-  Detected by Coverity.
-  Assisted-by: Harry Sintonen
-  Closes #7163
+  It should not assume that it can copy full lines into the buffer as it
+  will encourage sloppy coding practices. Instead use byte-wise logic and
+  check/acknowledge the buffer size appropriately.
+  
+  Reported-by: Harry Sintonen
+  Fixes #7330
+  Closes #7331
 
-- c-hyper: fix NTLM on closed connection tested with test159
+- test1519: adjusted to work with hyper
   
-  Closes #7154
+  Closes #7333
 
-- conncache: lowercase the hash key for better match
+- test1518: adjusted to work with hyper
   
-  As host names are case insensitive, the use of case sensitive hashing
-  caused unnecesary cache misses and therefore lost performance. This
-  lowercases the hash key.
+  ... by making sure the stdout output doesn't look like HTTP headers.
   
-  Reported-by: Harry Sintonen
-  Fixes #7159
-  Closes #7161
+  Closes #7333
 
-- mbedtls: make mbedtls_strerror always work
+- test1514: add a CRLF to the response to make it correct
   
-  If the function doesn't exist, provide a macro that just clears the
-  error message. Removes #ifdef uses from the code.
+  Makes hyper accept it fine instead returning HYPERE_UNEXPECTED_EOF on
+  us.
   
-  Closes #7162
+  Closes #7334
 
-- vtls: exit addsessionid if no cache is inited
+- formdata: avoid "Argument cannot be negative" warning
   
-  Follow-up to b249592d29ae0
+  ... when converting a curl_off_t to size_t, by using
+  CURL_ZERO_TERMINATED before passing the argument to the function.
   
-  Avoids NULL pointer derefs.
+  Detected by Coverity CID 1486590.
   
-  Closes #7165
-
-- [Harry Sintonen brought this change]
+  Closes #7328
+  Assisted-by: Daniel Gustafsson
 
-  Curl_ntlm_core_mk_nt_hash: fix OOM in error path
+- lib: more %u for port and int for %*s fixes
   
-  Closes #7164
+  Detected by Coverity
+  
+  Closes #7329
 
-Michael Kaufmann (1 Jun 2021)
-- ssl: read pending close notify alert before closing the connection
+- doh: (void)-prefix call to curl_easy_setopt
+
+- lib: fix type of len passed to *printf's %*s
   
-  This avoids a TCP reset (RST) if the server initiates a connection
-  shutdown by sending an SSL close notify alert and then closes the TCP
-  connection.
+  ... it needs to be 'int'. Detected by Coverity CID 1486611 (etc)
   
-  For SSL connections, usually the server announces that it will close the
-  connection with an SSL close notify alert. curl should read this alert.
-  If curl does not read this alert and just closes the connection, some
-  operating systems close the TCP connection with an RST flag.
+  Closes #7326
+
+- lib: use %u instead of %ld for port number printf
   
-  See RFC 1122, section 4.2.2.13
+  Follow-up to 764c6bd3bf which changed the type of some port number
+  fields. Detected by Coverity (CID 1486624) etc.
   
-  If curl reads the close notify alert, the TCP connection is closed
-  normally with a FIN flag.
+  Closes #7325
+
+- version: turn version number functions into returning void
   
-  The new code is similar to existing code in the "SSL shutdown" function:
-  try to read an alert (non-blocking), and ignore any read errors.
+  ... as we never use the return codes from them.
   
-  Closes #7095
-
-Daniel Stenberg (1 Jun 2021)
-- [Laurent Dufresne brought this change]
+  Reviewed-by: Daniel Gustafsson
+  Closes #7319
 
-  setopt: fix incorrect comments
+- mqtt: extend the error message for no topic
   
-  Closes #7157
+  ... and mention that it needs URL encoding.
+  
+  Reported-by: Peter Körner
+  Fixes #7316
+  Closes #7317
 
-- [Laurent Dufresne brought this change]
+- formdata: correct typecast in curl_mime_data call
+  
+  Coverity pointed out it the mismatch. CID 1486590
+  
+  Closes #7327
 
-  mbedtls: add support for cert and key blob options
+- url: (void)-prefix a curl_url_get() call
   
-  CURLOPT_SSLCERT_BLOB and CURLOPT_SSLKEY_BLOB weren't usable with
-  mbedtls backend, so the support was added.
+  Coverity (CID 1486645) pointed out a use of curl_url_get() in the
+  parse_proxy function where the return code wasn't checked. A
+  (void)-prefix makes the intention obvious.
   
-  Closes #7157
+  Closes #7320
 
-- [Gregor Jasny brought this change]
+- glob: pass an 'int' as len when using printf's %*s
+  
+  Detected by Coverity CID 1486629.
+  
+  Closes #7324
 
-  cmake: try well-known send/recv signature for Apple
+- vtls: use free() not curl_free()
   
-  The CMake `try_compile` command is especially slow for
-  the Xcode generator. With this patch applied it first tests
-  for the currently used (and Open Group specified) send/recv
-  signature. In case this fails testing falls-back to the
-  permutations.
+  curl_free() is provided for users of the API to free returned data,
+  there's no need to use it internally.
   
-  speed-up:
+  Closes #7318
+
+- zuul: use the new rustls directory name
   
-  ```
-  time cmake .. -GNinja -DCMAKE_USE_SECTRANSP=ON -DHTTP_ONLY=ON -DCMAKE_USE_LIBSSH2=OFF
-  before: 11.64s user 11.09s system 55% cpu 40.754 total
-  after:   7.84s user 6.57s  system 51% cpu 28.074 total
-  ```
+  Follow-up to 6d972c8b1cbb3 which missed updating this directory name.
   
-  ```
-  time cmake .. -GXcode -DCMAKE_USE_SECTRANSP=ON -DHTTP_ONLY=ON -DCMAKE_USE_LIBSSH2=OFF
-  before: 217.07s user 104.15s system 60% cpu 8:51.79 total
-  after:  108.76s user  51.80s system 58% cpu 4:32.58 total
-  ```
+  Also no longer call it crustls in the docs and bump to rusttls-ffi 0.7.1
   
-  Closes #7158
+  Closes #7311
 
-- http2: init recvbuf struct for pushed streams
+Jay Satiro (29 Jun 2021)
+- http: fix crash in rate-limited upload
   
-  Debug builds would warn that these structs were not initialized properly
-  for pushed streams.
+  - Don't set the size of the piece of data to send to the rate limit if
+    that limit is larger than the buffer size that will hold the piece.
   
-  Ref: #7148
-  Closes #7153
+  Prior to this change if CURLOPT_MAX_SEND_SPEED_LARGE
+  (curl tool: --limit-rate) was set then it was possible that a temporary
+  buffer used for uploading could be written to out of bounds. A likely
+  scenario for this would be a non-trivial amount of post data combined
+  with a rate limit larger than CURLOPT_UPLOAD_BUFFERSIZE (default 64k).
+  
+  The bug was introduced in 24e469f which is in releases since 7.76.0.
+  
+  perl -e "print '0' x 200000" > tmp
+  curl --limit-rate 128k -d @tmp httpbin.org/post
+  
+  Reported-by: Richard Marion
+  
+  Fixes https://github.com/curl/curl/issues/7308
+  Closes https://github.com/curl/curl/pull/7315
 
-- Curl_ssl_getsessionid: fail if no session cache exists
+Daniel Stenberg (29 Jun 2021)
+- copyright: add boiler-plate headers to CI config files
   
-  This function might get called for an easy handle for which the session
-  cache hasn't been setup. It now just returns a "miss" in that case.
+  And whitelist .zuul.ignore
   
-  Reported-by: Christoph M. Becker
-  Fixes #7148
-  Closes #7153
+  Closes #7314
 
-- GOVERNANCE: add 'user', 'committer' and 'contributor'
+- CI: remove travis details
   
-  As those are commonly used terms in the project.
+  Rename still used leftovers to "zuul" as that's now the CI using them.
   
-  Closes #7151
+  Closes #7313
 
-- URL-SYNTAX.md: document the new 'localhost' treatment
+- RELEASE-NOTES: synced
 
-- hostip: make 'localhost' return fixed values
+- openssl: avoid static variable for seed flag
   
-  Resolving the case insensitive host name 'localhost' now returns the
-  addresses 127.0.0.1 and (if IPv6 is enabled) ::1 without using any
-  resolver.
+  Avoid the race condition risk by instead storing the "seeded" flag in
+  the multi handle. Modern OpenSSL versions handle the seeding itself so
+  doing the seeding once per multi-handle instead of once per process is
+  less of an issue.
   
-  This removes the risk that users accidentally resolves 'localhost' to
-  something else. By making sure 'localhost' is always local, we can
-  assume a "secure context" for such transfers (for cookies etc).
+  Reported-by: Gerrit Renker
+  Fixes #7296
+  Closes #7306
+
+- configure: inhibit the implicit-fallthrough warning on gcc-12
   
-  Closes #7039
+  ... since it no longer acknowledges the comment markup we use for that
+  purpose.
+  
+  Reported-by: Younes El-karama
+  Fixes #7295
+  Closes #7307
 
-Daniel Gustafsson (31 May 2021)
-- docs: fix typos
+Daniel Gustafsson (28 Jun 2021)
+- [Andrei Rybak brought this change]
 
-Daniel Stenberg (30 May 2021)
-- hsts: ignore numberical IP address hosts
+  misc: fix typos in comments which repeat a word
   
-  Also, use a single function library-wide for detecting if a given hostname is
-  a numerical IP address.
+  Fix typos in code comments which repeat various words.  In trivial
+  cases, just delete the repeated word.  Reword the affected sentence in
+  "lib/url.c" for it to make sense.
   
-  Reported-by: Harry Sintonen
-  Fixes #7146
-  Closes #7149
+  Closes #7303
+  Reviewed-by: Daniel Gustafsson 
 
-- test178: adjust for hyper
+Daniel Stenberg (27 Jun 2021)
+- lib677: make it survive torture testing
   
-  Hyper returns the same error for wrong HTTP version as for negative
-  content-length. Test 178 verifies that negative content-length is
-  rejected but the hyper backend will return a different error for it (and
-  without any helpful message telling why the message was bad). It will
-  also not return any headers at all for the response, not even the ones
-  that arrived before the error.
+  Follow-up to a5ab72d5edd7
   
-  Closes #7147
+  Closes #7300
 
-- HYPER: remove mentions of deprecated development branch
+- [Tommy Chiang brought this change]
 
-- c-hyper: handle NULL from hyper_buf_copy()
+  docs/BINDINGS: fix outdated links
   
-  Closes #7143
-
-- HSTS: not experimental anymore
+  * luacurl page is now not accessible, fix it with wayback machine page
+  * Scheme one seems not providing https now, change it back to http one
+  
+  Closes #7301
 
-- [Douglas R. Reno brought this change]
+- [Jacob Hoffman-Andrews brought this change]
 
-  INSTALL: use correct extension for CURL-DISABLE.md
+  curstls: bump crustls version and use new URL
   
-  In INSTALL.MD, it's currently set to CURL-DISABLE-md instead of
-  CURL-DISABLE.md. This generates a 404 on the cURL website as well as
-  when viewing the docs through Github.
+  crustls moved to https://github.com/rustls/rustls-ffi. This also bumps
+  the expected version to 0.7.0.
   
-  Closes #7142
+  Closes #7297
 
-- travis: run tests 1 - 153 with hyper
+- RELEASE-NOTES: synced
 
-- c-hyper: convert HYPERE_INVALID_PEER_MESSAGE to CURLE_UNSUPPORTED_PROTOCOL
-  
-  Makes test 129 work (HTTP/1.2 response).
+- examples: length-limit two sscanf() uses of %s
   
-  Closes #7141
+  Reported-by: Jishan Shaikh
+  Fixes #7293
+  Closes #7294
 
-- http_proxy: deal with non-200 CONNECT response with Hyper
-  
-  Makes test 94 and 95 work
-  
-  Closes #7141
+- [Richard Whitehouse brought this change]
 
-- c-hyper: clear NTLM auth buffer when request is issued
+  multi: alter transfer timeout ordering
   
-  To prevent previous ones to get reused on subsequent requests. Matches
-  how the built-in HTTP code works. Makes test 90 to 93 work.
+  - Check whether a connection has succeded before checking whether it's
+    timed out.
   
-  Add test 90 to 93 in travis.
+    This means if we've connected quickly, but subsequently been
+    descheduled, we allow the connection to succeed. Note, if we timeout,
+    but between checking the timeout, and connecting to the server the
+    connection succeeds, we will allow it to go ahead. This is viewed as
+    an acceptable trade off.
   
-  Closes #7139
-
-- [Joel Depooter brought this change]
+  - Add additional failf logging around failed connection attempts to
+    propogate the cause up to the caller.
+  
+  Co-Authored-by: Martin Howarth
+  Closes #7178
 
-  schannel: set ALPN length correctly for HTTP/2
+- test677: IMAP CONNECT_ONLY, custom command and then exit
   
-  In a3268eca792f1 this code was changed to use the ALPN_H2 constant
-  instead of the NGHTTP2_PROTO_ALPN constant. However, these constants are
-  not the same. The nghttp2 constant included the length of the string,
-  like this: "\x2h2". The ALPN_H2 constant is just "h2". Therefore we need
-  to re-add the length of the string to the ALPN buffer.
+  Adjusted ftpserver.pl to add support for the IMAP IDLE command
   
-  Closes #7138
+  Adjusted test 660 to sync with the fix
 
-- travis: run tests 1-89 in the hyper build
+- multi: do not switch off connect_only flag when closing
   
-  Closes #7137
+  ... as it made protocol specific disconnect commands wrongly get used.
+  
+  Bug: https://curl.se/mail/lib-2021-06/0024.html
+  Reported-by: Aleksander Mazur
+  Closes #7288
 
-- Revert "c-hyper: handle body on HYPER_TASK_EMPTY"
+- http: make the haproxy support work with unix domain sockets
   
-  This reverts commit c3eefa95c31f55657f0af422e8268d738f689066.
+  ... it should then pass on "PROXY UNKNOWN" since it doesn't know the
+  involved IP addresses.
   
-  Reported-by: Kevin Burke
-  Fixes #7122
-  Closes #7136
+  Reported-by: Valentín Gutiérrez
+  Fixes #7290
+  Closes #7291
 
-- [Jon Rumsey brought this change]
+- [Xiang Xiao brought this change]
 
-  ccsidcurl: fix the compile errors
-  
-  Looks like the declaration of cpp shoule be const char ** and return
-  null if convert_version_info_string fails.
+  curl.h: include sys/select.h for NuttX RTOS
   
-  Fixes #7134
-  Closes #7135
+  Closes #7287
 
-- [Viktor Szakats brought this change]
+- [Bin Meng brought this change]
 
-  docs: use --max-redirs instead of --max-redir
+  curl.h: remove the execution bit
   
-  For consistency.
+  The execution bit of curl.h file was wrongly added:
   
-  Closes #7130
-
-- RELEASE-NOTES: synced
+    commit 2621025d6f96 ("curl.h:  is supported by VxWorks7")
   
-  ... and bump to 7.77.1
+  and should be removed.
+  
+  Follow-up to 2621025d6f96 ("curl.h:  is supported by VxWorks7")
+  Signed-off-by: Bin Meng 
+  Closes #7286
 
-- [Michael Forney brought this change]
+- [Bin Lan brought this change]
 
-  travis: add bearssl build
+  curl.h:  is supported by VxWorks7
   
-  Closes #7133
+  Closes #7285
 
-- [Michael Forney brought this change]
+- [Bachue Zhou brought this change]
 
-  bearssl: explicitly initialize all fields of Curl_ssl
+  quiche: use send() instead of sendto() to avoid macOS issue
   
-  Also, add comments like the other vtls backends.
+  sendto() always returns "Socket is already connected" error on macos
   
-  Closes #7133
+  Closes #7260
 
-- [Michael Forney brought this change]
+- [Li Xinwei brought this change]
 
-  bearssl: remove incorrect const on variable that is modified
+  cmake: fix support for UnixSockets feature on Win32
   
-  hostname may be set to NULL later on in this function if it is an
-  IP address.
+  Move the definition of sockaddr_un struct from config-win32.h to
+  curl_setup.h, so that it could be shared by all build systems.
   
-  Closes #7133
+  Add ADDRESS_FAMILY typedef for old mingw, now old mingw can also use
+  unix sockets.
+  
+  Also fix the build of tests/server/sws.c on Win32 when USE_UNIX_SOCKETS
+  is defined.
+  
+  Closes #7034
 
-Version 7.77.0 (26 May 2021)
+- [Gregory Muchka brought this change]
+
+  hostip: (macOS) free returned memory of SCDynamicStoreCopyProxies
+  
+  From Apples documentation on SCDynamicStoreCopyProxies, "Return Value: A
+  dictionary of key-value pairs that represent the current internet proxy
+  settings, or NULL if no proxy settings have been defined or if an error
+  occurred. You must release the returned value."
+  
+  Failure to release the returned value of SCDynamicStoreCopyProxies can
+  result in a memory leak.
+  
+  Source: https://developer.apple.com/documentation/systemconfiguration/1517088-scdynamicstorecopyproxies
+  
+  Closes #7265
 
-Daniel Stenberg (26 May 2021)
 - RELEASE-NOTES: synced
 
-- THANKS: added contributors from 7.77.0 cycle
+Jay Satiro (21 Jun 2021)
+- vtls: fix warning due to function prototype mismatch
+  
+  b09c8ee changed the function prototype. Caught by Visual Studio.
 
-- copyright: update copyright year ranges to 2021
+- curl_multibyte: Remove local encoding fallbacks
+  
+  - If the UTF-8 to UTF-16 conversion fails in Windows Unicode builds then
+    no longer fall back to assuming the string is in a local encoding.
+  
+  Background:
+  
+  Some functions in Windows Unicode builds must convert UTF-8 to UTF-16 to
+  pass to the Windows CRT API wide-character functions since in Windows
+  UTF-8 is not a valid locale (or at least 99% of the time right now).
+  
+  Prior to this change if the Unicode encoding conversion failed then
+  libcurl would assume, for backwards compatibility with applications that
+  may have written their code for non-Unicode builds, attempt to convert
+  the string from local encoding to UTF-16.
+  
+  That type of "best effort" could theoretically cause some type of
+  security or other problem if a string that was locally encoded was also
+  valid UTF-8, and therefore an unexpected UTF-8 to UTF-16 conversion
+  could occur.
+  
+  Ref: https://github.com/curl/curl/pull/7246
+  
+  Closes https://github.com/curl/curl/pull/7257
 
-- [Radek Zajic brought this change]
+Daniel Stenberg (20 Jun 2021)
+- curl_endian: remove the unused Curl_write64_le function
+  
+  The last usage was removed in cca455a36
+  
+  Closes #7280
 
-  hostip: fix broken macOS/CMake/GCC builds
+- vtls: only store TIMER_APPCONNECT for non-proxy connect
   
-  Follow-up to 31f631a142d855f06
+  Introducing a 'isproxy' argument to the connect function so that it
+  knows wether to store the time stamp or not.
   
-  Fixes #7128
-  Closes #7129
+  Reported-by: Yongkang Huang
+  Fixes #7274
+  Closes #7274
 
-- TODO: netrc caching and sharing
+- gnutls: set the preferred TLS versions in correct order
   
-  URL: https://curl.se/mail/archive-2021-05/0018.html
+  Regression since 781864bedbc57 (curl 7.77.0)
+  
+  Reported-by: civodul on github
+  Assisted-by: Nikos Mavrogiannopoulos
+  Fixes #7277
+  Closes #7278
 
-- [Orgad Shaneh brought this change]
+- [Gergely Nagy brought this change]
 
-  setopt: streamline ssl option code
-  
-  Make it use the same style as the code next to it
+  configure/cmake: remove checks for unused gethostbyaddr and gethostbyaddr_r
   
-  Closes #7123
+  Closes #7276
 
-- [Radek Zajic brought this change]
+- [Gergely Nagy brought this change]
 
-  lib/hostip6.c: make NAT64 address synthesis on macOS work
+  configure/cmake: remove checks for unused inet_ntoa and inet_ntoa_r
   
-  Closes #7121
+  Closes #7276
 
-- [ejanchivdorj brought this change]
+- [Gergely Nagy brought this change]
 
-  sectransp: fix EXC_BAD_ACCESS caused by uninitialized buffer
-  
-  When the SecCertificateCopyCommonName function fails, it leaves
-  common_name in a invalid state so CFStringCompare uses the invalid
-  result, causing EXC_BAD_ACCESS.
-  
-  The fix is to check the return value of the function before using the
-  name.
+  configure/cmake: remove unused define HAVE_PERROR
   
-  Closes #7126
+  Closes #7276
 
-- [Paweł Wegner brought this change]
+- [Gergely Nagy brought this change]
 
-  CMake: add CURL_ENABLE_EXPORT_TARGET option
-  
-  install(EXPORT ...) causes trouble when embedding curl dependencies
-  which don't provide install(EXPORT ...) targets (e.g libressl and
-  nghttp2) with cmake's add_subdirectory.
+  configure: remove unused check for gai_strerror
   
-  Reviewed-by: Jakub Zakrzewski
-  Closes #7060
+  Closes #7276
 
-- [Alessandro Ghedini brought this change]
+- [Gergely Nagy brought this change]
 
-  quiche: update for network path aware API
-  
-  Latest version of quiche requires the application to pass the peer
-  address of received packets, and it provides the address for outgoing
-  packets back.
+  configure/cmake: remove unused define HAVE_FREEIFADDRS
   
-  Closes #7120
+  Closes #7276
 
-- [Jacob Hoffman-Andrews brought this change]
+- [Gergely Nagy brought this change]
 
-  rustls: switch read_tls and write_tls to callbacks
-  
-  And update to 0.6.0, including a rename from session to connection for
-  many fields.
+  configure/cmake: remove unused define HAVE_FORK
   
-  Closes #7071
+  Closes #7276
 
-- [Koichi Shiraishi brought this change]
+- [Gergely Nagy brought this change]
 
-  sectransp: fix 7f4a9a9b2a49 commit about missing comma
-  
-  Follow-up to 7f4a9a9b2a495
+  configure/cmake: remove unused define HAVE_FDOPEN
   
-  Closes #7119
+  Closes #7276
 
-- [Harry Sintonen brought this change]
+- [Gergely Nagy brought this change]
 
-  openssl: associate/detach the transfer from connection
-  
-  CVE-2021-22901
+  configure/cmake: remove checks for unused sgtty.h
   
-  Bug: https://curl.se/docs/CVE-2021-22901.html
+  Closes #7276
 
-- [Harry Sintonen brought this change]
+- [Gergely Nagy brought this change]
 
-  telnet: check sscanf() for correct number of matches
-  
-  CVE-2021-22898
+  configure/cmake: remove remaining checks for rsa.h
   
-  Bug: https://curl.se/docs/CVE-2021-22898.html
+  Closes #7276
 
-- schannel: don't use static to store selected ciphers
-  
-  CVE-2021-22897
+- [Gergely Nagy brought this change]
+
+  configure/cmake: remove remaining checks for err.h
   
-  Bug: https://curl.se/docs/CVE-2021-22897.html
+  Closes #7276
 
-- docs/tests: remove freenode references
+- [Gergely Nagy brought this change]
 
-- RELEASE-NOTES: synced
+  configure/cmake: remove remaining checks for crypto.h
+  
+  Closes #7276
 
-- [Sergey Markelov brought this change]
+- [Gergely Nagy brought this change]
 
-  NSS: make colons, commas and spaces valid separators in cipher list
+  configure/cmake: remove checks for unused getservbyport_r
   
-  Fixes #7110
-  Closes #7115
+  Closes #7276
 
-- curl: include libmetalink version in --version output
+- --socks4[a]: clarify where the host name is resolved
   
-  Closes #7112
-
-Jay Satiro (21 May 2021)
-- [Matias N. Goldberg brought this change]
+  Closes #7273
 
-  cmake: Use multithreaded compilation on VS 2008+
+- libcurl-security.3: mention file descriptors and forks
   
-  Multithreaded compilation has been supported since at least VS 2005 and
-  been robustly stable since at least VS 2008
+  ... and move the security report section last.
   
-  Closes https://github.com/curl/curl/pull/7109
+  Reported-by: Harry Sintonen
+  Closes #7270
 
-Daniel Stenberg (21 May 2021)
-- [Matias N. Goldberg brought this change]
+- [Alex Xu (Hello71) brought this change]
 
-  cmake: fix two invokes result in different curl_config.h
+  configure.ac: make non-executable
   
-  Fixes #7100
-  Closes #7101
+  it needs to be processed by autoconf or autoreconf, and doesn't have a
+  suitable shebang to be directly executed. other projects normally set
+  configure.ac -x.
   
-  Reviewed-by: Jakub Zakrzewski
-  Signed-off-by: Matias N. Goldberg 
-
-- [Peng-Yu Chen brought this change]
+  Closes #7272
 
-  cmake: detect CURL_SA_FAMILY_T
+- configure: do not strip out debug flags
   
-  Fixes #7049
-  Closes #7065
+  To allow users to set them when invoking configure without using
+  --with-debug.
+  
+  Reported-by: Alex Xu
+  Fixes #7216
+  Closes #7267
 
-- [Lucas Clemente Vella brought this change]
+- libssh2: limit time a disconnect can take to 1 second
+  
+  Closes #7271
 
-  CURLOPT_IPRESOLVE: preventing wrong IP version from being used
+- TLS: prevent shutdown loops to get stuck
   
-  In some situations, it was possible that a transfer was setup to
-  use an specific IP version, but due do DNS caching or connection
-  reuse, it ended up using a different IP version from requested.
+  ... by making sure the loops are only allowed to read the shutdown
+  traffic a limited number of times.
   
-  This commit changes the effect of CURLOPT_IPRESOLVE from simply
-  restricting address resolution to preventing the wrong connection
-  type being used, when choosing a connection from the pool, and
-  to restricting what addresses could be used when establishing
-  a new connection.
+  Reported-by: Harry Sintonen
+  Closes #7271
+
+- hyper: propagate errors back up from read callbacks
   
-  It is important that all addresses versions are resolved, even if
-  not used in that transfer in particular, because the result is
-  cached, and could be useful for a different transfer with a
-  different CURLOPT_IPRESOLVE setting.
+  Makes test 513 work with hyper
   
-  Closes #6853
+  Closes #7266
 
-- [Oliver Urbann brought this change]
+- KNOWN_BUGS: Negotiate on Windows fails
+  
+  Closes #5881
 
-  AmigaOS: add functions definitions for SHA256
+- KNOWN_BUGS: renames instead of locking for atomic operations
   
-  AmiSSL replaces many functions with macros. Curl requires pointer
-  to some of these functions. Thus, we have to encapsulate these macros:
-  SHA256_Init, SHA256_Update, SHA256_Final, X509_INFO_free.
+  Closes #6882
+  Closes #6884
+
+- zuul: add two missing CI jobs
   
-  Bug: https://github.com/jens-maus/amissl/issues/15
-  Co-authored-by: Daniel Stenberg 
+  ... that were configured, just not run
   
-  Closes #7099
+  Closes #7261
 
-- test2100: make it run with and require IPv6
+Viktor Szakats (15 Jun 2021)
+- idn: fix libidn2 with windows unicode builds
   
-  Closes #7083
-
-- tests/getpart: generate output URL encoded for better diffs
+  Unicode Windows builds use UTF-8 strings internally in libcurl,
+  so make sure to call the UTF-8 flavour of the libidn2 API. Also
+  document that Windows builds with libidn2 and UNICODE do expect
+  CURLOPT_URL as an UTF-8 string.
   
-  Closes #7083
-
-- [Ryan Beck-Buysse brought this change]
+  Reported-by: dEajL3kA on github
+  Assisted-by: Jay Satiro
+  Reviewed-by: Marcel Raad
+  Closes #7246
+  Fixes #7228
 
-  docs/TheArtOfHttpScripting: fix markdown links
+Daniel Stenberg (15 Jun 2021)
+- curl_url_set: reject spaces in URLs w/o CURLU_ALLOW_SPACE
   
-  extra parens cause the links to be incorrectly formatted
-  and inconsistent with the rest of the document.
+  They were never officially allowed and slipped in only due to sloppy
+  parsing. Spaces (ascii 32) should be correctly encoded (to %20) before
+  being part of a URL.
   
-  Signed-off-by: Ryan Beck-Buysse 
-  Closes #7097
+  The new flag bit CURLU_ALLOW_SPACE when a full URL is set, makes libcurl
+  allow spaces.
+  
+  Updated test 1560 to verify.
+  
+  Closes #7073
 
 - RELEASE-NOTES: synced
+  
+  ... and bump to version 7.78.0 for the next planned release.
 
-- [Emil Engler brought this change]
-
-  docs: replace dots with dashes in markdown enums
+Jay Satiro (15 Jun 2021)
+- docs: Remove outdated curl tool limitation
   
-  We use dashes instead of dots nearly everywhere except for those few
-  cases. This commit addresses this issues and brings more coherency into
-  it.
+  - Document that HTTP/2 multiplexing is supported by the curl tool when
+    parallel transfers are used.
   
-  Closes #7093
-
-- [Emil Engler brought this change]
+  Supported since 7.66.0 via --parallel, but the doc wasn't updated.
+  
+  Closes https://github.com/curl/curl/pull/7259
 
-  docs: improve INTERNALS.md regarding getsock cb
+- http2: Clarify 'Using HTTP2' verbose message
   
-  This adds the I/O prefix to indicate that those "actions" are kind-of
-  related to those found in select(2) or poll(2) (reading/writing).
+  - Change phrasing from multi-use to multiplexing since the former may
+    not be as well understood.
   
-  It also adds a note where the prototypes of those functions can be found
-  in the source code.
+  Before: * Using HTTP2, server supports multi-use
   
-  Closes #7092
+  After: * Using HTTP2, server supports multiplexing
+  
+  Bug: https://github.com/curl/curl/discussions/7255
+  Reported-by: David Hu
+  
+  Closes https://github.com/curl/curl/pull/7258
 
-- [Emil Engler brought this change]
+Daniel Stenberg (14 Jun 2021)
+- winbuild/README: VC should be set to 6 'or larger'
+  
+  Previously it listed all versions up to 15 (missing 16) but this new
+  phrasing is more open ended.
+  
+  Reported-by: Hugh Macdonald
+  Fixes #7253
+  Closes #7254
+
+- [Jacob Hoffman-Andrews brought this change]
 
-  docs: document attach in INTERNALS.md
+  rustls: remove native_roots fallback
   
-  The new field in the Curl_handler struct still lacks documentation. This
-  adds it it from the information extracted from lib/urldata.h:797
+  For the commandline tool, we expect to be passed
+  SSL_CONN_CONFIG(CAfile); for library use, the use should pass a set of
+  trusted roots (like in other TLS backends).
   
-  Closes #7091
+  This also removes a dependency on Security.framework when building on
+  macOS.
+  
+  Closes #7250
 
-- [Marc Aldorasi brought this change]
+- [Albin Vass brought this change]
 
-  config: remove now-unused macros
+  travis: remove jobs that have migrated to zuul
   
-  Closes #7094
+  Closes #7245
 
-- [Marc Aldorasi brought this change]
+- [Mohammed Naser brought this change]
 
-  hostip.h: remove declaration of unimplemented function
+  CI: add jobs using Zuul
   
-  Closes #7094
-
-- h3: add 'attach' callback to protocol handlers
+  It also includes a few changes to get the builds going:
+  - Added autoconf to common dependencies
+  - Added automake to common dependencies
+  - Added libtool to common dependencies
+  - Added libssl-dev to common dependencies
   
-  Follow-up to 0c55fbab45be
+  Co-authored-by: Albin Vass
   
-  Reviewed-by: Emil Engler
-  Closes #7090
+  Closes #7245
 
-- wolfssl: remove SSLv3 support leftovers
+- netrc: skip 'macdef' definitions
   
-  Closes #7088
+  Add test 494 to verify
+  
+  Reported-by: Harry Sintonen
+  Fixes #7238
+  Closes #7244
 
-- curl-wolfssl.m4: without custom include path, assume /usr/include
+- multi: add scan-build-6 work-around in curl_multi_fdset
   
-  ... so that we can point out the root of the OpenSSL emulation headers.
-  Previously this used the '$includedir' variable which is wrong since
-  that defaults to the dir where the current configure invoke will install
-  the built libcurl headers: /usr/local by default.
+  scan-build-6 otherwise warns, saying: warning: The left operand of '>='
+  is a garbage value otherwise, which is false.
   
-  Fixes #7085
-  Reported-by: Joel Jakobsson
-  Closes #7087
-
-- [Joel Depooter brought this change]
+  Later scan-builds don't claim this on the same code.
+  
+  Closes #7248
 
-  data_pending: check only SECONDARY socket for FTP(S) transfers
+- asyn-ares: remove check for 'data' in Curl_resolver_cancel
   
-  Check the FIRST for all other protocols.
+  It implied it would survive a NULL in there which it won't. Instead do
+  an assert.
   
-  This fixes a timeout in an ftps download. The server sends a TLS
-  close_notify message in the same packet as the file data. The
-  close_notify seems to not be handled in the schannel_recv function, so
-  libcurl is not aware that the server has closed the connection. Thus
-  libcurl ends up waiting for action on the socket until a timeout is
-  reached. With the secondary socket check added to the data_pending
-  function, the close_notify is properly handled, and the ftps transfer
-  terminates as expected.
+  Pointed out by scan-build.
   
-  Fixes #7068
-  Closes #7069
+  Closes #7248
 
-- github: inhibit deprecated declarations for clang on macOS
+- url.c: remove two variable assigns that are never read
   
-  ... as they otherwise cause ldap build errors in the CI.
+  Pointed out by scan-build
   
-  Fixes #7081
-  Closes #7082
+  Closes #7248
 
-- conn: add 'attach' to protocol handler, make libssh2 use it
+- [Gealber Morales brought this change]
+
+  mqtt: add support for username and password
   
-  The libssh2 backend has SSH session associated with the connection but
-  the callback context is the easy handle, so when a connection gets
-  attached to a transfer, the protocol handler now allows for a custom
-  function to get used to set things up correctly.
+  Minor-edits-by: Daniel Stenberg
+  Added test 2200 to 2205
   
-  Reported-by: Michael O'Farrell
-  Fixes #6898
-  Closes #7078
+  Closes #7243
 
-- http2: make sure pause is done on HTTP
-  
-  Since the function is called for any protocol, we can't assume that the
-  HTTP struct is there without first making sure it is HTTP.
+- travis: remove the arm job
   
-  Reported-by: Denis Goleshchikhin
-  Fixes #7079
-  Closes #7080
+  We do it on circle CI instead
 
-- docs: cookies from HTTP headers need domain set
+- CI: add .circleci/config.yml
   
-  ... or the cookies won't get sent. Push users to using the "Netscape"
-  format instead, which curl uses when saving a cookie "jar".
+  Assisted-by: Gabriel Simmer
   
-  Reported-by: Martin Dorey
-  Reviewed-by: Daniel Gustafsson
-  Fixes #6723
-  Closes #7077
+  Closes #7239
 
 - RELEASE-NOTES: synced
 
-- github: add a workflow with libssh2 on macOS using cmake
-  
-  Closes #7047
+- runtests: init $VERSION to avoid warnings when using -l
 
-- sws: allow HTTP requests up to 2MB in size
+- openssl: don't remove session id entry in disassociate
   
-  To allow tests with slightly larger payloads. Like #7071 ...
+  When a connection is disassociated from a transfer, the Session ID entry
+  should remain.
   
-  Closes #7075
-
-Marc Hoersken (16 May 2021)
-- CI/azure: increase verbosity and fix outdated task names
+  Regression since 7f4a9a9 (shipped in libcurl 7.77.0)
+  Reported-by: Gergely Nagy
+  Reported-by: Paul Groke
   
-  Closes #7063
+  Fixes #7222
+  Closes #7230
 
-- CI/cirrus: add shared and static Windows release builds
+- single_transfer: ignore blank --output-dir
   
-  Azure Pipelines is currently being used for debug builds,
-  let's also run some non-debug (release) Windows builds and
-  make use of previously underutilized Cirrus CI for that.
+  ... as otherwise it creates a rather unexpected target directory with a
+  leading slash.
   
-  Reviewed-by: Marcel Raad
+  Reported-by: Harry Sintonen
+  Fixes #7218
+  Closes #7233
+
+- tests: update README about servers and port numbers
   
-  Closes #6991
+  Closes #7242
 
-Daniel Stenberg (16 May 2021)
-- CURLOPT_CAPATH.3: defaults to a path, not NULL
+- conn_shutdown: if closed during CONNECT cleanup properly
   
-  Reported-by: Andrew Barnert
+  Reported-by: Alex Xu
+  Reported-by: Phil E. Taylor
   
-  Closes #7062
+  Fixes #7236
+  Closes #7237
 
-- [Jacob Hoffman-Andrews brought this change]
+- [Christian Weisgerber brought this change]
 
-  c-hyper: handle body on HYPER_TASK_EMPTY
-  
-  Some of the time, we get a HYPER_TASK_EMPTY response before the status
-  line, headers, and body have been read. Previously, that would cause us
-  to poll again, leading to a 1 second timeout.
+  sws: malloc request struct instead of using stack
   
-  The HYPER_TASK_EMPTY docs say:
+  ... 2MB requests is otherwise just too big for some systems.
   
-     The value of this task is null (does not imply an error).
+  (The allocations are not freed properly.)
   
-  So, if we receive a HYPER_TASK_EMPTY, continue on with processing the
-  response.
+  Bug: https://curl.se/mail/lib-2021-06/0018.html
   
-  Reported-by: Kevin Burke
-  Fixes #7064
-  Closes #7070
+  Closes #7235
 
-- [Ikko Ashimine brought this change]
+- [Mark Swaanenburg brought this change]
 
-  tool_getparam: fix comment typo in tool_getparam.c
+  lib: don't compare fd to FD_SETSIZE when using poll
   
-  enfore -> enforce
+  FD_SETSIZE is irrelevant when using poll. So ensuring that the file
+  descriptor is smaller than FD_SETSIZE in VALID_SOCK, can cause
+  multi_wait to ignore perfectly valid file descriptors and simply wait
+  for 1s to avoid hammering the CPU in a busy loop.
   
-  Closes #7074
+  Fixes #7240
+  Closes #7241
 
-- mem-include-scan.pl: require a non-word letter before memory funcs
-  
-  ... so that ldap_memfree() for example doesn't match the scan for free.
-  
-  Closes #7061
+- [zhangxiuhua brought this change]
 
-- version: free the openldap info correctly
-  
-  ... to avoid memory leaks.
+  doh: fix wrong DEBUGASSERT for doh private_data
   
-  Follow-up to: bf0feae7768d9
-  Closes #7061
+  Closes #7227
 
-- dupset: remove totally off comment
-  
-  Closes #7067
+- [yb999 brought this change]
 
-- configure: if asked for, fail if ldap is not found
+  tests: update README.md with a missing single quote
   
-  Reported-by: Jakub Zakrzewski
-  Fixes #7053
-  Closes #7055
+  Closes #7231
 
-- version: add OpenLDAP version in the output
+- GHA: run all tests for hyper too
   
-  Assisted-by: Howard Chu
-  Closes #7054
-
-Jay Satiro (13 May 2021)
-- [Joel Depooter brought this change]
+  As it lists disabled ones in DISABLED now
+  
+  Closes #7209
 
-  schannel: Ensure the security context request flags are always set
+- tests/data/DISABLED: add tests not working with hyper
   
-  As of commit 54e7475, these flags would only be set when using a new
-  credential handle. When re-using an existing credential handle, the
-  flags would not be set.
+  The goal is to remove them all from here over time.
   
-  Closes https://github.com/curl/curl/pull/7051
-
-Dan Fandrich (12 May 2021)
-- tests: Fix some tag matching issues in a number of tests
+  Closes #7209
 
-Daniel Stenberg (12 May 2021)
-- sasl: use 'unsigned short' to store mechanism
-  
-  ... saves a few bytes of struct size in memory and it only uses
-  10 bits anyway.
+- runtests: also find the last test in Makefile.inc
   
-  Closes #7045
+  Closes #7209
 
-- hostip: remove the debug code for LocalHost
+- test3010: work with hyper mode
   
-  The Curl_resolv() had special code (when built in debug mode) for when
-  resolving the host name "LocalHost" (using that exact casing). It would
-  then get the host name from the --interface option instead.
+  Closes #7209
+
+- configure: disable RTSP when hyper is selected
   
-  This development-only feature was not used by anything (anymore) and we
-  have the --resolve feature if we want to play similar tricks properly
-  going forward.
+  Makes test 1013 work
   
-  Closes #7044
+  Closes #7209
 
-- progress: reset limit_size variables at transfer start
+- test1594/1595/1596: fix to work in hyper mode
   
-  Otherwise the old value would linger from a previous use and would mess
-  up the network speed cap logic.
+  Closes #7209
+
+- test1438/1457: add HTTP keyword to make hyper mode work
   
-  Reported-by: Ymir1711 on github
+  Closes #7209
+
+- test1340/1341: adjusted for hyper mode
   
-  Fixes #7042
-  Closes #7043
+  Closes #7209
 
-- RELEASE-NOTES: synced
+- test1218: adjusted for hyper mode
+  
+  Closes #7209
 
-- [Daniel Gustafsson brought this change]
+- test1216: adjusted for hyper mode
+  
+  Closes #7209
 
-  cookies: use CURLcode for cookie_output reporting
+- test1230: adjust to work in hyper mode
   
-  Writing the cookie file has multiple error conditions, and was using an
-  int with magic numbers to report the different error (which in turn were
-  disregarded anyways). This moves reporting to use a CURLcode value.
+  Closes #7209
+
+- c-hyper: abort CONNECT response reading early on non 2xx responses
   
-  Lightly-touched-by: Daniel Stenberg
+  Fixes test 493
   
-  Closes #7037
-  Closes #6749
+  Closes #7209
 
-- [Daniel Gustafsson brought this change]
+- test434: add HTTP keyword
+  
+  Closes #7209
 
-  cookies: make use of string duplication function
+- test599: adjusted to work in hyper mode
   
-  strstore() is defined as a strdup which ensures to free the target
-  pointer before duping the source char * into it. Make use of it in
-  two more cases where it can simplify the code.
+  Closes #7209
 
-- [Daniel Gustafsson brought this change]
+- c-hyper: fix the uploaded field in progress callbacks
+  
+  Makes test 578 work
+  
+  Closes #7209
 
-  cookies: refactor comments
+- test566: adjust to work with hyper mode
   
-  Comments in the cookie code were a bit all over the place in terms of
-  style and wording. This takes a stab at cleaning them up by keeping to
-  a single style and overall shape. Some comments are moved a little and
-  some removed alltogether due to being redundant. No functional changes
-  have been made,
+  Closes #7209
 
-- [Peng-Yu Chen brought this change]
+- [Fawad Mirza brought this change]
 
-  http2: skip immediate parsing of payload following protocol switch
-  
-  This is considered not harmful as a following http2_recv shall be
-  called very soon.
+  CURLOPT_WRITEFUNCTION.3: minor update of the example
   
-  This is considered helpful in the specific situation where some
-  servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately
-  following the return of HTTP status 101, other than waiting for
-  the client-side connection preface to arrive.
+  Safely avoid chunk.size garbage value if declared non globally.
   
-  Fixes #7036
-  Closes #7040
+  Closes #7219
 
-- [Peng-Yu Chen brought this change]
+- [Bastian Krause brought this change]
 
-  http2: use nghttp2_session_upgrade2 instead of nghttp2_session_upgrade
+  configure: rename get-easy-option configure option to get-easy-options
   
-  Following the upstream deprecation of nghttp2_session_upgrade.
+  "get-easy-options" is the configure option advertised by the help text
+  anyway, so use that.
   
-  Also provides further checks for requests with the HEAD method.
+  Fixes #7211
+  Closes #7213
   
-  Closes #7041
+  Follow-up to ad691b191 ("configure: added --disable-get-easy-options")
+  Suggested-by: Daniel Stenberg 
+  Signed-off-by: Bastian Krause 
 
-- progress/trspeed: use a local convenient pointer to beautify code
+- runtests: skip disabled tests unless -f is used
   
-  The function becomes easier to read and understand with less repetition.
+  To make it easier to write ranges like '115 to 229' without that
+  explicitly enabling tests that are listed in DISABLED, this makes
+  runtests always skip disabled tests unless the -f command line option is
+  used.
+  
+  Previously the code attempted to not run such tests, but didn't do it
+  correctly.
+  
+  Closes #7212
 
-- trspeed: use long double for transfer speed calculation
+- [Jun-ya Kato brought this change]
 
-- progress: move transfer speed calc into function
+  ngtcp2: disable TLSv1.3 compatible mode when using GnuTLS
   
-  This silences two scan-build-11 warnings: "The result of the '/'
-  expression is undefined"
+  The latest GnuTLS-3.7.2 implements disable switch for TLSv1.3 compatible
+  mode for middle box but it is enabled by default, which is unnecessary
+  for QUIC.
   
-  Bug: https://curl.se/mail/lib-2021-05/0022.html
-  Closes #7035
-
-- [Cameron Cawley brought this change]
+  Fixes #6896
+  Closes #7202
 
-  openssl: remove unneeded cast for CertOpenSystemStore()
+- test644: remove as duplicate of test 587
   
-  Closes #7025
+  Closes #7208
 
-- travis: disable the libssh build
+Daniel Gustafsson (8 Jun 2021)
+- RELEASE-NOTES: synced
+
+- cookies: track expiration in jar to optimize removals
   
-  It can't run on focal and causes warnings on bionic. Since the focal
-  failure started rather suddenly a while ago, we can suspect it might be
-  temporary.
+  Removing expired cookies needs to be a fast operation since we want to
+  be able to perform it often and speculatively. By tracking the timestamp
+  of the next known expiration we can exit early in case the timestamp is
+  in the future.
   
-  Added "bring back the build" to the TODO document.
+  Closes: #7172
+  Reviewed-by: Daniel Stenberg 
+
+Daniel Stenberg (7 Jun 2021)
+- GHA: add several libcurl tests to the hyper job
   
-  Fixes #7011
-  Closes #7012
+  500 to 512
 
-- [Peng-Yu Chen brought this change]
+- test500: adjust to work with hyper mode
 
-  http: use calculated offsets inst of integer literals for header parsing
+- c-hyper: support CURLINFO_STARTTRANSFER_TIME
   
-  Assumed to be a minor coding style improvement with no behavior change.
+  Closes #7204
+
+- c-hyper: support CURLOPT_HEADER
   
-  A modern compiler is expected to have the calculation optimized during
-  compilation. It may be deemed okay even if that's not the case, since
-  the added overhead is considered very low.
+  When enabled, the headers are passed to the body write callback as well.
   
-  Closes #7032
-
-- [Peng-Yu Chen brought this change]
-
-  GIT-INFO: suggest using autoreconf instead of buildconf
+  Like in test 500
   
-  Follow-up to 85868537d
+  Closes #7204
+
+- GHA: run the newly fixed tests with hyper
   
-  Closes #7033
+  Closes #7205
 
-- http: deal with partial CONNECT sends
+- test433: adjust for hyper mode
   
-  Also added 'CURL_SMALLSENDS' to make Curl_write() send short packets,
-  which helped verifying this even more.
+  Closes #7205
+
+- test395: hyper cannot work around > 64 bit content-lengths like built-in
   
-  Add test 363 to verify.
+  Closes #7205
+
+- test394: hyper returns a different error
   
-  Reported-by: ustcqidi on github
-  Fixes #6950
-  Closes #7024
+  Closes #7205
 
-- HTTP3: make the ngtcp2 build use the quictls fork
+- test393: make Content-Length fit within 64 bit for hyper
   
-  ... as ngtcp2 itself documents the build this way.
+  Closes #7205
+
+- test347: CRLFify to work in hyper mode
   
-  Closes #7031
+  Closes #7205
 
-- http: limit the initial send amount to used upload buffer size
+- test339: CRLFify better to work in hyper mode
   
-  Previously this logic would cap the send to CURL_MAX_WRITE_SIZE bytes,
-  but for the situations where a larger upload buffer has been set, this
-  function can benefit from sending more bytes. With default size used,
-  this does the same as before.
+  Closes #7205
+
+- travis: remove the hyper build
+
+- GHA: add a linux-hyper job
   
-  Also changed the storage of the size to an 'unsigned int' as it is not
-  allowed to be set larger than 2M.
+  Closes #7206
+
+- test328: avoid a header-looking body to make hyper mode work
   
-  Also added cautions to the man pages about changing buffer sizes in
-  run-time.
+  The test still works the same, just modified two bytes in the content.
   
-  Closes #7022
+  Closes #7203
 
-- RELEASE-NOTES: synced
+- release-notes.pl: also spot common 'closes' typo
 
-- ngtcp2: fix the cb_acked_stream_data_offset proto
+- metalink: remove
   
-  The 'datalen' value should be 64 bit, not size_t!
+  Warning: this will make existing curl command lines that use metalink to
+  stop working.
   
-  Reported-by: Dmitry Karpov
-  Bug: https://curl.se/mail/lib-2021-05/0019.html
-  Closes #7027
-
-- progress: when possible, calculate transfer speeds with microseconds
+  Reasons for removal:
   
-  ... this improves precision, especially for transfers in the few or even
-  sub millisecond range.
+  1. We've found several security problems and issues involving the
+     metalink support in curl. The issues are not detailed here. When
+     working on those, it become apparent to the team that several of the
+     problems are due to the system design, metalink library API and what
+     the metalink RFC says. They are very hard to fix on the curl side
+     only.
   
-  Reported-by: J. Bromley
-  Fixes #7017
-  Closes #7020
-
-- http: reset the header buffer when sending the request
+  2. The metalink usage with curl was only very briefly documented and was
+     not following the "normal" curl usage pattern in several ways, making
+     it surprising and non-intuitive which could lead to further security
+     issues.
   
-  A reused transfer handle could otherwise reuse the previous leftover
-  buffer and havoc would ensue.
+  3. The metalink library was last updated 6 years ago and wasn't so
+     active the years before that either. An unmaintained library means
+     there's a security problem waiting to happen. This is probably reason
+     enough.
+  
+  4. Metalink requires an XML parsing library, which is complex code (even
+     the smaller alternatives) and to this day often gets security
+     updates.
+  
+  5. Metalink is not a widely used curl feature. In the 2020 curl user
+     survey, only 1.4% of the responders said that they'd are using it. In
+     2021 that number was 1.2%. Searching the web also show very few
+     traces of it being used, even with other tools.
+  
+  6. The torrent format and associated technology clearly won for
+     downloading large files from multiple sources in parallel.
   
-  Reported-by: sergio-nsk on github
-  Fixes #7018
-  Closes #7021
+  Cloes #7176
 
-- curl_mprintf.3: add description
+- docs/INSTALL: remove mentions of configure --with-darwin-ssl
   
-  These functions have existed in the API since the dawn of time. It is
-  about time we describe how they work, even if we discourage users from
-  using them.
+  ... as it isn't supported since a while back.
   
-  Closes #7010
+  Make configure fail with a warning if used.
+  
+  Reported-by: Vadim Grinshpun
+  Bug: https://curl.se/mail/lib-2021-06/0008.html
+  Closes #7200
 
-- [Timothy Gu brought this change]
+- RELEASE-NOTES: synced
 
-  URL-SYNTAX: update IDNA section for WHATWG spec changes
+- [Gregor Jasny brought this change]
+
+  cmake: Avoid leaking absolute paths into exported config
   
-  WHATWG URL has dictated the use of Nontransitional Processing (IDNA
-  2008) for several years now. Chrome (and derivatives) still use
-  Transitional Processing, but Firefox and Safari have both switched.
+  The `find_libarary` command resolves the library or framework
+  into an absolute path. In case of system frameworks which are
+  located within an Xcode-provided SDK this results in the Xcode
+  path and SDK version being part of the library path.
   
-  Also document the fact that winidn functions differently from libidn2
-  here.
+  Because those library paths end up in the exported CMake config
+  importing curl will fail once the Xcode location or SDK version
+  changes:
   
-  Closes #7026
+  ```cmake
+  set_target_properties(CURL::libcurl PROPERTIES
+    INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
+    INTERFACE_LINK_LIBRARIES "lber;ldap;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/System/Library/Frameworks/SystemConfiguration.framework;OpenSSL::SSL;OpenSSL::Crypto;ZLIB::ZLIB"
+  )
+  ```
+  
+  A work-around is to link against system-level frameworks with
+  `-framework XYZ`. In case of `SystemConfiguration` we might be able
+  to omit the lookup-check because we could assume the framework is
+  always present.
+  
+  Closes #7152
 
-- [Calvin Buckley brought this change]
+- [Shikha Sharma brought this change]
 
-  INSTALL: add IBM i specific quirks
+  http2_connisdead: handle trailing GOAWAY better
   
-  Fixes #6830
-  Closes #7013
+  When checking the connection the input processing returns error
+  immediately, we now consider that a dead connnection.
+  
+  Bug: https://curl.se/mail/lib-2021-06/0001.html
+  Closes #7192
 
-- libcurl.3: mention the URL API
+- [Dmitry Karpov brought this change]
+
+  ares: always store IPv6 addresses first
   
-  To make it easier to find. Also a minor polish of libcurl-url.3
+  Trying dual-stack on some embedded platform, I noticed that quite
+  frequently (20%) libCurl starts from IPv4 regardless the Happy Eyeballs
+  timeout value.  After debugging this issue, I noticed that this happens
+  if c-ares resolver response for IPv6 family comes before IPv4 (which was
+  randomly happening in my tests).
   
-  Closes #7009
-
-- GnuTLS: don't allow TLS 1.3 for versions that don't support it
+  In such cases, because libCurl puts the last resolver response on top of
+  the address list, when IPv4 resolver response comes after IPv6 one - the
+  IPv4 family starts the connection phase instead of IPv6 family.
   
-  Follow-up to 781864bedbc5
+  The solution for this issue is to always put IPv6 addresses on top of
+  the address list, regardless the order of resolver responses.
   
-  ... as they don't understand it and will return error at us!
+  Bug: https://curl.se/mail/lib-2021-06/0003.html
   
-  Closes #7014
+  Closes #7188
 
-Kamil Dudka (6 May 2021)
-- tool_getparam: handle failure of curlx_convert_tchar_to_UTF8()
+- Revert "Revert "socketpair: fix potential hangs""
   
-  Reported by GCC analyzer:
+  This reverts commit 3e70c3430a370a31eff2c1d8fea29edaca8f1127.
   
-  Error: GCC_ANALYZER_WARNING (CWE-476):
-  src/tool_getparam.c: scope_hint: In function 'parse_args'
-  src/tool_getparam.c:2318:38: warning[-Wanalyzer-possible-null-dereference]: dereference of possibly-NULL 'orig_opt'
-  lib/curlx.h:56: included_from: Included from here.
-  src/tool_getparam.c:28: included_from: Included from here.
-  lib/curl_multibyte.h:70:51: note: in definition of macro 'curlx_convert_tchar_to_UTF8'
-  src/tool_getparam.c:2316:16: note: in expansion of macro 'curlx_convert_tchar_to_UTF8'
+  Thus brings back the change from #7144 as was originally landed in
+  c769d1eab4de8b
   
-  Reviewed-by: Marcel Raad
-  Reviewed-by: Daniel Stenberg
-  Closes #7023
+  Closes #7144 (again)
 
-Daniel Stenberg (6 May 2021)
-- scripts/delta: also show total number of days
+- [Ebe Janchivdorj brought this change]
 
-Marc Hoersken (5 May 2021)
-- sockfilt: fix invalid increment of handles index variable nfd
-  
-  Only increment the array index if we actually stored a handle.
+  schannel: move code out of SChannel_connect_step1
   
-  Follow up to e917492048f4b85a0fd58a033d10072fc7666c3b
-  Closes #6992
+  Reviewed-by: Marc Hoersken
+  Closes #7168
 
-- sockfilt: avoid getting stuck waiting for writable socket
-  
-  Reset FD_WRITE event using the same approach as in multi.c
+- tests/data/Makefile.inc: error: trailing backslash on last line
   
-  Follow up to b36442b24305f3cda7c13cc64b46838995a4985b
-  Closes #6992
+  Follow-up to d8dcb399b8009d
 
-Jay Satiro (5 May 2021)
-- test678: Fix for Windows multibyte builds
-  
-  Follow-up to 77fc385 from yesterday.
-  
-  Bug: https://github.com/curl/curl/pull/6662#issuecomment-832966557
-  Reported-by: Marc Hörsken
+- TODO: Support rate-limiting for MQTT
 
 - [Dmitry Kostjuchenko brought this change]
 
-  build: fix compilation for Windows UWP platform
+  warnless: simplify type size handling
   
-  - Include afunix.h which is necessary for sockaddr_un when
-    USE_UNIX_SOCKETS is defined on Windows.
+  By using sizeof(T), existing defines and relying on the compiler to
+  define the required signed/unsigned mask.
   
-  Closes https://github.com/curl/curl/pull/7006
+  Closes #7181
 
-Daniel Stenberg (5 May 2021)
-- gnutls: make setting only the MAX TLS allowed version work
-  
-  Previously, settting only the max allowed TLS version, leaving the
-  minimum one at default, didn't actually set it and left it to default
-  (TLS 1.3) too!
-  
-  As a bonus, this change also removes the dead code handling of SSLv3
-  since that version can't be set anymore (since eff614fb0242cb).
+Gisle Vanem (4 Jun 2021)
+- [Win32] Fix for USE_WATT32
   
-  Reported-by: Daniel Carpenter
-  Fixes #6998
-  Closes #7000
+  My Watt-32 tcp/ip stack works on Windows but it does not have `WSAIoctl()`
 
-- openldap: replace ldap_ prefix on private functions
-  
-  Since openldap itself uses that prefix and with OpenĹDAP 2.5.4 (at
-  least) there's a symbol collision because of that.
+Daniel Stenberg (4 Jun 2021)
+- [Alexis Vachette brought this change]
+
+  url: bad CURLOPT_CONNECT_TO syntax now returns error
   
-  The private functions now use the 'oldap_' prefix where it previously
-  used 'ldap_'.
+  Added test 3020 to verify
   
-  Reported-by: 3eka on github
-  Fixes #7004
-  Closes #7005
+  Closes #7183
 
-Jay Satiro (5 May 2021)
-- http2: fix potentially uninitialized variable
+- github: remove the cmake macOS gcc-8 jobs
   
-  introduced several days ago in 3193170. caught by visual studio linker.
-
-- [Gilles Vollant brought this change]
+  They're too similar to the gcc-9 ones to be useful (and seems to not
+  work anymore).
+  
+  Closes #7187
 
-  SSL: support in-memory CA certs for some backends
+- test269: disable for hyper
   
-  - New options CURLOPT_CAINFO_BLOB and CURLOPT_PROXY_CAINFO_BLOB to
-    specify in-memory PEM certificates for OpenSSL, Schannel (Windows)
-    and Secure Transport (Apple) SSL backends.
+  --ignore-content-length / CURLOPT_IGNORE_CONTENT_LENGTH doesn't work
+  with hyper.
   
-  Prior to this change PEM certificates could only be imported from a file
-  and not from memory.
+  Closes #7184
+
+- runtests: enable 'hyper mode' only for HTTP tests
   
-  Co-authored-by: moparisthebest@users.noreply.github.com
+  The 'hyper mode' makes line-ending checks work in the test suite for
+  when hyper is used. Now it also requires that HTTP or HTTPS are
+  mentioned as keywords to be enabled so that it doesn't wrongly adjusts
+  tests for other protocols.
   
-  Ref: https://github.com/curl/curl/pull/4679
-  Ref: https://github.com/curl/curl/pull/5677
-  Ref: https://github.com/curl/curl/pull/6109
+  This makes test 271 (TFTP) work again in hyper enabled builds.
   
-  Closes https://github.com/curl/curl/pull/6662
+  Closes #7185
 
-Daniel Stenberg (4 May 2021)
-- [David Cook brought this change]
+- [Alexis Vachette brought this change]
 
-  tests: ignore case of chunked hex numbers in tests
+  hostip: bad CURLOPT_RESOLVE syntax now returns error
   
-  When hyper is used, it emits uppercase hexadecimal numbers for chunked
-  encoding lengths. Without hyper, lowercase hexadecimal numbers are used.
-  This change adds preprocessor statements to tests where this is an
-  issue, and adapts the fixtures to match.
+  Added test 3019
+  Fixes #7170
+  Closes #7174
+
+Daniel Gustafsson (3 Jun 2021)
+- cookies: fix typo and expand comment
   
-  Closes #6987
+  Fix a typo in the sorting comment, and while in there elaborate slightly
+  on why creationtime can be used as a tiebreaker.
 
-- cmake: check for getppid and utimes
+- cookies: remove unused header
   
-  ... as they're checked for in the configure script and are used by
-  source code.
+  Commit 1c1d9f1affbd3367bcb24062e261d0ea5d185e3a removed the last use
+  for the inet_pton.h headerfile, this removes the inclusion of the
+  header.
   
-  Removed checks for perror, setvbuf and strlcat since those defines are
-  not checked for in source code.
+  Closes: #7182
+  Reviewed-by: Daniel Stenberg 
+
+Daniel Stenberg (3 Jun 2021)
+- Revert "socketpair: fix potential hangs"
   
-  Bonus: removed HAVE_STRLCPY from a few config-*.h files since that
-  symbol is not used in source code.
+  This reverts commit c769d1eab4de8b9f1bd84d992c63692fdc43c5be.
   
-  Closes #6997
+  See #7144 for details
 
-- libtest: remove lib530.c
+- [Paul Groke brought this change]
+
+  socketpair: fix potential hangs
   
-  Follow up from e50a877df when test 530 was removed. Since then this
-  source file has not been used/needed.
+  Fixes potential hang in accept by using select + non-blocking accept.
   
-  Closes #6999
-
-- FILEFORMAT: mention sectransp as a feature
+  Fixes potential hang in peer check by replacing the send/recv check with
+  a getsockname/getpeername check.
   
-  Been supported since at least 40259ca65
+  Adds length check for returned sockaddr data.
   
-  Closes #7001
-
-- RELEASE-NOTES: synced
+  Closes #7144
 
-- libssh2: ignore timeout during disconnect
+- runtests: parse data/Makefile.inc instead of using make
   
-  ... to avoid memory leaks!
+  The warning about missing entries in that file then doesn't require that
+  the Makefile has been regenerated which was confusing.
   
-  libssh2 is tricky as we have to deal with the non-blockiness even in
-  close and shutdown cases. In the cases when we shutdown after a timeout
-  already expired, it is crucial that curl doen't let the timeout abort
-  the shutdown process as that then leaks memory!
+  The scan for the test num is a little more error prone than before
+  (since now it doesn't actually verify that it is legitimate Makefile
+  syntax), but I think it is good enough.
   
-  Reported-by: Benjamin Riefenstahl
-  Fixes #6990
+  Closes #7177
 
-- KNOWN_BUGS: add two HTTP/2 bugs
+- [Harry Sintonen brought this change]
 
-- KNOWN_BUGS: add three HTTP/3 issues
-  
-  ... and moved the HTTP/2 issues to its own section
+  filecheck: quietly remove test-place/*~
   
-  Closes #6606
-  Closes #6510
-  Closes #6494
+  Closes #7179
 
-- [ejanchivdorj brought this change]
+- CURLE_SETOPT_OPTION_SYNTAX: new error name for wrong setopt syntax
+  
+  For options that pass in lists or strings that are subsequently parsed
+  and must be correct. This broadens the scope for the option previously
+  known as CURLE_TELNET_OPTION_SYNTAX but the old name is of course still
+  provided as a #define for existing applications.
+  
+  Closes #7175
 
-  CURLcode: add CURLE_SSL_CLIENTCERT
+- tests: fix Accept-Encoding strips to work with Hyper builds
   
-  When a TLS server requests a client certificate during handshake and
-  none can be provided, libcurl now returns this new error code
-  CURLE_SSL_CLIENTCERT
+  The previous strip also removed the CR which turned problematic.
   
-  Only supported by Secure Transport and OpenSSL for TLS 1.3 so far.
+  valgrind.supp: add zstd suppression using hyper
   
-  Closes #6721
-
-- [Tobias Gabriel brought this change]
+  Reported-and-analyzed-by: Kevin Burke
+  Fixes #7169
+  Closes #7171
 
-  .github/FUNDING: add link to GitHub sponsors
+- github: timeout jobs on macOS after 90 minutes
   
-  Closes #6985
+  Assisted-by: Marc Hoersken
+  Closes #7173
 
 - [Harry Sintonen brought this change]
 
-  krb5/name_to_level: replace checkprefix with curl_strequal
+  mqtt: detect illegal and too large file size
   
-  Closes #6993
+  Add test 3017 and 3018 to verify.
+  Closes #7166
 
-- [Harry Sintonen brought this change]
+- [Abhinav Singh brought this change]
 
-  Curl_input_digest: require space after Digest
+  cmake: add CURL_DISABLE_NTLM option
   
-  Closes #6993
+  Closes #7028
 
-- [Harry Sintonen brought this change]
+- [Abhinav Singh brought this change]
 
-  Curl_http_header: check for colon when matching Persistent-Auth
+  configure: add --disable-ntlm option
   
-  Closes #6993
-
-- [Harry Sintonen brought this change]
+  Closes #7028
 
-  Curl_http_input_auth: require valid separator after negotiation type
-  
-  Closes #6993
+- [Abhinav Singh brought this change]
 
-- http: fix the check for 'Authorization' with Bearer
+  define: re-add CURL_DISABLE_NTLM and corresponding ifdefs
   
-  The code would wrongly check for it using an additional colon.
+  This flag will be further exposed by adding build options.
   
-  Reported-by: Blake Burkhart
-  Closes #6988
+  Reverts #6809
+  Closes #7028
 
-- [Kamil Dudka brought this change]
+- RELEASE-NOTES: synced
 
-  http2: fix a resource leak in push_promise()
-  
-  ... detected by Coverity:
-  
-  Error: RESOURCE_LEAK (CWE-772):
-  lib/http2.c:532: alloc_fn: Storage is returned from allocation function "duphandle".
-  lib/http2.c:532: var_assign: Assigning: "newhandle" = storage returned from "duphandle(data)".
-  lib/http2.c:552: noescape: Resource "newhandle" is not freed or pointed-to in "set_transfer_url".
-  lib/http2.c:555: leaked_storage: Variable "newhandle" going out of scope leaks the storage it points to.
+Viktor Szakats (1 Jun 2021)
+- travis: delete --enable-hsts option (it is the default now) [ci skip]
   
-  Closes #6986
-
-- [Kamil Dudka brought this change]
+  Reviewed-by: Daniel Stenberg
+  Closes #7167
 
-  http2: fix resource leaks in set_transfer_url()
-  
-  ... detected by Coverity:
-  
-  Error: RESOURCE_LEAK (CWE-772):
-  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
-  lib/http2.c:486: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:488: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+Daniel Stenberg (1 Jun 2021)
+- hostip: fix 3 coverity complaints
   
-  Error: RESOURCE_LEAK (CWE-772):
-  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
-  lib/http2.c:493: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:495: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+  Follow-up to 1a0ebf6632f889eed
   
-  Error: RESOURCE_LEAK (CWE-772):
-  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
-  lib/http2.c:500: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:502: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+  - Check the return code to Curl_inet_pton() in two instances, even
+    though we know the input is valid so the functions won't fail.
   
-  Error: RESOURCE_LEAK (CWE-772):
-  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
-  lib/http2.c:505: noescape: Resource "u" is not freed or pointed-to in "curl_url_get". [Note: The source code implementation of the function has been overridden by a builtin model.]
-  lib/http2.c:507: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
+  - Clear the 'struct sockaddr_in' struct before use so that the
+    'sin_zero' field isn't left uninitialized.
   
-  Closes #6986
+  Detected by Coverity.
+  Assisted-by: Harry Sintonen
+  Closes #7163
 
-- [Jacob Hoffman-Andrews brought this change]
+- c-hyper: fix NTLM on closed connection tested with test159
+  
+  Closes #7154
 
-  rustls: use ALPN
+- conncache: lowercase the hash key for better match
   
-  Update required rustls to 0.5.0
+  As host names are case insensitive, the use of case sensitive hashing
+  caused unnecesary cache misses and therefore lost performance. This
+  lowercases the hash key.
   
-  Closes #6960
+  Reported-by: Harry Sintonen
+  Fixes #7159
+  Closes #7161
 
-- [Michał Antoniak brought this change]
+- mbedtls: make mbedtls_strerror always work
+  
+  If the function doesn't exist, provide a macro that just clears the
+  error message. Removes #ifdef uses from the code.
+  
+  Closes #7162
 
-  gskit: fix CURL_DISABLE_PROXY build
+- vtls: exit addsessionid if no cache is inited
   
-  Removed localfd and remotefd from ssl_backend_data (ued only with proxy
-  connection). Function pipe_ssloverssl return always 0, when proxy is not
-  used.
+  Follow-up to b249592d29ae0
   
-  Closes #6981
+  Avoids NULL pointer derefs.
+  
+  Closes #7165
 
-- [Michał Antoniak brought this change]
+- [Harry Sintonen brought this change]
 
-  gskit: fix undefined reference to 'conn'
+  Curl_ntlm_core_mk_nt_hash: fix OOM in error path
   
-  Closes #6980
-
-- [Jacob Hoffman-Andrews brought this change]
+  Closes #7164
 
-  tls: add USE_HTTP2 define
+Michael Kaufmann (1 Jun 2021)
+- ssl: read pending close notify alert before closing the connection
   
-  This abstracts across the two HTTP/2 backends: nghttp2 and Hyper.
+  This avoids a TCP reset (RST) if the server initiates a connection
+  shutdown by sending an SSL close notify alert and then closes the TCP
+  connection.
   
-  Add our own define for the "h2" ALPN protocol, so TLS backends can use
-  it without depending on a specific HTTP backend.
+  For SSL connections, usually the server announces that it will close the
+  connection with an SSL close notify alert. curl should read this alert.
+  If curl does not read this alert and just closes the connection, some
+  operating systems close the TCP connection with an RST flag.
   
-  Closes #6959
+  See RFC 1122, section 4.2.2.13
+  
+  If curl reads the close notify alert, the TCP connection is closed
+  normally with a FIN flag.
+  
+  The new code is similar to existing code in the "SSL shutdown" function:
+  try to read an alert (non-blocking), and ignore any read errors.
+  
+  Closes #7095
 
-- [Jacob Hoffman-Andrews brought this change]
+Daniel Stenberg (1 Jun 2021)
+- [Laurent Dufresne brought this change]
 
-  lib: fix 0-length Curl_client_write calls
+  setopt: fix incorrect comments
   
-  Closes #6954
+  Closes #7157
 
-- [Jacob Hoffman-Andrews brought this change]
+- [Laurent Dufresne brought this change]
 
-  lib: remove strlen call from Curl_client_write
+  mbedtls: add support for cert and key blob options
   
-  At all call sites with an explicit 0 len, pass an appropriate nonzero
-  len.
+  CURLOPT_SSLCERT_BLOB and CURLOPT_SSLKEY_BLOB weren't usable with
+  mbedtls backend, so the support was added.
   
-  Closes #6954
+  Closes #7157
 
-- [Ayushman Singh Chauhan brought this change]
+- [Gregor Jasny brought this change]
 
-  docs: camelcase it like GitHub everywhere
+  cmake: try well-known send/recv signature for Apple
   
-  Closes #6979
-
-Jay Satiro (27 Apr 2021)
-- [Lucas Servén Marín brought this change]
-
-  docs: fix typo in fail-with-body doc
+  The CMake `try_compile` command is especially slow for
+  the Xcode generator. With this patch applied it first tests
+  for the currently used (and Open Group specified) send/recv
+  signature. In case this fails testing falls-back to the
+  permutations.
   
-  This commit fixes a small typo in the documentation for the
-  --fail-with-body flag.
+  speed-up:
   
-  Closes https://github.com/curl/curl/pull/6977
-
-- lib: fix some misuse of curlx_convert_UTF8_to_tchar
+  ```
+  time cmake .. -GNinja -DCMAKE_USE_SECTRANSP=ON -DHTTP_ONLY=ON -DCMAKE_USE_LIBSSH2=OFF
+  before: 11.64s user 11.09s system 55% cpu 40.754 total
+  after:   7.84s user 6.57s  system 51% cpu 28.074 total
+  ```
   
-  curlx_convert_UTF8_to_tchar must be freed by curlx_unicodefree, but
-  prior to this change some uses mistakenly called free.
+  ```
+  time cmake .. -GXcode -DCMAKE_USE_SECTRANSP=ON -DHTTP_ONLY=ON -DCMAKE_USE_LIBSSH2=OFF
+  before: 217.07s user 104.15s system 60% cpu 8:51.79 total
+  after:  108.76s user  51.80s system 58% cpu 4:32.58 total
+  ```
   
-  I've reviewed all other uses of curlx_convert_UTF8_to_tchar and
-  curlx_convert_tchar_to_UTF8.
+  Closes #7158
+
+- http2: init recvbuf struct for pushed streams
   
-  Bug: https://github.com/curl/curl/pull/6602#issuecomment-825236763
-  Reported-by: sergio-nsk@users.noreply.github.com
+  Debug builds would warn that these structs were not initialized properly
+  for pushed streams.
   
-  Closes https://github.com/curl/curl/pull/6938
+  Ref: #7148
+  Closes #7153
 
-Daniel Stenberg (27 Apr 2021)
-- ntlm: precaution against super huge type2 offsets
+- Curl_ssl_getsessionid: fail if no session cache exists
   
-  ... which otherwise caused an integer overflow and circumvented the if()
-  conditional size check.
+  This function might get called for an easy handle for which the session
+  cache hasn't been setup. It now just returns a "miss" in that case.
   
-  Detected by OSS-Fuzz
-  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33720
-  Assisted-by: Max Dymond
-  Closes #6975
-
-- c-hyper: fix unused variable ‘wrote’
+  Reported-by: Christoph M. Becker
+  Fixes #7148
+  Closes #7153
 
-- libcurl-security.3: be careful of setuid
+- GOVERNANCE: add 'user', 'committer' and 'contributor'
   
-  Reported-by: Harry Sintonen
-  Closes #6970
+  As those are commonly used terms in the project.
+  
+  Closes #7151
 
-- [Kevin Burke brought this change]
+- URL-SYNTAX.md: document the new 'localhost' treatment
 
-  c-hyper: don't write to set.writeheader if null
+- hostip: make 'localhost' return fixed values
   
-  Previously if a caller set CURLOPT_WRITEFUNCTION but did not set a
-  CURLOPT_HEADERDATA buffer, Hyper would still attempt to write headers to
-  the data->set.writeheader header buffer, even though it is null.  This
-  led to NPE segfaults attempting to use libcurl+Hyper with Git, for
-  example.
+  Resolving the case insensitive host name 'localhost' now returns the
+  addresses 127.0.0.1 and (if IPv6 is enabled) ::1 without using any
+  resolver.
   
-  Instead, process the client write for the status line using the same
-  logic we use to process the client write for the later HTTP headers,
-  which contains the appropriate guard logic. As a side benefit,
-  data->set.writeheader is now only read in one file instead of two.
+  This removes the risk that users accidentally resolves 'localhost' to
+  something else. By making sure 'localhost' is always local, we can
+  assume a "secure context" for such transfers (for cookies etc).
   
-  Fixes #6619
-  Fixes abetterinternet/crustls#49
-  Fixes hyperium/hyper#2438
-  Closes #6971
+  Closes #7039
 
-- wolfssl: handle SSL_write() returns 0 for error
-  
-  Reported-by: Timo Lange
-  
-  Closes #6967
+Daniel Gustafsson (31 May 2021)
+- docs: fix typos
 
-- easy: ignore sigpipe in curl_easy_send
+Daniel Stenberg (30 May 2021)
+- hsts: ignore numberical IP address hosts
   
-  Closes #6965
-
-- sigpipe: ignore SIGPIPE when using wolfSSL as well
+  Also, use a single function library-wide for detecting if a given hostname is
+  a numerical IP address.
   
-  Closes #6966
+  Reported-by: Harry Sintonen
+  Fixes #7146
+  Closes #7149
 
-- libcurl-security.3: don't try to filter IPv4 hosts based on the URL
+- test178: adjust for hyper
   
-  Closes #6942
+  Hyper returns the same error for wrong HTTP version as for negative
+  content-length. Test 178 verifies that negative content-length is
+  rejected but the hyper backend will return a different error for it (and
+  without any helpful message telling why the message was bad). It will
+  also not return any headers at all for the response, not even the ones
+  that arrived before the error.
+  
+  Closes #7147
 
-- [Harry Sintonen brought this change]
+- HYPER: remove mentions of deprecated development branch
 
-  nss_set_blocking: avoid static for sock_opt
+- c-hyper: handle NULL from hyper_buf_copy()
   
-  Reviewed-by: Kamil Dudka
-  Closes #6945
-
-- RELEASE-NOTES: synced
+  Closes #7143
 
-- [Yusuke Nakamura brought this change]
+- HSTS: not experimental anymore
 
-  docs/HTTP3.md: fix nghttp2's HTTP/3 server port
-  
-  Port 8443 does not work now.
-  Correct origin is in the quicwg's wiki.
-  https://github.com/quicwg/base-drafts/wiki/Implementations#ngtcp2
-  
-  Closes #6964
+- [Douglas R. Reno brought this change]
 
-- krb5: don't use 'static' to store PBSZ size response
+  INSTALL: use correct extension for CURL-DISABLE.md
   
-  ... because it makes the knowledge and usage cross-transfer in funny and
-  unexpected ways.
+  In INSTALL.MD, it's currently set to CURL-DISABLE-md instead of
+  CURL-DISABLE.md. This generates a 404 on the cURL website as well as
+  when viewing the docs through Github.
   
-  Reported-by: Harry Sintonen
-  Closes #6963
+  Closes #7142
 
-- [Kevin Burke brought this change]
+- travis: run tests 1 - 153 with hyper
 
-  m4: add security frameworks on Mac when compiling rustls
-  
-  Previously compiling rustls on Mac would only complete if you also
-  compiled the SecureTransport TLS backend, which curl would prefer to
-  the Rust backend.
-  
-  Appending these flags to LDFLAGS makes it possible to compile the
-  Rustls backend on Mac without the SecureTransport backend, which means
-  this patch will make it possible for Mac users to use the Rustls
-  backend for TLS.
+- c-hyper: convert HYPERE_INVALID_PEER_MESSAGE to CURLE_UNSUPPORTED_PROTOCOL
   
-  Reviewed-by: Jacob Hoffman-Andrews
+  Makes test 129 work (HTTP/1.2 response).
   
-  Fixes #6955
-  Cloes #6956
+  Closes #7141
 
-- krb5: remove the unused 'overhead' function
+- http_proxy: deal with non-200 CONNECT response with Hyper
   
-  Closes #6947
-
-- [Johann150 brought this change]
+  Makes test 94 and 95 work
+  
+  Closes #7141
 
-  curl_url_set.3: add memory management information
+- c-hyper: clear NTLM auth buffer when request is issued
   
-  wording taken from man page for CURLOPT_URL.3
+  To prevent previous ones to get reused on subsequent requests. Matches
+  how the built-in HTTP code works. Makes test 90 to 93 work.
   
-  As far as I can see, the URL part is either malloc'ed before due to
-  encoding or it is strdup'ed.
+  Add test 90 to 93 in travis.
   
-  Closes #6953
+  Closes #7139
 
-- [Jacob Hoffman-Andrews brought this change]
+- [Joel Depooter brought this change]
 
-  c-hpyer: fix handling of zero-byte chunk from hyper
+  schannel: set ALPN length correctly for HTTP/2
   
-  Closes #6951
-
-- CURLOPT_POSTFIELDS.3: clarify how it gets the size of the data
+  In a3268eca792f1 this code was changed to use the ALPN_H2 constant
+  instead of the NGHTTP2_PROTO_ALPN constant. However, these constants are
+  not the same. The nghttp2 constant included the length of the string,
+  like this: "\x2h2". The ALPN_H2 constant is just "h2". Therefore we need
+  to re-add the length of the string to the ALPN buffer.
   
-  Ref: https://curl.se/mail/lib-2021-04/0085.html
-  Closes #6943
-
-- [Ralph Langendam brought this change]
+  Closes #7138
 
-  cmake: make libcurl output filename configurable
+- travis: run tests 1-89 in the hyper build
   
-  Reviewed-by: Jakub Zakrzewski
-  Closes #6933
-
-- [Patrick Monnerat brought this change]
+  Closes #7137
 
-  vtls: reset ssl use flag upon negotiation failure
-  
-  Fixes the segfault in ldaps disconnect.
+- Revert "c-hyper: handle body on HYPER_TASK_EMPTY"
   
-  Reported-by: Illarion Taev
-  Fixes #6934
-  Closes #6937
-
-- configure: fix typo in TLS error message
+  This reverts commit c3eefa95c31f55657f0af422e8268d738f689066.
   
-  Reported-by: Pontus Lundkvist
-
-- README: link to the commercial support option
+  Reported-by: Kevin Burke
+  Fixes #7122
+  Closes #7136
 
-Jay Satiro (22 Apr 2021)
-- [Martin Halle brought this change]
+- [Jon Rumsey brought this change]
 
-  version: add gsasl_version to curl_version_info_data
-  
-  - Add gsasl_version string and bump to CURLVERSION_TENTH.
+  ccsidcurl: fix the compile errors
   
-  Ref: https://curl.se/mail/lib-2021-04/0003.html
+  Looks like the declaration of cpp shoule be const char ** and return
+  null if convert_version_info_string fails.
   
-  Closes https://github.com/curl/curl/pull/6843
+  Fixes #7134
+  Closes #7135
 
-- [Morten Minde Neergaard brought this change]
+- [Viktor Szakats brought this change]
 
-  schannel: Support strong crypto option
-  
-  - Support enabling strong crypto via optional user cipher list when
-    USE_STRONG_CRYPTO or SCH_USE_STRONG_CRYPTO is in the list.
-  
-  MSDN says SCH_USE_STRONG_CRYPTO "Instructs Schannel to disable known
-  weak cryptographic algorithms, cipher suites, and SSL/TLS protocol
-  versions that may be otherwise enabled for better interoperability."
+  docs: use --max-redirs instead of --max-redir
   
-  Ref: https://curl.se/mail/lib-2021-02/0066.html
-  Ref: https://curl.se/docs/manpage.html#--ciphers
-  Ref: https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html
-  Ref: https://docs.microsoft.com/en-us/windows/win32/api/schannel/ns-schannel-schannel_cred
+  For consistency.
   
-  Closes https://github.com/curl/curl/pull/6734
+  Closes #7130
 
-Daniel Stenberg (22 Apr 2021)
 - RELEASE-NOTES: synced
+  
+  ... and bump to 7.77.1
 
-- ci: adapt to configure requiring an explicit TLS choice
+- [Michael Forney brought this change]
 
-- configure: split out each TLS library detector into its own function
+  travis: add bearssl build
   
-  ... and put those functions in separate m4 files per TLS library.
+  Closes #7133
 
-- configure: make the TLS library choice(s) explicit
-  
-  configure no longer tries to find a TLS library by default, but all
-  libraries are now equal: the user needs to explicitly ask what TLS
-  library or libraries to use.
-  
-  If no TLS library is selected, configure will error out unless
-  --without-ssl is explicitly used to request a built without TLS (as that
-  is very rare these days).
+- [Michael Forney brought this change]
+
+  bearssl: explicitly initialize all fields of Curl_ssl
   
-  Removes: --with-winssl, --with-darwinssl and all --without-* options for
-  TLS libraries.
+  Also, add comments like the other vtls backends.
   
-  Closes #6897
+  Closes #7133
 
-- tests/disable-scan.pl: also scan all m4 files
-  
-  Fixes test 1165 when functions are moved from configure.ac to files in
-  m4/
+- [Michael Forney brought this change]
 
-Jay Satiro (22 Apr 2021)
-- schannel: Disable auto credentials; add an option to enable it
-  
-  - Disable auto credentials by default. This is a breaking change
-    for clients that are using it, wittingly or not.
-  
-  - New libcurl ssl option value CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl
-    to automatically locate and use a client certificate for
-    authentication, when requested by the server.
-  
-  - New curl tool options --ssl-auto-client-cert and
-    --proxy-ssl-auto-client-cert map to CURLSSLOPT_AUTO_CLIENT_CERT.
-  
-  This option is only supported for Schannel (the native Windows SSL
-  library). Prior to this change Schannel would, with no notification to
-  the client, attempt to locate a client certificate and send it to the
-  server, when requested by the server. Since the server can request any
-  certificate that supports client authentication in the OS certificate
-  store it could be a privacy violation and unexpected.
-  
-  Fixes https://github.com/curl/curl/issues/2262
-  Reported-by: Jeroen Ooms
-  Assisted-by: Wes Hinsley
-  Assisted-by: Rich FitzJohn
+  bearssl: remove incorrect const on variable that is modified
   
-  Ref: https://curl.se/mail/lib-2021-02/0066.html
-  Reported-by: Morten Minde Neergaard
+  hostname may be set to NULL later on in this function if it is an
+  IP address.
   
-  Closes https://github.com/curl/curl/pull/6673
+  Closes #7133
 
-Daniel Stenberg (22 Apr 2021)
-- [Michał Antoniak brought this change]
+Version 7.77.0 (26 May 2021)
+
+Daniel Stenberg (26 May 2021)
+- RELEASE-NOTES: synced
+
+- THANKS: added contributors from 7.77.0 cycle
+
+- copyright: update copyright year ranges to 2021
+
+- [Radek Zajic brought this change]
 
-  vtls: deduplicate some DISABLE_PROXY ifdefs
-  
-  continue from #5735
-  
-  - using SSL_HOST_NAME, SSL_HOST_DISPNAME, SSL_PINNED_PUB_KEY for other
-    tls backend
+  hostip: fix broken macOS/CMake/GCC builds
   
-  - create SSL_HOST_PORT
+  Follow-up to 31f631a142d855f06
   
-  Closes #6660
+  Fixes #7128
+  Closes #7129
 
-Jay Satiro (22 Apr 2021)
-- OS400: fix typo
+- TODO: netrc caching and sharing
   
-  CURLVERSION_HEIGHTH -> CURLVERSION_EIGHTH
+  URL: https://curl.se/mail/archive-2021-05/0018.html
 
-Daniel Stenberg (22 Apr 2021)
-- checksrc: complain on == NULL or != 0 checks in conditions
-  
-  ... to make them all consistenly use if(!var) and if(var)
-  
-  Also added a few missing warnings to the documentation.
-  
-  Closes #6912
+- [Orgad Shaneh brought this change]
 
-- tidy-up: make conditional checks more consistent
+  setopt: streamline ssl option code
   
-  ... remove '== NULL' and '!= 0'
+  Make it use the same style as the code next to it
   
-  Closes #6912
+  Closes #7123
 
-- [Patrick Monnerat brought this change]
+- [Radek Zajic brought this change]
 
-  vauth: factor base64 conversions out of authentication procedures
-  
-  Input challenges and returned messages are now in binary.
-  Conversions from/to base64 are performed by callers (currently curl_sasl.c
-  and http_ntlm.c).
+  lib/hostip6.c: make NAT64 address synthesis on macOS work
   
-  Closes #6654
+  Closes #7121
 
-- [Patrick Monnerat brought this change]
+- [ejanchivdorj brought this change]
 
-  bufref: buffer reference support
+  sectransp: fix EXC_BAD_ACCESS caused by uninitialized buffer
   
-  A struct bufref holds a buffer pointer, a data size and a destructor.
-  When freed or its contents are changed, the previous buffer is implicitly
-  released by the associated destructor. The data size, although not used
-  internally, allows binary data support.
+  When the SecCertificateCopyCommonName function fails, it leaves
+  common_name in a invalid state so CFStringCompare uses the invalid
+  result, causing EXC_BAD_ACCESS.
   
-  A unit test checks its handling methods: test 1661
+  The fix is to check the return value of the function before using the
+  name.
   
-  Closes #6654
+  Closes #7126
 
-- [Patrick Monnerat brought this change]
+- [Paweł Wegner brought this change]
 
-  os400: additional support for options metadata
-  
-  New functions curl_easy_option_by_name_ccsid() and
-  curl_easy_option_get_name_ccsid() allows accessing metadata in alternate
-  character encoding.
-  
-  This commit also updates curl_version_info_ccsid() to handle info version 9
-  and adds recent definitions to the ILE/RPG include file.
+  CMake: add CURL_ENABLE_EXPORT_TARGET option
   
-  Documentation updated accordingly.
+  install(EXPORT ...) causes trouble when embedding curl dependencies
+  which don't provide install(EXPORT ...) targets (e.g libressl and
+  nghttp2) with cmake's add_subdirectory.
   
-  Reviewed-by: Jon Rumsey
-  Closes #6574
-
-- [Patrick Monnerat brought this change]
+  Reviewed-by: Jakub Zakrzewski
+  Closes #7060
 
-  test server: take care of siginterrupt() deprecation
-  
-  Closes #6529
+- [Alessandro Ghedini brought this change]
 
-Marc Hoersken (21 Apr 2021)
-- lib1564.c: enable last wakeup test part on Windows
+  quiche: update for network path aware API
   
-  Suggested-by: Gergely Nagy
-  Reviewed-by: Jay Satiro
-  Reviewed-by: Marcel Raad
+  Latest version of quiche requires the application to pass the peer
+  address of received packets, and it provides the address for outgoing
+  packets back.
   
-  Closes #6245
+  Closes #7120
 
-- multi: fix slow write/upload performance on Windows
-  
-  Reset FD_WRITE by sending zero bytes which is permissible
-  and will be treated by implementations as successful send.
-  
-  Without this we won't be notified in case a socket is still
-  writable if we already received such a notification and did
-  not send any data afterwards on the socket. This would lead
-  to waiting forever on a writable socket being writable again.
-  
-  Assisted-by: Tommy Odom
-  Reviewed-by: Jay Satiro
-  Reviewed-by: Marcel Raad
-  Tested-by: tmkk on github
-  
-  Bug: #6146
-  Closes #6245
+- [Jacob Hoffman-Andrews brought this change]
 
-- multi: reduce Win32 API calls to improve performance
-  
-  1. Consolidate pre-checks into a single Curl_poll call:
-  
-  This is an attempt to restructure the code in Curl_multi_wait
-  in such a way that less syscalls are made by removing individual
-  calls to Curl_socket_check via SOCKET_READABLE/SOCKET_WRITABLE.
-  
-  2. Avoid resetting the WinSock event multiple times:
-  
-  We finally call WSAResetEvent anyway, so specifying it as
-  an optional parameter to WSAEnumNetworkEvents is redundant.
-  
-  3. Wakeup directly in case no sockets are being monitoring:
-  
-  Fix the WinSock based implementation to skip extra waiting by
-  not sleeping in case no sockets are to be waited on and just
-  the WinSock event is being monitored for wakeup functionality.
+  rustls: switch read_tls and write_tls to callbacks
   
-  Assisted-by: Tommy Odom
-  Reviewed-by: Jay Satiro
-  Reviewed-by: Marcel Raad
+  And update to 0.6.0, including a rename from session to connection for
+  many fields.
   
-  Bug: #6146
-  Closes #6245
+  Closes #7071
 
-- Revert "Revert 'multi: implement wait using winsock events'"
-  
-  This reverts commit 2260e0ebe6d45529495231b3e37a0c58fb92a6a2,
-  also restoring previous follow up changes which were reverted.
-  
-  Authored-by: rcombs on github
-  Authored-by: Marc Hörsken
-  Reviewed-by: Jay Satiro
-  Reviewed-by: Marcel Raad
-  
-  Restores #5634
-  Reverts #6281
-  Part of #6245
+- [Koichi Shiraishi brought this change]
 
-Daniel Stenberg (21 Apr 2021)
-- Revert "cmake: make libcurl library output name configurable"
-  
-  This reverts commit 1cba36d2166c396f987eea587cf92671b27acb92.
+  sectransp: fix 7f4a9a9b2a49 commit about missing comma
   
-  CMake provides properties that can be set on a target to rename the
-  output artifact without changing the name of a target.
+  Follow-up to 7f4a9a9b2a495
   
-  Ref: #6899
+  Closes #7119
 
-- [Michael Kolechkin brought this change]
+- [Harry Sintonen brought this change]
 
-  sectransp: allow cipher name to be specified
-  
-  Add parser for CURLOPT_SSL_CIPHER_LIST option for Secure Transport (ST)
-  back-end. Similar to NSS and GSKit back-ends, new code parses string
-  value and configures ST library to use those ciphers for communication.
-  Create cipher spec data structure and initialize the array of specs with
-  cipher number, name, alias, and 'weak' flag.
+  openssl: associate/detach the transfer from connection
   
-  Mark triple-DES ciphers as 'weak', and exclude them from the default
-  ciphers list.
+  CVE-2021-22901
   
-  Closes #6464
+  Bug: https://curl.se/docs/CVE-2021-22901.html
 
-- [Michael Kolechkin brought this change]
+- [Harry Sintonen brought this change]
 
-  NSS: add ciphers to map
+  telnet: check sscanf() for correct number of matches
   
-  Add cipher names to the `cipherlist` map, based on the list of ciphers
-  implemented by the NSS in the source code file
-  https://github.com/nss-dev/nss/blob/master/lib/ssl/sslenum.c
+  CVE-2021-22898
   
-  Closes #6670
+  Bug: https://curl.se/docs/CVE-2021-22898.html
 
-- http2: remove DEBUG_HTTP2
+- schannel: don't use static to store selected ciphers
   
-  Accidentally committed in 605e84235
+  CVE-2021-22897
+  
+  Bug: https://curl.se/docs/CVE-2021-22897.html
 
-- [Ralph Langendam brought this change]
+- docs/tests: remove freenode references
 
-  cmake: make libcurl library output name configurable
-  
-  Closes #6899
+- RELEASE-NOTES: synced
 
-- sws: #ifdef S_IFSOCK use
-  
-  SCO OpenServer 5.0.7 does not define S_IFSOCK.
-  
-  Reported-by: Kevin R. Bulgrien
-  Bug: https://curl.se/mail/lib-2021-04/0074.html
-  Closes #6926
+- [Sergey Markelov brought this change]
 
-- curl_setup: provide the shutdown flags wider
-  
-  By using #ifdef on the symbol names to work on anything that don't
-  provide them. SCO OpenServer 5.0.7, sys/socket.h does not define either
-  SHUT_RDWR, SHUT_RD, and SHUT_WR.
+  NSS: make colons, commas and spaces valid separators in cipher list
   
-  Reported-by: Kevin R. Bulgrien
-  Bug: https://curl.se/mail/lib-2021-04/0073.html
-  Closes #6925
+  Fixes #7110
+  Closes #7115
 
-- connect: use CURL_SA_FAMILY_T for portability
-  
-  Reported-by: Kevin R. Bulgrien
-  Bug: https://curl.se/mail/lib-2021-04/0071.html
+- curl: include libmetalink version in --version output
   
-  Closes #6918
+  Closes #7112
 
-- urlapi: make sure no +/- signs are accepted in IPv4 numericals
-  
-  Follow-up to 56a037cc0ad1b2. Extends test 1560 to verify.
-  
-  Reported-by: Tuomas Siipola
-  Fixes #6916
-  Closes #6917
+Jay Satiro (21 May 2021)
+- [Matias N. Goldberg brought this change]
 
-- ConnectionExists: respect requests for h1 connections better
+  cmake: Use multithreaded compilation on VS 2008+
   
-  ... for situations when multiplexing isn't enabled on the h2 connection
-  and h1 is explicitly requested for the transfer.
+  Multithreaded compilation has been supported since at least VS 2005 and
+  been robustly stable since at least VS 2008
   
-  Assisted-by: Gergely Nagy
+  Closes https://github.com/curl/curl/pull/7109
 
-- multi: don't close connection HTTP_1_1_REQUIRED
-  
-  The ConnectionExists() function will note that the new transfer wants
-  less then h2 and that it can't multiplex it and therefor opt to open a
-  new connection instead.
+Daniel Stenberg (21 May 2021)
+- [Matias N. Goldberg brought this change]
 
-- http2: move the stream error field to the per-transfer storage
+  cmake: fix two invokes result in different curl_config.h
   
-  Storing a stream error in the per-connection struct was an error that lead to
-  race conditions as subsequent stream handling could overwrite the error code
-  before it was used for the stream with the actual problem.
+  Fixes #7100
+  Closes #7101
   
-  Closes #6910
+  Reviewed-by: Jakub Zakrzewski
+  Signed-off-by: Matias N. Goldberg 
 
-- http2: call the handle-closed function correctly on closed stream
-  
-  This was this one condition where the stream could be closed due to an
-  error and the function would still wrongly just return 0 for it.
-  
-  Reported-by: Gergely Nagy
-  Fixes #6862
-  Closes #6910
+- [Peng-Yu Chen brought this change]
 
-- test1660: check the created HSTS file as text mode
+  cmake: detect CURL_SA_FAMILY_T
   
-  Closes #6922
-
-- RELEASE-NOTES: synced
+  Fixes #7049
+  Closes #7065
 
-- test 493: require https in curl to run
-  
-  Closes #6927
+- [Lucas Clemente Vella brought this change]
 
-Jay Satiro (20 Apr 2021)
-- tool_operate: don't discard failed parallel transfer result
+  CURLOPT_IPRESOLVE: preventing wrong IP version from being used
   
-  - Save a parallel transfer's result code only when it fails and the
-    transfer is not being retried.
+  In some situations, it was possible that a transfer was setup to
+  use an specific IP version, but due do DNS caching or connection
+  reuse, it ended up using a different IP version from requested.
   
-  Prior to this change the result code was always set which meant that a
-  failed result could be erroneously discarded if a different transfer
-  later had a successful result (CURLE_OK).
+  This commit changes the effect of CURLOPT_IPRESOLVE from simply
+  restricting address resolution to preventing the wrong connection
+  type being used, when choosing a connection from the pool, and
+  to restricting what addresses could be used when establishing
+  a new connection.
   
-  Before:
+  It is important that all addresses versions are resolved, even if
+  not used in that transfer in particular, because the result is
+  cached, and could be useful for a different transfer with a
+  different CURLOPT_IPRESOLVE setting.
   
-  > curl --fail -Z https://httpbin.org/status/404 https://httpbin.org/delay/10
-  > echo %ERRORLEVEL%
-  0
+  Closes #6853
+
+- [Oliver Urbann brought this change]
+
+  AmigaOS: add functions definitions for SHA256
   
-  After:
+  AmiSSL replaces many functions with macros. Curl requires pointer
+  to some of these functions. Thus, we have to encapsulate these macros:
+  SHA256_Init, SHA256_Update, SHA256_Final, X509_INFO_free.
   
-  > curl --fail -Z https://httpbin.org/status/404 https://httpbin.org/delay/10
-  > echo %ERRORLEVEL%
-  22
+  Bug: https://github.com/jens-maus/amissl/issues/15
+  Co-authored-by: Daniel Stenberg 
   
-  Closes #xxxx
-
-- [Georeth Zhou brought this change]
+  Closes #7099
 
-  openssl: fix build error with OpenSSL < 1.0.2
+- test2100: make it run with and require IPv6
   
-  Closes https://github.com/curl/curl/pull/6920
+  Closes #7083
 
-Viktor Szakats (19 Apr 2021)
-- README.md: delete Codacy UTM parameters & follow permanent redirect [ci skip]
-  
-  UTM parameters leak referrer and various marketing/tracking information
-  even if these would normally be stripped by website or client policy.
-  This link also works fine without them. Also took the opportunity to
-  update the URL to the one pointed to by the previous one via permanent
-  redirect.
+- tests/getpart: generate output URL encoded for better diffs
   
-  Reviewed-by: Daniel Stenberg
-  Closes #6919
+  Closes #7083
+
+- [Ryan Beck-Buysse brought this change]
 
-Daniel Stenberg (19 Apr 2021)
-- urlapi: "normalize" numerical IPv4 host names
+  docs/TheArtOfHttpScripting: fix markdown links
   
-  When the host name in a URL is given as an IPv4 numerical address, the
-  address can be specified with dotted numericals in four different ways:
-  a32, a.b24, a.b.c16 or a.b.c.d and each part can be specified in
-  decimal, octal (0-prefixed) or hexadecimal (0x-prefixed).
+  extra parens cause the links to be incorrectly formatted
+  and inconsistent with the rest of the document.
   
-  Instead of passing on the name as-is and leaving the handling to the
-  underlying name functions, which made them not work with c-ares but work
-  with getaddrinfo, this change now makes the curl URL API itself detect
-  and "normalize" host names specified as IPv4 numericals.
+  Signed-off-by: Ryan Beck-Buysse 
+  Closes #7097
+
+- RELEASE-NOTES: synced
+
+- [Emil Engler brought this change]
+
+  docs: replace dots with dashes in markdown enums
   
-  The WHATWG URL Spec says this is an okay way to specify a host name in a
-  URL. RFC 3896 does not allow them, but curl didn't prevent them before
-  and it seems other RFC 3896-using tools have not either. Host names used
-  like this are widely supported by other tools as well due to the
-  handling being done by getaddrinfo and friends.
+  We use dashes instead of dots nearly everywhere except for those few
+  cases. This commit addresses this issues and brings more coherency into
+  it.
   
-  I decided to add the functionality into the URL API itself so that all
-  users of these functions get the benefits, when for example wanting to
-  compare two URLs. Also, it makes curl built to use c-ares now support
-  them as well and make curl builds more consistent.
+  Closes #7093
+
+- [Emil Engler brought this change]
+
+  docs: improve INTERNALS.md regarding getsock cb
   
-  The normalization makes HTTPS and virtual hosted HTTP work fine even
-  when curl gets the address specified using one of the "obscure" formats.
+  This adds the I/O prefix to indicate that those "actions" are kind-of
+  related to those found in select(2) or poll(2) (reading/writing).
   
-  Test 1560 is extended to verify.
+  It also adds a note where the prototypes of those functions can be found
+  in the source code.
   
-  Fixes #6863
-  Closes #6871
+  Closes #7092
 
-- libssh: fix "empty expression statement has no effect" warnings
-  
-  ... by fixing macros to do-while constructs and moving out the calls to
-  "break" outside of the actual macro. It also fixes the problem where the
-  macro was used witin a loop and the break didn't do right.
-  
-  Reported-by: Emil Engler
-  Fixes #6847
-  Closes #6909
+- [Emil Engler brought this change]
 
-- hsts: enable by default
+  docs: document attach in INTERNALS.md
   
-  No longer considered experimental.
+  The new field in the Curl_handler struct still lacks documentation. This
+  adds it it from the information extracted from lib/urldata.h:797
   
-  Closes #6700
+  Closes #7091
 
-- vtls: refuse setting any SSL version
-  
-  ... previously they were supported if a TLS library would (unexpectedly)
-  still support them, but from this change they will be refused already in
-  curl_easy_setopt(). SSLv2 and SSLv3 have been known to be insecure for
-  many years now.
+- [Marc Aldorasi brought this change]
+
+  config: remove now-unused macros
   
-  Closes #6773
+  Closes #7094
+
+- [Marc Aldorasi brought this change]
 
-- curl: ignore options asking for SSLv2 or SSLv3
+  hostip.h: remove declaration of unimplemented function
   
-  Instead output a warning about it and continue with the defaults.
+  Closes #7094
+
+- h3: add 'attach' callback to protocol handlers
   
-  These SSL versions are typically not supported by the TLS libraries since a
-  long time back already since they are inherently insecure and broken. Asking
-  for them to be used will just cause an error to be returned slightly later.
+  Follow-up to 0c55fbab45be
   
-  In the unlikely event that a user's TLS library actually still supports these
-  protocol versions, this change might make the request a little less insecure.
+  Reviewed-by: Emil Engler
+  Closes #7090
+
+- wolfssl: remove SSLv3 support leftovers
   
-  Closes #6772
+  Closes #7088
 
-- test972: verify the json output with jsonlint
+- curl-wolfssl.m4: without custom include path, assume /usr/include
   
-  Make sure one of the azure jobs has jsonlint installed so that the test
-  runs there.
+  ... so that we can point out the root of the OpenSSL emulation headers.
+  Previously this used the '$includedir' variable which is wrong since
+  that defaults to the dir where the current configure invoke will install
+  the built libcurl headers: /usr/local by default.
   
-  Ref: #6905
+  Fixes #7085
+  Reported-by: Joel Jakobsson
+  Closes #7087
 
-- [Jay Satiro brought this change]
+- [Joel Depooter brought this change]
 
-  tool_writeout: fix the HTTP_CODE json output
+  data_pending: check only SECONDARY socket for FTP(S) transfers
+  
+  Check the FIRST for all other protocols.
   
-  Update test 970 accordingly.
+  This fixes a timeout in an ftps download. The server sends a TLS
+  close_notify message in the same packet as the file data. The
+  close_notify seems to not be handled in the schannel_recv function, so
+  libcurl is not aware that the server has closed the connection. Thus
+  libcurl ends up waiting for action on the socket until a timeout is
+  reached. With the secondary socket check added to the data_pending
+  function, the close_notify is properly handled, and the ftps transfer
+  terminates as expected.
   
-  Reported-by: Michal Rus
-  Fixes #6905
-  Closes #6906
+  Fixes #7068
+  Closes #7069
 
-- openldap: protect SSL-specific code with proper #ifdef
+- github: inhibit deprecated declarations for clang on macOS
+  
+  ... as they otherwise cause ldap build errors in the CI.
   
-  Closes #6901
+  Fixes #7081
+  Closes #7082
 
-- libssh2: fix Value stored to 'sshp' is never read
+- conn: add 'attach' to protocol handler, make libssh2 use it
   
-  Pointed out by scan-build
+  The libssh2 backend has SSH session associated with the connection but
+  the callback context is the easy handle, so when a connection gets
+  attached to a transfer, the protocol handler now allows for a custom
+  function to get used to set things up correctly.
   
-  Closes #6900
-
-- [Victor Vieux brought this change]
+  Reported-by: Michael O'Farrell
+  Fixes #6898
+  Closes #7078
 
-  tool_getparam: replace (in-place) '%20' by '+' according to RFC1866
+- http2: make sure pause is done on HTTP
   
-  Signed-off-by: Victor Vieux 
+  Since the function is called for any protocol, we can't assume that the
+  HTTP struct is there without first making sure it is HTTP.
   
-  Closes #6895
+  Reported-by: Denis Goleshchikhin
+  Fixes #7079
+  Closes #7080
 
-- configure: provide --with-openssl, deprecate --with-ssl
+- docs: cookies from HTTP headers need domain set
   
-  Makes the option more explicit.
+  ... or the cookies won't get sent. Push users to using the "Netscape"
+  format instead, which curl uses when saving a cookie "jar".
   
-  Closes #6887
+  Reported-by: Martin Dorey
+  Reviewed-by: Daniel Gustafsson
+  Fixes #6723
+  Closes #7077
 
 - RELEASE-NOTES: synced
-  
-  and bumped curlver to 7.77.0
 
-- [Javier Blazquez brought this change]
+- github: add a workflow with libssh2 on macOS using cmake
+  
+  Closes #7047
 
-  rustls: only return CURLE_AGAIN when TLS session is fully drained
+- sws: allow HTTP requests up to 2MB in size
   
-  The code in cr_recv was returning prematurely as soon as the socket
-  reported no more data to read. However, this could be leaving some
-  unread plaintext data in the rustls session from a previous call,
-  causing causing the transfer to hang if the socket never receives
-  further data.
+  To allow tests with slightly larger payloads. Like #7071 ...
   
-  We need to ensure that the session is fully drained of plaintext data
-  before returning CURLE_AGAIN to the caller.
+  Closes #7075
+
+Marc Hoersken (16 May 2021)
+- CI/azure: increase verbosity and fix outdated task names
   
-  Reviewed-by: Jacob Hoffman-Andrews
-  Closes #6894
+  Closes #7063
 
-- cookie: CURLOPT_COOKIEFILE set to NULL switches off cookies
+- CI/cirrus: add shared and static Windows release builds
   
-  Add test 676 to verify that setting CURLOPT_COOKIEFILE to NULL again clears
-  the cookiejar from memory.
+  Azure Pipelines is currently being used for debug builds,
+  let's also run some non-debug (release) Windows builds and
+  make use of previously underutilized Cirrus CI for that.
   
-  Reported-by: Stefan Karpinski
-  Fixes #6889
-  Closes #6891
-
-Version 7.76.1 (14 Apr 2021)
-
-Daniel Stenberg (14 Apr 2021)
-- RELEASE-NOTES: synced
+  Reviewed-by: Marcel Raad
   
-  curl 7.76.1 release
-
-- THANKS: add names from 7.76.1
-
-- misc: update copyright year ranges to match latest updates
-
-- [Tatsuhiro Tsujikawa brought this change]
+  Closes #6991
 
-  ngtcp2: Use ALPN h3-29 for now
+Daniel Stenberg (16 May 2021)
+- CURLOPT_CAPATH.3: defaults to a path, not NULL
   
-  Fixes #6864
-  Cloes #6886
-
-Jay Satiro (11 Apr 2021)
-- TODO: remove 18.22 --fail-with-body
+  Reported-by: Andrew Barnert
   
-  --fail-with-body was added in 8a964cb (precedes curl-7_76_0).
+  Closes #7062
 
-Daniel Stenberg (10 Apr 2021)
-- [Jürgen Gmach brought this change]
+- [Jacob Hoffman-Andrews brought this change]
 
-  src/tool_vms.c: remove duplicated word in comment
+  c-hyper: handle body on HYPER_TASK_EMPTY
   
-  Closes #6881
-
-- configure: fix CURL_DARWIN_CFLAGS use
+  Some of the time, we get a HYPER_TASK_EMPTY response before the status
+  line, headers, and body have been read. Previously, that would cause us
+  to poll again, leading to a 1 second timeout.
   
-  The macro name change was not completely done.
+  The HYPER_TASK_EMPTY docs say:
   
-  Follow-up to 5d2c384452543c
-  Bug: https://github.com/curl/curl/commit/5d2c384452543c7b6c9fb02eaa0afc84fd5ab941#commitcomment-49315187
-  Reported-by: Marcel Raad
-  Closes #6878
-
-- [Anthony Shaw brought this change]
-
-  github/workflow: add "security-extended" to codeql-analysis.yml
+     The value of this task is null (does not imply an error).
   
-  Extends the CodeQL code scan.
+  So, if we receive a HYPER_TASK_EMPTY, continue on with processing the
+  response.
   
-  Closes #6815
+  Reported-by: Kevin Burke
+  Fixes #7064
+  Closes #7070
 
-- [Jochem Broekhoff brought this change]
+- [Ikko Ashimine brought this change]
 
-  examples/hiperfifo.c: check event_initialized before delete
+  tool_getparam: fix comment typo in tool_getparam.c
   
-  If event_del is called with the event struct (still) zeroed out, a
-  segmentation fault may occur.  event_initialized checks whether the
-  event struct is nonzero.
+  enfore -> enforce
   
-  Closes #6876
-
-- [Patrick Monnerat brought this change]
+  Closes #7074
 
-  ntlm: fix negotiated flags usage
+- mem-include-scan.pl: require a non-word letter before memory funcs
   
-  According to Microsoft document MS-NLMP, current flags usage is not
-  accurate: flag NTLMFLAG_NEGOTIATE_NTLM2_KEY controls the use of
-  extended security in an NTLM authentication message and NTLM version 2
-  cannot be negotiated within the protocol.
+  ... so that ldap_memfree() for example doesn't match the scan for free.
   
-  The solution implemented here is: if the extended security flag is set,
-  prefer using NTLM version 2 (as a server featuring extended security
-  should also support version 2). If version 2 has been disabled at
-  compile time, use extended security.
+  Closes #7061
+
+- version: free the openldap info correctly
   
-  Tests involving NTLM are adjusted to this new behavior.
+  ... to avoid memory leaks.
   
-  Fixes #6813
-  Closes #6849
-
-- [Patrick Monnerat brought this change]
+  Follow-up to: bf0feae7768d9
+  Closes #7061
 
-  ntlm: support version 2 on 32-bit platforms
+- dupset: remove totally off comment
   
-  Closes #6849
-
-- [Patrick Monnerat brought this change]
+  Closes #7067
 
-  curl_ntlm_core.h: simplify conditionals for USE_NTLM2SESSION
-  
-  ... as !defined(CURL_DISABLE_CRYPTO_AUTH) is a prerequisite for the
-  whole NTLM.
+- configure: if asked for, fail if ldap is not found
   
-  Closes #6849
+  Reported-by: Jakub Zakrzewski
+  Fixes #7053
+  Closes #7055
 
-- lib: remove unused HAVE_INET_NTOA_R* defines
+- version: add OpenLDAP version in the output
   
-  Closes #6867
+  Assisted-by: Howard Chu
+  Closes #7054
 
-- [Michael Forney brought this change]
+Jay Satiro (13 May 2021)
+- [Joel Depooter brought this change]
 
-  configure: include  unconditionally
-  
-  In 2682e5f5, several instances of AC_HEADER_TIME were removed since
-  it is a deprecated autoconf macro. However, this was the macro that
-  defined TIME_WITH_SYS_TIME, which was used to indicate that 
-  can be included alongside . TIME_WITH_SYS_TIME is still
-  used in the configure test body and since it is no longer defined,
-   is *not* included on systems that have .
-  
-  In particular, at least on musl libc and glibc,  does
-  not implicitly include  and does not declare clock_gettime,
-  gmtime_r, or localtime_r. This causes configure to fail to detect
-  those functions.
-  
-  The AC_HEADER_TIME macro deprecation text says
-  
-  > All current systems provide time.h; it need not be checked for.
-  > Not all systems provide sys/time.h, but those that do, all allow
-  > you to include it and time.h simultaneously.
+  schannel: Ensure the security context request flags are always set
   
-  So, to fix this issue, simply include  unconditionally when
-  testing for time-related functions and in libcurl, and don't bother
-  checking for it.
+  As of commit 54e7475, these flags would only be set when using a new
+  credential handle. When re-using an existing credential handle, the
+  flags would not be set.
   
-  Closes #6859
+  Closes https://github.com/curl/curl/pull/7051
 
-- [Michael Forney brought this change]
+Dan Fandrich (12 May 2021)
+- tests: Fix some tag matching issues in a number of tests
 
-  configure: remove use of RETSIGTYPE
+Daniel Stenberg (12 May 2021)
+- sasl: use 'unsigned short' to store mechanism
   
-  This was previously defined by the obsolete AC_TYPE_SIGNAL macro,
-  which was removed in 2682e5f5. The deprecation text says
+  ... saves a few bytes of struct size in memory and it only uses
+  10 bits anyway.
   
-  > Your code may safely assume C89 semantics that RETSIGTYPE is void.
+  Closes #7045
+
+- hostip: remove the debug code for LocalHost
   
-  So, remove it and just use void instead.
+  The Curl_resolv() had special code (when built in debug mode) for when
+  resolving the host name "LocalHost" (using that exact casing). It would
+  then get the host name from the --interface option instead.
   
-  Closes #6861
-
-- [Muhammed Yavuz Nuzumlalı brought this change]
-
-  install: add instructions for Apple Darwin platforms
+  This development-only feature was not used by anything (anymore) and we
+  have the --resolve feature if we want to play similar tricks properly
+  going forward.
   
-  Closes #6860
-
-- [Muhammed Yavuz Nuzumlalı brought this change]
+  Closes #7044
 
-  configure: disable min version set for Darwin
+- progress: reset limit_size variables at transfer start
   
-  Fixes #6838
-  Closes #6860
-
-- [David Hu brought this change]
-
-  docs/HTTP3.md: update the build instruction using gnutls
+  Otherwise the old value would linger from a previous use and would mess
+  up the network speed cap logic.
   
-  In ngtcp2 the `with-gnutls` option is disabled by default, which will
-  cause `curl` unable to be `make` because of lacking the libraries
-  needed.
+  Reported-by: Ymir1711 on github
   
-  Closes #6857
+  Fixes #7042
+  Closes #7043
 
 - RELEASE-NOTES: synced
 
-- typecheck-gcc: make the ssl-ctx-cb check use SSL_CTX pointers
-  
-  ... and not values.
-  
-  Reported-by: locpyl-tidnyd on github
-  Fixes #6818
-  Closes #6819
-
-- ngtcp2+gnutls: clear credentials when freed
-  
-  ... to avoid double-free.
-  
-  Reported-by: Kenneth Davidson
-  Fixes #6824
-  Closes #6856
-
-Jay Satiro (5 Apr 2021)
-- [Cherish98 brought this change]
+- [Daniel Gustafsson brought this change]
 
-  tool_progress: Fix progress meter in parallel mode
-  
-  Make sure the total amount of DL/UL bytes are counted before the
-  transfer finalizes. Otherwise if a transfer finishes too quick, its
-  total numbers are not added, and results in a DL%/UL% that goes above
-  100%.
+  cookies: use CURLcode for cookie_output reporting
   
-  Detail:
+  Writing the cookie file has multiple error conditions, and was using an
+  int with magic numbers to report the different error (which in turn were
+  disregarded anyways). This moves reporting to use a CURLcode value.
   
-  progress_meter() is called periodically, and it may not catch a
-  transfer's total bytes if the value was unknown during the last call,
-  and the transfer is finished and deleted (i.e., lost) during the next
-  call.
+  Lightly-touched-by: Daniel Stenberg
   
-  Closes https://github.com/curl/curl/pull/6840
+  Closes #7037
+  Closes #6749
 
-- [Emil Engler brought this change]
+- [Daniel Gustafsson brought this change]
 
-  libssh: get rid of PATH_MAX
-  
-  This removes the last occurrence of PATH_MAX inside our libssh
-  implementation by calculating the path length from the string length of
-  the two components.
+  cookies: make use of string duplication function
   
-  Closes #6829
+  strstore() is defined as a strdup which ensures to free the target
+  pointer before duping the source char * into it. Make use of it in
+  two more cases where it can simplify the code.
 
-Daniel Stenberg (5 Apr 2021)
-- http_proxy: only loop on 407 + close if we have credentials
-  
-  ... to fix the retry-loop.
-  
-  Add test 718 to verify.
-  
-  Reported-by: Daniel Kurečka
-  Fixes #6828
-  Closes #6850
+- [Daniel Gustafsson brought this change]
 
-- h2: allow 100 streams by default
-  
-  instead of 13, before the server has told how many streams it
-  accepts. The server can always reject new streams anyway if we go above
-  what it accepts.
+  cookies: refactor comments
   
-  Ref: #6826
-  Closes #6852
+  Comments in the cookie code were a bit all over the place in terms of
+  style and wording. This takes a stab at cleaning them up by keeping to
+  a single style and overall shape. Some comments are moved a little and
+  some removed alltogether due to being redundant. No functional changes
+  have been made,
 
-- [Luke Granger-Brown brought this change]
+- [Peng-Yu Chen brought this change]
 
-  file: support GETing directories again
-  
-  After 957bc1881e686f9714c4e6a01bf33535091f0e21, we no longer compute an
-  expected_size for directories. This has the upshot that when we compare
-  even an empty Range with the available size, we fail.
+  http2: skip immediate parsing of payload following protocol switch
   
-  This brings back the previous behaviour, which was to succeed, but with
-  empty content. This also removes the "Accept-ranges: bytes" header,
-  which is nonsensical on directories.
+  This is considered not harmful as a following http2_recv shall be
+  called very soon.
   
-  Adds test 3016
-  Fixes #6845
-  Closes #6846
-
-- RELEASE-NOTES: synced
+  This is considered helpful in the specific situation where some
+  servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately
+  following the return of HTTP status 101, other than waiting for
+  the client-side connection preface to arrive.
   
-  and bumped to 7.76.1
+  Fixes #7036
+  Closes #7040
 
-- TLS: fix HTTP/2 selection
-  
-  for GnuTLS, BearSSL, mbedTLS, NSS, SChannnel, Secure Transport and
-  wolfSSL...
-  
-  Regression since 88dd1a8a115b1f5ece (shipped in 7.76.0)
-  Reported-by: Kenneth Davidson
-  Reported-by: romamik om github
-  Fixes #6825
-  Closes #6827
+- [Peng-Yu Chen brought this change]
 
-Jay Satiro (2 Apr 2021)
-- hostip: Fix for builds that disable all asynchronous DNS
-  
-  - Define Curl_resolver_error function only when USE_CURL_ASYNC.
+  http2: use nghttp2_session_upgrade2 instead of nghttp2_session_upgrade
   
-  Prior to this change building curl without an asynchronous resolver
-  backend (c-ares or threaded) and without DoH (DNS-over-HTTPS, which is
-  also asynchronous but independent of resolver backend) would cause a
-  build error since Curl_resolver_error is called by and evaluates
-  variables only available in asynchronous builds.
+  Following the upstream deprecation of nghttp2_session_upgrade.
   
-  Reported-by: Benbuck Nason
+  Also provides further checks for requests with the HEAD method.
   
-  Fixes https://github.com/curl/curl/issues/6831
-  Closes https://github.com/curl/curl/pull/6832
-
-Daniel Stenberg (31 Mar 2021)
-- [Gilles Vollant brought this change]
+  Closes #7041
 
-  openssl: Fix CURLOPT_SSLCERT_BLOB without CURLOPT_SSLCERT_KEY
+- progress/trspeed: use a local convenient pointer to beautify code
   
-  Reported-by: Christian Schmitz
-  Fixes #6816
-  Closes #6820
+  The function becomes easier to read and understand with less repetition.
 
-Version 7.76.0 (31 Mar 2021)
+- trspeed: use long double for transfer speed calculation
 
-Daniel Stenberg (31 Mar 2021)
-- RELEASE-NOTES: synced
+- progress: move transfer speed calc into function
+  
+  This silences two scan-build-11 warnings: "The result of the '/'
+  expression is undefined"
   
-  curl 7.76.0 release
+  Bug: https://curl.se/mail/lib-2021-05/0022.html
+  Closes #7035
 
-- THANKS: added names from 7.76.0
+- [Cameron Cawley brought this change]
 
-- CURLOPT_AUTOREFERER.3: clarify that it sets the full URL
+  openssl: remove unneeded cast for CertOpenSystemStore()
   
-  ... some users may not want that!
+  Closes #7025
 
-- define: remove CURL_DISABLE_NTLM ifdefs
+- travis: disable the libssh build
   
-  It was never defined anywhere. Fixed disable-scan (test 1165) to also
-  scan headers, which found this issue.
+  It can't run on focal and causes warnings on bionic. Since the focal
+  failure started rather suddenly a while ago, we can suspect it might be
+  temporary.
   
-  Closes #6809
-
-- vtls: fix addsessionid for non-proxy builds
+  Added "bring back the build" to the TODO document.
   
-  Follow-up to b09c8ee15771c61
-  Fixes #6812
-  Closes #6811
-
-- [Li Xinwei brought this change]
+  Fixes #7011
+  Closes #7012
 
-  cmake: support WinIDN
-  
-  Closes #6807
+- [Peng-Yu Chen brought this change]
 
-- transfer: clear 'referer' in declaration
+  http: use calculated offsets inst of integer literals for header parsing
   
-  To silence (false positive) compiler warnings about it.
+  Assumed to be a minor coding style improvement with no behavior change.
   
-  Follow-up to 7214288898f5625
+  A modern compiler is expected to have the calculation optimized during
+  compilation. It may be deemed okay even if that's not the case, since
+  the added overhead is considered very low.
   
-  Reviewed-by: Marcel Raad
-  Closes #6810
+  Closes #7032
 
-- [Marc Hoersken brought this change]
+- [Peng-Yu Chen brought this change]
 
-  config: fix SSPI enabling NTLM if crypto auth is disabled
-  
-  Avoid enabling NTLM feature based upon Windows SSPI
-  being enabled in case that crypto auth is disabled.
+  GIT-INFO: suggest using autoreconf instead of buildconf
   
-  Reported-by: Marcel Raad
+  Follow-up to 85868537d
   
-  Follow-up to #6277
-  Fixes #6803
-  Closes #6808
-
-- HISTORY: add two 2021 events
+  Closes #7033
 
-- vtls: add 'isproxy' argument to Curl_ssl_get/addsessionid()
+- http: deal with partial CONNECT sends
   
-  To make sure we set and extract the correct session.
+  Also added 'CURL_SMALLSENDS' to make Curl_write() send short packets,
+  which helped verifying this even more.
   
-  Reported-by: Mingtao Yang
-  Bug: https://curl.se/docs/CVE-2021-22890.html
+  Add test 363 to verify.
   
-  CVE-2021-22890
-
-- [Viktor Szakats brought this change]
+  Reported-by: ustcqidi on github
+  Fixes #6950
+  Closes #7024
 
-  transfer: strip credentials from the auto-referer header field
-  
-  Added test 2081 to verify.
+- HTTP3: make the ngtcp2 build use the quictls fork
   
-  CVE-2021-22876
+  ... as ngtcp2 itself documents the build this way.
   
-  Bug: https://curl.se/docs/CVE-2021-22876.html
+  Closes #7031
 
-- curl_sasl: fix compiler error with --disable-crypto-auth
+- http: limit the initial send amount to used upload buffer size
   
-  ... if libgsasl was found.
+  Previously this logic would cap the send to CURL_MAX_WRITE_SIZE bytes,
+  but for the situations where a larger upload buffer has been set, this
+  function can benefit from sending more bytes. With default size used,
+  this does the same as before.
   
-  Closes #6806
-
-- [Patrick Monnerat brought this change]
-
-  ldap: only set the callback ptr for TLS context when TLS is used
+  Also changed the storage of the size to an 'unsigned int' as it is not
+  allowed to be set larger than 2M.
   
-  Follow-up to a5eee22e594c2460f
-  Fixes #6804
-  Closes #6805
-
-- copyright: update copyright year ranges to 2021
+  Also added cautions to the man pages about changing buffer sizes in
+  run-time.
   
-  Reviewed-by: Emil Engler
-  Closes #6802
+  Closes #7022
 
-- send_speed: simplify the checks for if a speed limit is set
-  
-  ... as we know the value cannot be set to negative: enforced by
-  setopt()
+- RELEASE-NOTES: synced
 
-- http: cap body data amount during send speed limiting
+- ngtcp2: fix the cb_acked_stream_data_offset proto
   
-  By making sure never to send off more than the allowed number of bytes
-  per second the speed limit logic is given more room to actually work.
+  The 'datalen' value should be 64 bit, not size_t!
   
-  Reported-by: Fabian Keil
-  Bug: https://curl.se/mail/lib-2021-03/0042.html
-  Closes #6797
+  Reported-by: Dmitry Karpov
+  Bug: https://curl.se/mail/lib-2021-05/0019.html
+  Closes #7027
 
-- urldata: merge "struct DynamicStatic" into "struct UrlState"
+- progress: when possible, calculate transfer speeds with microseconds
   
-  Both were used for the same purposes and there was no logical separation
-  between them. Combined, this also saves 16 bytes in less holes in my
-  test build.
+  ... this improves precision, especially for transfers in the few or even
+  sub millisecond range.
   
-  Closes #6798
+  Reported-by: J. Bromley
+  Fixes #7017
+  Closes #7020
 
-- tests/README.md: mentioned that en_US.UTF-8 is required
+- http: reset the header buffer when sending the request
   
-  Reported-by: Oumph on github
-  Fixes #6768
-
-- HISTORY: fixed the Mac OS X 10.1 release date
+  A reused transfer handle could otherwise reuse the previous leftover
+  buffer and havoc would ensue.
   
-  Based on what Wikipedia says
+  Reported-by: sergio-nsk on github
+  Fixes #7018
+  Closes #7021
 
-Jay Satiro (26 Mar 2021)
-- examples: Remove threaded-shared-conn.c due to bug
-  
-  Known bug 11.11 is the shared object's connection cache is not thread
-  safe, so we should not have an example for it.
+- curl_mprintf.3: add description
   
-  Ref: https://github.com/curl/curl/issues/4915
-  Ref: https://curl.se/docs/knownbugs.html#A_shared_connection_cache_is_not
+  These functions have existed in the API since the dawn of time. It is
+  about time we describe how they work, even if we discourage users from
+  using them.
   
-  Closes https://github.com/curl/curl/pull/6795
+  Closes #7010
 
-- KNOWN_BUGS: Update 11.9 - DoH option inheritance
-  
-  - Add description: Explain that some options aren't inherited because
-    they are not relevant for the DoH SSL connections or may result in
-    unexpected behavior.
-  
-  - Remove the reference to #4578 (SSL verify options not inherited) since
-    that was fixed by #6597 (separate DoH-specific options for verify).
+- [Timothy Gu brought this change]
+
+  URL-SYNTAX: update IDNA section for WHATWG spec changes
   
-  - Explain that DoH-specific options (those created by #6597) are
-    available: CURLOPT_DOH_SSL_VERIFYHOST, CURLOPT_DOH_SSL_VERIFYPEER and
-    CURLOPT_DOH_SSL_VERIFYSTATUS.
+  WHATWG URL has dictated the use of Nontransitional Processing (IDNA
+  2008) for several years now. Chrome (and derivatives) still use
+  Transitional Processing, but Firefox and Safari have both switched.
   
-  - Add a reference to #6605 and explain that the user's debug function is
-    not inherited because it would be unexpected to pass internal handles
-    (ie DoH handles) to the user's callback.
+  Also document the fact that winidn functions differently from libidn2
+  here.
   
-  Closes https://github.com/curl/curl/issues/6605
-
-Daniel Stenberg (26 Mar 2021)
-- curl_easy_setopt.3: add curl_easy_option* functions to SEE ALSO
+  Closes #7026
 
-- [Jean-Philippe Menil brought this change]
+- [Calvin Buckley brought this change]
 
-  openssl: ensure to check SSL_CTX_set_alpn_protos return values
-  
-  SSL_CTX_set_alpn_protos() return 0 on success, and non-0 on failure
-  
-  Signed-off-by: Jean-Philippe Menil 
+  INSTALL: add IBM i specific quirks
   
-  Closes #6794
+  Fixes #6830
+  Closes #7013
 
-- multi: close the connection when h2=>h1 downgrading
+- libcurl.3: mention the URL API
   
-  Otherwise libcurl is likely to reuse the connection again in the next
-  attempt since the connection reuse logic doesn't take downgrades into
-  account.
+  To make it easier to find. Also a minor polish of libcurl-url.3
   
-  Reported-by: Anthony Ramine
-  Fixes #6788
-  Closes #6793
+  Closes #7009
 
-- openssl: set the transfer pointer for logging early
+- GnuTLS: don't allow TLS 1.3 for versions that don't support it
   
-  Otherwise, the transfer will be NULL in the trace function when the
-  early handshake details arrive and then curl won't show them.
+  Follow-up to 781864bedbc5
   
-  Regresssion in 7.75.0
+  ... as they don't understand it and will return error at us!
   
-  Reported-by: David Hu
-  Fixes #6783
-  Closes #6792
-
-- RELEASE-NOTES: synced
+  Closes #7014
 
-- TODO: Custom progress meter update interval
+Kamil Dudka (6 May 2021)
+- tool_getparam: handle failure of curlx_convert_tchar_to_UTF8()
   
-  Ref: https://stackoverflow.com/q/66789977/93747
-
-- docs/ABI: tighten up the language
+  Reported by GCC analyzer:
   
-  Make the promises more firm
+  Error: GCC_ANALYZER_WARNING (CWE-476):
+  src/tool_getparam.c: scope_hint: In function 'parse_args'
+  src/tool_getparam.c:2318:38: warning[-Wanalyzer-possible-null-dereference]: dereference of possibly-NULL 'orig_opt'
+  lib/curlx.h:56: included_from: Included from here.
+  src/tool_getparam.c:28: included_from: Included from here.
+  lib/curl_multibyte.h:70:51: note: in definition of macro 'curlx_convert_tchar_to_UTF8'
+  src/tool_getparam.c:2316:16: note: in expansion of macro 'curlx_convert_tchar_to_UTF8'
   
-  Closes #6786
+  Reviewed-by: Marcel Raad
+  Reviewed-by: Daniel Stenberg
+  Closes #7023
+
+Daniel Stenberg (6 May 2021)
+- scripts/delta: also show total number of days
 
-- openldap: disconnect better
+Marc Hoersken (5 May 2021)
+- sockfilt: fix invalid increment of handles index variable nfd
   
-  Instead of clearing the callback argument in disconnect, set it to the
-  (new) transfer to make sure the correct data is passed to the callbacks.
+  Only increment the array index if we actually stored a handle.
   
-  Follow-up to e467ea3bd937f38
-  Assisted-by: Patrick Monnerat
-  Closes #6787
+  Follow up to e917492048f4b85a0fd58a033d10072fc7666c3b
+  Closes #6992
 
-- libssh2: kdb_callback: get the right struct pointer
-  
-  After the recent conn/data refactor in this source file, this function
-  was mistakenly still getting the old struct pointer which would lead to
-  crash on servers with keyboard-interactive auth enabled.
+- sockfilt: avoid getting stuck waiting for writable socket
   
-  Follow-up to a304051620b92e12b (shipped in 7.75.0)
+  Reset FD_WRITE event using the same approach as in multi.c
   
-  Reported-by: Christian Schmitz
-  Fixes #6691
-  Closes #6782
+  Follow up to b36442b24305f3cda7c13cc64b46838995a4985b
+  Closes #6992
 
-- tftp: remove unused struct fields
+Jay Satiro (5 May 2021)
+- test678: Fix for Windows multibyte builds
   
-  Follow-up to d3d90ad9c00530d
+  Follow-up to 77fc385 from yesterday.
   
-  Closes #6781
+  Bug: https://github.com/curl/curl/pull/6662#issuecomment-832966557
+  Reported-by: Marc Hörsken
 
-- openldap: avoid NULL pointer dereferences
-  
-  Follow-up to a59c33ceffb8f78
-  Reported-by: Patrick Monnerat
-  Fixes #6676
-  Closes #6780
+- [Dmitry Kostjuchenko brought this change]
 
-- http: strip default port from URL sent to proxy
+  build: fix compilation for Windows UWP platform
   
-  To make sure the Host: header and the URL provide the same authority
-  portion when sent to the proxy, strip the default port number from the
-  URL if one was provided.
+  - Include afunix.h which is necessary for sockaddr_un when
+    USE_UNIX_SOCKETS is defined on Windows.
   
-  Reported-by: Michael Brown
-  Fixes #6769
-  Closes #6778
+  Closes https://github.com/curl/curl/pull/7006
 
-- azure: disable test 433 on azure-ubuntu
-  
-  Something in that environment sets XDG_CONFIG_HOME for us in a way that
-  breaks the test.
+Daniel Stenberg (5 May 2021)
+- gnutls: make setting only the MAX TLS allowed version work
   
-  Reported-by: Marc Hörsken
-  Fixes #6739
-  Closes #6777
-
-- tftp: remove the 3600 second default timeout
+  Previously, settting only the max allowed TLS version, leaving the
+  minimum one at default, didn't actually set it and left it to default
+  (TLS 1.3) too!
   
-  ... it was never meant to be there.
+  As a bonus, this change also removes the dead code handling of SSLv3
+  since that version can't be set anymore (since eff614fb0242cb).
   
-  Reported-by: Tomas Berger
-  Fixes #6774
-  Closes #6776
+  Reported-by: Daniel Carpenter
+  Fixes #6998
+  Closes #7000
 
-- docs: make gen.pl support *italic* and **bold**
+- openldap: replace ldap_ prefix on private functions
   
-  Remove some nroffisms from the cmdline doc files to simplify editing,
-  and instead support this markdown style.
+  Since openldap itself uses that prefix and with OpenĹDAP 2.5.4 (at
+  least) there's a symbol collision because of that.
   
-  Closes #6771
-
-- ngtcp2: sync with recent API updates
+  The private functions now use the 'oldap_' prefix where it previously
+  used 'ldap_'.
   
-  Closes #6770
-
-- RELEASE-NOTES: synced
+  Reported-by: 3eka on github
+  Fixes #7004
+  Closes #7005
 
-- libssh2:ssh_connect: clear session pointer after free
-  
-  If libssh2_knownhost_init() returns NULL, like in an OOM situation, the
-  ssh session was freed but the pointer wasn't cleared which made libcurl
-  later call libssh2 to cleanup using the stale pointer.
+Jay Satiro (5 May 2021)
+- http2: fix potentially uninitialized variable
   
-  Fixes #6764
-  Closes #6766
+  introduced several days ago in 3193170. caught by visual studio linker.
 
-- [Jacob Hoffman-Andrews brought this change]
+- [Gilles Vollant brought this change]
 
-  docs: document version of crustls dependency
-  
-  This also pins a specific release in the Travis test so future
-  API-breaking changins in crustls won't break curl builds.
+  SSL: support in-memory CA certs for some backends
   
-  Add RUSTLS documentation to release tarball.
+  - New options CURLOPT_CAINFO_BLOB and CURLOPT_PROXY_CAINFO_BLOB to
+    specify in-memory PEM certificates for OpenSSL, Schannel (Windows)
+    and Secure Transport (Apple) SSL backends.
   
-  Enable running tests for rustls, minus FTP tests (require
-  connect_blocking, which rustls doesn't implement) and 313 (requires CRL
-  handling).
+  Prior to this change PEM certificates could only be imported from a file
+  and not from memory.
   
-  Closes #6763
-
-- [Jacob Hoffman-Andrews brought this change]
-
-  rustls: Handle close_notify.
+  Co-authored-by: moparisthebest@users.noreply.github.com
   
-  If we get a close_notify, treat that as EOF. If we get an EOF from the
-  TCP stream, treat that as an error (because we should have ended the
-  connection earlier, when we got a close_notify).
+  Ref: https://github.com/curl/curl/pull/4679
+  Ref: https://github.com/curl/curl/pull/5677
+  Ref: https://github.com/curl/curl/pull/6109
   
-  Closes #6763
+  Closes https://github.com/curl/curl/pull/6662
 
-- docs: clarify timeouts for queued transfers in multi API
-  
-  Closes #6758
+Daniel Stenberg (4 May 2021)
+- [David Cook brought this change]
 
-- ftpserver: only load the preprocessed test file
+  tests: ignore case of chunked hex numbers in tests
   
-  We always preprocess and tests are no longer sensible to load "raw"
+  When hyper is used, it emits uppercase hexadecimal numbers for chunked
+  encoding lengths. Without hyper, lowercase hexadecimal numbers are used.
+  This change adds preprocessor statements to tests where this is an
+  issue, and adapts the fixtures to match.
   
-  Closes #6738
+  Closes #6987
 
-- tests: use %TESTNUMBER instead of fixed number
+- cmake: check for getppid and utimes
   
-  This makes the tests easier to copy and relocate to other test numbers
-  without having to update content.
+  ... as they're checked for in the configure script and are used by
+  source code.
   
-  Closes #6738
-
-- KNOWN_BUGS: CURLOPT_OPENSOCKETPAIRFUNCTION is missing
+  Removed checks for perror, setvbuf and strlcat since those defines are
+  not checked for in source code.
   
-  Closes #5747
-
-- TODO: provide timing info for each redirect
+  Bonus: removed HAVE_STRLCPY from a few config-*.h files since that
+  symbol is not used in source code.
   
-  Closes #6743
+  Closes #6997
 
-Jay Satiro (17 Mar 2021)
-- docs: Add SSL backend names to CURL_SSL_BACKEND
-  
-  - Document the names that can be used with CURL_SSL_BACKEND:
-    bearssl, gnutls, gskit, mbedtls, mesalink, nss, openssl, rustls,
-    schannel, secure-transport, wolfssl
+- libtest: remove lib530.c
   
-  Ref: https://github.com/curl/curl/issues/2209#issuecomment-360623286
-  Ref: https://github.com/curl/curl/issues/6717#issuecomment-800745201
+  Follow up from e50a877df when test 530 was removed. Since then this
+  source file has not been used/needed.
   
-  Closes https://github.com/curl/curl/pull/6755
+  Closes #6999
 
-- docs: Explain DOH transfers inherit some SSL settings
-  
-  - Document in DOH that some SSL settings are inherited but DOH hostname
-    and peer verification are not and are controlled separately.
+- FILEFORMAT: mention sectransp as a feature
   
-  - Document that CURLOPT_SSL_CTX_FUNCTION is inherited by DOH handles but
-    we're considering changing behavior to no longer inherit it. Request
-    feedback.
+  Been supported since at least 40259ca65
   
-  Closes https://github.com/curl/curl/pull/6688
+  Closes #7001
 
-Daniel Stenberg (17 Mar 2021)
-- http: make 416 not fail with resume + CURLOPT_FAILONERRROR
+- RELEASE-NOTES: synced
+
+- libssh2: ignore timeout during disconnect
   
-  When asked to resume a download, libcurl will convert that to HTTP logic
-  and if then the entire file is already transferred it will result in a
-  416 response from the HTTP server. With CURLOPT_FAILONERRROR set in that
-  scenario, it should *not* lead to an error return.
+  ... to avoid memory leaks!
   
-  Updated test 1156, added test 1273
+  libssh2 is tricky as we have to deal with the non-blockiness even in
+  close and shutdown cases. In the cases when we shutdown after a timeout
+  already expired, it is crucial that curl doen't let the timeout abort
+  the shutdown process as that then leaks memory!
   
-  Reported-by: Jonathan Watt
-  Fixes #6740
-  Closes #6753
+  Reported-by: Benjamin Riefenstahl
+  Fixes #6990
 
-- Curl_timeleft: check both timeouts during connect
-  
-  The duration of a connect and the total transfer are calculated from two
-  different time-stamps. It can end up with the total timeout triggering
-  before the connect timeout expires and we should make sure to
-  acknowledge whichever timeout that is reached first.
-  
-  This is especially notable when a transfer first sits in PENDING, as
-  that time is counted in the total time but the connect timeout is based
-  on the time since the handle changed to the CONNECT state.
+- KNOWN_BUGS: add two HTTP/2 bugs
+
+- KNOWN_BUGS: add three HTTP/3 issues
   
-  The CONNECTTIMEOUT is per connect attempt. The TIMEOUT is for the entire
-  operation.
+  ... and moved the HTTP/2 issues to its own section
   
-  Fixes #6744
-  Closes #6745
-  Reported-by: Andrei Bica
-  Assisted-by: Jay Satiro
+  Closes #6606
+  Closes #6510
+  Closes #6494
 
-- configure: remove use of deprecated macros
-  
-  AC_HEADER_TIME, AC_HEADER_STDC and AC_TYPE_SIGNAL
+- [ejanchivdorj brought this change]
 
-- configure: make AC_TRY_* into AC_*_IFELSE
+  CURLcode: add CURLE_SSL_CLIENTCERT
   
-  ... as the former versions are deprecated.
-
-- configure: s/AC_HELP_STRING/AS_HELP_STRING
+  When a TLS server requests a client certificate during handshake and
+  none can be provided, libcurl now returns this new error code
+  CURLE_SSL_CLIENTCERT
   
-  AC_HELP_STRING is deprecated in 2.70+ and I believe AS_HELP_STRING works
-  already since 2.59 so bump the minimum required version to that.
+  Only supported by Secure Transport and OpenSSL for TLS 1.3 so far.
   
-  Reported-by: Emil Engler
-  Fixes #6647
-  Closes #6748
+  Closes #6721
 
-- RELEASE-NOTES: synced
+- [Tobias Gabriel brought this change]
 
-- travis: use ubuntu nghttp2 package instead of build our own
+  .github/FUNDING: add link to GitHub sponsors
   
-  Closes #6751
+  Closes #6985
 
-- travis: bump wolfssl to 4.7.0
+- [Harry Sintonen brought this change]
 
-- travis: only build wolfssl when needed
+  krb5/name_to_level: replace checkprefix with curl_strequal
   
-  Closes #6751
+  Closes #6993
 
-- [Jacob Hoffman-Andrews brought this change]
+- [Harry Sintonen brought this change]
 
-  rustls: allocate a buffer for TLS data.
-  
-  Previously, rustls was using an on-stack array for TLS data. However,
-  crustls has an (unusual) requirement that buffers it deals with are
-  initialized before writing to them. By using calloc, we can ensure the
-  buffer is initialized once and then reuse it across calls.
+  Curl_input_digest: require space after Digest
   
-  Closes #6742
+  Closes #6993
 
-- travis: add a rustls build
-  
-  ... that doesn't run any tests (yet)
+- [Harry Sintonen brought this change]
+
+  Curl_http_header: check for colon when matching Persistent-Auth
   
-  Closes #6750
+  Closes #6993
 
-- HTTP2: remove the outdated remark about multiplexing for the tool
+- [Harry Sintonen brought this change]
 
-- [Robert Ronto brought this change]
+  Curl_http_input_auth: require valid separator after negotiation type
+  
+  Closes #6993
 
-  http2: don't set KEEP_SEND when there's no more data to be sent
+- http: fix the check for 'Authorization' with Bearer
   
-  this should fix an issue where curl sometimes doesn't send out a request
-  with authorization info after a 401 is received over http2
+  The code would wrongly check for it using an additional colon.
   
-  Closes #6747
+  Reported-by: Blake Burkhart
+  Closes #6988
 
-Marc Hoersken (15 Mar 2021)
-- config: fix building SMB with configure using Win32 Crypto
-  
-  Align conditions for NTLM features between CMake and configure
-  builds by differentiating between USE_NTLM and USE_CURL_NTLM_CORE,
-  just like curl_setup.h does internally to detect support of:
+- [Kamil Dudka brought this change]
+
+  http2: fix a resource leak in push_promise()
   
-  - USE_NTLM: required for NTLM crypto authentication feature
-  - USE_CURL_NTLM_CORE: required for SMB protocol
+  ... detected by Coverity:
   
-  Implement USE_WIN32_CRYPTO detection by checking for Crypt functions
-  in wincrypt.h which are not available in the Windows App environment.
+  Error: RESOURCE_LEAK (CWE-772):
+  lib/http2.c:532: alloc_fn: Storage is returned from allocation function "duphandle".
+  lib/http2.c:532: var_assign: Assigning: "newhandle" = storage returned from "duphandle(data)".
+  lib/http2.c:552: noescape: Resource "newhandle" is not freed or pointed-to in "set_transfer_url".
+  lib/http2.c:555: leaked_storage: Variable "newhandle" going out of scope leaks the storage it points to.
   
-  Link advapi32 and crypt32 for Crypto API and Schannel SSL backend.
-  Fix condition of Schannel SSL backend in CMake build accordingly.
+  Closes #6986
+
+- [Kamil Dudka brought this change]
+
+  http2: fix resource leaks in set_transfer_url()
   
-  Reviewed-by: Marcel Raad
+  ... detected by Coverity:
   
-  Closes #6277
-
-- config: fix detection of restricted Windows App environment
+  Error: RESOURCE_LEAK (CWE-772):
+  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+  lib/http2.c:486: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:488: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
   
-  Move the detection of the restricted Windows App environment
-  in curl_setup.h before the definition of USE_WIN32_CRYPTO
-  via included config-win32.h in case no build system is used.
+  Error: RESOURCE_LEAK (CWE-772):
+  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+  lib/http2.c:493: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:495: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
   
-  Reviewed-by: Marcel Raad
+  Error: RESOURCE_LEAK (CWE-772):
+  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+  lib/http2.c:500: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:502: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
   
-  Part of #6277
-
-Daniel Stenberg (15 Mar 2021)
-- HISTORY: curl 7.7.2 was the first version used in Mac OS X 10.1
-
-- gen.pl: quote "bare" minuses in the nroff curl.1
+  Error: RESOURCE_LEAK (CWE-772):
+  lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()".
+  lib/http2.c:505: noescape: Resource "u" is not freed or pointed-to in "curl_url_get". [Note: The source code implementation of the function has been overridden by a builtin model.]
+  lib/http2.c:507: leaked_storage: Variable "u" going out of scope leaks the storage it points to.
   
-  Reported-by: Alejandro Colomar
-  Fixes #6698
-  Closes #6722
+  Closes #6986
 
-Daniel Gustafsson (14 Mar 2021)
-- hsts: remove unused defines
-  
-  MAX_HSTS_SUBLEN and MAX_HSTS_SUBLENSTR were unused from the initial commit,
-  and mostly likely leftovers from early development.  Remove as they're not
-  used for anything.
-  
-  Closes #6741
-  Reviewed-by: Daniel Stenberg 
+- [Jacob Hoffman-Andrews brought this change]
 
-Daniel Stenberg (12 Mar 2021)
-- github: add torture-ftp for FTP-only torture testing
+  rustls: use ALPN
   
-  and at 20% to try to keep the run-time reasonable
+  Update required rustls to 0.5.0
   
-  Closes #6728
+  Closes #6960
 
-- travis: split "torture" into a separate "events" build as well
-  
-  Run torture without FTP and reducing coverage to 20%
-  
-  For some reason the torture tests now run a lot slower on travis and run
-  into the 50 minute limit all the time.
-  
-  Closes #6728
+- [Michał Antoniak brought this change]
 
-- ftp: fix memory leak in ftp_done
-  
-  If after a transfer is complete Curl_GetFTPResponse() returns an error,
-  curl would not free the ftp->pathalloc block.
+  gskit: fix CURL_DISABLE_PROXY build
   
-  Found by torture-testing test 576
+  Removed localfd and remotefd from ssl_backend_data (ued only with proxy
+  connection). Function pipe_ssloverssl return always 0, when proxy is not
+  used.
   
-  Closes #6737
+  Closes #6981
 
-- [oxalica brought this change]
+- [Michał Antoniak brought this change]
 
-  http2: fail if connection terminated without END_STREAM
+  gskit: fix undefined reference to 'conn'
   
-  Closes #6736
-
-- RELEASE-NOTES: synced
+  Closes #6980
 
 - [Jacob Hoffman-Andrews brought this change]
 
-  rustls: support CURLOPT_SSL_VERIFYPEER
-  
-  This requires the latest main branch of crustls, which provides
-  rustls_client_config_builder_dangerous_set_certificate_verifier and
-  rustls_client_config_builder_set_enable_sni.
-  
-  This refactors the session setup into its own function, and adds a new
-  function cr_hostname_is_ip. Because crustls doesn't support verification
-  of IP addresses, special handling is needed: We disable SNI and set a
-  placeholder hostname (which never actually gets sent on the wire).
-  
-  Closes #6719
-
-Daniel Gustafsson (12 Mar 2021)
-- cookies: Fix potential NULL pointer deref with PSL
+  tls: add USE_HTTP2 define
   
-  Curl_cookie_init can be called with data being NULL, and this can in turn
-  be passed to Curl_cookie_add, meaning that both functions must be careful
-  to only use data where it's checked for being a NULL pointer.  The libpsl
-  support code does however dereference data without checking, so if we are
-  indeed having an unset data pointer we cannot PSL check the cookiedomain.
+  This abstracts across the two HTTP/2 backends: nghttp2 and Hyper.
   
-  This is currently not a reachable dereference, as the only caller with a
-  NULL data isn't passing a file to initialize cookies from, but since the
-  API has this contract let's ensure we hold it.
+  Add our own define for the "h2" ALPN protocol, so TLS backends can use
+  it without depending on a specific HTTP backend.
   
-  Closes #6731
-  Reviewed-by: Daniel Stenberg 
+  Closes #6959
 
-Daniel Stenberg (12 Mar 2021)
-- [Michael Hordijk brought this change]
+- [Jacob Hoffman-Andrews brought this change]
 
-  configure: only add OpenSSL paths if they are defined
-  
-  Add paths for OpenSSL compiling and linking only if they have been
-  defined.  If they haven't been defined, we'll assume that the paths are
-  already available to the toolchain.
+  lib: fix 0-length Curl_client_write calls
   
-  Closes #6730
+  Closes #6954
 
-Jay Satiro (12 Mar 2021)
-- retry.d: Clarify transient 5xx HTTP response codes
-  
-  - Clarify the only 5xx response codes that are treated as transient are
-    500, 502, 503 and 504.
-  
-  Prior to this change it said it treated all 5xx as transient, but the
-  code says otherwise.
-  
-  Ref: https://github.com/curl/curl/blob/curl-7_75_0/src/tool_operate.c#L462-L495
-  
-  Closes https://github.com/curl/curl/pull/6724
+- [Jacob Hoffman-Andrews brought this change]
 
-- retry-all-errors.d: Explain curl errors versus HTTP response errors
-  
-  - Add a paragraph explaining that curl does not consider HTTP response
-    errors as curl errors, and how that behavior can be modified by using
-    --retry and --fail.
-  
-  The --retry-all-errors doc says "Retry on any error" which some users
-  may find misleading without the added explanation.
-  
-  Ref: https://curl.se/docs/faq.html#Why_do_I_get_downloaded_data_eve
-  Ref: https://curl.se/docs/faq.html#curl_doesn_t_return_error_for_HT
+  lib: remove strlen call from Curl_client_write
   
-  Reported-by: Lawrence Gripper
+  At all call sites with an explicit 0 len, pass an appropriate nonzero
+  len.
   
-  Fixes https://github.com/curl/curl/issues/6712
-  Closes https://github.com/curl/curl/pull/6720
+  Closes #6954
 
-Daniel Stenberg (11 Mar 2021)
-- travis: switch ngtcp2 build over to quictls
-  
-  The ngtcp2 project switched over to using the quictls OpenSSL fork
-  instead of their own patched OpenSSL. We follow suit.
+- [Ayushman Singh Chauhan brought this change]
+
+  docs: camelcase it like GitHub everywhere
   
-  Closes #6729
+  Closes #6979
 
-- test220/314: adjust to run with Hyper
+Jay Satiro (27 Apr 2021)
+- [Lucas Servén Marín brought this change]
 
-- c-hyper: support automatic content-encoding
+  docs: fix typo in fail-with-body doc
   
-  Closes #6727
-
-- http: remove superfluous NULL assign
+  This commit fixes a small typo in the documentation for the
+  --fail-with-body flag.
   
-  Closes #6727
+  Closes https://github.com/curl/curl/pull/6977
 
-- tool_operate: bail if set CURLOPT_HTTP09_ALLOWED returns error
+- lib: fix some misuse of curlx_convert_UTF8_to_tchar
   
-  Closes #6727
-
-- setopt: error on CURLOPT_HTTP09_ALLOWED set true with Hyper
+  curlx_convert_UTF8_to_tchar must be freed by curlx_unicodefree, but
+  prior to this change some uses mistakenly called free.
   
-  Not supported.
+  I've reviewed all other uses of curlx_convert_UTF8_to_tchar and
+  curlx_convert_tchar_to_UTF8.
   
-  Closes #6727
-
-- test306: make it not run with Hyper
+  Bug: https://github.com/curl/curl/pull/6602#issuecomment-825236763
+  Reported-by: sergio-nsk@users.noreply.github.com
   
-  ... as it tests HTTP/0.9 which Hyper doesn't support.
-
-- test304: header CRLF cleanup to work with Hyper
+  Closes https://github.com/curl/curl/pull/6938
 
-- FTP: allow SIZE to fail when doing (resumed) upload
+Daniel Stenberg (27 Apr 2021)
+- ntlm: precaution against super huge type2 offsets
   
-  Added test 362 to verify.
+  ... which otherwise caused an integer overflow and circumvented the if()
+  conditional size check.
   
-  Reported-by: Jordan Brown
-  Regression since 7ea2e1d0c5a7f (7.73.0)
-  Fixes #6715
-  Closes #6725
+  Detected by OSS-Fuzz
+  Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33720
+  Assisted-by: Max Dymond
+  Closes #6975
 
-- configure: provide Largefile feature for curl-config
-  
-  ... as cmake now does it correctly, and make test1014 check for it
-  
-  Closes #6702
+- c-hyper: fix unused variable ‘wrote’
 
-- config: remove CURL_SIZEOF_CURL_OFF_T use only SIZEOF_CURL_OFF_T
-  
-  Make the code consistently use a single name for the size of the
-  "curl_off_t" type.
+- libcurl-security.3: be careful of setuid
   
-  Closes #6702
+  Reported-by: Harry Sintonen
+  Closes #6970
 
-Jay Satiro (10 Mar 2021)
-- [Jun-ya Kato brought this change]
+- [Kevin Burke brought this change]
 
-  ngtcp2: Fix build error due to change in ngtcp2_addr_init
+  c-hyper: don't write to set.writeheader if null
   
-  ngtcp2/ngtcp2@b8d90a9 changed the function prototype.
+  Previously if a caller set CURLOPT_WRITEFUNCTION but did not set a
+  CURLOPT_HEADERDATA buffer, Hyper would still attempt to write headers to
+  the data->set.writeheader header buffer, even though it is null.  This
+  led to NPE segfaults attempting to use libcurl+Hyper with Git, for
+  example.
   
-  Closes https://github.com/curl/curl/pull/6716
-
-Daniel Stenberg (10 Mar 2021)
-- [ejanchivdorj brought this change]
+  Instead, process the client write for the status line using the same
+  logic we use to process the client write for the later HTTP headers,
+  which contains the appropriate guard logic. As a side benefit,
+  data->set.writeheader is now only read in one file instead of two.
+  
+  Fixes #6619
+  Fixes abetterinternet/crustls#49
+  Fixes hyperium/hyper#2438
+  Closes #6971
 
-  multi: update pending list when removing handle
+- wolfssl: handle SSL_write() returns 0 for error
   
-  when removing a handle, most of the lists are updated but pending list
-  is not updated. Updating now.
+  Reported-by: Timo Lange
   
-  Closes #6713
-
-- [kokke brought this change]
+  Closes #6967
 
-  lib1536: check ptr against NULL before dereferencing it
+- easy: ignore sigpipe in curl_easy_send
   
-  Closes #6710
-
-- [kokke brought this change]
+  Closes #6965
 
-  lib1537: check ptr against NULL before dereferencing it
+- sigpipe: ignore SIGPIPE when using wolfSSL as well
   
-  Fixes #6707
-  Closes #6708
+  Closes #6966
 
-- travis: make torture tests skip TLS-SRP tests
-  
-  ... as it seems to often hang.
-  
-  Also: skip the "normal" tests as they're already run by many other
-  builds.
+- libcurl-security.3: don't try to filter IPv4 hosts based on the URL
   
-  Closes #6705
+  Closes #6942
 
-- openssl: adapt to v3's new const for a few API calls
-  
-  Closes #6703
+- [Harry Sintonen brought this change]
 
-- quiche: fix crash when failing to connect
+  nss_set_blocking: avoid static for sock_opt
   
-  Reported-by: ウさん
-  Fixes #6664
-  Closes #6701
+  Reviewed-by: Kamil Dudka
+  Closes #6945
 
 - RELEASE-NOTES: synced
-  
-  Fixed the release counter and added a missing contributor
 
-- RELEASE-NOTES: synced
+- [Yusuke Nakamura brought this change]
 
-- dynbuf: bump the max HTTP request to 1MB
+  docs/HTTP3.md: fix nghttp2's HTTP/3 server port
   
-  Raised from 128KB to allow longer request headers.
+  Port 8443 does not work now.
+  Correct origin is in the quicwg's wiki.
+  https://github.com/quicwg/base-drafts/wiki/Implementations#ngtcp2
   
-  Reported-by: Carl Zogheib
-  Fixes #6681
-  Closes #6685
+  Closes #6964
 
-Jay Satiro (6 Mar 2021)
-- schannel: Evaluate CURLOPT_SSL_OPTIONS via SSL_SET_OPTION macro
-  
-  - Change use of those options from CURLOPT_SSL_OPTIONS that are not
-    already evaluated via SSL_SET_OPTION in schannel and secure transport
-    to use that instead of data->set.ssl.optname.
-  
-  Example:
-  
-  Evaluate SSL_SET_OPTION(no_revoke) instead of data->set.ssl.no_revoke.
-  
-  This change is because options set via CURLOPT_SSL_OPTIONS
-  (data->set.ssl.optname) are separate from those set for HTTPS proxy via
-  CURLOPT_PROXY_SSL_OPTIONS (data->set.proxy_ssl.optname). The
-  SSL_SET_OPTION macro determines whether the connection is for HTTPS
-  proxy and based on that which option to evaluate.
+- krb5: don't use 'static' to store PBSZ size response
   
-  Since neither Schannel nor Secure Transport backends currently support
-  HTTPS proxy in libcurl, this change is for posterity and has no other
-  effect.
+  ... because it makes the knowledge and usage cross-transfer in funny and
+  unexpected ways.
   
-  Closes https://github.com/curl/curl/pull/6690
+  Reported-by: Harry Sintonen
+  Closes #6963
 
-- [kokke brought this change]
+- [Kevin Burke brought this change]
 
-  c-hyper: Remove superfluous pointer check
-  
-  `n` pointer is never NULL once set. Found by static analysis.
-  
-  Ref: https://github.com/curl/curl/issues/6696
+  m4: add security frameworks on Mac when compiling rustls
   
-  Closes https://github.com/curl/curl/pull/6697
-
-- version.d: Add missing features to the features list
+  Previously compiling rustls on Mac would only complete if you also
+  compiled the SecureTransport TLS backend, which curl would prefer to
+  the Rust backend.
   
-  - Add missing entries for gsasl, Kerberos, NTLM_WB, TrackMemory,
-    Unicode and zstd.
+  Appending these flags to LDFLAGS makes it possible to compile the
+  Rustls backend on Mac without the SecureTransport backend, which means
+  this patch will make it possible for Mac users to use the Rustls
+  backend for TLS.
   
-  - Remove krb4 since it's no longer a feature.
+  Reviewed-by: Jacob Hoffman-Andrews
   
-  Reported-by: Ádler Jonas Gross
+  Fixes #6955
+  Cloes #6956
+
+- krb5: remove the unused 'overhead' function
   
-  Fixes https://github.com/curl/curl/issues/6677
-  Closes https://github.com/curl/curl/pull/6687
+  Closes #6947
 
-- [Vladimir Varlamov brought this change]
+- [Johann150 brought this change]
 
-  docs: add missing Arg tag to --stderr
-  
-  Prior to this change the required argument was not shown.
-  
-  curl.1 before: --stderr
-  curl.1 after: --stderr 
+  curl_url_set.3: add memory management information
   
-  curl --help before:
-       --stderr        Where to redirect stderr
+  wording taken from man page for CURLOPT_URL.3
   
-  curl --help after:
-       --stderr   Where to redirect stderr
+  As far as I can see, the URL part is either malloc'ed before due to
+  encoding or it is strdup'ed.
   
-  Closes https://github.com/curl/curl/pull/6692
+  Closes #6953
 
-- projects: Update VS projects for OpenSSL 1.1.x
-  
-  - Update VS project templates to use the OpenSSL lib names and include
-    directories for OpenSSL 1.1.x.
-  
-  This change means the VS project files will now build only with OpenSSL
-  1.1.x when an OpenSSL configuration is chosen. Prior to this change the
-  project files built only with OpenSSL 1.0.x (end-of-life) when an
-  OpenSSL configuration was chosen.
-  
-  The template changes in this commit were made by script:
-  
-  libeay32.lib => libcrypto.lib
-  ssleay32.lib => libssl.lib
-  ..\..\..\..\..\openssl\inc32 => ..\..\..\..\..\openssl\include
-  
-  And since the output directory now contains the includes it's prepended:
-  ..\..\..\..\..\openssl\build\Win{32,64}\VC{6..15}\{DLL,LIB}
-  {Debug,Release}\include
-  
-  - Change build-openssl.bat to copy the build's include directory to the
-    output directory (as seen above).
-  
-  Each build has its own opensslconf.h which is different so we can't just
-  include the source include directory any longer.
-  
-  Note the include directory in the output directory is a full copy from
-  the build so technically we don't need to include the OpenSSL source
-  include directory in the template. However, I left it last in case the
-  user made a custom OpenSSL build using the old method which would put
-  opensslconf in the OpenSSL source include directory.
-  
-  - Change build-openssl.bat to use a temporary install directory that is
-    different from the temporary build directory.
-  
-  For OpenSSL 1.1.x the temporary paths must be separate not a descendant
-  of the other, otherwise pdb files will be lost between builds.
-  
-  Ref: https://curl.se/mail/lib-2018-10/0049.html
-  Ref: https://gist.github.com/jay/125191c35bbeb894444eff827651f755
-  Ref; https://github.com/openssl/openssl/issues/10005
-  
-  Fixes https://github.com/curl/curl/issues/984
-  Closes https://github.com/curl/curl/pull/6675
+- [Jacob Hoffman-Andrews brought this change]
 
-- doh: Inherit CURLOPT_STDERR from user's easy handle
-  
-  Prior to this change if the user set their easy handle's error stream
-  to something other than stderr it was not inherited by the doh handles,
-  which meant that they would still write to the default standard error
-  stream (stderr) for verbose output.
-  
-  Bug: https://github.com/curl/curl/issues/6605
-  Reported-by: arvids-kokins-bidstack@users.noreply.github.com
+  c-hpyer: fix handling of zero-byte chunk from hyper
   
-  Closes https://github.com/curl/curl/pull/6661
+  Closes #6951
 
-Marc Hoersken (1 Mar 2021)
-- CI/azure: replace python-impacket with python3-impacket
-  
-  As of this month Azure DevOps uses Ubuntu 20.04 LTS which
-  no longer supports Python 2 and instead ships Python 3.
+- CURLOPT_POSTFIELDS.3: clarify how it gets the size of the data
   
-  Closes #6678
+  Ref: https://curl.se/mail/lib-2021-04/0085.html
+  Closes #6943
 
-- runtests.pl: kill processes locking test log files
-  
-  Introduce a new runtests.pl command option: -rm
-  
-  For now only required and implemented for Windows.
-  Ignore stunnel logs due to long running processes.
-  
-  Requires Sysinternals handle[64].exe to be on PATH.
-  
-  Reviewed-by: Jay Satiro
-  
-  Ref: #6058
-  Closes #6179
+- [Ralph Langendam brought this change]
 
-- pathhelp.pm: fix use of pwd -L in Msys environment
-  
-  While Msys2 has a pwd binary which supports -L,
-  Msys1 only has a shell built-in with that feature.
-  
-  Reviewed-by: Jay Satiro
+  cmake: make libcurl output filename configurable
   
-  Part of #6179
+  Reviewed-by: Jakub Zakrzewski
+  Closes #6933
 
-Daniel Gustafsson (1 Mar 2021)
-- ldap: use correct memory free function
+- [Patrick Monnerat brought this change]
+
+  vtls: reset ssl use flag upon negotiation failure
   
-  unescaped is coming from Curl_urldecode and not a unicode conversion
-  function, so reclaiming its memory should be performed with a normal
-  call to free rather than curlx_unicodefree.  In reality, this is the
-  same thing as curlx_unicodefree is implemented as a call to free but
-  that's not guaranteed to always hold.  Using the curlx macro present
-  issues with memory debugging as well.
+  Fixes the segfault in ldaps disconnect.
   
-  Closes #6671
-  Reviewed-by: Jay Satiro 
-  Reviewed-by: Daniel Stenberg 
+  Reported-by: Illarion Taev
+  Fixes #6934
+  Closes #6937
 
-- url: fix typo in comment
+- configure: fix typo in TLS error message
   
-  Correct a small typo which snuck in with a304051620.
+  Reported-by: Pontus Lundkvist
 
-Jay Satiro (28 Feb 2021)
-- tool_help: Increase space between option and description
-  
-  - Increase the minimum number of spaces between the option and the
-    description from 1 to 2.
+- README: link to the commercial support option
+
+Jay Satiro (22 Apr 2021)
+- [Martin Halle brought this change]
+
+  version: add gsasl_version to curl_version_info_data
   
-  Before:
-  ~~~
-   -u, --user  Server user and password
-   -A, --user-agent  Send User-Agent  to server
-   -v, --verbose       Make the operation more talkative
-   -V, --version       Show version number and quit
-   -w, --write-out  Use output FORMAT after completion
-       --xattr         Store metadata in extended file attributes
-  ~~~
+  - Add gsasl_version string and bump to CURLVERSION_TENTH.
   
-  After:
-  ~~~
-   -u, --user   Server user and password
-   -A, --user-agent   Send User-Agent  to server
-   -v, --verbose       Make the operation more talkative
-   -V, --version       Show version number and quit
-   -w, --write-out   Use output FORMAT after completion
-       --xattr         Store metadata in extended file attributes
-  ~~~
+  Ref: https://curl.se/mail/lib-2021-04/0003.html
   
-  Closes https://github.com/curl/curl/pull/6674
+  Closes https://github.com/curl/curl/pull/6843
+
+- [Morten Minde Neergaard brought this change]
 
-Daniel Stenberg (27 Feb 2021)
-- curl: set CURLOPT_NEW_FILE_PERMS if requested
+  schannel: Support strong crypto option
   
-  The --create-file-mode code logic accepted the value but never actually
-  passed it on to libcurl!
+  - Support enabling strong crypto via optional user cipher list when
+    USE_STRONG_CRYPTO or SCH_USE_STRONG_CRYPTO is in the list.
   
-  Follow-up to a7696c73436f (shipped in 7.75.0)
-  Reported-by: Johannes Lesr
-  Fixes #6657
-  Closes #6666
-
-- tool_operate: check argc before accessing argv[1]
+  MSDN says SCH_USE_STRONG_CRYPTO "Instructs Schannel to disable known
+  weak cryptographic algorithms, cipher suites, and SSL/TLS protocol
+  versions that may be otherwise enabled for better interoperability."
   
-  Follow-up to 09363500b
-  Reported-by: Emil Engler
-  Reviewed-by: Daniel Gustafsson
-  Closes #6668
+  Ref: https://curl.se/mail/lib-2021-02/0066.html
+  Ref: https://curl.se/docs/manpage.html#--ciphers
+  Ref: https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html
+  Ref: https://docs.microsoft.com/en-us/windows/win32/api/schannel/ns-schannel-schannel_cred
+  
+  Closes https://github.com/curl/curl/pull/6734
+
+Daniel Stenberg (22 Apr 2021)
+- RELEASE-NOTES: synced
 
-Daniel Gustafsson (26 Feb 2021)
-- [Jean-Philippe Menil brought this change]
+- ci: adapt to configure requiring an explicit TLS choice
 
-  openssl: remove get_ssl_version_txt in favor of SSL_get_version
-  
-  openssl: use SSL_get_version to get connection protocol
-  
-  Replace our bespoke get_ssl_version_txt in favor of SSL_get_version.
-  We can get rid of few lines of code, since SSL_get_version achieve
-  the exact same thing
+- configure: split out each TLS library detector into its own function
   
-  Closes #6665
-  Reviewed-by: Daniel Gustafsson 
-  Signed-off-by: Jean-Philippe Menil 
+  ... and put those functions in separate m4 files per TLS library.
diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS
index 82755c72d3..e29cbeedf6 100644
--- a/libs/libcurl/docs/THANKS
+++ b/libs/libcurl/docs/THANKS
@@ -273,6 +273,7 @@ Benoit Neil
 Benoit Sigoure
 Bernard Leak
 Bernard Spil
+Bernat Mut
 Bernd Mueller
 Bernhard Iselborn
 Bernhard M. Wiedemann
@@ -341,6 +342,7 @@ Bru Rom
 Bruce Mitchener
 Bruce Stephens
 BrumBrum on hackerone
+Bruno Baguette
 Bruno de Carvalho
 Bruno Grasselli
 Bruno Thomsen
@@ -478,6 +480,7 @@ Dambaev Alexander
 Damian Dixon
 Damien Adant
 Damien Vielpeau
+Damien Walsh
 Dan Becker
 Dan Cristian
 Dan Donahue
@@ -537,6 +540,7 @@ David Bau
 David Benjamin
 David Binderman
 David Blaikie
+David Bohman
 David Byron
 David Cohen
 David Cook
@@ -709,6 +713,7 @@ Eric Lavigne
 Eric Lubin
 Eric Melville
 Eric Mertens
+Eric Musser
 Eric Rautman
 Eric Rescorla
 Eric Ridge
@@ -771,6 +776,7 @@ Flameborn on github
 Flavio Medeiros
 Florian Pritz
 Florian Schoppmann
+Florian Van Heghe
 Florian Weimer
 Florin Petriuc
 Forrest Cahoon
@@ -814,6 +820,7 @@ Gavin Wong
 Gavrie Philipson
 Gaz Iqbal
 Gaël Portay
+gclinch on github
 Gealber Morales
 Geeknik Labs
 Geoff Beier
@@ -849,6 +856,7 @@ Glen Nakamura
 Glen Scott
 Glenn de boer
 Glenn Sheridan
+Glenn Strauss
 Godwin Stewart
 Google Inc.
 Gordon Marler
@@ -1060,12 +1068,14 @@ Jeff Hodges
 Jeff Johnson
 Jeff King
 Jeff Lawson
+Jeff Luszcz
 Jeff Mears
 Jeff Phillips
 Jeff Pohlmeyer
 Jeff Weber
 Jeffrey Tolar
 Jeffrey Walton
+jeffrson on github
 Jens Finkhaeuser
 Jens Rantil
 Jens Schleusener
@@ -1223,6 +1233,7 @@ Julian Z
 Julien Chaffraix
 Julien Nabet
 Julien Royer
+Jun Tseng
 Jun-ichiro itojun Hagino
 Jun-ya Kato
 jungle-boogie on github
@@ -1363,6 +1374,7 @@ Leon Breedt
 Leon Winter
 Leonardo Rosati
 Leonardo Taccari
+Leszek Kubik
 Li Xinwei
 Liam Healy
 lijian996 on github
@@ -1379,6 +1391,7 @@ Lior Kaplan
 Lisa Xu
 Liviu Chircu
 Liza Alenchery
+lllaffer on github
 Lloyd Fournier
 Lluís Batlle i Rossell
 locpyl-tidnyd on github
@@ -1459,6 +1472,7 @@ Mario Schroeder
 Mark Brand
 Mark Butler
 Mark Davies
+Mark Dodgson
 Mark Hamilton
 Mark Incley
 Mark Karpeles
@@ -1557,6 +1571,7 @@ mccormickt12 on github
 Mehmet Bozkurt
 Mekonikum
 Melissa Mears
+Melroy van den Berg
 Mert Yazıcıoğlu
 Mettgut Jamalla
 Michael Afanasiev
@@ -1713,6 +1728,7 @@ Niklas Hambüchen
 Nikolai Kondrashov
 Nikos Mavrogiannopoulos
 Nikos Tsipinakis
+nimaje on github
 niner on github
 Ning Dong
 Nir Soffer
@@ -1942,6 +1958,7 @@ Red Hat Product Security
 Reed Loden
 Reinhard Max
 Reinout van Schouwen
+RekGRpth on github
 Remco van Hooff
 Remi Gacogne
 Remo E
@@ -2070,6 +2087,7 @@ Ryan Mast
 Ryan Nelson
 Ryan Schmidt
 Ryan Scott
+Ryan Sleevi
 Ryan Winograd
 ryancaicse on github
 Ryuichi KAWAMATA
@@ -2182,6 +2200,7 @@ Spork Schivago
 sspiri on github
 sstruchtrup on github
 Stadler Stephan
+Stan Hu
 Stan van de Burgt
 Stanislav Ivochkin
 Stanislav Zidek
@@ -2192,6 +2211,7 @@ Stefan Bühler
 Stefan Eissing
 Stefan Esser
 Stefan Grether
+Stefan Huber
 Stefan Kanthak
 Stefan Karpinski
 Stefan Krause
@@ -2210,9 +2230,11 @@ Stephan Bergmann
 Stephan Lagerholm
 Stephan Mühlstrasser
 Stephan Szabo
+Stephane Pellegrino
 Stephen Brokenshire
 Stephen Collyer
 Stephen Kick
+Stephen M. Coakley
 Stephen More
 Stephen Toub
 Sterling Hughes
@@ -2325,6 +2347,7 @@ Tobias Hieta
 Tobias Hintze
 Tobias Lindgren
 Tobias Markus
+Tobias Nießen
 Tobias Nyholm
 Tobias Rundström
 Tobias Stoeckmann
@@ -2398,6 +2421,7 @@ User Sg
 ustcqidi on github
 Vadim Grinshpun
 Valentin David
+Valentin Richter
 Valentyn Korniienko
 Valentín Gutiérrez
 Valerii Zapodovnikov
@@ -2432,6 +2456,7 @@ Vlad Ureche
 Vladimir Grishchenko
 Vladimir Kotal
 Vladimir Lazarenko
+Vladimir Panteleev
 Vladimir Varlamov
 Vlastimil Ovčáčík
 Vojtech Janota
diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h
index 6b6ac8a05e..7b69ce2d67 100644
--- a/libs/libcurl/include/curl/curl.h
+++ b/libs/libcurl/include/curl/curl.h
@@ -2132,6 +2132,9 @@ typedef enum {
    * (in seconds) */
   CURLOPT(CURLOPT_MAXLIFETIME_CONN, CURLOPTTYPE_LONG, 314),
 
+  /* Set MIME option flags. */
+  CURLOPT(CURLOPT_MIME_OPTIONS, CURLOPTTYPE_LONG, 315),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
@@ -2291,6 +2294,9 @@ CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
 typedef struct curl_mime      curl_mime;      /* Mime context. */
 typedef struct curl_mimepart  curl_mimepart;  /* Mime part context. */
 
+/* CURLMIMEOPT_ defines are for the CURLOPT_MIME_OPTIONS option. */
+#define CURLMIMEOPT_FORMESCAPE  (1<<0) /* Use backslash-escaping for forms. */
+
 /*
  * NAME curl_mime_init()
  *
diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h
index 6756c31bff..6d2f99b6da 100644
--- a/libs/libcurl/include/curl/curlver.h
+++ b/libs/libcurl/include/curl/curlver.h
@@ -30,12 +30,12 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.80.0"
+#define LIBCURL_VERSION "7.81.0"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 80
+#define LIBCURL_VERSION_MINOR 81
 #define LIBCURL_VERSION_PATCH 0
 
 /* This is the numeric version of the libcurl version number, meant for easier
@@ -57,7 +57,7 @@
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
 */
-#define LIBCURL_VERSION_NUM 0x075000
+#define LIBCURL_VERSION_NUM 0x075100
 
 /*
  * This is the date and time when the full source package was created. The
@@ -68,7 +68,7 @@
  *
  * "2007-11-23"
  */
-#define LIBCURL_TIMESTAMP "2021-11-10"
+#define LIBCURL_TIMESTAMP "2022-01-05"
 
 #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
 #define CURL_AT_LEAST_VERSION(x,y,z) \
diff --git a/libs/libcurl/include/curl/multi.h b/libs/libcurl/include/curl/multi.h
index 37f9829b3b..91cd95d323 100644
--- a/libs/libcurl/include/curl/multi.h
+++ b/libs/libcurl/include/curl/multi.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -73,7 +73,8 @@ typedef enum {
   CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a
                                callback */
   CURLM_WAKEUP_FAILURE,  /* wakeup is unavailable or failed */
-  CURLM_BAD_FUNCTION_ARGUMENT,  /* function called with a bad parameter */
+  CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */
+  CURLM_ABORTED_BY_CALLBACK,
   CURLM_LAST
 } CURLMcode;
 
diff --git a/libs/libcurl/include/curl/urlapi.h b/libs/libcurl/include/curl/urlapi.h
index 3c4b4e18aa..a475f91b60 100644
--- a/libs/libcurl/include/curl/urlapi.h
+++ b/libs/libcurl/include/curl/urlapi.h
@@ -48,6 +48,18 @@ typedef enum {
   CURLUE_NO_PORT,             /* 15 */
   CURLUE_NO_QUERY,            /* 16 */
   CURLUE_NO_FRAGMENT,         /* 17 */
+  CURLUE_NO_ZONEID,           /* 18 */
+  CURLUE_BAD_FILE_URL,        /* 19 */
+  CURLUE_BAD_FRAGMENT,        /* 20 */
+  CURLUE_BAD_HOSTNAME,        /* 21 */
+  CURLUE_BAD_IPV6,            /* 22 */
+  CURLUE_BAD_LOGIN,           /* 23 */
+  CURLUE_BAD_PASSWORD,        /* 24 */
+  CURLUE_BAD_PATH,            /* 25 */
+  CURLUE_BAD_QUERY,           /* 26 */
+  CURLUE_BAD_SCHEME,          /* 27 */
+  CURLUE_BAD_SLASHES,         /* 28 */
+  CURLUE_BAD_USER,            /* 29 */
   CURLUE_LAST
 } CURLUcode;
 
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt
index 2575288f70..46973bf2b8 100644
--- a/libs/libcurl/src/CMakeLists.txt
+++ b/libs/libcurl/src/CMakeLists.txt
@@ -95,10 +95,6 @@ endif()
 
 target_link_libraries(${LIB_NAME} ${CURL_LIBS})
 
-if(WIN32)
-  add_definitions(-D_USRDLL)
-endif()
-
 set_target_properties(${LIB_NAME} PROPERTIES
   COMPILE_DEFINITIONS BUILDING_LIBCURL
   OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
@@ -121,6 +117,7 @@ endif()
 
 if(WIN32)
   if(BUILD_SHARED_LIBS)
+    set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "_USRDLL")
     if(MSVC)
       # Add "_imp" as a suffix before the extension to avoid conflicting with
       # the statically linked "libcurl.lib"
diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32
index d78614da33..2bb208fbe4 100644
--- a/libs/libcurl/src/Makefile.m32
+++ b/libs/libcurl/src/Makefile.m32
@@ -168,76 +168,76 @@ endif
 ########################################################
 ## Nothing more to do below this line!
 
-ifeq ($(findstring -dyn,$(CFG)),-dyn)
+ifneq ($(findstring -dyn,$(CFG)),)
 DYN = 1
 endif
-ifeq ($(findstring -ares,$(CFG)),-ares)
+ifneq ($(findstring -ares,$(CFG)),)
 ARES = 1
 endif
-ifeq ($(findstring -sync,$(CFG)),-sync)
+ifneq ($(findstring -sync,$(CFG)),)
 SYNC = 1
 endif
-ifeq ($(findstring -rtmp,$(CFG)),-rtmp)
+ifneq ($(findstring -rtmp,$(CFG)),)
 RTMP = 1
 ZLIB = 1
 endif
-ifeq ($(findstring -ssh2,$(CFG)),-ssh2)
+ifneq ($(findstring -ssh2,$(CFG)),)
 SSH2 = 1
 ZLIB = 1
 endif
-ifeq ($(findstring -ssl,$(CFG)),-ssl)
+ifneq ($(findstring -ssl,$(CFG)),)
 SSL = 1
 endif
-ifeq ($(findstring -srp,$(CFG)),-srp)
+ifneq ($(findstring -srp,$(CFG)),)
 SRP = 1
 endif
-ifeq ($(findstring -zlib,$(CFG)),-zlib)
+ifneq ($(findstring -zlib,$(CFG)),)
 ZLIB = 1
 endif
-ifeq ($(findstring -zstd,$(CFG)),-zstd)
+ifneq ($(findstring -zstd,$(CFG)),)
 ZSTD = 1
 endif
-ifeq ($(findstring -brotli,$(CFG)),-brotli)
+ifneq ($(findstring -brotli,$(CFG)),)
 BROTLI = 1
 endif
-ifeq ($(findstring -gsasl,$(CFG)),-gsasl)
+ifneq ($(findstring -gsasl,$(CFG)),)
 GSASL = 1
 endif
-ifeq ($(findstring -idn2,$(CFG)),-idn2)
+ifneq ($(findstring -idn2,$(CFG)),)
 IDN2 = 1
 endif
-ifeq ($(findstring -winidn,$(CFG)),-winidn)
+ifneq ($(findstring -winidn,$(CFG)),)
 WINIDN = 1
 endif
-ifeq ($(findstring -sspi,$(CFG)),-sspi)
+ifneq ($(findstring -sspi,$(CFG)),)
 SSPI = 1
 endif
-ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
+ifneq ($(findstring -ldaps,$(CFG)),)
 LDAPS = 1
 endif
-ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
+ifneq ($(findstring -ipv6,$(CFG)),)
 IPV6 = 1
 endif
-ifeq ($(findstring -winssl,$(CFG)),-winssl)
-WINSSL = 1
+ifneq ($(findstring -schannel,$(CFG))$(findstring -winssl,$(CFG)),)
+SCHANNEL = 1
 SSPI = 1
 endif
-ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
+ifneq ($(findstring -nghttp2,$(CFG)),)
 NGHTTP2 = 1
 endif
-ifeq ($(findstring -nghttp3,$(CFG)),-nghttp3)
+ifneq ($(findstring -nghttp3,$(CFG)),)
 NGHTTP3 = 1
 endif
-ifeq ($(findstring -ngtcp2,$(CFG)),-ngtcp2)
+ifneq ($(findstring -ngtcp2,$(CFG)),)
 NGTCP2 = 1
 endif
-ifeq ($(findstring -unicode,$(CFG)),-unicode)
+ifneq ($(findstring -unicode,$(CFG)),)
 UNICODE = 1
 endif
 
 # SSH2 and RTMP require an SSL library; assume OpenSSL if none specified
 ifneq ($(SSH2)$(RTMP),)
-  ifeq ($(SSL)$(WINSSL),)
+  ifeq ($(SSL)$(SCHANNEL),)
     SSL = 1
   endif
 endif
@@ -245,7 +245,7 @@ endif
 INCLUDES = -I. -I../include
 CFLAGS += -DBUILDING_LIBCURL
 ifdef SSL
-  ifdef WINSSL
+  ifdef SCHANNEL
     CFLAGS += -DCURL_WITH_MULTI_SSL
   endif
 endif
@@ -277,7 +277,7 @@ ifdef SSH2
   INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32"
   CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
   DLL_LIBS += -L"$(LIBSSH2_PATH)/win32" -lssh2
-  ifdef WINSSL
+  ifdef SCHANNEL
     ifndef DYN
       DLL_LIBS += -lbcrypt -lcrypt32
     endif
@@ -329,7 +329,7 @@ ifdef SSL
     endif
   endif
 endif
-ifdef WINSSL
+ifdef SCHANNEL
   CFLAGS += -DUSE_SCHANNEL
   DLL_LIBS += -lcrypt32
 endif
diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c
index fc168baa6e..fd0bb6c96a 100644
--- a/libs/libcurl/src/asyn-ares.c
+++ b/libs/libcurl/src/asyn-ares.c
@@ -109,7 +109,9 @@ struct thread_data {
   struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
                                     parts */
   int last_status;
+#ifndef HAVE_CARES_GETADDRINFO
   struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
+#endif
 };
 
 /* How long we are willing to wait for additional parallel responses after
@@ -375,6 +377,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
 
   waitperform(data, 0);
 
+#ifndef HAVE_CARES_GETADDRINFO
   /* Now that we've checked for any last minute results above, see if there are
      any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
      expires. */
@@ -397,6 +400,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
     ares_cancel((ares_channel)data->state.async.resolver);
     DEBUGASSERT(res->num_pending == 0);
   }
+#endif
 
   if(res && !res->num_pending) {
     (void)Curl_addrinfo_callback(data, res->last_status, res->temp_ai);
diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl
index 8f98a99ab5..eea1126d1c 100644
--- a/libs/libcurl/src/checksrc.pl
+++ b/libs/libcurl/src/checksrc.pl
@@ -502,7 +502,7 @@ sub scanfile {
         }
         # check for '== NULL' in if/while conditions but not if the thing on
         # the left of it is a function call
-        if($nostr =~ /^(.*)(if|while)(\(.*[^)]) == NULL/) {
+        if($nostr =~ /^(.*)(if|while)(\(.*?)([!=]= NULL|NULL [!=]=)/) {
             checkwarn("EQUALSNULL", $line,
                       length($1) + length($2) + length($3),
                       $file, $l, "we prefer !variable instead of \"== NULL\" comparisons");
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index ef98f6cbdf..89593a815d 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.h
@@ -225,10 +225,6 @@
 /* Define if you have the socket function. */
 #define HAVE_SOCKET 1
 
-/* Define if libSSH2 is in use */
-#define USE_LIBSSH2 1
-#define HAVE_LIBSSH2_H 1
-
 /* Define if you have the strcasecmp function. */
 #ifdef __MINGW32__
 #define HAVE_STRCASECMP 1
@@ -669,9 +665,6 @@ Vista
 #  define CURL_DISABLE_LDAP 1
 #endif
 
-/* if SSL is enabled */
-#define USE_OPENSSL 1
-
 /* Define to use the Windows crypto library. */
 #if !defined(CURL_WINDOWS_APP)
 #define USE_WIN32_CRYPTO
diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c
index f5ba8ff70a..fec1937f0b 100644
--- a/libs/libcurl/src/conncache.c
+++ b/libs/libcurl/src/conncache.c
@@ -113,21 +113,16 @@ static void free_bundle_hash_entry(void *freethis)
 
 int Curl_conncache_init(struct conncache *connc, int size)
 {
-  int rc;
-
   /* allocate a new easy handle to use when closing cached connections */
   connc->closure_handle = curl_easy_init();
   if(!connc->closure_handle)
     return 1; /* bad */
 
-  rc = Curl_hash_init(&connc->hash, size, Curl_hash_str,
-                      Curl_str_key_compare, free_bundle_hash_entry);
-  if(rc)
-    Curl_close(&connc->closure_handle);
-  else
-    connc->closure_handle->state.conn_cache = connc;
+  Curl_hash_init(&connc->hash, size, Curl_hash_str,
+                 Curl_str_key_compare, free_bundle_hash_entry);
+  connc->closure_handle->state.conn_cache = connc;
 
-  return rc;
+  return 0; /* good */
 }
 
 void Curl_conncache_destroy(struct conncache *connc)
diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c
index af60947314..5252f9714d 100644
--- a/libs/libcurl/src/connect.c
+++ b/libs/libcurl/src/connect.c
@@ -744,15 +744,17 @@ void Curl_conninfo_local(struct Curl_easy *data, curl_socket_t sockfd,
 void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
                          curl_socket_t sockfd)
 {
-  /* 'local_ip' and 'local_port' get filled with local's numerical ip address
-     and port number whenever an outgoing connection is **established** from
-     the primary socket to a remote address. */
+  /* 'local_ip' and 'local_port' get filled with local's numerical
+     ip address and port number whenever an outgoing connection is
+     **established** from the primary socket to a remote address. */
   char local_ip[MAX_IPADR_LEN] = "";
   int local_port = -1;
 
-  if(!conn->bits.reuse && !conn->bits.tcp_fastopen)
-    Curl_conninfo_remote(data, conn, sockfd);
-  Curl_conninfo_local(data, sockfd, local_ip, &local_port);
+  if(conn->transport == TRNSPRT_TCP) {
+    if(!conn->bits.reuse && !conn->bits.tcp_fastopen)
+      Curl_conninfo_remote(data, conn, sockfd);
+    Curl_conninfo_local(data, sockfd, local_ip, &local_port);
+  } /* end of TCP-only section */
 
   /* persist connection info in session handle */
   Curl_persistconninfo(data, conn, local_ip, local_port);
@@ -892,6 +894,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
         connkeep(conn, "HTTP/3 default");
         return CURLE_OK;
       }
+      /* When a QUIC connect attempt fails, the better error explanation is in
+         'result' and not in errno */
       if(result) {
         conn->tempsock[i] = CURL_SOCKET_BAD;
         error = SOCKERRNO;
@@ -975,6 +979,13 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
         char buffer[STRERROR_LEN];
         Curl_printable_address(conn->tempaddr[i], ipaddress,
                                sizeof(ipaddress));
+#ifdef ENABLE_QUIC
+        if(conn->transport == TRNSPRT_QUIC) {
+          infof(data, "connect to %s port %u failed: %s",
+                ipaddress, conn->port, curl_easy_strerror(result));
+        }
+        else
+#endif
         infof(data, "connect to %s port %u failed: %s",
               ipaddress, conn->port,
               Curl_strerror(error, buffer, sizeof(buffer)));
@@ -986,9 +997,11 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
         ainext(conn, i, TRUE);
         status = trynextip(data, conn, sockindex, i);
         if((status != CURLE_COULDNT_CONNECT) ||
-           conn->tempsock[other] == CURL_SOCKET_BAD)
+           conn->tempsock[other] == CURL_SOCKET_BAD) {
           /* the last attempt failed and no other sockets remain open */
-          result = status;
+          if(!result)
+            result = status;
+        }
       }
     }
   }
@@ -1014,6 +1027,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
     /* no more addresses to try */
     const char *hostname;
     char buffer[STRERROR_LEN];
+    CURLcode failreason = result;
 
     /* if the first address family runs out of addresses to try before the
        happy eyeball timeout, go ahead and try the next family now */
@@ -1021,6 +1035,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
     if(!result)
       return result;
 
+    result = failreason;
+
 #ifndef CURL_DISABLE_PROXY
     if(conn->bits.socksproxy)
       hostname = conn->socks_proxy.host.name;
@@ -1034,10 +1050,14 @@ CURLcode Curl_is_connected(struct Curl_easy *data,
       hostname = conn->host.name;
 
     failf(data, "Failed to connect to %s port %u after "
-                "%" CURL_FORMAT_TIMEDIFF_T " ms: %s",
-        hostname, conn->port,
-        Curl_timediff(now, data->progress.t_startsingle),
-        Curl_strerror(error, buffer, sizeof(buffer)));
+          "%" CURL_FORMAT_TIMEDIFF_T " ms: %s",
+          hostname, conn->port,
+          Curl_timediff(now, data->progress.t_startsingle),
+#ifdef ENABLE_QUIC
+          (conn->transport == TRNSPRT_QUIC) ?
+          curl_easy_strerror(result) :
+#endif
+          Curl_strerror(error, buffer, sizeof(buffer)));
 
     Curl_quic_disconnect(data, conn, 0);
     Curl_quic_disconnect(data, conn, 1);
@@ -1125,7 +1145,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
   static int detectOsState = DETECT_OS_NONE;
 
   if(detectOsState == DETECT_OS_NONE) {
-    if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
+    if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
                                     VERSION_GREATER_THAN_EQUAL))
       detectOsState = DETECT_OS_VISTA_OR_LATER;
     else
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index b7531f7424..d418efa33d 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.c
@@ -1164,7 +1164,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
   bool fromfile = TRUE;
   char *line = NULL;
 
-  if(NULL == inc) {
+  if(!inc) {
     /* we didn't get a struct, create one */
     c = calloc(1, sizeof(struct CookieInfo));
     if(!c)
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index 751f6a4f65..2bce4ecc48 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -498,9 +498,6 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_OPENSSL_SSL_H
 
-/* Define to 1 if you have the `OpenSSL_version' function. */
-#undef HAVE_OPENSSL_VERSION
-
 /* Define to 1 if you have the  header file. */
 #undef HAVE_OPENSSL_X509_H
 
@@ -600,9 +597,6 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_SOCKET_H
 
-/* Define to 1 if you have the `SSLv2_client_method' function. */
-#undef HAVE_SSLV2_CLIENT_METHOD
-
 /* Define to 1 if you have the `SSL_get_ech_status' function. */
 #undef HAVE_SSL_GET_ECH_STATUS
 
diff --git a/libs/libcurl/src/curl_hmac.h b/libs/libcurl/src/curl_hmac.h
index 84c73121bd..5755655d02 100644
--- a/libs/libcurl/src/curl_hmac.h
+++ b/libs/libcurl/src/curl_hmac.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,7 +26,7 @@
 
 #define HMAC_MD5_LENGTH 16
 
-typedef void    (* HMAC_hinit_func)(void *context);
+typedef CURLcode (* HMAC_hinit_func)(void *context);
 typedef void    (* HMAC_hupdate_func)(void *context,
                                       const unsigned char *data,
                                       unsigned int len);
diff --git a/libs/libcurl/src/curl_md5.h b/libs/libcurl/src/curl_md5.h
index 5739c89ca4..b7d7c1f5d2 100644
--- a/libs/libcurl/src/curl_md5.h
+++ b/libs/libcurl/src/curl_md5.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,7 +27,7 @@
 
 #define MD5_DIGEST_LEN  16
 
-typedef void (* Curl_MD5_init_func)(void *context);
+typedef CURLcode (* Curl_MD5_init_func)(void *context);
 typedef void (* Curl_MD5_update_func)(void *context,
                                       const unsigned char *data,
                                       unsigned int len);
@@ -49,8 +49,8 @@ struct MD5_context {
 extern const struct MD5_params Curl_DIGEST_MD5[1];
 extern const struct HMAC_params Curl_HMAC_MD5[1];
 
-void Curl_md5it(unsigned char *output, const unsigned char *input,
-                const size_t len);
+CURLcode Curl_md5it(unsigned char *output, const unsigned char *input,
+                    const size_t len);
 
 struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params);
 CURLcode Curl_MD5_update(struct MD5_context *context,
diff --git a/libs/libcurl/src/curl_sha256.h b/libs/libcurl/src/curl_sha256.h
index b14c475ef8..55dc30ad74 100644
--- a/libs/libcurl/src/curl_sha256.h
+++ b/libs/libcurl/src/curl_sha256.h
@@ -37,8 +37,8 @@ extern const struct HMAC_params Curl_HMAC_SHA256[1];
 #define SHA256_DIGEST_LENGTH 32
 #endif
 
-void Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
-                   const size_t len);
+CURLcode Curl_sha256it(unsigned char *outbuffer, const unsigned char *input,
+                       const size_t len);
 
 #endif
 
diff --git a/libs/libcurl/src/curl_sspi.c b/libs/libcurl/src/curl_sspi.c
index 06841ddec6..339bf549fb 100644
--- a/libs/libcurl/src/curl_sspi.c
+++ b/libs/libcurl/src/curl_sspi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -83,7 +83,7 @@ CURLcode Curl_sspi_global_init(void)
      * have both these DLLs (security.dll forwards calls to secur32.dll) */
 
     /* Load SSPI dll into the address space of the calling process */
-    if(curlx_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL))
+    if(curlx_verify_windows_version(4, 0, 0, PLATFORM_WINNT, VERSION_EQUAL))
       s_hSecDll = Curl_load_library(TEXT("security.dll"));
     else
       s_hSecDll = Curl_load_library(TEXT("secur32.dll"));
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index 2aca93845b..20293a710b 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -822,7 +822,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
 struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
 {
   struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
-  if(NULL == outcurl)
+  if(!outcurl)
     goto fail;
 
   /*
@@ -1087,14 +1087,16 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
       /* if not pausing again, force a recv/send check of this connection as
          the data might've been read off the socket already */
       data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT;
-    if(data->multi)
-      Curl_update_timer(data->multi);
+    if(data->multi) {
+      if(Curl_update_timer(data->multi))
+        return CURLE_ABORTED_BY_CALLBACK;
+    }
   }
 
   if(!data->state.done)
     /* This transfer may have been moved in or out of the bundle, update the
        corresponding socket callback, if used */
-    Curl_updatesocket(data);
+    result = Curl_updatesocket(data);
 
   return result;
 }
diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c
index b6131d4321..04871ad1e3 100644
--- a/libs/libcurl/src/easyoptions.c
+++ b/libs/libcurl/src/easyoptions.c
@@ -170,6 +170,7 @@ struct curl_easyoption Curl_easyopts[] = {
   {"MAX_RECV_SPEED_LARGE", CURLOPT_MAX_RECV_SPEED_LARGE, CURLOT_OFF_T, 0},
   {"MAX_SEND_SPEED_LARGE", CURLOPT_MAX_SEND_SPEED_LARGE, CURLOT_OFF_T, 0},
   {"MIMEPOST", CURLOPT_MIMEPOST, CURLOT_OBJECT, 0},
+  {"MIME_OPTIONS", CURLOPT_MIME_OPTIONS, CURLOT_LONG, 0},
   {"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0},
   {"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0},
   {"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0},
@@ -359,6 +360,6 @@ struct curl_easyoption Curl_easyopts[] = {
  */
 int Curl_easyopts_check(void)
 {
-  return ((CURLOPT_LASTENTRY%10000) != (314 + 1));
+  return ((CURLOPT_LASTENTRY%10000) != (315 + 1));
 }
 #endif
diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c
index a8d209e3fb..f6921e4262 100644
--- a/libs/libcurl/src/ftp.c
+++ b/libs/libcurl/src/ftp.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -1004,7 +1004,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
       }
 
     /* parse the port */
-    if(ip_end != NULL) {
+    if(ip_end) {
       port_start = strchr(ip_end, ':');
       if(port_start) {
         port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
@@ -4102,6 +4102,11 @@ static CURLcode ftp_disconnect(struct Curl_easy *data,
   return CURLE_OK;
 }
 
+#ifdef _MSC_VER
+/* warning C4706: assignment within conditional expression */
+#pragma warning(disable:4706)
+#endif
+
 /***********************************************************************
  *
  * ftp_parse_url_path()
@@ -4190,7 +4195,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
         }
 
         /* parse the URL path into separate path components */
-        while((slashPos = strchr(curPos, '/')) != NULL) {
+        while((slashPos = strchr(curPos, '/'))) {
           size_t compLen = slashPos - curPos;
 
           /* path starts with a slash: add that as a directory */
@@ -4357,7 +4362,7 @@ static CURLcode ftp_setup_connection(struct Curl_easy *data,
   struct FTP *ftp;
 
   data->req.p.ftp = ftp = calloc(sizeof(struct FTP), 1);
-  if(NULL == ftp)
+  if(!ftp)
     return CURLE_OUT_OF_MEMORY;
 
   ftp->path = &data->state.up.path[1]; /* don't include the initial slash */
diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c
index 12e7aa5f27..8848906947 100644
--- a/libs/libcurl/src/hash.c
+++ b/libs/libcurl/src/hash.c
@@ -53,32 +53,25 @@ hash_element_dtor(void *user, void *element)
  * @unittest: 1602
  * @unittest: 1603
  */
-int
+void
 Curl_hash_init(struct Curl_hash *h,
                int slots,
                hash_function hfunc,
                comp_function comparator,
                Curl_hash_dtor dtor)
 {
-  if(!slots || !hfunc || !comparator ||!dtor) {
-    return 1; /* failure */
-  }
+  DEBUGASSERT(h);
+  DEBUGASSERT(slots);
+  DEBUGASSERT(hfunc);
+  DEBUGASSERT(comparator);
+  DEBUGASSERT(dtor);
 
+  h->table = NULL;
   h->hash_func = hfunc;
   h->comp_func = comparator;
   h->dtor = dtor;
   h->size = 0;
   h->slots = slots;
-
-  h->table = malloc(slots * sizeof(struct Curl_llist));
-  if(h->table) {
-    int i;
-    for(i = 0; i < slots; ++i)
-      Curl_llist_init(&h->table[i], (Curl_llist_dtor) hash_element_dtor);
-    return 0; /* fine */
-  }
-  h->slots = 0;
-  return 1; /* failure */
 }
 
 static struct Curl_hash_element *
@@ -98,8 +91,9 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
 
 #define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
 
-/* Insert the data in the hash. If there already was a match in the hash,
- * that data is replaced.
+/* Insert the data in the hash. If there already was a match in the hash, that
+ * data is replaced. This function also "lazily" allocates the table if
+ * needed, as it isn't done in the _init function (anymore).
  *
  * @unittest: 1305
  * @unittest: 1602
@@ -110,7 +104,20 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
 {
   struct Curl_hash_element  *he;
   struct Curl_llist_element *le;
-  struct Curl_llist *l = FETCH_LIST(h, key, key_len);
+  struct Curl_llist *l;
+
+  DEBUGASSERT(h);
+  DEBUGASSERT(h->slots);
+  if(!h->table) {
+    int i;
+    h->table = malloc(h->slots * sizeof(struct Curl_llist));
+    if(!h->table)
+      return NULL; /* OOM */
+    for(i = 0; i < h->slots; ++i)
+      Curl_llist_init(&h->table[i], hash_element_dtor);
+  }
+
+  l = FETCH_LIST(h, key, key_len);
 
   for(le = l->head; le; le = le->next) {
     he = (struct Curl_hash_element *) le->ptr;
@@ -139,14 +146,20 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
 int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len)
 {
   struct Curl_llist_element *le;
-  struct Curl_llist *l = FETCH_LIST(h, key, key_len);
+  struct Curl_llist *l;
 
-  for(le = l->head; le; le = le->next) {
-    struct Curl_hash_element *he = le->ptr;
-    if(h->comp_func(he->key, he->key_len, key, key_len)) {
-      Curl_llist_remove(l, le, (void *) h);
-      --h->size;
-      return 0;
+  DEBUGASSERT(h);
+  DEBUGASSERT(h->slots);
+  if(h->table) {
+    l = FETCH_LIST(h, key, key_len);
+
+    for(le = l->head; le; le = le->next) {
+      struct Curl_hash_element *he = le->ptr;
+      if(h->comp_func(he->key, he->key_len, key, key_len)) {
+        Curl_llist_remove(l, le, (void *) h);
+        --h->size;
+        return 0;
+      }
     }
   }
   return 1;
@@ -162,7 +175,9 @@ Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
   struct Curl_llist_element *le;
   struct Curl_llist *l;
 
-  if(h) {
+  DEBUGASSERT(h);
+  if(h->table) {
+    DEBUGASSERT(h->slots);
     l = FETCH_LIST(h, key, key_len);
     for(le = l->head; le; le = le->next) {
       struct Curl_hash_element *he = le->ptr;
@@ -204,13 +219,13 @@ Curl_hash_apply(Curl_hash *h, void *user,
 void
 Curl_hash_destroy(struct Curl_hash *h)
 {
-  int i;
-
-  for(i = 0; i < h->slots; ++i) {
-    Curl_llist_destroy(&h->table[i], (void *) h);
+  if(h->table) {
+    int i;
+    for(i = 0; i < h->slots; ++i) {
+      Curl_llist_destroy(&h->table[i], (void *) h);
+    }
+    Curl_safefree(h->table);
   }
-
-  Curl_safefree(h->table);
   h->size = 0;
   h->slots = 0;
 }
@@ -235,7 +250,7 @@ Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
   struct Curl_llist *list;
   int i;
 
-  if(!h)
+  if(!h || !h->table)
     return;
 
   for(i = 0; i < h->slots; ++i) {
@@ -290,6 +305,9 @@ Curl_hash_next_element(struct Curl_hash_iterator *iter)
 {
   struct Curl_hash *h = iter->hash;
 
+  if(!h->table)
+    return NULL; /* empty hash, nothing to return */
+
   /* Get the next element in the current list, if any */
   if(iter->current_element)
     iter->current_element = iter->current_element->next;
diff --git a/libs/libcurl/src/hash.h b/libs/libcurl/src/hash.h
index b7f828e071..e166916a90 100644
--- a/libs/libcurl/src/hash.h
+++ b/libs/libcurl/src/hash.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -69,11 +69,11 @@ struct Curl_hash_iterator {
   struct Curl_llist_element *current_element;
 };
 
-int Curl_hash_init(struct Curl_hash *h,
-                   int slots,
-                   hash_function hfunc,
-                   comp_function comparator,
-                   Curl_hash_dtor dtor);
+void Curl_hash_init(struct Curl_hash *h,
+                    int slots,
+                    hash_function hfunc,
+                    comp_function comparator,
+                    Curl_hash_dtor dtor);
 
 void *Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p);
 int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len);
diff --git a/libs/libcurl/src/hostcheck.c b/libs/libcurl/src/hostcheck.c
index cf267a7659..cd45bd07ee 100644
--- a/libs/libcurl/src/hostcheck.c
+++ b/libs/libcurl/src/hostcheck.c
@@ -89,7 +89,7 @@ static int hostmatch(char *hostname, char *pattern)
      match. */
   wildcard_enabled = 1;
   pattern_label_end = strchr(pattern, '.');
-  if(!pattern_label_end || strchr(pattern_label_end + 1, '.') == NULL ||
+  if(!pattern_label_end || !strchr(pattern_label_end + 1, '.') ||
      pattern_wildcard > pattern_label_end ||
      strncasecompare(pattern, "xn--", 4)) {
     wildcard_enabled = 0;
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index c33c9af9d0..911d5ed6d3 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -609,7 +609,11 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
   enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */
   struct connectdata *conn = data->conn;
   *entry = NULL;
+#ifndef CURL_DISABLE_DOH
   conn->bits.doh = FALSE; /* default is not */
+#else
+  (void)allowDOH;
+#endif
 
   if(data->share)
     Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
@@ -630,11 +634,15 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
 
     struct Curl_addrinfo *addr = NULL;
     int respwait = 0;
+#if !defined(CURL_DISABLE_DOH) || !defined(USE_RESOLVE_ON_IPS)
     struct in_addr in;
+#endif
+#ifndef CURL_DISABLE_DOH
 #ifndef USE_RESOLVE_ON_IPS
     const
 #endif
       bool ipnum = FALSE;
+#endif
 
     /* notify the resolver start callback */
     if(data->set.resolver_start) {
@@ -686,6 +694,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
 #endif /* ENABLE_IPV6 */
 
 #else /* if USE_RESOLVE_ON_IPS */
+#ifndef CURL_DISABLE_DOH
     /* First check if this is an IPv4 address string */
     if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
       /* This is a dotted IP address 123.123.123.123-style */
@@ -699,6 +708,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
         ipnum = TRUE;
     }
 #endif /* ENABLE_IPV6 */
+#endif /* CURL_DISABLE_DOH */
 
 #endif /* !USE_RESOLVE_ON_IPS */
 
@@ -708,8 +718,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
 
       if(strcasecompare(hostname, "localhost"))
         addr = get_localhost(port);
+#ifndef CURL_DISABLE_DOH
       else if(allowDOH && data->set.doh && !ipnum)
         addr = Curl_doh(data, hostname, port, &respwait);
+#endif
       else {
         /* Check what IP specifics the app has requested and if we can provide
          * it. If not, bail out. */
@@ -977,12 +989,12 @@ static void freednsentry(void *freethis)
 }
 
 /*
- * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
+ * Curl_init_dnscache() inits a new DNS cache.
  */
-int Curl_mk_dnscache(struct Curl_hash *hash)
+void Curl_init_dnscache(struct Curl_hash *hash)
 {
-  return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
-                        freednsentry);
+  Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+                 freednsentry);
 }
 
 /*
@@ -1210,9 +1222,10 @@ CURLcode Curl_resolv_check(struct Curl_easy *data,
 #if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH)
   (void)dns;
 #endif
-
+#ifndef CURL_DISABLE_DOH
   if(data->conn->bits.doh)
     return Curl_doh_is_resolved(data, dns);
+#endif
   return Curl_resolver_is_resolved(data, dns);
 }
 
@@ -1220,10 +1233,12 @@ int Curl_resolv_getsock(struct Curl_easy *data,
                         curl_socket_t *socks)
 {
 #ifdef CURLRES_ASYNCH
+#ifndef CURL_DISABLE_DOH
   if(data->conn->bits.doh)
     /* nothing to wait for during DoH resolve, those handles have their own
        sockets */
     return GETSOCK_BLANK;
+#endif
   return Curl_resolver_getsock(data, socks);
 #else
   (void)data;
diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h
index 67a688aebd..1db5981842 100644
--- a/libs/libcurl/src/hostip.h
+++ b/libs/libcurl/src/hostip.h
@@ -129,8 +129,8 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data,
 void Curl_resolv_unlock(struct Curl_easy *data,
                         struct Curl_dns_entry *dns);
 
-/* init a new dns cache and return success */
-int Curl_mk_dnscache(struct Curl_hash *hash);
+/* init a new dns cache */
+void Curl_init_dnscache(struct Curl_hash *hash);
 
 /* prune old entries from the DNS cache */
 void Curl_hostcache_prune(struct Curl_easy *data);
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index 78ad10edea..f08a343e3b 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -1153,7 +1153,6 @@ static bool http_should_fail(struct Curl_easy *data)
   return data->state.authproblem;
 }
 
-#ifndef USE_HYPER
 /*
  * readmoredata() is a "fread() emulation" to provide POST and/or request
  * data. It is used when a huge POST is to be made and the entire chunk wasn't
@@ -1412,8 +1411,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
   return result;
 }
 
-#endif
-
 /* end of the add_buffer functions */
 /* ------------------------------------------------------------------------- */
 
@@ -2375,6 +2372,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
 #ifndef USE_HYPER
   /* Hyper always handles the body separately */
   curl_off_t included_body = 0;
+#else
+  /* from this point down, this function should not be used */
+#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
 #endif
   CURLcode result = CURLE_OK;
   struct HTTP *http = data->req.p.http;
@@ -2685,7 +2685,6 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
     /* issue the request */
     result = Curl_buffer_send(r, data, &data->info.request_size, 0,
                               FIRSTSOCKET);
-
     if(result)
       failf(data, "Failed sending HTTP request");
     else
@@ -3312,7 +3311,7 @@ checkhttpprefix(struct Curl_easy *data,
 #ifdef CURL_DOES_CONVERSIONS
   /* convert from the network encoding using a scratch area */
   char *scratch = strdup(s);
-  if(NULL == scratch) {
+  if(!scratch) {
     failf(data, "Failed to allocate memory for conversion!");
     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
   }
@@ -3352,7 +3351,7 @@ checkrtspprefix(struct Curl_easy *data,
 #ifdef CURL_DOES_CONVERSIONS
   /* convert from the network encoding using a scratch area */
   char *scratch = strdup(s);
-  if(NULL == scratch) {
+  if(!scratch) {
     failf(data, "Failed to allocate memory for conversion!");
     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
   }
@@ -4245,7 +4244,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
            The sscanf() line above will also allow zero-prefixed and negative
            numbers, so we check for that too here.
         */
-        else if(ISDIGIT(digit4) || (k->httpcode < 100)) {
+        else if(ISDIGIT(digit4) || (nc >= 4 && k->httpcode < 100)) {
           failf(data, "Unsupported response code in HTTP response");
           return CURLE_UNSUPPORTED_PROTOCOL;
         }
diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h
index cb5b56faf3..b4aaba2a26 100644
--- a/libs/libcurl/src/http.h
+++ b/libs/libcurl/src/http.h
@@ -54,15 +54,11 @@ char *Curl_copy_header_value(const char *header);
 char *Curl_checkProxyheaders(struct Curl_easy *data,
                              const struct connectdata *conn,
                              const char *thisheader);
-#ifndef USE_HYPER
 CURLcode Curl_buffer_send(struct dynbuf *in,
                           struct Curl_easy *data,
                           curl_off_t *bytes_written,
                           curl_off_t included_body_bytes,
                           int socketindex);
-#else
-#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
-#endif
 
 CURLcode Curl_add_timecondition(struct Curl_easy *data,
 #ifndef USE_HYPER
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index 992fbbb26d..e74400a4ca 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -505,10 +505,13 @@ static int set_transfer_url(struct Curl_easy *data,
                             struct curl_pushheaders *hp)
 {
   const char *v;
-  CURLU *u = curl_url();
   CURLUcode uc;
   char *url = NULL;
   int rc = 0;
+  CURLU *u = curl_url();
+
+  if(!u)
+    return 5;
 
   v = curl_pushheader_byname(hp, ":scheme");
   if(v) {
diff --git a/libs/libcurl/src/http_aws_sigv4.c b/libs/libcurl/src/http_aws_sigv4.c
index cbbecb7129..751e5af5f9 100644
--- a/libs/libcurl/src/http_aws_sigv4.c
+++ b/libs/libcurl/src/http_aws_sigv4.c
@@ -286,8 +286,11 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
     post_data_len = strlen(post_data);
   else
     post_data_len = (size_t)data->set.postfieldsize;
-  Curl_sha256it(sha_hash,
-                (const unsigned char *) post_data, post_data_len);
+  if(Curl_sha256it(sha_hash, (const unsigned char *) post_data,
+                   post_data_len)) {
+    goto fail;
+  }
+
   sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
 
   Curl_http_method(data, conn, &method, &httpreq);
@@ -320,8 +323,11 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
     goto fail;
   }
 
-  Curl_sha256it(sha_hash, (unsigned char *) canonical_request,
-                strlen(canonical_request));
+  if(Curl_sha256it(sha_hash, (unsigned char *) canonical_request,
+                   strlen(canonical_request))) {
+    goto fail;
+  }
+
   sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
 
   /*
diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c
index fc050a07d5..e13f485a73 100644
--- a/libs/libcurl/src/http_proxy.c
+++ b/libs/libcurl/src/http_proxy.c
@@ -158,6 +158,10 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit)
 {
   struct http_connect_state *s;
   struct connectdata *conn = data->conn;
+  if(conn->handler->flags & PROTOPT_NOTCPPROXY) {
+    failf(data, "%s cannot be done over CONNECT", conn->handler->scheme);
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
   if(!reinit) {
     CURLcode result;
     DEBUGASSERT(!conn->connect_state);
@@ -198,17 +202,18 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit)
   return CURLE_OK;
 }
 
-static void connect_done(struct Curl_easy *data)
+void Curl_connect_done(struct Curl_easy *data)
 {
   struct connectdata *conn = data->conn;
   struct http_connect_state *s = conn->connect_state;
-  if(s->tunnel_state != TUNNEL_EXIT) {
+  if(s && (s->tunnel_state != TUNNEL_EXIT)) {
     s->tunnel_state = TUNNEL_EXIT;
     Curl_dyn_free(&s->rcvbuf);
     Curl_dyn_free(&s->req);
 
-    /* restore the protocol pointer */
-    data->req.p.http = s->prot_save;
+    /* restore the protocol pointer, if not already done */
+    if(s->prot_save)
+      data->req.p.http = s->prot_save;
     s->prot_save = NULL;
     data->info.httpcode = 0; /* clear it as it might've been used for the
                                 proxy */
@@ -662,15 +667,13 @@ static CURLcode CONNECT(struct Curl_easy *data,
     if(s->close_connection && data->req.newurl) {
       conn->bits.proxy_connect_closed = TRUE;
       infof(data, "Connect me again please");
-      connect_done(data);
+      Curl_connect_done(data);
     }
     else {
       free(data->req.newurl);
       data->req.newurl = NULL;
       /* failure, close this connection to avoid re-use */
       streamclose(conn, "proxy CONNECT failure");
-      Curl_closesocket(data, conn, conn->sock[sockindex]);
-      conn->sock[sockindex] = CURL_SOCKET_BAD;
     }
 
     /* to back to init state */
@@ -974,7 +977,7 @@ static CURLcode CONNECT(struct Curl_easy *data,
       if(conn->bits.close && data->req.newurl) {
         conn->bits.proxy_connect_closed = TRUE;
         infof(data, "Connect me again please");
-        connect_done(data);
+        Curl_connect_done(data);
       }
       else {
         free(data->req.newurl);
@@ -1048,7 +1051,7 @@ CURLcode Curl_proxyCONNECT(struct Curl_easy *data,
   result = CONNECT(data, sockindex, hostname, remote_port);
 
   if(result || Curl_connect_complete(conn))
-    connect_done(data);
+    Curl_connect_done(data);
 
   return result;
 }
diff --git a/libs/libcurl/src/http_proxy.h b/libs/libcurl/src/http_proxy.h
index cdf8de4fba..2820e11841 100644
--- a/libs/libcurl/src/http_proxy.h
+++ b/libs/libcurl/src/http_proxy.h
@@ -39,6 +39,7 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex);
 bool Curl_connect_complete(struct connectdata *conn);
 bool Curl_connect_ongoing(struct connectdata *conn);
 int Curl_connect_getsock(struct connectdata *conn);
+void Curl_connect_done(struct Curl_easy *data);
 
 #else
 #define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
@@ -46,10 +47,10 @@ int Curl_connect_getsock(struct connectdata *conn);
 #define Curl_connect_complete(x) CURLE_OK
 #define Curl_connect_ongoing(x) FALSE
 #define Curl_connect_getsock(x) 0
+#define Curl_connect_done(x)
 #endif
 
 void Curl_connect_free(struct Curl_easy *data);
-void Curl_connect_done(struct Curl_easy *data);
 
 /* struct for HTTP CONNECT state data */
 struct http_connect_state {
diff --git a/libs/libcurl/src/if2ip.c b/libs/libcurl/src/if2ip.c
index 21e00b1f16..132b3eeeea 100644
--- a/libs/libcurl/src/if2ip.c
+++ b/libs/libcurl/src/if2ip.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -114,7 +114,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
 
   if(getifaddrs(&head) >= 0) {
     for(iface = head; iface != NULL; iface = iface->ifa_next) {
-      if(iface->ifa_addr != NULL) {
+      if(iface->ifa_addr) {
         if(iface->ifa_addr->sa_family == af) {
           if(strcasecompare(iface->ifa_name, interf)) {
             void *addr;
diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c
index bea964f79a..958ad1456c 100644
--- a/libs/libcurl/src/imap.c
+++ b/libs/libcurl/src/imap.c
@@ -329,7 +329,7 @@ static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn,
   /* Do we have a continuation response? This should be a + symbol followed by
      a space and optionally some text as per RFC-3501 for the AUTHENTICATE and
      APPEND commands and as outlined in Section 4. Examples of RFC-4959 but
-     some e-mail servers ignore this and only send a single + instead. */
+     some email servers ignore this and only send a single + instead. */
   if(imap && !imap->custom && ((len == 3 && line[0] == '+') ||
      (len >= 2 && !memcmp("+ ", line, 2)))) {
     switch(imapc->state) {
diff --git a/libs/libcurl/src/inet_pton.c b/libs/libcurl/src/inet_pton.c
index 4923cae245..ada57af289 100644
--- a/libs/libcurl/src/inet_pton.c
+++ b/libs/libcurl/src/inet_pton.c
@@ -1,6 +1,6 @@
 /* This is from the BIND 4.9.4 release, modified to compile by itself */
 
-/* Copyright (c) 1996 - 2020 by Internet Software Consortium.
+/* Copyright (c) 1996 - 2021 by Internet Software Consortium.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -174,7 +174,7 @@ inet_pton6(const char *src, unsigned char *dst)
     pch = strchr((xdigits = xdigits_l), ch);
     if(!pch)
       pch = strchr((xdigits = xdigits_u), ch);
-    if(pch != NULL) {
+    if(pch) {
       val <<= 4;
       val |= (pch - xdigits);
       if(++saw_xdigit > 4)
@@ -211,7 +211,7 @@ inet_pton6(const char *src, unsigned char *dst)
     *tp++ = (unsigned char) ((val >> 8) & 0xff);
     *tp++ = (unsigned char) (val & 0xff);
   }
-  if(colonp != NULL) {
+  if(colonp) {
     /*
      * Since some memmove()'s erroneously fail to handle
      * overlapping regions, we'll do the shift by hand.
diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c
index afe425b046..5edd34cbdf 100644
--- a/libs/libcurl/src/krb5.c
+++ b/libs/libcurl/src/krb5.c
@@ -880,7 +880,7 @@ Curl_sec_login(struct Curl_easy *data, struct connectdata *conn)
 void
 Curl_sec_end(struct connectdata *conn)
 {
-  if(conn->mech != NULL && conn->mech->end)
+  if(conn->mech && conn->mech->end)
     conn->mech->end(conn->app_data);
   free(conn->app_data);
   conn->app_data = NULL;
diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c
index 1d9e44cc9c..3154db5cf0 100644
--- a/libs/libcurl/src/ldap.c
+++ b/libs/libcurl/src/ldap.c
@@ -464,6 +464,11 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
 #endif
 #endif /* CURL_LDAP_USE_SSL */
   }
+  else if(data->set.use_ssl > CURLUSESSL_TRY) {
+    failf(data, "LDAP local: explicit TLS not supported");
+    result = CURLE_NOT_BUILT_IN;
+    goto quit;
+  }
   else {
     server = ldap_init(host, (int)conn->port);
     if(!server) {
@@ -590,7 +595,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done)
       attr_len = strlen(attr);
 
       vals = ldap_get_values_len(server, entryIterator, attribute);
-      if(vals != NULL) {
+      if(vals) {
         for(i = 0; (vals[i] != NULL); i++) {
           result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
           if(result) {
diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist
index daf485621b..0e5311b5a4 100644
--- a/libs/libcurl/src/libcurl.plist
+++ b/libs/libcurl/src/libcurl.plist
@@ -15,7 +15,7 @@
 	se.curl.libcurl
 
 	CFBundleVersion
-	7.80.0
+	7.81.0
 
 	CFBundleName
 	libcurl
@@ -27,9 +27,9 @@
 	????
 
 	CFBundleShortVersionString
-	libcurl 7.80.0
+	libcurl 7.81.0
 
 	CFBundleGetInfoString
-	libcurl.plist 7.80.0
+	libcurl.plist 7.81.0
 
 
diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c
index d90e45475c..117cce4fd9 100644
--- a/libs/libcurl/src/md4.c
+++ b/libs/libcurl/src/md4.c
@@ -189,7 +189,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
 {
   if(!ctx->data) {
     ctx->data = malloc(size);
-    if(ctx->data != NULL) {
+    if(ctx->data) {
       memcpy(ctx->data, data, size);
       ctx->size = size;
     }
@@ -198,7 +198,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
 
 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
 {
-  if(ctx->data != NULL) {
+  if(ctx->data) {
 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
     mbedtls_md4(ctx->data, ctx->size, result);
 #else
diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c
index 810c5fba8e..c6923e036b 100644
--- a/libs/libcurl/src/md5.c
+++ b/libs/libcurl/src/md5.c
@@ -62,9 +62,10 @@
 
 typedef struct md5_ctx MD5_CTX;
 
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
 {
   md5_init(ctx);
+  return CURLE_OK;
 }
 
 static void MD5_Update(MD5_CTX *ctx,
@@ -98,13 +99,14 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
 
 typedef mbedtls_md5_context MD5_CTX;
 
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
 {
 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
   (void) mbedtls_md5_starts(ctx);
 #else
   (void) mbedtls_md5_starts_ret(ctx);
 #endif
+  return CURLE_OK;
 }
 
 static void MD5_Update(MD5_CTX *ctx,
@@ -146,9 +148,10 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
 /* The last #include file should be: */
 #include "memdebug.h"
 
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
 {
   CC_MD5_Init(ctx);
+  return CURLE_OK;
 }
 
 static void MD5_Update(MD5_CTX *ctx,
@@ -176,12 +179,13 @@ struct md5_ctx {
 };
 typedef struct md5_ctx MD5_CTX;
 
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
 {
   if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
   }
+  return CURLE_OK;
 }
 
 static void MD5_Update(MD5_CTX *ctx,
@@ -261,7 +265,7 @@ struct md5_ctx {
 };
 typedef struct md5_ctx MD5_CTX;
 
-static void MD5_Init(MD5_CTX *ctx);
+static CURLcode MD5_Init(MD5_CTX *ctx);
 static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
 static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
 
@@ -422,7 +426,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
   return ptr;
 }
 
-static void MD5_Init(MD5_CTX *ctx)
+static CURLcode MD5_Init(MD5_CTX *ctx)
 {
   ctx->a = 0x67452301;
   ctx->b = 0xefcdab89;
@@ -431,6 +435,8 @@ static void MD5_Init(MD5_CTX *ctx)
 
   ctx->lo = 0;
   ctx->hi = 0;
+
+  return CURLE_OK;
 }
 
 static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
@@ -555,8 +561,9 @@ const struct MD5_params Curl_DIGEST_MD5[] = {
 
 /*
  * @unittest: 1601
+ * Returns CURLE_OK on success.
  */
-void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
+CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
                 const size_t len)
 {
   MD5_CTX ctx;
@@ -564,6 +571,8 @@ void Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
   MD5_Init(&ctx);
   MD5_Update(&ctx, input, curlx_uztoui(len));
   MD5_Final(outbuffer, &ctx);
+
+  return CURLE_OK;
 }
 
 struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index f40cc1a618..7783b8990a 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.c
@@ -40,6 +40,7 @@
 #include "rand.h"
 #include "slist.h"
 #include "strcase.h"
+#include "dynbuf.h"
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
@@ -279,29 +280,52 @@ static void mimesetstate(struct mime_state *state,
 
 
 /* Escape header string into allocated memory. */
-static char *escape_string(const char *src)
-{
-  size_t bytecount = 0;
-  size_t i;
-  char *dst;
+static char *escape_string(struct Curl_easy *data,
+                           const char *src, enum mimestrategy strategy)
+{
+  CURLcode result;
+  struct dynbuf db;
+  const char * const *table;
+  const char * const *p;
+  /* replace first character by rest of string. */
+  static const char * const mimetable[] = {
+    "\\\\\\",
+    "\"\\\"",
+    NULL
+  };
+  /* WHATWG HTML living standard 4.10.21.8 2 specifies:
+     For field names and filenames for file fields, the result of the
+     encoding in the previous bullet point must be escaped by replacing
+     any 0x0A (LF) bytes with the byte sequence `%0A`, 0x0D (CR) with `%0D`
+     and 0x22 (") with `%22`.
+     The user agent must not perform any other escapes. */
+  static const char * const formtable[] = {
+    "\"%22",
+    "\r%0D",
+    "\n%0A",
+    NULL
+  };
 
-  for(i = 0; src[i]; i++)
-    if(src[i] == '"' || src[i] == '\\')
-      bytecount++;
+  table = formtable;
+  /* data can be NULL when this function is called indirectly from
+     curl_formget(). */
+  if(strategy == MIMESTRATEGY_MAIL ||
+     (data && (data->set.mime_options & CURLMIMEOPT_FORMESCAPE)))
+    table = mimetable;
 
-  bytecount += i;
-  dst = malloc(bytecount + 1);
-  if(!dst)
-    return NULL;
+  Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH);
 
-  for(i = 0; *src; src++) {
-    if(*src == '"' || *src == '\\')
-      dst[i++] = '\\';
-    dst[i++] = *src;
+  for(result = Curl_dyn_add(&db, ""); !result && *src; src++) {
+    for(p = table; *p && **p != *src; p++)
+      ;
+
+    if(*p)
+      result = Curl_dyn_add(&db, *p + 1);
+    else
+      result = Curl_dyn_addn(&db, src, 1);
   }
 
-  dst[i] = '\0';
-  return dst;
+  return Curl_dyn_ptr(&db);
 }
 
 /* Check if header matches. */
@@ -1866,12 +1890,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
       char *filename = NULL;
 
       if(part->name) {
-        name = escape_string(part->name);
+        name = escape_string(part->easy, part->name, strategy);
         if(!name)
           ret = CURLE_OUT_OF_MEMORY;
       }
       if(!ret && part->filename) {
-        filename = escape_string(part->filename);
+        filename = escape_string(part->easy, part->filename, strategy);
         if(!filename)
           ret = CURLE_OUT_OF_MEMORY;
       }
diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c
index 7a1aec570e..0fd3afc8ae 100644
--- a/libs/libcurl/src/mprintf.c
+++ b/libs/libcurl/src/mprintf.c
@@ -858,7 +858,7 @@ static int dprintf_formatf(
       {
         void *ptr;
         ptr = (void *) p->data.ptr;
-        if(ptr != NULL) {
+        if(ptr) {
           /* If the pointer is not NULL, write it as a %#x spec.  */
           base = 16;
           digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index f307d63b93..f8dcc63b47 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -243,6 +243,26 @@ static void trhash_dtor(void *nada)
   (void)nada;
 }
 
+/*
+ * The sockhash has its own separate subhash in each entry that need to be
+ * safely destroyed first.
+ */
+static void sockhash_destroy(struct Curl_hash *h)
+{
+  struct Curl_hash_iterator iter;
+  struct Curl_hash_element *he;
+
+  DEBUGASSERT(h);
+  Curl_hash_start_iterate(h, &iter);
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct Curl_sh_entry *sh = (struct Curl_sh_entry *)he->ptr;
+    Curl_hash_destroy(&sh->transfers);
+    he = Curl_hash_next_element(&iter);
+  }
+  Curl_hash_destroy(h);
+}
+
 
 /* make sure this socket is present in the hash for this handle */
 static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
@@ -261,11 +281,8 @@ static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
   if(!check)
     return NULL; /* major failure */
 
-  if(Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash,
-                    trhash_compare, trhash_dtor)) {
-    free(check);
-    return NULL;
-  }
+  Curl_hash_init(&check->transfers, TRHASH_SIZE, trhash, trhash_compare,
+                 trhash_dtor);
 
   /* make/add new hash entry */
   if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
@@ -332,10 +349,10 @@ static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
  * per call."
  *
  */
-static int sh_init(struct Curl_hash *hash, int hashsize)
+static void sh_init(struct Curl_hash *hash, int hashsize)
 {
-  return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
-                        sh_freeentry);
+  Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
+                 sh_freeentry);
 }
 
 /*
@@ -362,11 +379,9 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
 
   multi->magic = CURL_MULTI_HANDLE;
 
-  if(Curl_mk_dnscache(&multi->hostcache))
-    goto error;
+  Curl_init_dnscache(&multi->hostcache);
 
-  if(sh_init(&multi->sockhash, hashsize))
-    goto error;
+  sh_init(&multi->sockhash, hashsize);
 
   if(Curl_conncache_init(&multi->conn_cache, chashsize))
     goto error;
@@ -405,7 +420,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
 
   error:
 
-  Curl_hash_destroy(&multi->sockhash);
+  sockhash_destroy(&multi->sockhash);
   Curl_hash_destroy(&multi->hostcache);
   Curl_conncache_destroy(&multi->conn_cache);
   Curl_llist_destroy(&multi->msglist, NULL);
@@ -424,6 +439,7 @@ struct Curl_multi *curl_multi_init(void)
 CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
                                 struct Curl_easy *data)
 {
+  CURLMcode rc;
   /* First, make some basic checks that the CURLM handle is a good handle */
   if(!GOOD_MULTI_HANDLE(multi))
     return CURLM_BAD_HANDLE;
@@ -440,6 +456,15 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
   if(multi->in_callback)
     return CURLM_RECURSIVE_API_CALL;
 
+  if(multi->dead) {
+    /* a "dead" handle cannot get added transfers while any existing easy
+       handles are still alive - but if there are none alive anymore, it is
+       fine to start over and unmark the "deadness" of this handle */
+    if(multi->num_alive)
+      return CURLM_ABORTED_BY_CALLBACK;
+    multi->dead = FALSE;
+  }
+
   /* Initialize timeout list for this handle */
   Curl_llist_init(&data->state.timeoutlist, NULL);
 
@@ -452,6 +477,34 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
   if(data->set.errorbuffer)
     data->set.errorbuffer[0] = 0;
 
+  /* make the Curl_easy refer back to this multi handle - before Curl_expire()
+     is called. */
+  data->multi = multi;
+
+  /* Set the timeout for this handle to expire really soon so that it will
+     be taken care of even when this handle is added in the midst of operation
+     when only the curl_multi_socket() API is used. During that flow, only
+     sockets that time-out or have actions will be dealt with. Since this
+     handle has no action yet, we make sure it times out to get things to
+     happen. */
+  Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+  /* A somewhat crude work-around for a little glitch in Curl_update_timer()
+     that happens if the lastcall time is set to the same time when the handle
+     is removed as when the next handle is added, as then the check in
+     Curl_update_timer() that prevents calling the application multiple times
+     with the same timer info will not trigger and then the new handle's
+     timeout will not be notified to the app.
+
+     The work-around is thus simply to clear the 'lastcall' variable to force
+     Curl_update_timer() to always trigger a callback to the app when a new
+     easy handle is added */
+  memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+
+  rc = Curl_update_timer(multi);
+  if(rc)
+    return rc;
+
   /* set the easy handle */
   multistate(data, MSTATE_INIT);
 
@@ -492,35 +545,12 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
     multi->easylp = multi->easyp = data; /* both first and last */
   }
 
-  /* make the Curl_easy refer back to this multi handle */
-  data->multi = multi;
-
-  /* Set the timeout for this handle to expire really soon so that it will
-     be taken care of even when this handle is added in the midst of operation
-     when only the curl_multi_socket() API is used. During that flow, only
-     sockets that time-out or have actions will be dealt with. Since this
-     handle has no action yet, we make sure it times out to get things to
-     happen. */
-  Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
   /* increase the node-counter */
   multi->num_easy++;
 
   /* increase the alive-counter */
   multi->num_alive++;
 
-  /* A somewhat crude work-around for a little glitch in Curl_update_timer()
-     that happens if the lastcall time is set to the same time when the handle
-     is removed as when the next handle is added, as then the check in
-     Curl_update_timer() that prevents calling the application multiple times
-     with the same timer info will not trigger and then the new handle's
-     timeout will not be notified to the app.
-
-     The work-around is thus simply to clear the 'lastcall' variable to force
-     Curl_update_timer() to always trigger a callback to the app when a new
-     easy handle is added */
-  memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
-
   CONNCACHE_LOCK(data);
   /* The closure handle only ever has default timeouts set. To improve the
      state somewhat we clone the timeouts from each added handle so that the
@@ -533,14 +563,13 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
     data->set.no_signal;
   CONNCACHE_UNLOCK(data);
 
-  Curl_update_timer(multi);
   return CURLM_OK;
 }
 
 #if 0
 /* Debug-function, used like this:
  *
- * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
+ * Curl_hash_print(&multi->sockhash, debug_print_sock_hash);
  *
  * Enable the hash print function first by editing hash.c
  */
@@ -548,8 +577,8 @@ static void debug_print_sock_hash(void *p)
 {
   struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
 
-  fprintf(stderr, " [easy %p/magic %x/socket %d]",
-          (void *)sh->data, sh->data->magic, (int)sh->socket);
+  fprintf(stderr, " [readers %u][writers %u]",
+          sh->readers, sh->writers);
 }
 #endif
 
@@ -562,7 +591,8 @@ static CURLcode multi_done(struct Curl_easy *data,
   struct connectdata *conn = data->conn;
   unsigned int i;
 
-  DEBUGF(infof(data, "multi_done"));
+  DEBUGF(infof(data, "multi_done: status: %d prem: %d done: %d",
+               (int)status, (int)premature, data->state.done));
 
   if(data->state.done)
     /* Stop if multi_done() has already been called */
@@ -719,6 +749,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
   struct Curl_easy *easy = data;
   bool premature;
   struct Curl_llist_element *e;
+  CURLMcode rc;
 
   /* First, make some basic checks that the CURLM handle is a good handle */
   if(!GOOD_MULTI_HANDLE(multi))
@@ -792,8 +823,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
   /* change state without using multistate(), only to make singlesocket() do
      what we want */
   data->mstate = MSTATE_COMPLETED;
-  singlesocket(multi, easy); /* to let the application know what sockets that
-                                vanish with this handle */
+
+  /* This ignores the return code even in case of problems because there's
+     nothing more to do about that, here */
+  (void)singlesocket(multi, easy); /* to let the application know what sockets
+                                      that vanish with this handle */
 
   /* Remove the association between the connection and the handle */
   Curl_detach_connnection(data);
@@ -858,7 +892,9 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
 
   process_pending_handles(multi);
 
-  Curl_update_timer(multi);
+  rc = Curl_update_timer(multi);
+  if(rc)
+    return rc;
   return CURLM_OK;
 }
 
@@ -878,6 +914,7 @@ void Curl_detach_connnection(struct Curl_easy *data)
 {
   struct connectdata *conn = data->conn;
   if(conn) {
+    Curl_connect_done(data); /* if mid-CONNECT, shut it down */
     Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL);
     Curl_ssl_detach_conn(data, conn);
   }
@@ -1742,6 +1779,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
   if(!GOOD_EASY_HANDLE(data))
     return CURLM_BAD_EASY_HANDLE;
 
+  if(multi->dead) {
+    /* a multi-level callback returned error before, meaning every individual
+     transfer now has failed */
+    result = CURLE_ABORTED_BY_CALLBACK;
+    Curl_posttransfer(data);
+    multi_done(data, result, FALSE);
+    multistate(data, MSTATE_COMPLETED);
+  }
+
   do {
     /* A "stream" here is a logical stream if the protocol can handle that
        (HTTP/2), or the full connection for older protocols */
@@ -1892,7 +1938,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
          down.  If the name has not yet been resolved, it is likely
          that new sockets have been opened in an attempt to contact
          another resolver. */
-      singlesocket(multi, data);
+      rc = singlesocket(multi, data);
+      if(rc)
+        return rc;
 
       if(dns) {
         /* Perform the next step in the connection phase, and then move on
@@ -2617,7 +2665,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
   *running_handles = multi->num_alive;
 
   if(CURLM_OK >= returncode)
-    Curl_update_timer(multi);
+    returncode = Curl_update_timer(multi);
 
   return returncode;
 }
@@ -2662,7 +2710,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
     /* Close all the connections in the connection cache */
     Curl_conncache_close_all_connections(&multi->conn_cache);
 
-    Curl_hash_destroy(&multi->sockhash);
+    sockhash_destroy(&multi->sockhash);
     Curl_conncache_destroy(&multi->conn_cache);
     Curl_llist_destroy(&multi->msglist, NULL);
     Curl_llist_destroy(&multi->pending, NULL);
@@ -2737,6 +2785,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
   int num;
   unsigned int curraction;
   unsigned char actions[MAX_SOCKSPEREASYHANDLE];
+  int rc;
 
   for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
     socks[i] = CURL_SOCKET_BAD;
@@ -2808,8 +2857,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
 
       /* add 'data' to the transfer hash on this socket! */
       if(!Curl_hash_add(&entry->transfers, (char *)&data, /* hash key */
-                        sizeof(struct Curl_easy *), data))
+                        sizeof(struct Curl_easy *), data)) {
+        Curl_hash_destroy(&entry->transfers);
         return CURLM_OUT_OF_MEMORY;
+      }
     }
 
     comboaction = (entry->writers? CURL_POLL_OUT : 0) |
@@ -2820,9 +2871,14 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
       /* same, continue */
       continue;
 
-    if(multi->socket_cb)
-      multi->socket_cb(data, s, comboaction, multi->socket_userp,
-                       entry->socketp);
+    if(multi->socket_cb) {
+      rc = multi->socket_cb(data, s, comboaction, multi->socket_userp,
+                            entry->socketp);
+      if(rc == -1) {
+        multi->dead = TRUE;
+        return CURLM_ABORTED_BY_CALLBACK;
+      }
+    }
 
     entry->action = comboaction; /* store the current action state */
   }
@@ -2857,10 +2913,14 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
       if(oldactions & CURL_POLL_IN)
         entry->readers--;
       if(!entry->users) {
-        if(multi->socket_cb)
-          multi->socket_cb(data, s, CURL_POLL_REMOVE,
-                           multi->socket_userp,
-                           entry->socketp);
+        if(multi->socket_cb) {
+          rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
+                                multi->socket_userp, entry->socketp);
+          if(rc == -1) {
+            multi->dead = TRUE;
+            return CURLM_ABORTED_BY_CALLBACK;
+          }
+        }
         sh_delentry(entry, &multi->sockhash, s);
       }
       else {
@@ -2879,9 +2939,11 @@ static CURLMcode singlesocket(struct Curl_multi *multi,
   return CURLM_OK;
 }
 
-void Curl_updatesocket(struct Curl_easy *data)
+CURLcode Curl_updatesocket(struct Curl_easy *data)
 {
-  singlesocket(data->multi, data);
+  if(singlesocket(data->multi, data))
+    return CURLE_ABORTED_BY_CALLBACK;
+  return CURLE_OK;
 }
 
 
@@ -2906,13 +2968,18 @@ void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s)
       struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
 
       if(entry) {
+        int rc = 0;
         if(multi->socket_cb)
-          multi->socket_cb(data, s, CURL_POLL_REMOVE,
-                           multi->socket_userp,
-                           entry->socketp);
+          rc = multi->socket_cb(data, s, CURL_POLL_REMOVE,
+                                multi->socket_userp, entry->socketp);
 
         /* now remove it from the socket hash */
         sh_delentry(entry, &multi->sockhash, s);
+        if(rc == -1)
+          /* This just marks the multi handle as "dead" without returning an
+             error code primarily because this function is used from many
+             places where propagating an error back is tricky. */
+          multi->dead = TRUE;
       }
     }
   }
@@ -3172,7 +3239,7 @@ CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
     return CURLM_RECURSIVE_API_CALL;
   result = multi_socket(multi, FALSE, s, 0, running_handles);
   if(CURLM_OK >= result)
-    Curl_update_timer(multi);
+    result = Curl_update_timer(multi);
   return result;
 }
 
@@ -3184,7 +3251,7 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
     return CURLM_RECURSIVE_API_CALL;
   result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
   if(CURLM_OK >= result)
-    Curl_update_timer(multi);
+    result = Curl_update_timer(multi);
   return result;
 }
 
@@ -3195,7 +3262,7 @@ CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
     return CURLM_RECURSIVE_API_CALL;
   result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
   if(CURLM_OK >= result)
-    Curl_update_timer(multi);
+    result = Curl_update_timer(multi);
   return result;
 }
 
@@ -3204,6 +3271,11 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
 {
   static const struct curltime tv_zero = {0, 0};
 
+  if(multi->dead) {
+    *timeout_ms = 0;
+    return CURLM_OK;
+  }
+
   if(multi->timetree) {
     /* we have a tree of expire times */
     struct curltime now = Curl_now();
@@ -3255,14 +3327,15 @@ CURLMcode curl_multi_timeout(struct Curl_multi *multi,
  * Tell the application it should update its timers, if it subscribes to the
  * update timer callback.
  */
-void Curl_update_timer(struct Curl_multi *multi)
+CURLMcode Curl_update_timer(struct Curl_multi *multi)
 {
   long timeout_ms;
+  int rc;
 
-  if(!multi->timer_cb)
-    return;
+  if(!multi->timer_cb || multi->dead)
+    return CURLM_OK;
   if(multi_timeout(multi, &timeout_ms)) {
-    return;
+    return CURLM_OK;
   }
   if(timeout_ms < 0) {
     static const struct curltime none = {0, 0};
@@ -3270,10 +3343,14 @@ void Curl_update_timer(struct Curl_multi *multi)
       multi->timer_lastcall = none;
       /* there's no timeout now but there was one previously, tell the app to
          disable it */
-      multi->timer_cb(multi, -1, multi->timer_userp);
-      return;
+      rc = multi->timer_cb(multi, -1, multi->timer_userp);
+      if(rc == -1) {
+        multi->dead = TRUE;
+        return CURLM_ABORTED_BY_CALLBACK;
+      }
+      return CURLM_OK;
     }
-    return;
+    return CURLM_OK;
   }
 
   /* When multi_timeout() is done, multi->timetree points to the node with the
@@ -3281,11 +3358,16 @@ void Curl_update_timer(struct Curl_multi *multi)
    * if this is the same (fixed) time as we got in a previous call and then
    * avoid calling the callback again. */
   if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
-    return;
+    return CURLM_OK;
 
   multi->timer_lastcall = multi->timetree->key;
 
-  multi->timer_cb(multi, timeout_ms, multi->timer_userp);
+  rc = multi->timer_cb(multi, timeout_ms, multi->timer_userp);
+  if(rc == -1) {
+    multi->dead = TRUE;
+    return CURLM_ABORTED_BY_CALLBACK;
+  }
+  return CURLM_OK;
 }
 
 /*
diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h
index 2e4a6ffba5..db7f130efd 100644
--- a/libs/libcurl/src/multihandle.h
+++ b/libs/libcurl/src/multihandle.h
@@ -156,6 +156,8 @@ struct Curl_multi {
 #ifdef USE_OPENSSL
   bool ssl_seeded;
 #endif
+  bool dead; /* a callback returned error, everything needs to crash and
+                burn */
 };
 
 #endif /* HEADER_CURL_MULTIHANDLE_H */
diff --git a/libs/libcurl/src/multiif.h b/libs/libcurl/src/multiif.h
index 2fbef53c48..f4d0ada8e8 100644
--- a/libs/libcurl/src/multiif.h
+++ b/libs/libcurl/src/multiif.h
@@ -26,11 +26,11 @@
  * Prototypes for library-wide functions provided by multi.c
  */
 
-void Curl_updatesocket(struct Curl_easy *data);
+CURLcode Curl_updatesocket(struct Curl_easy *data);
 void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id);
 void Curl_expire_clear(struct Curl_easy *data);
 void Curl_expire_done(struct Curl_easy *data, expire_id id);
-void Curl_update_timer(struct Curl_multi *multi);
+CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT;
 void Curl_attach_connnection(struct Curl_easy *data,
                              struct connectdata *conn);
 void Curl_detach_connnection(struct Curl_easy *data);
diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c
index fb5e743c27..0ffb6a36a2 100644
--- a/libs/libcurl/src/openldap.c
+++ b/libs/libcurl/src/openldap.c
@@ -70,6 +70,17 @@
  */
 /* #define CURL_OPENLDAP_DEBUG */
 
+/* Machine states. */
+typedef enum {
+  OLDAP_STOP,           /* Do nothing state, stops the state machine */
+  OLDAP_SSL,            /* Performing SSL handshake. */
+  OLDAP_STARTTLS,       /* STARTTLS request sent. */
+  OLDAP_TLS,            /* Performing TLS handshake. */
+  OLDAP_BIND,           /* Simple bind reply. */
+  OLDAP_BINDV2,         /* Simple bind reply in protocol version 2. */
+  OLDAP_LAST            /* Never used */
+} ldapstate;
+
 #ifndef _LDAP_PVT_H
 extern int ldap_pvt_url_scheme2proto(const char *);
 extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
@@ -143,29 +154,13 @@ const struct Curl_handler Curl_handler_ldaps = {
 };
 #endif
 
-static const char *url_errs[] = {
-  "success",
-  "out of memory",
-  "bad parameter",
-  "unrecognized scheme",
-  "unbalanced delimiter",
-  "bad URL",
-  "bad host or port",
-  "bad or missing attributes",
-  "bad or missing scope",
-  "bad or missing filter",
-  "bad or missing extensions"
-};
-
 struct ldapconninfo {
-  LDAP *ld;
-  Curl_recv *recv;  /* for stacking SSL handler */
+  LDAP *ld;                  /* Openldap connection handle. */
+  Curl_recv *recv;           /* For stacking SSL handler */
   Curl_send *send;
-  int proto;
-  int msgid;
-  bool ssldone;
-  bool sslinst;
-  bool didbind;
+  ldapstate state;           /* Current machine state. */
+  int proto;                 /* LDAP_PROTO_TCP/LDAP_PROTO_UDP/LDAP_PROTO_IPC */
+  int msgid;                 /* Current message id. */
 };
 
 struct ldapreqinfo {
@@ -173,194 +168,379 @@ struct ldapreqinfo {
   int nument;
 };
 
-static CURLcode oldap_setup_connection(struct Curl_easy *data,
-                                       struct connectdata *conn)
+/*
+ * state()
+ *
+ * This is the ONLY way to change LDAP state!
+ */
+static void state(struct Curl_easy *data, ldapstate newstate)
 {
-  struct ldapconninfo *li;
-  LDAPURLDesc *lud;
-  int rc, proto;
-  CURLcode status;
+  struct ldapconninfo *ldapc = data->conn->proto.ldapc;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "STOP",
+    "SSL",
+    "STARTTLS",
+    "TLS",
+    "BIND",
+    "BINDV2",
+    /* LAST */
+  };
+
+  if(ldapc->state != newstate)
+    infof(data, "LDAP %p state change from %s to %s",
+          (void *)ldapc, names[ldapc->state], names[newstate]);
+#endif
+
+  ldapc->state = newstate;
+}
 
-  rc = ldap_url_parse(data->state.url, &lud);
+/* Map some particular LDAP error codes to CURLcode values. */
+static CURLcode oldap_map_error(int rc, CURLcode result)
+{
+  switch(rc) {
+  case LDAP_NO_MEMORY:
+    result = CURLE_OUT_OF_MEMORY;
+    break;
+  case LDAP_INVALID_CREDENTIALS:
+    result = CURLE_LOGIN_DENIED;
+    break;
+  case LDAP_PROTOCOL_ERROR:
+    result = CURLE_UNSUPPORTED_PROTOCOL;
+    break;
+  case LDAP_INSUFFICIENT_ACCESS:
+    result = CURLE_REMOTE_ACCESS_DENIED;
+    break;
+  }
+  return result;
+}
+
+static CURLcode oldap_url_parse(struct Curl_easy *data, LDAPURLDesc **ludp)
+{
+  CURLcode result = CURLE_OK;
+  int rc = LDAP_URL_ERR_BADURL;
+  static const char * const url_errs[] = {
+    "success",
+    "out of memory",
+    "bad parameter",
+    "unrecognized scheme",
+    "unbalanced delimiter",
+    "bad URL",
+    "bad host or port",
+    "bad or missing attributes",
+    "bad or missing scope",
+    "bad or missing filter",
+    "bad or missing extensions"
+  };
+
+  *ludp = NULL;
+  if(!data->state.up.user && !data->state.up.password &&
+     !data->state.up.options)
+    rc = ldap_url_parse(data->state.url, ludp);
   if(rc != LDAP_URL_SUCCESS) {
     const char *msg = "url parsing problem";
-    status = CURLE_URL_MALFORMAT;
-    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
-      if(rc == LDAP_URL_ERR_MEM)
-        status = CURLE_OUT_OF_MEMORY;
+
+    result = rc == LDAP_URL_ERR_MEM? CURLE_OUT_OF_MEMORY: CURLE_URL_MALFORMAT;
+    rc -= LDAP_URL_SUCCESS;
+    if((size_t) rc < sizeof(url_errs) / sizeof(url_errs[0]))
       msg = url_errs[rc];
-    }
     failf(data, "LDAP local: %s", msg);
-    return status;
   }
-  proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
+  return result;
+}
+
+static CURLcode oldap_setup_connection(struct Curl_easy *data,
+                                       struct connectdata *conn)
+{
+  CURLcode result;
+  LDAPURLDesc *lud;
+  struct ldapconninfo *li;
+
+  /* Early URL syntax check. */
+  result = oldap_url_parse(data, &lud);
   ldap_free_urldesc(lud);
 
-  li = calloc(1, sizeof(struct ldapconninfo));
-  if(!li)
-    return CURLE_OUT_OF_MEMORY;
-  li->proto = proto;
-  conn->proto.ldapc = li;
-  connkeep(conn, "OpenLDAP default");
-  return CURLE_OK;
+  if(!result) {
+    li = calloc(1, sizeof(struct ldapconninfo));
+    if(!li)
+      result = CURLE_OUT_OF_MEMORY;
+    else {
+      li->proto = ldap_pvt_url_scheme2proto(data->state.up.scheme);
+      conn->proto.ldapc = li;
+      connkeep(conn, "OpenLDAP default");
+
+      /* Clear the TLS upgraded flag */
+      conn->bits.tls_upgraded = FALSE;
+    }
+  }
+
+  return result;
+}
+
+/* Starts LDAP simple bind. */
+static CURLcode oldap_perform_bind(struct Curl_easy *data, ldapstate newstate)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn = data->conn;
+  struct ldapconninfo *li = conn->proto.ldapc;
+  char *binddn = NULL;
+  struct berval passwd;
+  int rc;
+
+  passwd.bv_val = NULL;
+  passwd.bv_len = 0;
+
+  if(conn->bits.user_passwd) {
+    binddn = conn->user;
+    passwd.bv_val = conn->passwd;
+    passwd.bv_len = strlen(passwd.bv_val);
+  }
+
+  rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
+                      NULL, NULL, &li->msgid);
+  if(rc == LDAP_SUCCESS)
+    state(data, newstate);
+  else
+    result = oldap_map_error(rc,
+                             conn->bits.user_passwd?
+                             CURLE_LOGIN_DENIED: CURLE_LDAP_CANNOT_BIND);
+  return result;
 }
 
 #ifdef USE_SSL
 static Sockbuf_IO ldapsb_tls;
-#endif
 
-static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
+static bool ssl_installed(struct connectdata *conn)
+{
+  return conn->proto.ldapc->recv != NULL;
+}
+
+static CURLcode oldap_ssl_connect(struct Curl_easy *data, ldapstate newstate)
 {
+  CURLcode result = CURLE_OK;
   struct connectdata *conn = data->conn;
   struct ldapconninfo *li = conn->proto.ldapc;
-  int rc, proto = LDAP_VERSION3;
-  char hosturl[1024];
-  char *ptr;
+  bool ssldone = 0;
 
-  (void)done;
+  result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
+                                        FIRSTSOCKET, &ssldone);
+  if(!result) {
+    state(data, newstate);
 
-  strcpy(hosturl, "ldap");
-  ptr = hosturl + 4;
-  if(conn->handler->flags & PROTOPT_SSL)
-    *ptr++ = 's';
-  msnprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
-            conn->host.name, conn->remote_port);
+    if(ssldone) {
+      Sockbuf *sb;
 
-#ifdef CURL_OPENLDAP_DEBUG
-  static int do_trace = 0;
-  const char *env = getenv("CURL_OPENLDAP_TRACE");
-  do_trace = (env && strtol(env, NULL, 10) > 0);
-  if(do_trace) {
-    ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace);
+      /* Install the libcurl SSL handlers into the sockbuf. */
+      ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
+      ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
+      li->recv = conn->recv[FIRSTSOCKET];
+      li->send = conn->send[FIRSTSOCKET];
+    }
   }
+
+  return result;
+}
+
+/* Send the STARTTLS request */
+static CURLcode oldap_perform_starttls(struct Curl_easy *data)
+{
+  CURLcode result = CURLE_OK;
+  struct ldapconninfo *li = data->conn->proto.ldapc;
+  int rc = ldap_start_tls(li->ld, NULL, NULL, &li->msgid);
+
+  if(rc == LDAP_SUCCESS)
+    state(data, OLDAP_STARTTLS);
+  else
+    result = oldap_map_error(rc, CURLE_USE_SSL_FAILED);
+  return result;
+}
 #endif
 
+static CURLcode oldap_connect(struct Curl_easy *data, bool *done)
+{
+  struct connectdata *conn = data->conn;
+  struct ldapconninfo *li = conn->proto.ldapc;
+  static const int version = LDAP_VERSION3;
+  int rc;
+  char *hosturl;
+#ifdef CURL_OPENLDAP_DEBUG
+  static int do_trace = -1;
+#endif
+
+  (void)done;
+
+  hosturl = aprintf("ldap%s://%s:%d",
+                    conn->handler->flags & PROTOPT_SSL? "s": "",
+                    conn->host.name, conn->remote_port);
+  if(!hosturl)
+    return CURLE_OUT_OF_MEMORY;
+
   rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
   if(rc) {
     failf(data, "LDAP local: Cannot connect to %s, %s",
           hosturl, ldap_err2string(rc));
+    free(hosturl);
     return CURLE_COULDNT_CONNECT;
   }
 
-  ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+  free(hosturl);
+
+#ifdef CURL_OPENLDAP_DEBUG
+  if(do_trace < 0) {
+    const char *env = getenv("CURL_OPENLDAP_TRACE");
+    do_trace = (env && strtol(env, NULL, 10) > 0);
+  }
+  if(do_trace)
+    ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace);
+#endif
+
+  /* Try version 3 first. */
+  ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+
+  /* Do not chase referrals. */
+  ldap_set_option(li->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
 
 #ifdef USE_SSL
-  if(conn->handler->flags & PROTOPT_SSL) {
-    CURLcode result;
-    result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
-                                          FIRSTSOCKET, &li->ssldone);
-    if(result)
+  if(conn->handler->flags & PROTOPT_SSL)
+    return oldap_ssl_connect(data, OLDAP_SSL);
+
+  if(data->set.use_ssl) {
+    CURLcode result = oldap_perform_starttls(data);
+
+    if(!result || data->set.use_ssl != CURLUSESSL_TRY)
       return result;
   }
 #endif
 
-  return CURLE_OK;
+  /* Force bind even if anonymous bind is not needed in protocol version 3
+     to detect missing version 3 support. */
+  return oldap_perform_bind(data, OLDAP_BIND);
 }
 
-static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
+/* Handle a simple bind response. */
+static CURLcode oldap_state_bind_resp(struct Curl_easy *data, LDAPMessage *msg,
+                                      int code)
 {
   struct connectdata *conn = data->conn;
   struct ldapconninfo *li = conn->proto.ldapc;
-  LDAPMessage *msg = NULL;
-  struct timeval tv = {0, 1}, *tvp;
-  int rc, err;
-  char *info = NULL;
+  CURLcode result = CURLE_OK;
+  struct berval *bv = NULL;
+  int rc;
 
-#ifdef USE_SSL
-  if(conn->handler->flags & PROTOPT_SSL) {
-    /* Is the SSL handshake complete yet? */
-    if(!li->ssldone) {
-      CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE,
-                                                     FIRSTSOCKET,
-                                                     &li->ssldone);
-      if(result || !li->ssldone)
-        return result;
-    }
+  if(code != LDAP_SUCCESS)
+    return oldap_map_error(code, CURLE_LDAP_CANNOT_BIND);
 
-    /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
-    if(!li->sslinst) {
-      Sockbuf *sb;
-      ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
-      ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
-      li->sslinst = TRUE;
-      li->recv = conn->recv[FIRSTSOCKET];
-      li->send = conn->send[FIRSTSOCKET];
-    }
+  rc = ldap_parse_sasl_bind_result(li->ld, msg, &bv, 0);
+  if(rc != LDAP_SUCCESS) {
+    failf(data, "LDAP local: bind ldap_parse_sasl_bind_result %s",
+          ldap_err2string(rc));
+    result = oldap_map_error(rc, CURLE_LDAP_CANNOT_BIND);
   }
-#endif
+  else
+    state(data, OLDAP_STOP);
 
-  tvp = &tv;
-
-  retry:
-  if(!li->didbind) {
-    char *binddn;
-    struct berval passwd;
+  if(bv)
+    ber_bvfree(bv);
+  return result;
+}
 
-    if(conn->bits.user_passwd) {
-      binddn = conn->user;
-      passwd.bv_val = conn->passwd;
-      passwd.bv_len = strlen(passwd.bv_val);
+static CURLcode oldap_connecting(struct Curl_easy *data, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn = data->conn;
+  struct ldapconninfo *li = conn->proto.ldapc;
+  LDAPMessage *msg = NULL;
+  struct timeval tv = {0, 0};
+  int code = LDAP_SUCCESS;
+  int rc;
+
+  if(li->state != OLDAP_SSL && li->state != OLDAP_TLS) {
+    /* Get response to last command. */
+    rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, &tv, &msg);
+    if(!rc)
+      return CURLE_OK;                    /* Timed out. */
+    if(rc < 0) {
+      failf(data, "LDAP local: connecting ldap_result %s",
+            ldap_err2string(rc));
+      return oldap_map_error(rc, CURLE_COULDNT_CONNECT);
     }
+
+    /* Get error code from message. */
+    rc = ldap_parse_result(li->ld, msg, &code, NULL, NULL, NULL, NULL, 0);
+    if(rc)
+      code = rc;
     else {
-      binddn = NULL;
-      passwd.bv_val = NULL;
-      passwd.bv_len = 0;
+      /* store the latest code for later retrieval */
+      data->info.httpcode = code;
     }
-    rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
-                        NULL, NULL, &li->msgid);
-    if(rc)
-      return CURLE_LDAP_CANNOT_BIND;
-    li->didbind = TRUE;
-    if(tvp)
-      return CURLE_OK;
-  }
 
-  rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
-  if(rc < 0) {
-    failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
-    return CURLE_LDAP_CANNOT_BIND;
-  }
-  if(rc == 0) {
-    /* timed out */
-    return CURLE_OK;
-  }
+    /* If protocol version 3 is not supported, fallback to version 2. */
+    if(code == LDAP_PROTOCOL_ERROR && li->state != OLDAP_BINDV2
+#ifdef USE_SSL
+       && (ssl_installed(conn) || data->set.use_ssl <= CURLUSESSL_TRY)
+#endif
+       ) {
+      static const int version = LDAP_VERSION2;
 
-  rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
-  if(rc) {
-    failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
-    return CURLE_LDAP_CANNOT_BIND;
+      ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+      ldap_msgfree(msg);
+      return oldap_perform_bind(data, OLDAP_BINDV2);
+    }
   }
 
-  /* Try to fallback to LDAPv2? */
-  if(err == LDAP_PROTOCOL_ERROR) {
-    int proto;
-    ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
-    if(proto == LDAP_VERSION3) {
-      if(info) {
-        ldap_memfree(info);
-        info = NULL;
+  /* Handle response message according to current state. */
+  switch(li->state) {
+
+#ifdef USE_SSL
+  case OLDAP_SSL:
+    result = oldap_ssl_connect(data, OLDAP_SSL);
+    if(!result && ssl_installed(conn))
+      result = oldap_perform_bind(data, OLDAP_BIND);
+    break;
+  case OLDAP_STARTTLS:
+    if(code != LDAP_SUCCESS) {
+      if(data->set.use_ssl != CURLUSESSL_TRY)
+        result = oldap_map_error(code, CURLE_USE_SSL_FAILED);
+      else
+        result = oldap_perform_bind(data, OLDAP_BIND);
+      break;
+    }
+    /* FALLTHROUGH */
+  case OLDAP_TLS:
+    result = oldap_ssl_connect(data, OLDAP_TLS);
+    if(result && data->set.use_ssl != CURLUSESSL_TRY)
+      result = oldap_map_error(code, CURLE_USE_SSL_FAILED);
+    else if(ssl_installed(conn)) {
+      conn->bits.tls_upgraded = TRUE;
+      if(conn->bits.user_passwd)
+        result = oldap_perform_bind(data, OLDAP_BIND);
+      else {
+        state(data, OLDAP_STOP); /* Version 3 supported: no bind required */
+        result = CURLE_OK;
       }
-      proto = LDAP_VERSION2;
-      ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
-      li->didbind = FALSE;
-      goto retry;
     }
-  }
+    break;
+#endif
 
-  if(err) {
-    failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
-          info ? info : "");
-    if(info)
-      ldap_memfree(info);
-    return CURLE_LOGIN_DENIED;
+  case OLDAP_BIND:
+  case OLDAP_BINDV2:
+    result = oldap_state_bind_resp(data, msg, code);
+    break;
+  default:
+    /* internal error */
+    result = CURLE_COULDNT_CONNECT;
+    break;
   }
 
-  if(info)
-    ldap_memfree(info);
-  conn->recv[FIRSTSOCKET] = oldap_recv;
-  *done = TRUE;
+  ldap_msgfree(msg);
 
-  return CURLE_OK;
+  *done = li->state == OLDAP_STOP;
+  if(*done)
+    conn->recv[FIRSTSOCKET] = oldap_recv;
+
+  return result;
 }
 
 static CURLcode oldap_disconnect(struct Curl_easy *data,
@@ -373,7 +553,7 @@ static CURLcode oldap_disconnect(struct Curl_easy *data,
   if(li) {
     if(li->ld) {
 #ifdef USE_SSL
-      if(conn->ssl[FIRSTSOCKET].use) {
+      if(ssl_installed(conn)) {
         Sockbuf *sb;
         ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
         ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data);
@@ -393,44 +573,40 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done)
   struct connectdata *conn = data->conn;
   struct ldapconninfo *li = conn->proto.ldapc;
   struct ldapreqinfo *lr;
-  CURLcode status = CURLE_OK;
-  int rc = 0;
-  LDAPURLDesc *ludp = NULL;
+  CURLcode result;
+  int rc;
+  LDAPURLDesc *lud;
   int msgid;
 
   connkeep(conn, "OpenLDAP do");
 
   infof(data, "LDAP local: %s", data->state.url);
 
-  rc = ldap_url_parse(data->state.url, &ludp);
-  if(rc != LDAP_URL_SUCCESS) {
-    const char *msg = "url parsing problem";
-    status = CURLE_URL_MALFORMAT;
-    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
-      if(rc == LDAP_URL_ERR_MEM)
-        status = CURLE_OUT_OF_MEMORY;
-      msg = url_errs[rc];
+  result = oldap_url_parse(data, &lud);
+  if(!result) {
+    rc = ldap_search_ext(li->ld, lud->lud_dn, lud->lud_scope,
+                         lud->lud_filter, lud->lud_attrs, 0,
+                         NULL, NULL, NULL, 0, &msgid);
+    ldap_free_urldesc(lud);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
+      result = CURLE_LDAP_SEARCH_FAILED;
+    }
+    else {
+      lr = calloc(1, sizeof(struct ldapreqinfo));
+      if(!lr) {
+        ldap_abandon_ext(li->ld, msgid, NULL, NULL);
+        result = CURLE_OUT_OF_MEMORY;
+      }
+      else {
+        lr->msgid = msgid;
+        data->req.p.ldap = lr;
+        Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
+        *done = TRUE;
+      }
     }
-    failf(data, "LDAP local: %s", msg);
-    return status;
-  }
-
-  rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
-                       ludp->lud_filter, ludp->lud_attrs, 0,
-                       NULL, NULL, NULL, 0, &msgid);
-  ldap_free_urldesc(ludp);
-  if(rc != LDAP_SUCCESS) {
-    failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
-    return CURLE_LDAP_SEARCH_FAILED;
   }
-  lr = calloc(1, sizeof(struct ldapreqinfo));
-  if(!lr)
-    return CURLE_OUT_OF_MEMORY;
-  lr->msgid = msgid;
-  data->req.p.ldap = lr;
-  Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
-  *done = TRUE;
-  return CURLE_OK;
+  return result;
 }
 
 static CURLcode oldap_done(struct Curl_easy *data, CURLcode res,
@@ -456,163 +632,146 @@ static CURLcode oldap_done(struct Curl_easy *data, CURLcode res,
   return CURLE_OK;
 }
 
+static CURLcode client_write(struct Curl_easy *data, const char *prefix,
+                             const char *value, size_t len, const char *suffix)
+{
+  CURLcode result = CURLE_OK;
+  size_t l;
+
+  if(prefix) {
+    l = strlen(prefix);
+    /* If we have a zero-length value and the prefix ends with a space
+       separator, drop the latter. */
+    if(!len && l && prefix[l - 1] == ' ')
+      l--;
+    result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) prefix, l);
+    if(!result)
+      data->req.bytecount += l;
+  }
+  if(!result && value) {
+    result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) value, len);
+    if(!result)
+      data->req.bytecount += len;
+  }
+  if(!result && suffix) {
+    l = strlen(suffix);
+    result = Curl_client_write(data, CLIENTWRITE_BODY, (char *) suffix, l);
+    if(!result)
+      data->req.bytecount += l;
+  }
+  return result;
+}
+
 static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf,
                           size_t len, CURLcode *err)
 {
   struct connectdata *conn = data->conn;
   struct ldapconninfo *li = conn->proto.ldapc;
   struct ldapreqinfo *lr = data->req.p.ldap;
-  int rc, ret;
+  int rc;
   LDAPMessage *msg = NULL;
-  LDAPMessage *ent;
   BerElement *ber = NULL;
-  struct timeval tv = {0, 1};
+  struct timeval tv = {0, 0};
+  struct berval bv, *bvals;
+  int binary = 0;
+  CURLcode result = CURLE_AGAIN;
+  int code;
+  char *info = NULL;
 
   (void)len;
   (void)buf;
   (void)sockindex;
 
-  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
+  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_ONE, &tv, &msg);
   if(rc < 0) {
     failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
-    *err = CURLE_RECV_ERROR;
-    return -1;
+    result = CURLE_RECV_ERROR;
   }
 
-  *err = CURLE_AGAIN;
-  ret = -1;
+  *err = result;
 
-  /* timed out */
+  /* error or timed out */
   if(!msg)
-    return ret;
-
-  for(ent = ldap_first_message(li->ld, msg); ent;
-      ent = ldap_next_message(li->ld, ent)) {
-    struct berval bv, *bvals;
-    int binary = 0, msgtype;
-    CURLcode writeerr;
-
-    msgtype = ldap_msgtype(ent);
-    if(msgtype == LDAP_RES_SEARCH_RESULT) {
-      int code;
-      char *info = NULL;
-      rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
-      if(rc) {
-        failf(data, "LDAP local: search ldap_parse_result %s",
-              ldap_err2string(rc));
-        *err = CURLE_LDAP_SEARCH_FAILED;
-      }
-      else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
-        failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
-              info ? info : "");
-        *err = CURLE_LDAP_SEARCH_FAILED;
-      }
-      else {
-        /* successful */
-        if(code == LDAP_SIZELIMIT_EXCEEDED)
-          infof(data, "There are more than %d entries", lr->nument);
-        data->req.size = data->req.bytecount;
-        *err = CURLE_OK;
-        ret = 0;
-      }
-      lr->msgid = 0;
-      ldap_memfree(info);
+    return -1;
+
+  result = CURLE_OK;
+
+  switch(ldap_msgtype(msg)) {
+  case LDAP_RES_SEARCH_RESULT:
+    lr->msgid = 0;
+    rc = ldap_parse_result(li->ld, msg, &code, NULL, &info, NULL, NULL, 0);
+    if(rc) {
+      failf(data, "LDAP local: search ldap_parse_result %s",
+            ldap_err2string(rc));
+      result = CURLE_LDAP_SEARCH_FAILED;
       break;
     }
-    else if(msgtype != LDAP_RES_SEARCH_ENTRY)
-      continue;
 
+    /* store the latest code for later retrieval */
+    data->info.httpcode = code;
+
+    switch(code) {
+    case LDAP_SIZELIMIT_EXCEEDED:
+      infof(data, "There are more than %d entries", lr->nument);
+      /* FALLTHROUGH */
+    case LDAP_SUCCESS:
+      data->req.size = data->req.bytecount;
+      break;
+    default:
+      failf(data, "LDAP remote: search failed %s %s", ldap_err2string(code),
+            info ? info : "");
+      result = CURLE_LDAP_SEARCH_FAILED;
+      break;
+    }
+    if(info)
+      ldap_memfree(info);
+    break;
+  case LDAP_RES_SEARCH_ENTRY:
     lr->nument++;
-    rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
+    rc = ldap_get_dn_ber(li->ld, msg, &ber, &bv);
     if(rc < 0) {
-      *err = CURLE_RECV_ERROR;
-      return -1;
-    }
-    writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
-    if(writeerr) {
-      *err = writeerr;
-      return -1;
-    }
-
-    writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
-                                 bv.bv_len);
-    if(writeerr) {
-      *err = writeerr;
-      return -1;
+      result = CURLE_RECV_ERROR;
+      break;
     }
 
-    writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
-    if(writeerr) {
-      *err = writeerr;
-      return -1;
-    }
-    data->req.bytecount += bv.bv_len + 5;
+    result = client_write(data, "DN: ", bv.bv_val, bv.bv_len, "\n");
+    if(result)
+      break;
 
-    for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals);
+    for(rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals);
         rc == LDAP_SUCCESS;
-        rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) {
+        rc = ldap_get_attribute_ber(li->ld, msg, ber, &bv, &bvals)) {
       int i;
 
       if(!bv.bv_val)
         break;
 
-      if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
-        binary = 1;
-      else
-        binary = 0;
-
       if(!bvals) {
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
-        }
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
-                                     bv.bv_len);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
-        }
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":\n", 2);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
-        }
-        data->req.bytecount += bv.bv_len + 3;
+        result = client_write(data, "\t", bv.bv_val, bv.bv_len, ":\n");
+        if(result)
+          break;
         continue;
       }
 
+      binary = bv.bv_len > 7 &&
+               !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7);
+
       for(i = 0; bvals[i].bv_val != NULL; i++) {
         int binval = 0;
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
-        }
 
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)bv.bv_val,
-                                     bv.bv_len);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
-        }
-
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)":", 1);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
-        }
-        data->req.bytecount += bv.bv_len + 2;
+        result = client_write(data, "\t", bv.bv_val, bv.bv_len, ":");
+        if(result)
+          break;
 
         if(!binary) {
           /* check for leading or trailing whitespace */
           if(ISSPACE(bvals[i].bv_val[0]) ||
-             ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
+             ISSPACE(bvals[i].bv_val[bvals[i].bv_len - 1]))
             binval = 1;
           else {
             /* check for unprintable characters */
             unsigned int j;
-            for(j = 0; jreq.bytecount += 2;
-          if(val_b64_sz > 0) {
-            writeerr = Curl_client_write(data, CLIENTWRITE_BODY, val_b64,
-                                         val_b64_sz);
-            if(writeerr) {
-              *err = writeerr;
-              return -1;
-            }
-            free(val_b64);
-            data->req.bytecount += val_b64_sz;
-          }
-        }
-        else {
-          writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)" ", 1);
-          if(writeerr) {
-            *err = writeerr;
-            return -1;
-          }
 
-          writeerr = Curl_client_write(data, CLIENTWRITE_BODY, bvals[i].bv_val,
-                                       bvals[i].bv_len);
-          if(writeerr) {
-            *err = writeerr;
-            return -1;
-          }
-
-          data->req.bytecount += bvals[i].bv_len + 1;
-        }
-        writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
-        if(writeerr) {
-          *err = writeerr;
-          return -1;
+          /* Binary value, encode to base64. */
+          if(bvals[i].bv_len)
+            result = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len,
+                                        &val_b64, &val_b64_sz);
+          if(!result)
+            result = client_write(data, ": ", val_b64, val_b64_sz, "\n");
+          free(val_b64);
         }
-
-        data->req.bytecount++;
+        else
+          result = client_write(data, " ",
+                                bvals[i].bv_val, bvals[i].bv_len, "\n");
+        if(result)
+          break;
       }
+
       ber_memfree(bvals);
-      writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
-      if(writeerr) {
-        *err = writeerr;
-        return -1;
-      }
-      data->req.bytecount++;
-    }
-    writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
-    if(writeerr) {
-      *err = writeerr;
-      return -1;
+      bvals = NULL;
+      if(!result)
+        result = client_write(data, "\n", NULL, 0, NULL);
+      if(result)
+        break;
     }
-    data->req.bytecount++;
+
     ber_free(ber, 0);
+
+    if(!result)
+      result = client_write(data, "\n", NULL, 0, NULL);
+    if(!result)
+      result = CURLE_AGAIN;
+    break;
   }
+
   ldap_msgfree(msg);
-  return ret;
+  *err = result;
+  return result? -1: 0;
 }
 
 #ifdef USE_SSL
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index 56d9c49926..599ed5d994 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -1870,6 +1870,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
         data->set.ssl.primary.verifypeer;
     }
     break;
+#ifndef CURL_DISABLE_DOH
   case CURLOPT_DOH_SSL_VERIFYPEER:
     /*
      * Enable peer SSL verifying for DoH.
@@ -1877,6 +1878,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     data->set.doh_verifypeer = (0 != va_arg(param, long)) ?
       TRUE : FALSE;
     break;
+#endif
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_SSL_VERIFYPEER:
     /*
@@ -1909,6 +1911,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
         data->set.ssl.primary.verifyhost;
     }
     break;
+#ifndef CURL_DISABLE_DOH
   case CURLOPT_DOH_SSL_VERIFYHOST:
     /*
      * Enable verification of the host name in the peer certificate for DoH
@@ -1918,6 +1921,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     /* Treat both 1 and 2 as TRUE */
     data->set.doh_verifyhost = (bool)((arg & 3) ? TRUE : FALSE);
     break;
+#endif
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_SSL_VERIFYHOST:
     /*
@@ -1953,6 +1957,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
         data->set.ssl.primary.verifystatus;
     }
     break;
+#ifndef CURL_DISABLE_DOH
   case CURLOPT_DOH_SSL_VERIFYSTATUS:
     /*
      * Enable certificate status verifying for DoH.
@@ -1965,6 +1970,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     data->set.doh_verifystatus = (0 != va_arg(param, long)) ?
       TRUE : FALSE;
     break;
+#endif
   case CURLOPT_SSL_CTX_FUNCTION:
     /*
      * Set a SSL_CTX callback
@@ -2609,6 +2615,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     break;
 #endif
 
+#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
+  !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
+  case CURLOPT_MIME_OPTIONS:
+    data->set.mime_options = va_arg(param, long);
+    break;
+#endif
+
   case CURLOPT_SASL_AUTHZID:
     /* Authorisation identity (identity to act as) */
     result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c
index 1391412ce5..cf7ea4f543 100644
--- a/libs/libcurl/src/sha256.c
+++ b/libs/libcurl/src/sha256.c
@@ -82,10 +82,14 @@ struct sha256_ctx {
 };
 typedef struct sha256_ctx my_sha256_ctx;
 
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
 {
   ctx->openssl_ctx = EVP_MD_CTX_create();
+  if(!ctx->openssl_ctx)
+    return CURLE_OUT_OF_MEMORY;
+
   EVP_DigestInit_ex(ctx->openssl_ctx, EVP_sha256(), NULL);
+  return CURLE_OK;
 }
 
 static void my_sha256_update(my_sha256_ctx *ctx,
@@ -112,9 +116,10 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
 
 typedef struct sha256_ctx my_sha256_ctx;
 
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
 {
   sha256_init(ctx);
+  return CURLE_OK;
 }
 
 static void my_sha256_update(my_sha256_ctx *ctx,
@@ -140,13 +145,14 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
 
 typedef mbedtls_sha256_context my_sha256_ctx;
 
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
 {
 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
   (void) mbedtls_sha256_starts(ctx, 0);
 #else
   (void) mbedtls_sha256_starts_ret(ctx, 0);
 #endif
+  return CURLE_OK;
 }
 
 static void my_sha256_update(my_sha256_ctx *ctx,
@@ -183,9 +189,10 @@ static void my_sha256_final(unsigned char *digest, my_sha256_ctx *ctx)
 
 typedef CC_SHA256_CTX my_sha256_ctx;
 
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
 {
   (void) CC_SHA256_Init(ctx);
+  return CURLE_OK;
 }
 
 static void my_sha256_update(my_sha256_ctx *ctx,
@@ -214,12 +221,14 @@ typedef struct sha256_ctx my_sha256_ctx;
 #define CALG_SHA_256 0x0000800c
 #endif
 
-static void my_sha256_init(my_sha256_ctx *ctx)
+static CURLcode my_sha256_init(my_sha256_ctx *ctx)
 {
   if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
   }
+
+  return CURLE_OK;
 }
 
 static void my_sha256_update(my_sha256_ctx *ctx,
@@ -375,7 +384,7 @@ static int sha256_compress(struct sha256_state *md,
 }
 
 /* Initialize the hash state */
-static void my_sha256_init(struct sha256_state *md)
+static CURLcode my_sha256_init(struct sha256_state *md)
 {
   md->curlen = 0;
   md->length = 0;
@@ -387,6 +396,8 @@ static void my_sha256_init(struct sha256_state *md)
   md->state[5] = 0x9B05688CUL;
   md->state[6] = 0x1F83D9ABUL;
   md->state[7] = 0x5BE0CD19UL;
+
+  return CURLE_OK;
 }
 
 /*
@@ -394,7 +405,7 @@ static void my_sha256_init(struct sha256_state *md)
    @param md     The hash state
    @param in     The data to hash
    @param inlen  The length of the data (octets)
-   @return CRYPT_OK if successful
+   @return 0 if successful
 */
 static int my_sha256_update(struct sha256_state *md,
                             const unsigned char *in,
@@ -435,7 +446,7 @@ static int my_sha256_update(struct sha256_state *md,
    Terminate the hash to get the digest
    @param md  The hash state
    @param out [out] The destination of the hash (32 bytes)
-   @return CRYPT_OK if successful
+   @return 0 if successful
 */
 static int my_sha256_final(unsigned char *out,
                            struct sha256_state *md)
@@ -491,15 +502,21 @@ static int my_sha256_final(unsigned char *out,
  * output [in/out] - The output buffer.
  * input  [in]     - The input data.
  * length [in]     - The input length.
+ *
+ * Returns CURLE_OK on success.
  */
-void Curl_sha256it(unsigned char *output, const unsigned char *input,
+CURLcode Curl_sha256it(unsigned char *output, const unsigned char *input,
                    const size_t length)
 {
+  CURLcode result;
   my_sha256_ctx ctx;
 
-  my_sha256_init(&ctx);
-  my_sha256_update(&ctx, input, curlx_uztoui(length));
-  my_sha256_final(output, &ctx);
+  result = my_sha256_init(&ctx);
+  if(!result) {
+    my_sha256_update(&ctx, input, curlx_uztoui(length));
+    my_sha256_final(output, &ctx);
+  }
+  return result;
 }
 
 
diff --git a/libs/libcurl/src/share.c b/libs/libcurl/src/share.c
index 9c43c8f705..403563fdd6 100644
--- a/libs/libcurl/src/share.c
+++ b/libs/libcurl/src/share.c
@@ -39,11 +39,7 @@ curl_share_init(void)
   if(share) {
     share->magic = CURL_GOOD_SHARE;
     share->specifier |= (1<hostcache)) {
-      free(share);
-      return NULL;
-    }
+    Curl_init_dnscache(&share->hostcache);
   }
 
   return share;
diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c
index 8e0b046096..6c08293783 100644
--- a/libs/libcurl/src/smtp.c
+++ b/libs/libcurl/src/smtp.c
@@ -222,7 +222,7 @@ static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn,
 
   /* Do we have a command response? This should be the response code followed
      by a space and optionally some text as per RFC-5321 and as outlined in
-     Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
+     Section 4. Examples of RFC-4954 but some email servers ignore this and
      only send the response code instead as per Section 4.2. */
   if(line[3] == ' ' || len == 5) {
     char tmpline[6];
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c
index db4c80834e..a014aa6684 100644
--- a/libs/libcurl/src/socks.c
+++ b/libs/libcurl/src/socks.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -38,6 +38,7 @@
 #include "timeval.h"
 #include "socks.h"
 #include "multiif.h" /* for getsock macros */
+#include "inet_pton.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -856,10 +857,32 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
     socksreq[len++] = 0; /* must be zero */
 
     if(!socks5_resolve_local) {
-      socksreq[len++] = 3; /* ATYP: domain name = 3 */
-      socksreq[len++] = (char) hostname_len; /* one byte address length */
-      memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
-      len += hostname_len;
+      /* ATYP: domain name = 3,
+         IPv6 == 4,
+         IPv4 == 1 */
+      unsigned char ip4[4];
+#ifdef ENABLE_IPV6
+      if(conn->bits.ipv6_ip) {
+        char ip6[16];
+        if(1 != Curl_inet_pton(AF_INET6, hostname, ip6))
+          return CURLPX_BAD_ADDRESS_TYPE;
+        socksreq[len++] = 4;
+        memcpy(&socksreq[len], ip6, sizeof(ip6));
+        len += sizeof(ip6);
+      }
+      else
+#endif
+      if(1 == Curl_inet_pton(AF_INET, hostname, ip4)) {
+        socksreq[len++] = 1;
+        memcpy(&socksreq[len], ip4, sizeof(ip4));
+        len += sizeof(ip4);
+      }
+      else {
+        socksreq[len++] = 3;
+        socksreq[len++] = (char) hostname_len; /* one byte address length */
+        memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
+        len += hostname_len;
+      }
       infof(data, "SOCKS5 connect to %s:%d (remotely resolved)",
             hostname, remote_port);
     }
diff --git a/libs/libcurl/src/splay.c b/libs/libcurl/src/splay.c
index 1c1dafb920..bcc0795212 100644
--- a/libs/libcurl/src/splay.c
+++ b/libs/libcurl/src/splay.c
@@ -107,7 +107,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i,
   if(!node)
     return t;
 
-  if(t != NULL) {
+  if(t) {
     t = Curl_splay(i, t);
     if(compare(i, t->key) == 0) {
       /* There already exists a node in the tree with the very same key. Build
diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c
index 31eb2bf790..07d73a74b7 100644
--- a/libs/libcurl/src/strerror.c
+++ b/libs/libcurl/src/strerror.c
@@ -404,6 +404,9 @@ curl_multi_strerror(CURLMcode error)
   case CURLM_BAD_FUNCTION_ARGUMENT:
     return "A libcurl function was given a bad argument";
 
+  case CURLM_ABORTED_BY_CALLBACK:
+    return "Operation was aborted by an application callback";
+
   case CURLM_LAST:
     break;
   }
@@ -468,10 +471,10 @@ curl_url_strerror(CURLUcode error)
     return "An invalid 'part' argument was passed as argument";
 
   case CURLUE_MALFORMED_INPUT:
-    return "A malformed input was passed to a URL API function";
+    return "Malformed input to a URL function";
 
   case CURLUE_BAD_PORT_NUMBER:
-    return "The port number was not a decimal number between 0 and 65535";
+    return "Port number was not a decimal number between 0 and 65535";
 
   case CURLUE_UNSUPPORTED_SCHEME:
     return "This libcurl build doesn't support the given URL scheme";
@@ -489,28 +492,64 @@ curl_url_strerror(CURLUcode error)
     return "An unknown part ID was passed to a URL API function";
 
   case CURLUE_NO_SCHEME:
-    return "There is no scheme part in the URL";
+    return "No scheme part in the URL";
 
   case CURLUE_NO_USER:
-    return "There is no user part in the URL";
+    return "No user part in the URL";
 
   case CURLUE_NO_PASSWORD:
-    return "There is no password part in the URL";
+    return "No password part in the URL";
 
   case CURLUE_NO_OPTIONS:
-    return "There is no options part in the URL";
+    return "No options part in the URL";
 
   case CURLUE_NO_HOST:
-    return "There is no host part in the URL";
+    return "No host part in the URL";
 
   case CURLUE_NO_PORT:
-    return "There is no port part in the URL";
+    return "No port part in the URL";
 
   case CURLUE_NO_QUERY:
-    return "There is no query part in the URL";
+    return "No query part in the URL";
 
   case CURLUE_NO_FRAGMENT:
-    return "There is no fragment part in the URL";
+    return "No fragment part in the URL";
+
+  case CURLUE_NO_ZONEID:
+    return "No zoneid part in the URL";
+
+  case CURLUE_BAD_LOGIN:
+    return "Bad login part";
+
+  case CURLUE_BAD_IPV6:
+    return "Bad IPv6 address";
+
+  case CURLUE_BAD_HOSTNAME:
+    return "Bad hostname";
+
+  case CURLUE_BAD_FILE_URL:
+    return "Bad file:// URL";
+
+  case CURLUE_BAD_SLASHES:
+    return "Unsupported number of slashes";
+
+  case CURLUE_BAD_SCHEME:
+    return "Bad scheme";
+
+  case CURLUE_BAD_PATH:
+    return "Bad path";
+
+  case CURLUE_BAD_FRAGMENT:
+    return "Bad fragment";
+
+  case CURLUE_BAD_QUERY:
+    return "Bad query";
+
+  case CURLUE_BAD_PASSWORD:
+    return "Bad password";
+
+  case CURLUE_BAD_USER:
+    return "Bad user";
 
   case CURLUE_LAST:
     break;
diff --git a/libs/libcurl/src/system_win32.c b/libs/libcurl/src/system_win32.c
index d4e194831f..9a6dd9cef6 100644
--- a/libs/libcurl/src/system_win32.c
+++ b/libs/libcurl/src/system_win32.c
@@ -104,7 +104,7 @@ CURLcode Curl_win32_init(long flags)
 
   /* curlx_verify_windows_version must be called during init at least once
      because it has its own initialization routine. */
-  if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
+  if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
                                   VERSION_GREATER_THAN_EQUAL)) {
     Curl_isVistaOrGreater = TRUE;
   }
diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c
index 7e5246f010..f8c68441ca 100644
--- a/libs/libcurl/src/tftp.c
+++ b/libs/libcurl/src/tftp.c
@@ -186,7 +186,7 @@ const struct Curl_handler Curl_handler_tftp = {
   PORT_TFTP,                            /* defport */
   CURLPROTO_TFTP,                       /* protocol */
   CURLPROTO_TFTP,                       /* family */
-  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
+  PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY /* flags */
 };
 
 /**********************************************************
diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c
index 05fec7998c..22704fa158 100644
--- a/libs/libcurl/src/transfer.c
+++ b/libs/libcurl/src/transfer.c
@@ -1631,7 +1631,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
 
   if((type != FOLLOW_RETRY) &&
      (data->req.httpcode != 401) && (data->req.httpcode != 407) &&
-     Curl_is_absolute_url(newurl, NULL, MAX_SCHEME_LEN))
+     Curl_is_absolute_url(newurl, NULL, 0))
     /* If this is not redirect due to a 401 or 407 response and an absolute
        URL: don't allow a custom port number */
     disallowport = TRUE;
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index 93b4397bff..9f1013554f 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -137,6 +137,15 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "curl_memory.h"
 #include "memdebug.h"
 
+/* Count of the backend ssl objects to allocate */
+#ifdef USE_SSL
+#  ifndef CURL_DISABLE_PROXY
+#    define SSL_BACKEND_CNT 4
+#  else
+#    define SSL_BACKEND_CNT 2
+#  endif
+#endif
+
 static void conn_free(struct connectdata *conn);
 
 /* Some parts of the code (e.g. chunked encoding) assume this buffer has at
@@ -354,9 +363,7 @@ static void up_free(struct Curl_easy *data)
  * This is the internal function curl_easy_cleanup() calls. This should
  * cleanup and free all resources associated with this sessionhandle.
  *
- * NOTE: if we ever add something that attempts to write to a socket or
- * similar here, we must ignore SIGPIPE first. It is currently only done
- * when curl_easy_perform() is invoked.
+ * We ignore SIGPIPE when this is called from curl_easy_cleanup.
  */
 
 CURLcode Curl_close(struct Curl_easy **datap)
@@ -542,8 +549,10 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
    * libcurl 7.10 introduced SSL verification *by default*! This needs to be
    * switched off unless wanted.
    */
+#ifndef CURL_DISABLE_DOH
   set->doh_verifyhost = TRUE;
   set->doh_verifypeer = TRUE;
+#endif
   set->ssl.primary.verifypeer = TRUE;
   set->ssl.primary.verifyhost = TRUE;
 #ifdef USE_TLS_SRP
@@ -845,7 +854,7 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
     return CURLE_OK;
   }
 
-  if(conn->dns_entry != NULL) {
+  if(conn->dns_entry) {
     Curl_resolv_unlock(data, conn->dns_entry);
     conn->dns_entry = NULL;
   }
@@ -1300,13 +1309,12 @@ ConnectionExists(struct Curl_easy *data,
             if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
               continue;
           }
-          else {
-            if(!Curl_ssl_config_matches(&needle->ssl_config,
-                                        &check->ssl_config))
-              continue;
-            if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
-              continue;
-          }
+
+          if(!Curl_ssl_config_matches(&needle->ssl_config,
+                                      &check->ssl_config))
+            continue;
+          if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
+            continue;
         }
       }
 #endif
@@ -1683,7 +1691,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
      data becomes proxy backend data). */
   {
     size_t sslsize = Curl_ssl->sizeof_ssl_backend_data;
-    char *ssl = calloc(4, sslsize);
+    char *ssl = calloc(SSL_BACKEND_CNT, sslsize);
     if(!ssl) {
       free(conn);
       return NULL;
@@ -1950,7 +1958,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
     return CURLE_OUT_OF_MEMORY;
 
   if(data->set.str[STRING_DEFAULT_PROTOCOL] &&
-     !Curl_is_absolute_url(data->state.url, NULL, MAX_SCHEME_LEN)) {
+     !Curl_is_absolute_url(data->state.url, NULL, 0)) {
     char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL],
                         data->state.url);
     if(!url)
@@ -2593,7 +2601,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
   if(data->set.str[STRING_PROXY]) {
     proxy = strdup(data->set.str[STRING_PROXY]);
     /* if global proxy is set, this is it */
-    if(NULL == proxy) {
+    if(!proxy) {
       failf(data, "memory shortage");
       result = CURLE_OUT_OF_MEMORY;
       goto out;
@@ -2603,7 +2611,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data,
   if(data->set.str[STRING_PRE_PROXY]) {
     socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
     /* if global socks proxy is set, this is it */
-    if(NULL == socksproxy) {
+    if(!socksproxy) {
       failf(data, "memory shortage");
       result = CURLE_OUT_OF_MEMORY;
       goto out;
diff --git a/libs/libcurl/src/urlapi-int.h b/libs/libcurl/src/urlapi-int.h
index 4257233094..bd6b601751 100644
--- a/libs/libcurl/src/urlapi-int.h
+++ b/libs/libcurl/src/urlapi-int.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -22,8 +22,6 @@
  *
  ***************************************************************************/
 #include "curl_setup.h"
-/* scheme is not URL encoded, the longest libcurl supported ones are... */
-#define MAX_SCHEME_LEN 40
 
 bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
 
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c
index 6d116b61bf..d29aeb238f 100644
--- a/libs/libcurl/src/urlapi.c
+++ b/libs/libcurl/src/urlapi.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -30,6 +30,7 @@
 #include "escape.h"
 #include "curl_ctype.h"
 #include "inet_pton.h"
+#include "inet_ntop.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -50,6 +51,9 @@
    ((str)[1] == ':' || (str)[1] == '|') && \
    ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0))
 
+/* scheme is not URL encoded, the longest libcurl supported ones are... */
+#define MAX_SCHEME_LEN 40
+
 /* Internal representation of CURLU. Point to URL-encoded strings. */
 struct Curl_URL {
   char *scheme;
@@ -228,33 +232,40 @@ static void strcpy_url(char *output, const char *url, bool relative)
 }
 
 /*
- * Returns true if the given URL is absolute (as opposed to relative) within
- * the buffer size. Returns the scheme in the buffer if TRUE and 'buf' is
- * non-NULL.
+ * Returns true if the given URL is absolute (as opposed to relative). Returns
+ * the scheme in the buffer if TRUE and 'buf' is non-NULL. The buflen must
+ * be larger than MAX_SCHEME_LEN if buf is set.
  */
 bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
 {
   size_t i;
+  DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
+  (void)buflen; /* only used in debug-builds */
+  if(buf)
+    buf[0] = 0; /* always leave a defined value in buf */
 #ifdef WIN32
   if(STARTS_WITH_DRIVE_PREFIX(url))
     return FALSE;
 #endif
-  for(i = 0; i < buflen && url[i]; ++i) {
+  for(i = 0; i < MAX_SCHEME_LEN; ++i) {
     char s = url[i];
-    if((s == ':') && (url[i + 1] == '/')) {
-      if(buf)
-        buf[i] = 0;
-      return TRUE;
-    }
-    /* RFC 3986 3.1 explains:
-      scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-    */
-    else if(ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') ) {
-      if(buf)
-        buf[i] = (char)TOLOWER(s);
+    if(s && (ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') )) {
+      /* RFC 3986 3.1 explains:
+        scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+      */
     }
-    else
+    else {
       break;
+    }
+  }
+  if(i && (url[i] == ':') && (url[i + 1] == '/')) {
+    if(buf) {
+      buf[i] = 0;
+      while(i--) {
+        buf[i] = (char)TOLOWER(url[i]);
+      }
+    }
+    return TRUE;
   }
   return FALSE;
 }
@@ -418,6 +429,29 @@ static char *concat_url(const char *base, const char *relurl)
   return newest;
 }
 
+/* scan for byte values < 31 or 127 */
+static bool junkscan(const char *part, unsigned int flags)
+{
+  if(part) {
+    static const char badbytes[]={
+      /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+      0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+      0x7f, 0x00 /* null-terminate */
+    };
+    size_t n = strlen(part);
+    size_t nfine = strcspn(part, badbytes);
+    if(nfine != n)
+      /* since we don't know which part is scanned, return a generic error
+         code */
+      return TRUE;
+    if(!(flags & CURLU_ALLOW_SPACE) && strchr(part, ' '))
+      return TRUE;
+  }
+  return FALSE;
+}
+
 /*
  * parse_hostname_login()
  *
@@ -465,7 +499,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
                                    (h && (h->flags & PROTOPT_URLOPTIONS)) ?
                                    &optionsp:NULL);
   if(ccode) {
-    result = CURLUE_MALFORMED_INPUT;
+    result = CURLUE_BAD_LOGIN;
     goto out;
   }
 
@@ -475,15 +509,28 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
       result = CURLUE_USER_NOT_ALLOWED;
       goto out;
     }
-
+    if(junkscan(userp, flags)) {
+      result = CURLUE_BAD_USER;
+      goto out;
+    }
     u->user = userp;
   }
 
-  if(passwdp)
+  if(passwdp) {
+    if(junkscan(passwdp, flags)) {
+      result = CURLUE_BAD_PASSWORD;
+      goto out;
+    }
     u->password = passwdp;
+  }
 
-  if(optionsp)
+  if(optionsp) {
+    if(junkscan(optionsp, flags)) {
+      result = CURLUE_BAD_LOGIN;
+      goto out;
+    }
     u->options = optionsp;
+  }
 
   return CURLUE_OK;
   out:
@@ -491,6 +538,9 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
   free(userp);
   free(passwdp);
   free(optionsp);
+  u->user = NULL;
+  u->password = NULL;
+  u->options = NULL;
 
   return result;
 }
@@ -514,19 +564,19 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
       int zonelen = len;
       if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) {
         if(']' != endbracket)
-          return CURLUE_MALFORMED_INPUT;
+          return CURLUE_BAD_IPV6;
         portptr = &hostname[--zonelen + len + 1];
       }
       else
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_BAD_IPV6;
     }
     else
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_IPV6;
 
     /* this is a RFC2732-style specified IP-address */
     if(portptr && *portptr) {
       if(*portptr != ':')
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_BAD_IPV6;
     }
     else
       portptr = NULL;
@@ -556,9 +606,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
 
     port = strtol(portptr + 1, &rest, 10);  /* Port number must be decimal */
 
-    if((port <= 0) || (port > 0xffff))
-      /* Single unix standard says port numbers are 16 bits long, but we don't
-         treat port zero as OK. */
+    if(port > 0xffff)
       return CURLUE_BAD_PORT_NUMBER;
 
     if(rest[0])
@@ -577,46 +625,20 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
   return CURLUE_OK;
 }
 
-/* scan for byte values < 31 or 127 */
-static bool junkscan(const char *part, unsigned int flags)
-{
-  if(part) {
-    static const char badbytes[]={
-      /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-      0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-      0x7f, 0x00 /* null-terminate */
-    };
-    size_t n = strlen(part);
-    size_t nfine = strcspn(part, badbytes);
-    if(nfine != n)
-      /* since we don't know which part is scanned, return a generic error
-         code */
-      return TRUE;
-    if(!(flags & CURLU_ALLOW_SPACE) && strchr(part, ' '))
-      return TRUE;
-  }
-  return FALSE;
-}
-
 static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
 {
   size_t len;
   size_t hlen = strlen(hostname);
 
   if(hostname[0] == '[') {
-#ifdef ENABLE_IPV6
-    char dest[16]; /* fits a binary IPv6 address */
-#endif
     const char *l = "0123456789abcdefABCDEF:.";
     if(hlen < 4) /* '[::]' is the shortest possible valid string */
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_IPV6;
     hostname++;
     hlen -= 2;
 
     if(hostname[hlen] != ']')
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_IPV6;
 
     /* only valid letters are ok */
     len = strspn(hostname, l);
@@ -633,6 +655,7 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
         while(*h && (*h != ']') && (i < 15))
           zoneid[i++] = *h++;
         if(!i || (']' != *h))
+          /* impossible to reach? */
           return CURLUE_MALFORMED_INPUT;
         zoneid[i] = 0;
         u->zoneid = strdup(zoneid);
@@ -642,14 +665,26 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
         hostname[len + 1] = 0; /* terminate the hostname */
       }
       else
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_BAD_IPV6;
       /* hostname is fine */
     }
 #ifdef ENABLE_IPV6
-    hostname[hlen] = 0; /* end the address there */
-    if(1 != Curl_inet_pton(AF_INET6, hostname, dest))
-      return CURLUE_MALFORMED_INPUT;
-    hostname[hlen] = ']'; /* restore ending bracket */
+    {
+      char dest[16]; /* fits a binary IPv6 address */
+      char norm[MAX_IPADR_LEN];
+      hostname[hlen] = 0; /* end the address there */
+      if(1 != Curl_inet_pton(AF_INET6, hostname, dest))
+        return CURLUE_BAD_IPV6;
+
+      /* check if it can be done shorter */
+      if(Curl_inet_ntop(AF_INET6, dest, norm, sizeof(norm)) &&
+         (strlen(norm) < hlen)) {
+        strcpy(hostname, norm);
+        hlen = strlen(norm);
+        hostname[hlen + 1] = 0;
+      }
+      hostname[hlen] = ']'; /* restore ending bracket */
+    }
 #endif
   }
   else {
@@ -657,7 +692,7 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname)
     len = strcspn(hostname, " \r\n");
     if(hlen != len)
       /* hostname with bad content */
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_HOSTNAME;
   }
   if(!hostname[0])
     return CURLUE_NO_HOST;
@@ -772,7 +807,7 @@ static CURLUcode decode_host(char *hostname, char **outp)
     CURLcode result = Curl_urldecode(NULL, hostname, 0,
                                      outp, &dlen, REJECT_CTRL);
     if(result)
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_HOSTNAME;
   }
 
   return CURLUE_OK;
@@ -817,7 +852,11 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
   }
 
   /* handle the file: scheme */
-  if(url_has_scheme && strcasecompare(schemebuf, "file")) {
+  if(url_has_scheme && !strcmp(schemebuf, "file")) {
+    if(urllen <= 6)
+      /* file:/ is not enough to actually be a complete file: URL */
+      return CURLUE_BAD_FILE_URL;
+
     /* path has been allocated large enough to hold this */
     strcpy(path, &url[5]);
 
@@ -870,7 +909,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
              host name */
           path = strpbrk(ptr, "/\\:*?\"<>|");
           if(!path || *path != '/')
-            return CURLUE_MALFORMED_INPUT;
+            return CURLUE_BAD_FILE_URL;
 
           len = path - ptr;
           if(len) {
@@ -883,7 +922,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
 #else
           /* Invalid file://hostname/, expected localhost or 127.0.0.1 or
              none */
-          return CURLUE_MALFORMED_INPUT;
+          return CURLUE_BAD_FILE_URL;
 #endif
         }
       }
@@ -900,7 +939,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
     if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) ||
        STARTS_WITH_URL_DRIVE_PREFIX(path)) {
       /* File drive letters are only accepted in MSDOS/Windows */
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_FILE_URL;
     }
 #else
     /* If the path starts with a slash and a drive letter, ditch the slash */
@@ -927,7 +966,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
       }
       if((i < 1) || (i>3))
         /* less than one or more than three slashes */
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_BAD_SLASHES;
 
       schemep = schemebuf;
       if(!Curl_builtin_scheme(schemep) &&
@@ -935,13 +974,13 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
         return CURLUE_UNSUPPORTED_SCHEME;
 
       if(junkscan(schemep, flags))
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_BAD_SCHEME;
     }
     else {
       /* no scheme! */
 
       if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME)))
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_BAD_SCHEME;
       if(flags & CURLU_DEFAULT_SCHEME)
         schemep = DEFAULT_SCHEME;
 
@@ -952,7 +991,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
     }
     hostp = p; /* host name starts here */
 
-    while(*p && !HOSTNAME_END(*p)) /* find end of host name */
+    /* find the end of the host name + port number */
+    while(*p && !HOSTNAME_END(*p))
       p++;
 
     len = p - hostp;
@@ -962,7 +1002,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
     }
     else {
       if(!(flags & CURLU_NO_AUTHORITY))
-        return CURLUE_MALFORMED_INPUT;
+        return CURLUE_NO_HOST;
     }
 
     len = strlen(p);
@@ -976,9 +1016,6 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
     }
   }
 
-  if(junkscan(path, flags))
-    return CURLUE_MALFORMED_INPUT;
-
   if((flags & CURLU_URLENCODE) && path[0]) {
     /* worst case output length is 3x the original! */
     char *newp = malloc(strlen(path) * 3);
@@ -992,6 +1029,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
   fragment = strchr(path, '#');
   if(fragment) {
     *fragment++ = 0;
+    if(junkscan(fragment, flags))
+      return CURLUE_BAD_FRAGMENT;
     if(fragment[0]) {
       u->fragment = strdup(fragment);
       if(!u->fragment)
@@ -1002,12 +1041,17 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
   query = strchr(path, '?');
   if(query) {
     *query++ = 0;
+    if(junkscan(query, flags))
+      return CURLUE_BAD_QUERY;
     /* done even if the query part is a blank string */
     u->query = strdup(query);
     if(!u->query)
       return CURLUE_OUT_OF_MEMORY;
   }
 
+  if(junkscan(path, flags))
+    return CURLUE_BAD_PATH;
+
   if(!path[0])
     /* if there's no path left set, unset */
     path = NULL;
@@ -1037,12 +1081,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
 
   if(hostname) {
     char normalized_ipv4[sizeof("255.255.255.255") + 1];
+
     /*
      * Parse the login details and strip them out of the host name.
      */
-    if(junkscan(hostname, flags))
-      return CURLUE_MALFORMED_INPUT;
-
     result = parse_hostname_login(u, &hostname, flags);
     if(result)
       return result;
@@ -1051,6 +1093,9 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
     if(result)
       return result;
 
+    if(junkscan(hostname, flags))
+      return CURLUE_BAD_HOSTNAME;
+
     if(0 == strlen(hostname) && (flags & CURLU_NO_AUTHORITY)) {
       /* Skip hostname check, it's allowed to be empty. */
       u->host = strdup("");
@@ -1196,6 +1241,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what,
     break;
   case CURLUPART_ZONEID:
     ptr = u->zoneid;
+    ifmissing = CURLUE_NO_ZONEID;
     break;
   case CURLUPART_PORT:
     ptr = u->port;
@@ -1453,7 +1499,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
   case CURLUPART_SCHEME:
     if(strlen(part) > MAX_SCHEME_LEN)
       /* too long */
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_SCHEME;
     if(!(flags & CURLU_NON_SUPPORT_SCHEME) &&
        /* verify that it is a fine scheme */
        !Curl_builtin_scheme(part))
@@ -1474,7 +1520,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
     size_t len = strcspn(part, " \r\n");
     if(strlen(part) != len)
       /* hostname with bad content */
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_HOSTNAME;
     storep = &u->host;
     Curl_safefree(u->zoneid);
     break;
@@ -1491,7 +1537,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
       return CURLUE_BAD_PORT_NUMBER;
     if(*endp)
       /* weirdly provided number, not good! */
-      return CURLUE_MALFORMED_INPUT;
+      return CURLUE_BAD_PORT_NUMBER;
     storep = &u->port;
   }
   break;
@@ -1520,7 +1566,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
     char *redired_url;
     CURLU *handle2;
 
-    if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN + 1)) {
+    if(Curl_is_absolute_url(part, NULL, 0)) {
       handle2 = curl_url();
       if(!handle2)
         return CURLUE_OUT_OF_MEMORY;
@@ -1655,7 +1701,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
       else {
         if(hostname_check(u, (char *)newp)) {
           free((char *)newp);
-          return CURLUE_MALFORMED_INPUT;
+          return CURLUE_BAD_HOSTNAME;
         }
       }
     }
diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h
index 22068882f0..cc9c888709 100644
--- a/libs/libcurl/src/urldata.h
+++ b/libs/libcurl/src/urldata.h
@@ -518,7 +518,9 @@ struct ConnectBits {
   BIT(tls_enable_npn);  /* TLS NPN extension? */
   BIT(tls_enable_alpn); /* TLS ALPN extension? */
   BIT(connect_only);
+#ifndef CURL_DISABLE_DOH
   BIT(doh);
+#endif
 #ifdef USE_UNIX_SOCKETS
   BIT(abstract_unix_socket);
 #endif
@@ -835,6 +837,7 @@ struct Curl_handler {
 #define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */
 #define PROTOPT_USERPWDCTRL (1<<13) /* Allow "control bytes" (< 32 ascii) in
                                        user name and password */
+#define PROTOPT_NOTCPPROXY (1<<14) /* this protocol can't proxy over TCP */
 
 #define CONNCHECK_NONE 0                 /* No checks */
 #define CONNCHECK_ISDEAD (1<<0)          /* Check if the connection is dead. */
@@ -1749,6 +1752,7 @@ struct UserDefined {
   unsigned int scope_id;  /* Scope id for IPv6 */
   long allowed_protocols;
   long redir_protocols;
+  long mime_options;      /* Mime option flags. */
   struct curl_slist *mail_rcpt; /* linked list of mail recipients */
   /* Common RTSP header options */
   Curl_RtspReq rtspreq; /* RTSP request type */
@@ -1856,10 +1860,12 @@ struct UserDefined {
                            header */
   BIT(abstract_unix_socket);
   BIT(disallow_username_in_url); /* disallow username in url */
+#ifndef CURL_DISABLE_DOH
   BIT(doh); /* DNS-over-HTTPS enabled */
   BIT(doh_verifypeer);     /* DoH certificate peer verification */
   BIT(doh_verifyhost);     /* DoH certificate hostname verification */
   BIT(doh_verifystatus);   /* DoH certificate status verification */
+#endif
   BIT(http09_allowed); /* allow HTTP/0.9 responses */
   BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
                                 recipients */
diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c
index a04ffab6fb..d8aac66bda 100644
--- a/libs/libcurl/src/vauth/digest.c
+++ b/libs/libcurl/src/vauth/digest.c
@@ -230,7 +230,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
     return CURLE_OUT_OF_MEMORY;
 
   token = strtok_r(tmp, ",", &tok_buf);
-  while(token != NULL) {
+  while(token) {
     if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
       *value |= DIGEST_QOP_VALUE_AUTH;
     else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
@@ -556,7 +556,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
           return CURLE_OUT_OF_MEMORY;
 
         token = strtok_r(tmp, ",", &tok_buf);
-        while(token != NULL) {
+        while(token) {
           if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
             foundAuth = TRUE;
           }
@@ -666,8 +666,8 @@ static CURLcode auth_create_digest_http_message(
                   struct digestdata *digest,
                   char **outptr, size_t *outlen,
                   void (*convert_to_ascii)(unsigned char *, unsigned char *),
-                  void (*hash)(unsigned char *, const unsigned char *,
-                               const size_t))
+                  CURLcode (*hash)(unsigned char *, const unsigned char *,
+                                   const size_t))
 {
   CURLcode result;
   unsigned char hashbuf[32]; /* 32 bytes/256 bits */
@@ -722,8 +722,7 @@ static CURLcode auth_create_digest_http_message(
            unq(nonce-value) ":" unq(cnonce-value)
   */
 
-  hashthis = aprintf("%s:%s:%s", digest->userhash ? userh : userp,
-                                 digest->realm, passwdp);
+  hashthis = aprintf("%s:%s:%s", userp, digest->realm, passwdp);
   if(!hashthis)
     return CURLE_OUT_OF_MEMORY;
 
diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c
index 0aa3f1c8ca..04f6590acf 100644
--- a/libs/libcurl/src/vauth/ntlm.c
+++ b/libs/libcurl/src/vauth/ntlm.c
@@ -603,7 +603,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
     memcpy(tmp, &ntlm->nonce[0], 8);
     memcpy(tmp + 8, entropy, 8);
 
-    Curl_md5it(md5sum, tmp, 16);
+    result = Curl_md5it(md5sum, tmp, 16);
+    if(result)
+      return result;
 
     /* We shall only use the first 8 bytes of md5sum, but the des code in
        Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
diff --git a/libs/libcurl/src/version_win32.c b/libs/libcurl/src/version_win32.c
index 2f845413cc..79a2aa6ab4 100644
--- a/libs/libcurl/src/version_win32.c
+++ b/libs/libcurl/src/version_win32.c
@@ -57,6 +57,8 @@ struct OUR_OSVERSIONINFOEXW {
  *
  * majorVersion [in] - The major version number.
  * minorVersion [in] - The minor version number.
+ * buildVersion [in] - The build version number. If 0, this parameter is
+ *                     ignored.
  * platform     [in] - The optional platform identifier.
  * condition    [in] - The test condition used to specifier whether we are
  *                     checking a version less then, equal to or greater than
@@ -67,6 +69,7 @@ struct OUR_OSVERSIONINFOEXW {
  */
 bool curlx_verify_windows_version(const unsigned int majorVersion,
                                   const unsigned int minorVersion,
+                                  const unsigned int buildVersion,
                                   const PlatformIdentifier platform,
                                   const VersionCondition condition)
 {
@@ -118,34 +121,52 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
     case VERSION_LESS_THAN:
       if(osver.dwMajorVersion < majorVersion ||
         (osver.dwMajorVersion == majorVersion &&
-         osver.dwMinorVersion < minorVersion))
+         osver.dwMinorVersion < minorVersion) ||
+        (buildVersion != 0 &&
+         (osver.dwMajorVersion == majorVersion &&
+          osver.dwMinorVersion == minorVersion &&
+          osver.dwBuildNumber < buildVersion)))
         matched = TRUE;
       break;
 
     case VERSION_LESS_THAN_EQUAL:
       if(osver.dwMajorVersion < majorVersion ||
         (osver.dwMajorVersion == majorVersion &&
-         osver.dwMinorVersion <= minorVersion))
+         osver.dwMinorVersion < minorVersion) ||
+        (osver.dwMajorVersion == majorVersion &&
+         osver.dwMinorVersion == minorVersion &&
+         (buildVersion == 0 ||
+          osver.dwBuildNumber <= buildVersion)))
         matched = TRUE;
       break;
 
     case VERSION_EQUAL:
       if(osver.dwMajorVersion == majorVersion &&
-         osver.dwMinorVersion == minorVersion)
+         osver.dwMinorVersion == minorVersion &&
+        (buildVersion == 0 ||
+         osver.dwBuildNumber == buildVersion))
         matched = TRUE;
       break;
 
     case VERSION_GREATER_THAN_EQUAL:
       if(osver.dwMajorVersion > majorVersion ||
         (osver.dwMajorVersion == majorVersion &&
-         osver.dwMinorVersion >= minorVersion))
+         osver.dwMinorVersion > minorVersion) ||
+        (osver.dwMajorVersion == majorVersion &&
+         osver.dwMinorVersion == minorVersion &&
+         (buildVersion == 0 ||
+          osver.dwBuildNumber >= buildVersion)))
         matched = TRUE;
       break;
 
     case VERSION_GREATER_THAN:
       if(osver.dwMajorVersion > majorVersion ||
         (osver.dwMajorVersion == majorVersion &&
-         osver.dwMinorVersion > minorVersion))
+         osver.dwMinorVersion > minorVersion) ||
+        (buildVersion != 0 &&
+         (osver.dwMajorVersion == majorVersion &&
+          osver.dwMinorVersion == minorVersion &&
+          osver.dwBuildNumber > buildVersion)))
         matched = TRUE;
       break;
     }
@@ -161,6 +182,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
       case PLATFORM_WINNT:
         if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
           matched = FALSE;
+        break;
 
       default: /* like platform == PLATFORM_DONT_CARE */
         break;
@@ -172,8 +194,11 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   struct OUR_OSVERSIONINFOEXW osver;
   BYTE majorCondition;
   BYTE minorCondition;
+  BYTE buildCondition;
   BYTE spMajorCondition;
   BYTE spMinorCondition;
+  DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
+                     VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
 
   typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
     (struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
@@ -190,6 +215,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   case VERSION_LESS_THAN:
     majorCondition = VER_LESS;
     minorCondition = VER_LESS;
+    buildCondition = VER_LESS;
     spMajorCondition = VER_LESS_EQUAL;
     spMinorCondition = VER_LESS_EQUAL;
     break;
@@ -197,6 +223,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   case VERSION_LESS_THAN_EQUAL:
     majorCondition = VER_LESS_EQUAL;
     minorCondition = VER_LESS_EQUAL;
+    buildCondition = VER_LESS_EQUAL;
     spMajorCondition = VER_LESS_EQUAL;
     spMinorCondition = VER_LESS_EQUAL;
     break;
@@ -204,6 +231,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   case VERSION_EQUAL:
     majorCondition = VER_EQUAL;
     minorCondition = VER_EQUAL;
+    buildCondition = VER_EQUAL;
     spMajorCondition = VER_GREATER_EQUAL;
     spMinorCondition = VER_GREATER_EQUAL;
     break;
@@ -211,6 +239,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   case VERSION_GREATER_THAN_EQUAL:
     majorCondition = VER_GREATER_EQUAL;
     minorCondition = VER_GREATER_EQUAL;
+    buildCondition = VER_GREATER_EQUAL;
     spMajorCondition = VER_GREATER_EQUAL;
     spMinorCondition = VER_GREATER_EQUAL;
     break;
@@ -218,6 +247,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   case VERSION_GREATER_THAN:
     majorCondition = VER_GREATER;
     minorCondition = VER_GREATER;
+    buildCondition = VER_GREATER;
     spMajorCondition = VER_GREATER_EQUAL;
     spMinorCondition = VER_GREATER_EQUAL;
     break;
@@ -230,6 +260,7 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   osver.dwOSVersionInfoSize = sizeof(osver);
   osver.dwMajorVersion = majorVersion;
   osver.dwMinorVersion = minorVersion;
+  osver.dwBuildNumber = buildVersion;
   if(platform == PLATFORM_WINDOWS)
     osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
   else if(platform == PLATFORM_WINNT)
@@ -239,26 +270,43 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
   cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
   cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
   cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
-  if(platform != PLATFORM_DONT_CARE)
+
+  if(platform != PLATFORM_DONT_CARE) {
     cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
+    dwTypeMask |= VER_PLATFORMID;
+  }
 
   /* Later versions of Windows have version functions that may not return the
      real version of Windows unless the application is so manifested. We prefer
      the real version always, so we use the Rtl variant of the function when
      possible. Note though the function signatures have underlying fundamental
      types that are the same, the return values are different. */
-  if(pRtlVerifyVersionInfo) {
-    matched = !pRtlVerifyVersionInfo(&osver,
-      (VER_MAJORVERSION | VER_MINORVERSION |
-       VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
-      cm);
-  }
-  else {
-    matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
-      (VER_MAJORVERSION | VER_MINORVERSION |
-       VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
-      cm);
+  if(pRtlVerifyVersionInfo)
+    matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
+  else
+    matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm);
+
+  /* Compare the build number separately. VerifyVersionInfo normally compares
+     major.minor in hierarchical order (eg 1.9 is less than 2.0) but does not
+     do the same for build (eg 1.9 build 222 is not less than 2.0 build 111).
+     Build comparison is only needed when build numbers are equal (eg 1.9 is
+     always less than 2.0 so build comparison is not needed). */
+  if(matched && buildVersion &&
+     (condition == VERSION_EQUAL ||
+      ((condition == VERSION_GREATER_THAN_EQUAL ||
+        condition == VERSION_LESS_THAN_EQUAL) &&
+        curlx_verify_windows_version(majorVersion, minorVersion, 0,
+                                     platform, VERSION_EQUAL)))) {
+
+    cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition);
+    dwTypeMask = VER_BUILDNUMBER;
+    if(pRtlVerifyVersionInfo)
+      matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
+    else
+      matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
+                                      dwTypeMask, cm);
   }
+
 #endif
 
   return matched;
diff --git a/libs/libcurl/src/version_win32.h b/libs/libcurl/src/version_win32.h
index 9b1bd88874..38af87fa09 100644
--- a/libs/libcurl/src/version_win32.h
+++ b/libs/libcurl/src/version_win32.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2016 - 2020, Steve Holme, .
+ * Copyright (C) 2016 - 2021, Steve Holme, .
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -45,6 +45,7 @@ typedef enum {
 /* This is used to verify if we are running on a specific windows version */
 bool curlx_verify_windows_version(const unsigned int majorVersion,
                                   const unsigned int minorVersion,
+                                  const unsigned int buildVersion,
                                   const PlatformIdentifier platform,
                                   const VersionCondition condition);
 
diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c
index dfe8f96fb1..1596049b77 100644
--- a/libs/libcurl/src/vquic/ngtcp2.c
+++ b/libs/libcurl/src/vquic/ngtcp2.c
@@ -29,8 +29,10 @@
 #ifdef USE_OPENSSL
 #include 
 #include 
+#include "vtls/openssl.h"
 #elif defined(USE_GNUTLS)
 #include 
+#include "vtls/gtls.h"
 #endif
 #include "urldata.h"
 #include "sendf.h"
@@ -287,6 +289,27 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
     SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
   }
 
+  {
+    struct connectdata *conn = data->conn;
+    const char * const ssl_cafile = conn->ssl_config.CAfile;
+    const char * const ssl_capath = conn->ssl_config.CApath;
+
+    if(conn->ssl_config.verifypeer) {
+      SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
+      /* tell OpenSSL where to find CA certificates that are used to verify
+         the server's certificate. */
+      if(!SSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate verify locations:"
+              "  CAfile: %s CApath: %s",
+              ssl_cafile ? ssl_cafile : "none",
+              ssl_capath ? ssl_capath : "none");
+        return NULL;
+      }
+      infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
+      infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
+    }
+  }
   return ssl_ctx;
 }
 
@@ -1638,8 +1661,10 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data,
   return sent;
 }
 
-static void ng_has_connected(struct connectdata *conn, int tempindex)
+static CURLcode ng_has_connected(struct Curl_easy *data,
+                                 struct connectdata *conn, int tempindex)
 {
+  CURLcode result = CURLE_OK;
   conn->recv[FIRSTSOCKET] = ngh3_stream_recv;
   conn->send[FIRSTSOCKET] = ngh3_stream_send;
   conn->handler = &Curl_handler_http3;
@@ -1647,6 +1672,27 @@ static void ng_has_connected(struct connectdata *conn, int tempindex)
   conn->httpversion = 30;
   conn->bundle->multiuse = BUNDLE_MULTIPLEX;
   conn->quic = &conn->hequic[tempindex];
+
+  if(conn->ssl_config.verifyhost) {
+#ifdef USE_OPENSSL
+    X509 *server_cert;
+    CURLcode result;
+    server_cert = SSL_get_peer_certificate(conn->quic->ssl);
+    if(!server_cert) {
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    result = Curl_ossl_verifyhost(data, conn, server_cert);
+    X509_free(server_cert);
+    if(result)
+      return result;
+    infof(data, "Verified certificate just fine");
+#else
+    result = Curl_gtls_verifyserver(data, conn, conn->quic->ssl, FIRSTSOCKET);
+#endif
+  }
+  else
+    infof(data, "Skipped certificate verification");
+  return result;
 }
 
 /*
@@ -1670,8 +1716,9 @@ CURLcode Curl_quic_is_connected(struct Curl_easy *data,
     goto error;
 
   if(ngtcp2_conn_get_handshake_completed(qs->qconn)) {
-    *done = TRUE;
-    ng_has_connected(conn, sockindex);
+    result = ng_has_connected(data, conn, sockindex);
+    if(!result)
+      *done = TRUE;
   }
 
   return result;
@@ -1718,6 +1765,10 @@ static CURLcode ng_process_ingress(struct Curl_easy *data,
     rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
     if(rv) {
       /* TODO Send CONNECTION_CLOSE if possible */
+      if(rv == NGTCP2_ERR_CRYPTO)
+        /* this is a "TLS problem", but a failed certificate verification
+           is a common reason for this */
+        return CURLE_PEER_FAILED_VERIFICATION;
       return CURLE_RECV_ERROR;
     }
   }
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c
index 7466840ffa..581bc1be82 100644
--- a/libs/libcurl/src/vssh/libssh2.c
+++ b/libs/libcurl/src/vssh/libssh2.c
@@ -645,8 +645,8 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
 
     hostkey = libssh2_session_hostkey(sshc->ssh_session, &len, NULL);
     if(hostkey) {
-      Curl_sha256it(hash, (const unsigned char *) hostkey, len);
-      fingerprint = (char *) hash;
+      if(!Curl_sha256it(hash, (const unsigned char *) hostkey, len))
+        fingerprint = (char *) hash;
     }
 #endif
 
@@ -661,16 +661,15 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
 
     /* The length of fingerprint is 32 bytes for SHA256.
      * See libssh2_hostkey_hash documentation. */
-    if(Curl_base64_encode (data, fingerprint, 32, &fingerprint_b64,
-        &fingerprint_b64_len) != CURLE_OK) {
+    if(Curl_base64_encode(data, fingerprint, 32, &fingerprint_b64,
+                          &fingerprint_b64_len) != CURLE_OK) {
       state(data, SSH_SESSION_FREE);
       sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
       return sshc->actualcode;
     }
 
     if(!fingerprint_b64) {
-      failf(data,
-          "sha256 fingerprint could not be encoded");
+      failf(data, "sha256 fingerprint could not be encoded");
       state(data, SSH_SESSION_FREE);
       sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
       return sshc->actualcode;
@@ -698,7 +697,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
 
       failf(data,
           "Denied establishing ssh session: mismatch sha256 fingerprint. "
-          "Remote %s is not equal to %s", fingerprint, pubkey_sha256);
+          "Remote %s is not equal to %s", fingerprint_b64, pubkey_sha256);
       state(data, SSH_SESSION_FREE);
       sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
       return sshc->actualcode;
diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c
index 2053fd439d..18864aa4b2 100644
--- a/libs/libcurl/src/vtls/gtls.c
+++ b/libs/libcurl/src/vtls/gtls.c
@@ -497,6 +497,7 @@ gtls_connect_step1(struct Curl_easy *data,
   /* use system ca certificate store as fallback */
   if(SSL_CONN_CONFIG(verifypeer) &&
      !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
+    /* this ignores errors on purpose */
     gnutls_certificate_set_x509_system_trust(backend->cred);
   }
 #endif
@@ -631,7 +632,10 @@ gtls_connect_step1(struct Curl_easy *data,
     cur++;
     infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
 
-    gnutls_alpn_set_protocols(session, protocols, cur, 0);
+    if(gnutls_alpn_set_protocols(session, protocols, cur, 0)) {
+      failf(data, "failed setting ALPN");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
   }
 
   if(SSL_SET_OPTION(primary.clientcert)) {
@@ -757,10 +761,10 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
   CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
 
   /* if a path wasn't specified, don't pin */
-  if(NULL == pinnedpubkey)
+  if(!pinnedpubkey)
     return CURLE_OK;
 
-  if(NULL == cert)
+  if(!cert)
     return result;
 
   do {
@@ -778,7 +782,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
       break; /* failed */
 
     buff1 = malloc(len1);
-    if(NULL == buff1)
+    if(!buff1)
       break; /* failed */
 
     len2 = len1;
@@ -793,7 +797,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
     result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
   } while(0);
 
-  if(NULL != key)
+  if(key)
     gnutls_pubkey_deinit(key);
 
   Curl_safefree(buff1);
@@ -804,10 +808,11 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
 static Curl_recv gtls_recv;
 static Curl_send gtls_send;
 
-static CURLcode
-gtls_connect_step3(struct Curl_easy *data,
-                   struct connectdata *conn,
-                   int sockindex)
+CURLcode
+Curl_gtls_verifyserver(struct Curl_easy *data,
+                       struct connectdata *conn,
+                       gnutls_session_t session,
+                       int sockindex)
 {
   unsigned int cert_list_size;
   const gnutls_datum_t *chainp;
@@ -819,9 +824,6 @@ gtls_connect_step3(struct Curl_easy *data,
   size_t size;
   time_t certclock;
   const char *ptr;
-  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-  struct ssl_backend_data *backend = connssl->backend;
-  gnutls_session_t session = backend->session;
   int rc;
   gnutls_datum_t proto;
   CURLcode result = CURLE_OK;
@@ -1265,8 +1267,6 @@ gtls_connect_step3(struct Curl_easy *data,
   }
 
   conn->ssl[sockindex].state = ssl_connection_complete;
-  conn->recv[sockindex] = gtls_recv;
-  conn->send[sockindex] = gtls_send;
 
   if(SSL_SET_OPTION(primary.sessionid)) {
     /* we always unconditionally get the session id here, as even if we
@@ -1351,9 +1351,13 @@ gtls_connect_common(struct Curl_easy *data,
 
   /* Finish connecting once the handshake is done */
   if(ssl_connect_1 == connssl->connecting_state) {
-    rc = gtls_connect_step3(data, conn, sockindex);
+    struct ssl_backend_data *backend = connssl->backend;
+    gnutls_session_t session = backend->session;
+    rc = Curl_gtls_verifyserver(data, conn, session, sockindex);
     if(rc)
       return rc;
+    conn->recv[sockindex] = gtls_recv;
+    conn->send[sockindex] = gtls_send;
   }
 
   *done = ssl_connect_1 == connssl->connecting_state;
diff --git a/libs/libcurl/src/vtls/gtls.h b/libs/libcurl/src/vtls/gtls.h
index 1a146a3a93..642d5f093a 100644
--- a/libs/libcurl/src/vtls/gtls.h
+++ b/libs/libcurl/src/vtls/gtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -27,7 +27,11 @@
 #ifdef USE_GNUTLS
 
 #include "urldata.h"
-
+#include 
+CURLcode
+Curl_gtls_verifyserver(struct Curl_easy *data, struct connectdata *conn,
+                       gnutls_session_t session,
+                       int sockindex);
 extern const struct Curl_ssl Curl_ssl_gnutls;
 
 #endif /* USE_GNUTLS */
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index 08c79e1624..1d209b2732 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2021, Daniel Stenberg, , et al.
+ * Copyright (C) 2012 - 2022, Daniel Stenberg, , et al.
  * Copyright (C) 2010 - 2011, Hoi-Ho Chan, 
  *
  * This software is licensed as described in the file COPYING, which
@@ -270,7 +270,10 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   struct ssl_backend_data *backend = connssl->backend;
-  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob);
+  const char * const ssl_cafile =
+    /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
+    (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
   char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
@@ -316,16 +319,34 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
   /* Load the trusted CA */
   mbedtls_x509_crt_init(&backend->cacert);
 
-  if(ssl_cafile) {
+  if(ca_info_blob && verifypeer) {
+    /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
+       terminated even when provided the exact length, forcing us to waste
+       extra memory here. */
+    unsigned char *newblob = malloc(ca_info_blob->len + 1);
+    if(!newblob)
+      return CURLE_OUT_OF_MEMORY;
+    memcpy(newblob, ca_info_blob->data, ca_info_blob->len);
+    newblob[ca_info_blob->len] = 0; /* null terminate */
+    ret = mbedtls_x509_crt_parse(&backend->cacert, newblob,
+                                 ca_info_blob->len + 1);
+    free(newblob);
+    if(ret<0) {
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+      failf(data, "Error importing ca cert blob - mbedTLS: (-0x%04X) %s",
+            -ret, errorbuf);
+      return ret;
+    }
+  }
+
+  if(ssl_cafile && verifypeer) {
     ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile);
 
     if(ret<0) {
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
       failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
             ssl_cafile, -ret, errorbuf);
-
-      if(verifypeer)
-        return CURLE_SSL_CACERT_BADFILE;
+      return CURLE_SSL_CACERT_BADFILE;
     }
   }
 
@@ -358,10 +379,17 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
   }
 
   if(ssl_cert_blob) {
-    const unsigned char *blob_data =
-      (const unsigned char *)ssl_cert_blob->data;
-    ret = mbedtls_x509_crt_parse(&backend->clicert, blob_data,
+    /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null
+       terminated even when provided the exact length, forcing us to waste
+       extra memory here. */
+    unsigned char *newblob = malloc(ssl_cert_blob->len + 1);
+    if(!newblob)
+      return CURLE_OUT_OF_MEMORY;
+    memcpy(newblob, ssl_cert_blob->data, ssl_cert_blob->len);
+    newblob[ssl_cert_blob->len] = 0; /* null terminate */
+    ret = mbedtls_x509_crt_parse(&backend->clicert, newblob,
                                  ssl_cert_blob->len);
+    free(newblob);
 
     if(ret) {
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@@ -671,7 +699,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
     mbedtls_x509_crt *p = NULL;
     unsigned char *pubkey = NULL;
 
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
     if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) ||
        !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) {
 #else
@@ -698,7 +726,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
     /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
        needs a non-const key, for now.
        https://github.com/ARMmbed/mbedtls/issues/396 */
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
     if(mbedtls_x509_crt_parse_der(p,
                         peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p),
                         peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) {
@@ -710,7 +738,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn,
       goto pinnedpubkey_error;
     }
 
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#if MBEDTLS_VERSION_NUMBER == 0x03000000
     size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey,
                                        PUB_DER_MAX_BYTES);
 #else
@@ -1154,6 +1182,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
   { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */
 
   SSLSUPP_CA_PATH |
+  SSLSUPP_CAINFO_BLOB |
   SSLSUPP_PINNEDPUBKEY |
   SSLSUPP_SSL_CTX,
 
diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c
index 0a1dea3ac0..35a916586e 100644
--- a/libs/libcurl/src/vtls/mesalink.c
+++ b/libs/libcurl/src/vtls/mesalink.c
@@ -68,8 +68,6 @@ struct ssl_backend_data
   SSL *handle;
 };
 
-#define BACKEND connssl->backend
-
 static Curl_recv mesalink_recv;
 static Curl_send mesalink_send;
 
@@ -100,9 +98,9 @@ mesalink_connect_step1(struct Curl_easy *data,
 #endif
   const char * const hostname = SSL_HOST_NAME();
   size_t hostname_len = strlen(hostname);
-
   SSL_METHOD *req_method = NULL;
   curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   if(connssl->state == ssl_connection_complete)
     return CURLE_OK;
@@ -139,22 +137,22 @@ mesalink_connect_step1(struct Curl_easy *data,
     return CURLE_OUT_OF_MEMORY;
   }
 
-  if(BACKEND->ctx)
-    SSL_CTX_free(BACKEND->ctx);
-  BACKEND->ctx = SSL_CTX_new(req_method);
+  if(backend->ctx)
+    SSL_CTX_free(backend->ctx);
+  backend->ctx = SSL_CTX_new(req_method);
 
-  if(!BACKEND->ctx) {
+  if(!backend->ctx) {
     failf(data, "SSL: couldn't create a context!");
     return CURLE_OUT_OF_MEMORY;
   }
 
   SSL_CTX_set_verify(
-    BACKEND->ctx, SSL_CONN_CONFIG(verifypeer) ?
+    backend->ctx, SSL_CONN_CONFIG(verifypeer) ?
       SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
 
   if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath)) {
-    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, SSL_CONN_CONFIG(CAfile),
-                                                    SSL_CONN_CONFIG(CApath))) {
+    if(!SSL_CTX_load_verify_locations(backend->ctx, SSL_CONN_CONFIG(CAfile),
+                                      SSL_CONN_CONFIG(CApath))) {
       if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data,
               "error setting certificate verify locations: "
@@ -181,7 +179,7 @@ mesalink_connect_step1(struct Curl_easy *data,
   if(SSL_SET_OPTION(primary.clientcert) && SSL_SET_OPTION(key)) {
     int file_type = do_file_type(SSL_SET_OPTION(cert_type));
 
-    if(SSL_CTX_use_certificate_chain_file(BACKEND->ctx,
+    if(SSL_CTX_use_certificate_chain_file(backend->ctx,
                                           SSL_SET_OPTION(primary.clientcert),
                                           file_type) != 1) {
       failf(data, "unable to use client certificate (no key or wrong pass"
@@ -190,8 +188,8 @@ mesalink_connect_step1(struct Curl_easy *data,
     }
 
     file_type = do_file_type(SSL_SET_OPTION(key_type));
-    if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
-                                    file_type) != 1) {
+    if(SSL_CTX_use_PrivateKey_file(backend->ctx, SSL_SET_OPTION(key),
+                                   file_type) != 1) {
       failf(data, "unable to set private key");
       return CURLE_SSL_CONNECT_ERROR;
     }
@@ -204,7 +202,7 @@ mesalink_connect_step1(struct Curl_easy *data,
   ciphers = SSL_CONN_CONFIG(cipher_list);
   if(ciphers) {
 #ifdef MESALINK_HAVE_CIPHER
-    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+    if(!SSL_CTX_set_cipher_list(backend->ctx, ciphers)) {
       failf(data, "failed setting cipher list: %s", ciphers);
       return CURLE_SSL_CIPHER;
     }
@@ -212,10 +210,10 @@ mesalink_connect_step1(struct Curl_easy *data,
     infof(data, "Cipher selection: %s", ciphers);
   }
 
-  if(BACKEND->handle)
-    SSL_free(BACKEND->handle);
-  BACKEND->handle = SSL_new(BACKEND->ctx);
-  if(!BACKEND->handle) {
+  if(backend->handle)
+    SSL_free(backend->handle);
+  backend->handle = SSL_new(backend->ctx);
+  if(!backend->handle) {
     failf(data, "SSL: couldn't create a context (handle)!");
     return CURLE_OUT_OF_MEMORY;
   }
@@ -227,7 +225,7 @@ mesalink_connect_step1(struct Curl_easy *data,
 #endif
   ) {
     /* hostname is not a valid IP address */
-    if(SSL_set_tlsext_host_name(BACKEND->handle, hostname) != SSL_SUCCESS) {
+    if(SSL_set_tlsext_host_name(backend->handle, hostname) != SSL_SUCCESS) {
       failf(data,
             "WARNING: failed to configure server name indication (SNI) "
             "TLS extension\n");
@@ -244,7 +242,7 @@ mesalink_connect_step1(struct Curl_easy *data,
        || strncmp(hostname, "[::1]", 5) == 0
 #endif
     ) {
-      SSL_set_tlsext_host_name(BACKEND->handle, "localhost");
+      SSL_set_tlsext_host_name(backend->handle, "localhost");
     }
     else
 #endif
@@ -264,12 +262,12 @@ mesalink_connect_step1(struct Curl_easy *data,
                               SSL_IS_PROXY() ? TRUE : FALSE,
                               &ssl_sessionid, NULL, sockindex)) {
       /* we got a session id, use it! */
-      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+      if(!SSL_set_session(backend->handle, ssl_sessionid)) {
         Curl_ssl_sessionid_unlock(data);
         failf(
           data,
           "SSL: SSL_set_session failed: %s",
-          ERR_error_string(SSL_get_error(BACKEND->handle, 0), error_buffer));
+          ERR_error_string(SSL_get_error(backend->handle, 0), error_buffer));
         return CURLE_SSL_CONNECT_ERROR;
       }
       /* Informational message */
@@ -279,7 +277,7 @@ mesalink_connect_step1(struct Curl_easy *data,
   }
 #endif /* MESALINK_HAVE_SESSION */
 
-  if(SSL_set_fd(BACKEND->handle, (int)sockfd) != SSL_SUCCESS) {
+  if(SSL_set_fd(backend->handle, (int)sockfd) != SSL_SUCCESS) {
     failf(data, "SSL: SSL_set_fd failed");
     return CURLE_SSL_CONNECT_ERROR;
   }
@@ -294,13 +292,14 @@ mesalink_connect_step2(struct Curl_easy *data,
 {
   int ret = -1;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   conn->recv[sockindex] = mesalink_recv;
   conn->send[sockindex] = mesalink_send;
 
-  ret = SSL_connect(BACKEND->handle);
+  ret = SSL_connect(backend->handle);
   if(ret != SSL_SUCCESS) {
-    int detail = SSL_get_error(BACKEND->handle, ret);
+    int detail = SSL_get_error(backend->handle, ret);
 
     if(SSL_ERROR_WANT_CONNECT == detail || SSL_ERROR_WANT_READ == detail) {
       connssl->connecting_state = ssl_connect_2_reading;
@@ -327,8 +326,8 @@ mesalink_connect_step2(struct Curl_easy *data,
   connssl->connecting_state = ssl_connect_3;
   infof(data,
         "SSL connection using %s / %s",
-        SSL_get_version(BACKEND->handle),
-        SSL_get_cipher_name(BACKEND->handle));
+        SSL_get_version(backend->handle),
+        SSL_get_cipher_name(backend->handle));
 
   return CURLE_OK;
 }
@@ -347,8 +346,9 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex)
     SSL_SESSION *our_ssl_sessionid;
     void *old_ssl_sessionid = NULL;
     bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE;
+    struct ssl_backend_data *backend = connssl->backend;
 
-    our_ssl_sessionid = SSL_get_session(BACKEND->handle);
+    our_ssl_sessionid = SSL_get_session(backend->handle);
 
     Curl_ssl_sessionid_lock(data);
     incache =
@@ -387,12 +387,13 @@ mesalink_send(struct Curl_easy *data, int sockindex, const void *mem,
 {
   struct connectdata *conn = data->conn;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   char error_buffer[MESALINK_MAX_ERROR_SZ];
   int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
-  int rc = SSL_write(BACKEND->handle, mem, memlen);
+  int rc = SSL_write(backend->handle, mem, memlen);
 
   if(rc < 0) {
-    int err = SSL_get_error(BACKEND->handle, rc);
+    int err = SSL_get_error(backend->handle, rc);
     switch(err) {
     case SSL_ERROR_WANT_READ:
     case SSL_ERROR_WANT_WRITE:
@@ -415,17 +416,18 @@ static void
 mesalink_close(struct Curl_easy *data, struct connectdata *conn, int sockindex)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   (void) data;
 
-  if(BACKEND->handle) {
-    (void)SSL_shutdown(BACKEND->handle);
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+  if(backend->handle) {
+    (void)SSL_shutdown(backend->handle);
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
-  if(BACKEND->ctx) {
-    SSL_CTX_free(BACKEND->ctx);
-    BACKEND->ctx = NULL;
+  if(backend->ctx) {
+    SSL_CTX_free(backend->ctx);
+    backend->ctx = NULL;
   }
 }
 
@@ -435,12 +437,13 @@ mesalink_recv(struct Curl_easy *data, int num, char *buf, size_t buffersize,
 {
   struct connectdata *conn = data->conn;
   struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct ssl_backend_data *backend = connssl->backend;
   char error_buffer[MESALINK_MAX_ERROR_SZ];
   int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
-  int nread = SSL_read(BACKEND->handle, buf, buffsize);
+  int nread = SSL_read(backend->handle, buf, buffsize);
 
   if(nread <= 0) {
-    int err = SSL_get_error(BACKEND->handle, nread);
+    int err = SSL_get_error(backend->handle, nread);
 
     switch(err) {
     case SSL_ERROR_ZERO_RETURN: /* no more data */
@@ -485,12 +488,13 @@ mesalink_shutdown(struct Curl_easy *data,
 {
   int retval = 0;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   (void) data;
 
-  if(BACKEND->handle) {
-    SSL_free(BACKEND->handle);
-    BACKEND->handle = NULL;
+  if(backend->handle) {
+    SSL_free(backend->handle);
+    backend->handle = NULL;
   }
   return retval;
 }
@@ -636,8 +640,9 @@ static void *
 mesalink_get_internals(struct ssl_connect_data *connssl,
                        CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return BACKEND->handle;
+  return backend->handle;
 }
 
 const struct Curl_ssl Curl_ssl_mesalink = {
diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c
index 1897b9ab1d..2b44f05126 100644
--- a/libs/libcurl/src/vtls/nss.c
+++ b/libs/libcurl/src/vtls/nss.c
@@ -304,13 +304,14 @@ static char *nss_sslver_to_name(PRUint16 nssver)
   }
 }
 
-static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
-                             char *cipher_list)
+/* the longest cipher name this supports */
+#define MAX_CIPHER_LENGTH 128
+
+static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model,
+                             const char *cipher_list)
 {
   unsigned int i;
-  PRBool cipher_state[NUM_OF_CIPHERS];
-  PRBool found;
-  char *cipher;
+  const char *cipher;
 
   /* use accessors to avoid dynamic linking issues after an update of NSS */
   const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
@@ -326,51 +327,52 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
     SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
   }
 
-  /* Set every entry in our list to false */
-  for(i = 0; i < NUM_OF_CIPHERS; i++) {
-    cipher_state[i] = PR_FALSE;
-  }
-
   cipher = cipher_list;
 
-  while(cipher_list && (cipher_list[0])) {
+  while(cipher && cipher[0]) {
+    const char *end;
+    char name[MAX_CIPHER_LENGTH + 1];
+    size_t len;
+    bool found = FALSE;
     while((*cipher) && (ISSPACE(*cipher)))
       ++cipher;
 
-    cipher_list = strpbrk(cipher, ":, ");
-    if(cipher_list) {
-      *cipher_list++ = '\0';
-    }
-
-    found = PR_FALSE;
-
-    for(i = 0; i MAX_CIPHER_LENGTH) {
+      failf(data, "Bad cipher list");
       return SECFailure;
     }
-
-    if(cipher_list) {
-      cipher = cipher_list;
+    else if(len) {
+      memcpy(name, cipher, len);
+      name[len] = 0;
+
+      for(i = 0; inickname;
-  if(NULL == nickname)
+  if(!nickname)
     nickname = "[unknown]";
 
   if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
@@ -1229,7 +1231,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
     return SECFailure;
   }
 
-  if(NULL == *pRetKey) {
+  if(!*pRetKey) {
     failf(data, "NSS: private key not found for certificate: %s", nickname);
     return SECFailure;
   }
@@ -1344,7 +1346,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
   PRErrorCode err;
   const char *err_name;
 
-  if(nss_context != NULL)
+  if(nss_context)
     return CURLE_OK;
 
   memset((void *) &initparams, '\0', sizeof(initparams));
@@ -1360,7 +1362,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
                                   NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
     free(certpath);
 
-    if(nss_context != NULL)
+    if(nss_context)
       return CURLE_OK;
 
     err = PR_GetError();
@@ -1372,7 +1374,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
   nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
          | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
          | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
-  if(nss_context != NULL)
+  if(nss_context)
     return CURLE_OK;
 
   err = PR_GetError();
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index a1baef9c3f..f836c63b07 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -171,6 +171,21 @@
 #define OPENSSL_load_builtin_modules(x)
 #endif
 
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+#define HAVE_EVP_PKEY_GET_PARAMS 1
+#else
+#define SSL_get1_peer_certificate SSL_get_peer_certificate
+#endif
+
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+#include 
+#define DECLARE_PKEY_PARAM_BIGNUM(name) BIGNUM *name = NULL
+#define FREE_PKEY_PARAM_BIGNUM(name) BN_clear_free(name)
+#else
+#define DECLARE_PKEY_PARAM_BIGNUM(name) const BIGNUM *name
+#define FREE_PKEY_PARAM_BIGNUM(name)
+#endif
+
 /*
  * Whether SSL_CTX_set_keylog_callback is available.
  * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287
@@ -231,6 +246,13 @@
 #define HAVE_RANDOM_INIT_BY_DEFAULT 1
 #endif
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !(defined(LIBRESSL_VERSION_NUMBER) && \
+      LIBRESSL_VERSION_NUMBER < 0x2070100fL) && \
+    !defined(OPENSSL_IS_BORINGSSL)
+#define HAVE_OPENSSL_VERSION
+#endif
+
 struct ssl_backend_data {
   struct Curl_easy *logger; /* transfer handle to pass trace logs to, only
                                using sockindex 0 */
@@ -1099,7 +1121,8 @@ int cert_stuff(struct Curl_easy *data,
       EVP_PKEY_free(pktmp);
     }
 
-#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL)
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL) && \
+    !defined(OPENSSL_NO_DEPRECATED_3_0)
     {
       /* If RSA is used, don't check the private key if its flags indicate
        * it doesn't support it. */
@@ -1412,6 +1435,12 @@ static void ossl_closeone(struct Curl_easy *data,
   if(backend->handle) {
     char buf[32];
     set_logger(conn, data);
+    /*
+     * The conn->sock[0] socket is passed to openssl with SSL_set_fd().  Make
+     * sure the socket is not closed before calling OpenSSL functions that
+     * will use it.
+     */
+    DEBUGASSERT(conn->sock[FIRSTSOCKET] != CURL_SOCKET_BAD);
 
     /* Maybe the server has already sent a close notify alert.
        Read it to avoid an RST on the TCP connection. */
@@ -1650,9 +1679,10 @@ static bool subj_alt_hostcheck(struct Curl_easy *data,
    hostname. In this case, the iPAddress subjectAltName must be present
    in the certificate and must exactly match the IP in the URI.
 
+   This function is now used from ngtcp2 (QUIC) as well.
 */
-static CURLcode verifyhost(struct Curl_easy *data, struct connectdata *conn,
-                           X509 *server_cert)
+CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+                              X509 *server_cert)
 {
   bool matched = FALSE;
   int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
@@ -1937,7 +1967,7 @@ static CURLcode verifystatus(struct Curl_easy *data,
   }
 
   /* Compute the certificate's ID */
-  cert = SSL_get_peer_certificate(backend->handle);
+  cert = SSL_get1_peer_certificate(backend->handle);
   if(!cert) {
     failf(data, "Error getting peer certificate");
     result = CURLE_SSL_INVALIDCERTSTATUS;
@@ -3466,10 +3496,7 @@ static void pubkey_show(struct Curl_easy *data,
                         int num,
                         const char *type,
                         const char *name,
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
-                        const
-#endif
-                        BIGNUM *bn)
+                        const BIGNUM *bn)
 {
   char *ptr;
   char namebuf[32];
@@ -3534,12 +3561,6 @@ typedef size_t numcert_t;
 typedef int numcert_t;
 #endif
 
-#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
-#define OSSL3_CONST const
-#else
-#define OSSL3_CONST
-#endif
-
 static CURLcode get_cert_chain(struct Curl_easy *data,
                                struct ssl_connect_data *connssl)
 {
@@ -3563,6 +3584,9 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
   }
 
   mem = BIO_new(BIO_s_mem());
+  if(!mem) {
+    return CURLE_OUT_OF_MEMORY;
+  }
 
   for(i = 0; i < (int)numcerts; i++) {
     ASN1_INTEGER *num;
@@ -3647,92 +3671,115 @@ static CURLcode get_cert_chain(struct Curl_easy *data,
       switch(pktype) {
       case EVP_PKEY_RSA:
       {
-        OSSL3_CONST RSA *rsa;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+        RSA *rsa;
 #ifdef HAVE_OPAQUE_EVP_PKEY
         rsa = EVP_PKEY_get0_RSA(pubkey);
 #else
         rsa = pubkey->pkey.rsa;
-#endif
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
 
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
         {
-          const BIGNUM *n;
-          const BIGNUM *e;
-
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+          DECLARE_PKEY_PARAM_BIGNUM(n);
+          DECLARE_PKEY_PARAM_BIGNUM(e);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
+#else
           RSA_get0_key(rsa, &n, &e, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
           BIO_printf(mem, "%d", BN_num_bits(n));
+#else
+          BIO_printf(mem, "%d", BN_num_bits(rsa->n));
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
           push_certinfo("RSA Public Key", i);
           print_pubkey_BN(rsa, n, i);
           print_pubkey_BN(rsa, e, i);
+          FREE_PKEY_PARAM_BIGNUM(n);
+          FREE_PKEY_PARAM_BIGNUM(e);
         }
-#else
-        BIO_printf(mem, "%d", BN_num_bits(rsa->n));
-        push_certinfo("RSA Public Key", i);
-        print_pubkey_BN(rsa, n, i);
-        print_pubkey_BN(rsa, e, i);
-#endif
 
         break;
       }
       case EVP_PKEY_DSA:
       {
 #ifndef OPENSSL_NO_DSA
-        OSSL3_CONST DSA *dsa;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+        DSA *dsa;
 #ifdef HAVE_OPAQUE_EVP_PKEY
         dsa = EVP_PKEY_get0_DSA(pubkey);
 #else
         dsa = pubkey->pkey.dsa;
-#endif
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
         {
-          const BIGNUM *p;
-          const BIGNUM *q;
-          const BIGNUM *g;
-          const BIGNUM *pub_key;
-
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+          DECLARE_PKEY_PARAM_BIGNUM(p);
+          DECLARE_PKEY_PARAM_BIGNUM(q);
+          DECLARE_PKEY_PARAM_BIGNUM(g);
+          DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
           DSA_get0_pqg(dsa, &p, &q, &g);
           DSA_get0_key(dsa, &pub_key, NULL);
-
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
           print_pubkey_BN(dsa, p, i);
           print_pubkey_BN(dsa, q, i);
           print_pubkey_BN(dsa, g, i);
           print_pubkey_BN(dsa, pub_key, i);
+          FREE_PKEY_PARAM_BIGNUM(p);
+          FREE_PKEY_PARAM_BIGNUM(q);
+          FREE_PKEY_PARAM_BIGNUM(g);
+          FREE_PKEY_PARAM_BIGNUM(pub_key);
         }
-#else
-        print_pubkey_BN(dsa, p, i);
-        print_pubkey_BN(dsa, q, i);
-        print_pubkey_BN(dsa, g, i);
-        print_pubkey_BN(dsa, pub_key, i);
-#endif
 #endif /* !OPENSSL_NO_DSA */
         break;
       }
       case EVP_PKEY_DH:
       {
-        OSSL3_CONST DH *dh;
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+        DH *dh;
 #ifdef HAVE_OPAQUE_EVP_PKEY
         dh = EVP_PKEY_get0_DH(pubkey);
 #else
         dh = pubkey->pkey.dh;
-#endif
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
         {
-          const BIGNUM *p;
-          const BIGNUM *q;
-          const BIGNUM *g;
-          const BIGNUM *pub_key;
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+          DECLARE_PKEY_PARAM_BIGNUM(p);
+          DECLARE_PKEY_PARAM_BIGNUM(q);
+          DECLARE_PKEY_PARAM_BIGNUM(g);
+          DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+          EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
           DH_get0_pqg(dh, &p, &q, &g);
           DH_get0_key(dh, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
           print_pubkey_BN(dh, p, i);
           print_pubkey_BN(dh, q, i);
           print_pubkey_BN(dh, g, i);
+#else
+          print_pubkey_BN(dh, p, i);
+          print_pubkey_BN(dh, g, i);
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
           print_pubkey_BN(dh, pub_key, i);
+          FREE_PKEY_PARAM_BIGNUM(p);
+          FREE_PKEY_PARAM_BIGNUM(q);
+          FREE_PKEY_PARAM_BIGNUM(g);
+          FREE_PKEY_PARAM_BIGNUM(pub_key);
        }
-#else
-        print_pubkey_BN(dh, p, i);
-        print_pubkey_BN(dh, g, i);
-        print_pubkey_BN(dh, pub_key, i);
-#endif
         break;
       }
       }
@@ -3836,11 +3883,20 @@ static CURLcode servercert(struct Curl_easy *data,
   BIO *mem = BIO_new(BIO_s_mem());
   struct ssl_backend_data *backend = connssl->backend;
 
+  if(!mem) {
+    failf(data,
+          "BIO_new return NULL, " OSSL_PACKAGE
+          " error %s",
+          ossl_strerror(ERR_get_error(), error_buffer,
+                        sizeof(error_buffer)) );
+    return CURLE_OUT_OF_MEMORY;
+  }
+
   if(data->set.ssl.certinfo)
     /* we've been asked to gather certificate info! */
     (void)get_cert_chain(data, connssl);
 
-  backend->server_cert = SSL_get_peer_certificate(backend->handle);
+  backend->server_cert = SSL_get1_peer_certificate(backend->handle);
   if(!backend->server_cert) {
     BIO_free(mem);
     if(!strict)
@@ -3874,7 +3930,7 @@ static CURLcode servercert(struct Curl_easy *data,
   BIO_free(mem);
 
   if(SSL_CONN_CONFIG(verifyhost)) {
-    result = verifyhost(data, conn, backend->server_cert);
+    result = Curl_ossl_verifyhost(data, conn, backend->server_cert);
     if(result) {
       X509_free(backend->server_cert);
       backend->server_cert = NULL;
@@ -4354,13 +4410,7 @@ static ssize_t ossl_recv(struct Curl_easy *data,   /* transfer */
 static size_t ossl_version(char *buffer, size_t size)
 {
 #ifdef LIBRESSL_VERSION_NUMBER
-#if LIBRESSL_VERSION_NUMBER < 0x2070100fL
-  return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
-                   OSSL_PACKAGE,
-                   (LIBRESSL_VERSION_NUMBER>>28)&0xf,
-                   (LIBRESSL_VERSION_NUMBER>>20)&0xff,
-                   (LIBRESSL_VERSION_NUMBER>>12)&0xff);
-#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */
+#ifdef HAVE_OPENSSL_VERSION
   char *p;
   int count;
   const char *ver = OpenSSL_version(OPENSSL_VERSION);
@@ -4374,6 +4424,12 @@ static size_t ossl_version(char *buffer, size_t size)
       *p = '_';
   }
   return count;
+#else
+  return msnprintf(buffer, size, "%s/%lx.%lx.%lx",
+                   OSSL_PACKAGE,
+                   (LIBRESSL_VERSION_NUMBER>>28)&0xf,
+                   (LIBRESSL_VERSION_NUMBER>>20)&0xff,
+                   (LIBRESSL_VERSION_NUMBER>>12)&0xff);
 #endif
 #elif defined(OPENSSL_IS_BORINGSSL)
   return msnprintf(buffer, size, OSSL_PACKAGE);
diff --git a/libs/libcurl/src/vtls/openssl.h b/libs/libcurl/src/vtls/openssl.h
index 2f6e1b2db8..28058453c0 100644
--- a/libs/libcurl/src/vtls/openssl.h
+++ b/libs/libcurl/src/vtls/openssl.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -26,11 +26,15 @@
 
 #ifdef USE_OPENSSL
 /*
- * This header should only be needed to get included by vtls.c and openssl.c
+ * This header should only be needed to get included by vtls.c, openssl.c
+ * and ngtcp2.c
  */
 
+#include 
 #include "urldata.h"
 
+CURLcode Curl_ossl_verifyhost(struct Curl_easy *data, struct connectdata *conn,
+                              X509 *server_cert);
 extern const struct Curl_ssl Curl_ssl_openssl;
 
 #endif /* USE_OPENSSL */
diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c
index 2ac97ce28e..6dbb1ef3cd 100644
--- a/libs/libcurl/src/vtls/rustls.c
+++ b/libs/libcurl/src/vtls/rustls.c
@@ -27,7 +27,7 @@
 #include "curl_printf.h"
 
 #include 
-#include 
+#include 
 
 #include "inet_pton.h"
 #include "urldata.h"
@@ -138,11 +138,6 @@ cr_recv(struct Curl_easy *data, int sockindex,
     *err = CURLE_READ_ERROR;
     return -1;
   }
-  else if(tls_bytes_read == 0) {
-    failf(data, "connection closed without TLS close_notify alert");
-    *err = CURLE_READ_ERROR;
-    return -1;
-  }
 
   infof(data, "cr_recv read %ld bytes from the network", tls_bytes_read);
 
@@ -161,22 +156,21 @@ cr_recv(struct Curl_easy *data, int sockindex,
       (uint8_t *)plainbuf + plain_bytes_copied,
       plainlen - plain_bytes_copied,
       &n);
-    if(rresult == RUSTLS_RESULT_ALERT_CLOSE_NOTIFY) {
-      *err = CURLE_OK;
-      return 0;
+    if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
+      infof(data, "cr_recv got PLAINTEXT_EMPTY. will try again later.");
+      backend->data_pending = FALSE;
+      break;
     }
     else if(rresult != RUSTLS_RESULT_OK) {
-      failf(data, "error in rustls_connection_read");
+      /* n always equals 0 in this case, don't need to check it */
+      failf(data, "error in rustls_connection_read: %d", rresult);
       *err = CURLE_READ_ERROR;
       return -1;
     }
     else if(n == 0) {
-      /* rustls returns 0 from connection_read to mean "all currently
-        available data has been read." If we bring in more ciphertext with
-        read_tls, more plaintext will become available. So don't tell curl
-        this is an EOF. Instead, say "come back later." */
-      infof(data, "cr_recv got 0 bytes of plaintext");
-      backend->data_pending = FALSE;
+      /* n == 0 indicates clean EOF, but we may have read some other
+         plaintext bytes before we reached this. Break out of the loop
+         so we can figure out whether to return success or EOF. */
       break;
     }
     else {
@@ -185,15 +179,23 @@ cr_recv(struct Curl_easy *data, int sockindex,
     }
   }
 
-  /* If we wrote out 0 plaintext bytes, it might just mean we haven't yet
-     read a full TLS record. Return CURLE_AGAIN so curl doesn't treat this
-     as EOF. */
-  if(plain_bytes_copied == 0) {
+  if(plain_bytes_copied) {
+    *err = CURLE_OK;
+    return plain_bytes_copied;
+  }
+
+  /* If we wrote out 0 plaintext bytes, that means either we hit a clean EOF,
+     OR we got a RUSTLS_RESULT_PLAINTEXT_EMPTY.
+     If the latter, return CURLE_AGAIN so curl doesn't treat this as EOF. */
+  if(!backend->data_pending) {
     *err = CURLE_AGAIN;
     return -1;
   }
 
-  return plain_bytes_copied;
+  /* Zero bytes read, and no RUSTLS_RESULT_PLAINTEXT_EMPTY, means the TCP
+     connection was cleanly closed (with a close_notify alert). */
+  *err = CURLE_OK;
+  return 0;
 }
 
 /*
@@ -309,10 +311,10 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn,
   config_builder = rustls_client_config_builder_new();
 #ifdef USE_HTTP2
   infof(data, "offering ALPN for HTTP/1.1 and HTTP/2");
-  rustls_client_config_builder_set_protocols(config_builder, alpn, 2);
+  rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 2);
 #else
   infof(data, "offering ALPN for HTTP/1.1 only");
-  rustls_client_config_builder_set_protocols(config_builder, alpn, 1);
+  rustls_client_config_builder_set_alpn_protocols(config_builder, alpn, 1);
 #endif
   if(!verifypeer) {
     rustls_client_config_builder_dangerous_set_certificate_verifier(
@@ -358,7 +360,7 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn,
   size_t len = 0;
 
   rustls_connection_get_alpn_protocol(rconn, &protocol, &len);
-  if(NULL == protocol) {
+  if(!protocol) {
     infof(data, "ALPN, server did not agree to a protocol");
     return;
   }
@@ -414,9 +416,6 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn,
     /*
     * Connection has been established according to rustls. Set send/recv
     * handlers, and update the state machine.
-    * This check has to come last because is_handshaking starts out false,
-    * then becomes true when we first write data, then becomes false again
-    * once the handshake is done.
     */
     if(!rustls_connection_is_handshaking(rconn)) {
       infof(data, "Done handshaking");
@@ -543,6 +542,12 @@ cr_close(struct Curl_easy *data, struct connectdata *conn,
   }
 }
 
+static size_t cr_version(char *buffer, size_t size)
+{
+  struct rustls_str ver = rustls_version();
+  return msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data);
+}
+
 const struct Curl_ssl Curl_ssl_rustls = {
   { CURLSSLBACKEND_RUSTLS, "rustls" },
   SSLSUPP_TLS13_CIPHERSUITES,      /* supports */
@@ -550,7 +555,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
 
   Curl_none_init,                  /* init */
   Curl_none_cleanup,               /* cleanup */
-  rustls_version,                  /* version */
+  cr_version,                      /* version */
   Curl_none_check_cxn,             /* check_cxn */
   Curl_none_shutdown,              /* shutdown */
   cr_data_pending,                 /* data_pending */
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 44c59e7796..0a8e60610d 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -147,8 +147,6 @@
 #define ALG_CLASS_DHASH ALG_CLASS_HASH
 #endif
 
-#define BACKEND connssl->backend
-
 static Curl_recv schannel_recv;
 static Curl_send schannel_send;
 
@@ -423,6 +421,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
   PCCERT_CONTEXT client_certs[1] = { NULL };
   SECURITY_STATUS sspi_status = SEC_E_OK;
   CURLcode result;
+  struct ssl_backend_data *backend = connssl->backend;
 
   /* setup Schannel API options */
   memset(&schannel_cred, 0, sizeof(schannel_cred));
@@ -430,7 +429,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
 
   if(conn->ssl_config.verifypeer) {
 #ifdef HAS_MANUAL_VERIFY_API
-    if(BACKEND->use_manual_cred_validation)
+    if(backend->use_manual_cred_validation)
       schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
     else
 #endif
@@ -503,7 +502,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
 
   if(SSL_CONN_CONFIG(cipher_list)) {
     result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list),
-                             BACKEND->algIds);
+                             backend->algIds);
     if(CURLE_OK != result) {
       failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG");
       return result;
@@ -600,7 +599,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
       datablob.pbData = (BYTE*)certdata;
       datablob.cbData = (DWORD)certsize;
 
-      if(data->set.ssl.key_passwd != NULL)
+      if(data->set.ssl.key_passwd)
         pwd_len = strlen(data->set.ssl.key_passwd);
       pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
       if(pszPassword) {
@@ -704,9 +703,9 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
 #endif
 
   /* allocate memory for the re-usable credential handle */
-  BACKEND->cred = (struct Curl_schannel_cred *)
+  backend->cred = (struct Curl_schannel_cred *)
     calloc(1, sizeof(struct Curl_schannel_cred));
-  if(!BACKEND->cred) {
+  if(!backend->cred) {
     failf(data, "schannel: unable to allocate memory");
 
     if(client_certs[0])
@@ -714,14 +713,14 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
 
     return CURLE_OUT_OF_MEMORY;
   }
-  BACKEND->cred->refcount = 1;
+  backend->cred->refcount = 1;
 
   sspi_status =
     s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
                                        SECPKG_CRED_OUTBOUND, NULL,
                                        &schannel_cred, NULL, NULL,
-                                       &BACKEND->cred->cred_handle,
-                                       &BACKEND->cred->time_stamp);
+                                       &backend->cred->cred_handle,
+                                       &backend->cred->time_stamp);
 
   if(client_certs[0])
     CertFreeCertificateContext(client_certs[0]);
@@ -730,7 +729,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data,
     char buffer[STRERROR_LEN];
     failf(data, "schannel: AcquireCredentialsHandle failed: %s",
           Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
-    Curl_safefree(BACKEND->cred);
+    Curl_safefree(backend->cred);
     switch(sspi_status) {
     case SEC_E_INSUFFICIENT_MEMORY:
       return CURLE_OUT_OF_MEMORY;
@@ -769,12 +768,13 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
   TCHAR *host_name;
   CURLcode result;
   char * const hostname = SSL_HOST_NAME();
+  struct ssl_backend_data *backend = connssl->backend;
 
   DEBUGF(infof(data,
                "schannel: SSL/TLS connection with %s port %hu (step 1/3)",
                hostname, conn->remote_port));
 
-  if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT,
+  if(curlx_verify_windows_version(5, 1, 0, PLATFORM_WINNT,
                                   VERSION_LESS_THAN_EQUAL)) {
     /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
        algorithms that may not be supported by all servers. */
@@ -785,29 +785,29 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
 #ifdef HAS_ALPN
   /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
      Also it doesn't seem to be supported for Wine, see curl bug #983. */
-  BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
+  backend->use_alpn = conn->bits.tls_enable_alpn &&
     !GetProcAddress(GetModuleHandle(TEXT("ntdll")),
                     "wine_get_version") &&
-    curlx_verify_windows_version(6, 3, PLATFORM_WINNT,
+    curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
                                  VERSION_GREATER_THAN_EQUAL);
 #else
-  BACKEND->use_alpn = false;
+  backend->use_alpn = false;
 #endif
 
 #ifdef _WIN32_WCE
 #ifdef HAS_MANUAL_VERIFY_API
   /* certificate validation on CE doesn't seem to work right; we'll
    * do it following a more manual process. */
-  BACKEND->use_manual_cred_validation = true;
+  backend->use_manual_cred_validation = true;
 #else
 #error "compiler too old to support requisite manual cert verify for Win CE"
 #endif
 #else
 #ifdef HAS_MANUAL_VERIFY_API
   if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
-    if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT,
+    if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
                                     VERSION_GREATER_THAN_EQUAL)) {
-      BACKEND->use_manual_cred_validation = true;
+      backend->use_manual_cred_validation = true;
     }
     else {
       failf(data, "schannel: this version of Windows is too old to support "
@@ -816,7 +816,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
     }
   }
   else
-    BACKEND->use_manual_cred_validation = false;
+    backend->use_manual_cred_validation = false;
 #else
   if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) {
     failf(data, "schannel: CA cert support not built in");
@@ -825,7 +825,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
 #endif
 #endif
 
-  BACKEND->cred = NULL;
+  backend->cred = NULL;
 
   /* check for an existing re-usable credential handle */
   if(SSL_SET_OPTION(primary.sessionid)) {
@@ -833,19 +833,19 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
     if(!Curl_ssl_getsessionid(data, conn,
                               SSL_IS_PROXY() ? TRUE : FALSE,
                               (void **)&old_cred, NULL, sockindex)) {
-      BACKEND->cred = old_cred;
+      backend->cred = old_cred;
       DEBUGF(infof(data, "schannel: re-using existing credential handle"));
 
       /* increment the reference counter of the credential/session handle */
-      BACKEND->cred->refcount++;
+      backend->cred->refcount++;
       DEBUGF(infof(data,
                    "schannel: incremented credential handle refcount = %d",
-                   BACKEND->cred->refcount));
+                   backend->cred->refcount));
     }
     Curl_ssl_sessionid_unlock(data);
   }
 
-  if(!BACKEND->cred) {
+  if(!backend->cred) {
     result = schannel_acquire_credential_handle(data, conn, sockindex);
     if(result != CURLE_OK) {
       return result;
@@ -862,7 +862,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
   }
 
 #ifdef HAS_ALPN
-  if(BACKEND->use_alpn) {
+  if(backend->use_alpn) {
     int cur = 0;
     int list_start_index = 0;
     unsigned int *extension_len = NULL;
@@ -920,18 +920,18 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
   InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
 
   /* security request flags */
-  BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+  backend->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
     ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
     ISC_REQ_STREAM;
 
   if(!SSL_SET_OPTION(auto_client_cert)) {
-    BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+    backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
   }
 
   /* allocate memory for the security context handle */
-  BACKEND->ctxt = (struct Curl_schannel_ctxt *)
+  backend->ctxt = (struct Curl_schannel_ctxt *)
     calloc(1, sizeof(struct Curl_schannel_ctxt));
-  if(!BACKEND->ctxt) {
+  if(!backend->ctxt) {
     failf(data, "schannel: unable to allocate memory");
     return CURLE_OUT_OF_MEMORY;
   }
@@ -948,16 +948,16 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
      us problems with inbuf regardless. https://github.com/curl/curl/issues/983
   */
   sspi_status = s_pSecFn->InitializeSecurityContext(
-    &BACKEND->cred->cred_handle, NULL, host_name, BACKEND->req_flags, 0, 0,
-    (BACKEND->use_alpn ? &inbuf_desc : NULL),
-    0, &BACKEND->ctxt->ctxt_handle,
-    &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
+    &backend->cred->cred_handle, NULL, host_name, backend->req_flags, 0, 0,
+    (backend->use_alpn ? &inbuf_desc : NULL),
+    0, &backend->ctxt->ctxt_handle,
+    &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
 
   curlx_unicodefree(host_name);
 
   if(sspi_status != SEC_I_CONTINUE_NEEDED) {
     char buffer[STRERROR_LEN];
-    Curl_safefree(BACKEND->ctxt);
+    Curl_safefree(backend->ctxt);
     switch(sspi_status) {
     case SEC_E_INSUFFICIENT_MEMORY:
       failf(data, "schannel: initial InitializeSecurityContext failed: %s",
@@ -1001,10 +1001,10 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
   DEBUGF(infof(data, "schannel: sent initial handshake data: "
                "sent %zd bytes", written));
 
-  BACKEND->recv_unrecoverable_err = CURLE_OK;
-  BACKEND->recv_sspi_close_notify = false;
-  BACKEND->recv_connection_closed = false;
-  BACKEND->encdata_is_incomplete = false;
+  backend->recv_unrecoverable_err = CURLE_OK;
+  backend->recv_sspi_close_notify = false;
+  backend->recv_connection_closed = false;
+  backend->encdata_is_incomplete = false;
 
   /* continue to second handshake step */
   connssl->connecting_state = ssl_connect_2;
@@ -1029,6 +1029,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
   bool doread;
   char * const hostname = SSL_HOST_NAME();
   const char *pubkey_ptr;
+  struct ssl_backend_data *backend = connssl->backend;
 
   doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
 
@@ -1036,39 +1037,39 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
                "schannel: SSL/TLS connection with %s port %hu (step 2/3)",
                hostname, conn->remote_port));
 
-  if(!BACKEND->cred || !BACKEND->ctxt)
+  if(!backend->cred || !backend->ctxt)
     return CURLE_SSL_CONNECT_ERROR;
 
   /* buffer to store previously received and decrypted data */
-  if(!BACKEND->decdata_buffer) {
-    BACKEND->decdata_offset = 0;
-    BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
-    BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
-    if(!BACKEND->decdata_buffer) {
+  if(!backend->decdata_buffer) {
+    backend->decdata_offset = 0;
+    backend->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    backend->decdata_buffer = malloc(backend->decdata_length);
+    if(!backend->decdata_buffer) {
       failf(data, "schannel: unable to allocate memory");
       return CURLE_OUT_OF_MEMORY;
     }
   }
 
   /* buffer to store previously received and encrypted data */
-  if(!BACKEND->encdata_buffer) {
-    BACKEND->encdata_is_incomplete = false;
-    BACKEND->encdata_offset = 0;
-    BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
-    BACKEND->encdata_buffer = malloc(BACKEND->encdata_length);
-    if(!BACKEND->encdata_buffer) {
+  if(!backend->encdata_buffer) {
+    backend->encdata_is_incomplete = false;
+    backend->encdata_offset = 0;
+    backend->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    backend->encdata_buffer = malloc(backend->encdata_length);
+    if(!backend->encdata_buffer) {
       failf(data, "schannel: unable to allocate memory");
       return CURLE_OUT_OF_MEMORY;
     }
   }
 
   /* if we need a bigger buffer to read a full message, increase buffer now */
-  if(BACKEND->encdata_length - BACKEND->encdata_offset <
+  if(backend->encdata_length - backend->encdata_offset <
      CURL_SCHANNEL_BUFFER_FREE_SIZE) {
     /* increase internal encrypted data buffer */
-    size_t reallocated_length = BACKEND->encdata_offset +
+    size_t reallocated_length = backend->encdata_offset +
       CURL_SCHANNEL_BUFFER_FREE_SIZE;
-    reallocated_buffer = realloc(BACKEND->encdata_buffer,
+    reallocated_buffer = realloc(backend->encdata_buffer,
                                  reallocated_length);
 
     if(!reallocated_buffer) {
@@ -1076,8 +1077,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
       return CURLE_OUT_OF_MEMORY;
     }
     else {
-      BACKEND->encdata_buffer = reallocated_buffer;
-      BACKEND->encdata_length = reallocated_length;
+      backend->encdata_buffer = reallocated_buffer;
+      backend->encdata_length = reallocated_length;
     }
   }
 
@@ -1086,10 +1087,10 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
     if(doread) {
       /* read encrypted handshake data from socket */
       result = Curl_read_plain(conn->sock[sockindex],
-                               (char *) (BACKEND->encdata_buffer +
-                                         BACKEND->encdata_offset),
-                               BACKEND->encdata_length -
-                               BACKEND->encdata_offset,
+                               (char *) (backend->encdata_buffer +
+                                         backend->encdata_offset),
+                               backend->encdata_length -
+                               backend->encdata_offset,
                                &nread);
       if(result == CURLE_AGAIN) {
         if(connssl->connecting_state != ssl_connect_2_writing)
@@ -1105,18 +1106,18 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
       }
 
       /* increase encrypted data buffer offset */
-      BACKEND->encdata_offset += nread;
-      BACKEND->encdata_is_incomplete = false;
+      backend->encdata_offset += nread;
+      backend->encdata_is_incomplete = false;
       DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
     }
 
     DEBUGF(infof(data,
                  "schannel: encrypted data buffer: offset %zu length %zu",
-                 BACKEND->encdata_offset, BACKEND->encdata_length));
+                 backend->encdata_offset, backend->encdata_length));
 
     /* setup input buffers */
-    InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
-                  curlx_uztoul(BACKEND->encdata_offset));
+    InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(backend->encdata_offset),
+                  curlx_uztoul(backend->encdata_offset));
     InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
     InitSecBufferDesc(&inbuf_desc, inbuf, 2);
 
@@ -1132,17 +1133,17 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
     }
 
     /* copy received handshake data into input buffer */
-    memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
-           BACKEND->encdata_offset);
+    memcpy(inbuf[0].pvBuffer, backend->encdata_buffer,
+           backend->encdata_offset);
 
     host_name = curlx_convert_UTF8_to_tchar(hostname);
     if(!host_name)
       return CURLE_OUT_OF_MEMORY;
 
     sspi_status = s_pSecFn->InitializeSecurityContext(
-      &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
-      host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
-      &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
+      &backend->cred->cred_handle, &backend->ctxt->ctxt_handle,
+      host_name, backend->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+      &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
 
     curlx_unicodefree(host_name);
 
@@ -1151,7 +1152,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
 
     /* check if the handshake was incomplete */
     if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
-      BACKEND->encdata_is_incomplete = true;
+      backend->encdata_is_incomplete = true;
       connssl->connecting_state = ssl_connect_2_reading;
       DEBUGF(infof(data,
                    "schannel: received incomplete message, need more data"));
@@ -1162,8 +1163,8 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
        the handshake without one. This will allow connections to servers which
        request a client certificate but do not require it. */
     if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
-       !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
-      BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+       !(backend->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+      backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
       connssl->connecting_state = ssl_connect_2_writing;
       DEBUGF(infof(data,
                    "schannel: a client certificate has been requested"));
@@ -1191,7 +1192,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
         }
 
         /* free obsolete buffer */
-        if(outbuf[i].pvBuffer != NULL) {
+        if(outbuf[i].pvBuffer) {
           s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
         }
       }
@@ -1245,11 +1246,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
       */
       /* check if the remaining data is less than the total amount
          and therefore begins after the already processed data */
-      if(BACKEND->encdata_offset > inbuf[1].cbBuffer) {
-        memmove(BACKEND->encdata_buffer,
-                (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+      if(backend->encdata_offset > inbuf[1].cbBuffer) {
+        memmove(backend->encdata_buffer,
+                (backend->encdata_buffer + backend->encdata_offset) -
                 inbuf[1].cbBuffer, inbuf[1].cbBuffer);
-        BACKEND->encdata_offset = inbuf[1].cbBuffer;
+        backend->encdata_offset = inbuf[1].cbBuffer;
         if(sspi_status == SEC_I_CONTINUE_NEEDED) {
           doread = FALSE;
           continue;
@@ -1257,7 +1258,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
       }
     }
     else {
-      BACKEND->encdata_offset = 0;
+      backend->encdata_offset = 0;
     }
     break;
   }
@@ -1284,7 +1285,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn,
   }
 
 #ifdef HAS_MANUAL_VERIFY_API
-  if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) {
+  if(conn->ssl_config.verifypeer && backend->use_manual_cred_validation) {
     return Curl_verify_certificate(data, conn, sockindex);
   }
 #endif
@@ -1366,6 +1367,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
 #ifdef HAS_ALPN
   SecPkgContext_ApplicationProtocol alpn_result;
 #endif
+  struct ssl_backend_data *backend = connssl->backend;
 
   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
 
@@ -1373,28 +1375,28 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
                "schannel: SSL/TLS connection with %s port %hu (step 3/3)",
                hostname, conn->remote_port));
 
-  if(!BACKEND->cred)
+  if(!backend->cred)
     return CURLE_SSL_CONNECT_ERROR;
 
   /* check if the required context attributes are met */
-  if(BACKEND->ret_flags != BACKEND->req_flags) {
-    if(!(BACKEND->ret_flags & ISC_RET_SEQUENCE_DETECT))
+  if(backend->ret_flags != backend->req_flags) {
+    if(!(backend->ret_flags & ISC_RET_SEQUENCE_DETECT))
       failf(data, "schannel: failed to setup sequence detection");
-    if(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT))
+    if(!(backend->ret_flags & ISC_RET_REPLAY_DETECT))
       failf(data, "schannel: failed to setup replay detection");
-    if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY))
+    if(!(backend->ret_flags & ISC_RET_CONFIDENTIALITY))
       failf(data, "schannel: failed to setup confidentiality");
-    if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+    if(!(backend->ret_flags & ISC_RET_ALLOCATED_MEMORY))
       failf(data, "schannel: failed to setup memory allocation");
-    if(!(BACKEND->ret_flags & ISC_RET_STREAM))
+    if(!(backend->ret_flags & ISC_RET_STREAM))
       failf(data, "schannel: failed to setup stream orientation");
     return CURLE_SSL_CONNECT_ERROR;
   }
 
 #ifdef HAS_ALPN
-  if(BACKEND->use_alpn) {
+  if(backend->use_alpn) {
     sspi_status =
-      s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+      s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
                                        SECPKG_ATTR_APPLICATION_PROTOCOL,
                                        &alpn_result);
 
@@ -1439,7 +1441,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
     incache = !(Curl_ssl_getsessionid(data, conn, isproxy, (void **)&old_cred,
                                       NULL, sockindex));
     if(incache) {
-      if(old_cred != BACKEND->cred) {
+      if(old_cred != backend->cred) {
         DEBUGF(infof(data,
                      "schannel: old credential handle is stale, removing"));
         /* we're not taking old_cred ownership here, no refcount++ is needed */
@@ -1448,7 +1450,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
       }
     }
     if(!incache) {
-      result = Curl_ssl_addsessionid(data, conn, isproxy, BACKEND->cred,
+      result = Curl_ssl_addsessionid(data, conn, isproxy, backend->cred,
                                      sizeof(struct Curl_schannel_cred),
                                      sockindex, &added);
       if(result) {
@@ -1458,7 +1460,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
       }
       else if(added) {
         /* this cred session is now also referenced by sessionid cache */
-        BACKEND->cred->refcount++;
+        backend->cred->refcount++;
         DEBUGF(infof(data,
                      "schannel: stored credential handle in session cache"));
       }
@@ -1469,7 +1471,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn,
   if(data->set.ssl.certinfo) {
     int certs_count = 0;
     sspi_status =
-      s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+      s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
                                        SECPKG_ATTR_REMOTE_CERT_CONTEXT,
                                        &ccert_context);
 
@@ -1606,7 +1608,10 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn,
      * binding to pass the IIS extended protection checks.
      * Available on Windows 7 or later.
      */
-    conn->sslContext = &BACKEND->ctxt->ctxt_handle;
+    {
+      struct ssl_backend_data *backend = connssl->backend;
+      conn->sslContext = &backend->ctxt->ctxt_handle;
+    }
 #endif
 
     *done = TRUE;
@@ -1633,13 +1638,14 @@ schannel_send(struct Curl_easy *data, int sockindex,
   SecBufferDesc outbuf_desc;
   SECURITY_STATUS sspi_status = SEC_E_OK;
   CURLcode result;
+  struct ssl_backend_data *backend = connssl->backend;
 
   /* check if the maximum stream sizes were queried */
-  if(BACKEND->stream_sizes.cbMaximumMessage == 0) {
+  if(backend->stream_sizes.cbMaximumMessage == 0) {
     sspi_status = s_pSecFn->QueryContextAttributes(
-      &BACKEND->ctxt->ctxt_handle,
+      &backend->ctxt->ctxt_handle,
       SECPKG_ATTR_STREAM_SIZES,
-      &BACKEND->stream_sizes);
+      &backend->stream_sizes);
     if(sspi_status != SEC_E_OK) {
       *err = CURLE_SEND_ERROR;
       return -1;
@@ -1647,13 +1653,13 @@ schannel_send(struct Curl_easy *data, int sockindex,
   }
 
   /* check if the buffer is longer than the maximum message length */
-  if(len > BACKEND->stream_sizes.cbMaximumMessage) {
-    len = BACKEND->stream_sizes.cbMaximumMessage;
+  if(len > backend->stream_sizes.cbMaximumMessage) {
+    len = backend->stream_sizes.cbMaximumMessage;
   }
 
   /* calculate the complete message length and allocate a buffer for it */
-  data_len = BACKEND->stream_sizes.cbHeader + len +
-    BACKEND->stream_sizes.cbTrailer;
+  data_len = backend->stream_sizes.cbHeader + len +
+    backend->stream_sizes.cbTrailer;
   ptr = (unsigned char *) malloc(data_len);
   if(!ptr) {
     *err = CURLE_OUT_OF_MEMORY;
@@ -1662,12 +1668,12 @@ schannel_send(struct Curl_easy *data, int sockindex,
 
   /* setup output buffers (header, data, trailer, empty) */
   InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
-                ptr, BACKEND->stream_sizes.cbHeader);
+                ptr, backend->stream_sizes.cbHeader);
   InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
-                ptr + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
+                ptr + backend->stream_sizes.cbHeader, curlx_uztoul(len));
   InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
-                ptr + BACKEND->stream_sizes.cbHeader + len,
-                BACKEND->stream_sizes.cbTrailer);
+                ptr + backend->stream_sizes.cbHeader + len,
+                backend->stream_sizes.cbTrailer);
   InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
   InitSecBufferDesc(&outbuf_desc, outbuf, 4);
 
@@ -1675,7 +1681,7 @@ schannel_send(struct Curl_easy *data, int sockindex,
   memcpy(outbuf[1].pvBuffer, buf, len);
 
   /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
-  sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0,
+  sspi_status = s_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0,
                                          &outbuf_desc, 0);
 
   /* check if the message was encrypted */
@@ -1780,9 +1786,10 @@ schannel_recv(struct Curl_easy *data, int sockindex,
   /* we want the length of the encrypted buffer to be at least large enough
      that it can hold all the bytes requested and some TLS record overhead. */
   size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+  struct ssl_backend_data *backend = connssl->backend;
 
   /****************************************************************************
-   * Don't return or set BACKEND->recv_unrecoverable_err unless in the cleanup.
+   * Don't return or set backend->recv_unrecoverable_err unless in the cleanup.
    * The pattern for return error is set *err, optional infof, goto cleanup.
    *
    * Our priority is to always return as much decrypted data to the caller as
@@ -1794,16 +1801,16 @@ schannel_recv(struct Curl_easy *data, int sockindex,
   DEBUGF(infof(data, "schannel: client wants to read %zu bytes", len));
   *err = CURLE_OK;
 
-  if(len && len <= BACKEND->decdata_offset) {
+  if(len && len <= backend->decdata_offset) {
     infof(data, "schannel: enough decrypted data is already available");
     goto cleanup;
   }
-  else if(BACKEND->recv_unrecoverable_err) {
-    *err = BACKEND->recv_unrecoverable_err;
+  else if(backend->recv_unrecoverable_err) {
+    *err = backend->recv_unrecoverable_err;
     infof(data, "schannel: an unrecoverable error occurred in a prior call");
     goto cleanup;
   }
-  else if(BACKEND->recv_sspi_close_notify) {
+  else if(backend->recv_sspi_close_notify) {
     /* once a server has indicated shutdown there is no more encrypted data */
     infof(data, "schannel: server indicated shutdown in a prior call");
     goto cleanup;
@@ -1813,17 +1820,17 @@ schannel_recv(struct Curl_easy *data, int sockindex,
      immediately because there may be data to decrypt (in the case we want to
      decrypt all encrypted cached data) so handle !len later in cleanup.
   */
-  else if(len && !BACKEND->recv_connection_closed) {
+  else if(len && !backend->recv_connection_closed) {
     /* increase enc buffer in order to fit the requested amount of data */
-    size = BACKEND->encdata_length - BACKEND->encdata_offset;
+    size = backend->encdata_length - backend->encdata_offset;
     if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
-       BACKEND->encdata_length < min_encdata_length) {
-      reallocated_length = BACKEND->encdata_offset +
+       backend->encdata_length < min_encdata_length) {
+      reallocated_length = backend->encdata_offset +
         CURL_SCHANNEL_BUFFER_FREE_SIZE;
       if(reallocated_length < min_encdata_length) {
         reallocated_length = min_encdata_length;
       }
-      reallocated_buffer = realloc(BACKEND->encdata_buffer,
+      reallocated_buffer = realloc(backend->encdata_buffer,
                                    reallocated_length);
       if(!reallocated_buffer) {
         *err = CURLE_OUT_OF_MEMORY;
@@ -1831,21 +1838,21 @@ schannel_recv(struct Curl_easy *data, int sockindex,
         goto cleanup;
       }
 
-      BACKEND->encdata_buffer = reallocated_buffer;
-      BACKEND->encdata_length = reallocated_length;
-      size = BACKEND->encdata_length - BACKEND->encdata_offset;
+      backend->encdata_buffer = reallocated_buffer;
+      backend->encdata_length = reallocated_length;
+      size = backend->encdata_length - backend->encdata_offset;
       DEBUGF(infof(data, "schannel: encdata_buffer resized %zu",
-                   BACKEND->encdata_length));
+                   backend->encdata_length));
     }
 
     DEBUGF(infof(data,
                  "schannel: encrypted data buffer: offset %zu length %zu",
-                 BACKEND->encdata_offset, BACKEND->encdata_length));
+                 backend->encdata_offset, backend->encdata_length));
 
     /* read encrypted data from socket */
     *err = Curl_read_plain(conn->sock[sockindex],
-                           (char *)(BACKEND->encdata_buffer +
-                                    BACKEND->encdata_offset),
+                           (char *)(backend->encdata_buffer +
+                                    backend->encdata_offset),
                            size, &nread);
     if(*err) {
       nread = -1;
@@ -1858,27 +1865,27 @@ schannel_recv(struct Curl_easy *data, int sockindex,
         infof(data, "schannel: Curl_read_plain returned error %d", *err);
     }
     else if(nread == 0) {
-      BACKEND->recv_connection_closed = true;
+      backend->recv_connection_closed = true;
       DEBUGF(infof(data, "schannel: server closed the connection"));
     }
     else if(nread > 0) {
-      BACKEND->encdata_offset += (size_t)nread;
-      BACKEND->encdata_is_incomplete = false;
+      backend->encdata_offset += (size_t)nread;
+      backend->encdata_is_incomplete = false;
       DEBUGF(infof(data, "schannel: encrypted data got %zd", nread));
     }
   }
 
   DEBUGF(infof(data,
                "schannel: encrypted data buffer: offset %zu length %zu",
-               BACKEND->encdata_offset, BACKEND->encdata_length));
+               backend->encdata_offset, backend->encdata_length));
 
   /* decrypt loop */
-  while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
-        (!len || BACKEND->decdata_offset < len ||
-         BACKEND->recv_connection_closed)) {
+  while(backend->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+        (!len || backend->decdata_offset < len ||
+         backend->recv_connection_closed)) {
     /* prepare data buffer for DecryptMessage call */
-    InitSecBuffer(&inbuf[0], SECBUFFER_DATA, BACKEND->encdata_buffer,
-                  curlx_uztoul(BACKEND->encdata_offset));
+    InitSecBuffer(&inbuf[0], SECBUFFER_DATA, backend->encdata_buffer,
+                  curlx_uztoul(backend->encdata_offset));
 
     /* we need 3 more empty input buffers for possible output */
     InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
@@ -1888,7 +1895,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
 
     /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
      */
-    sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
+    sspi_status = s_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle,
                                            &inbuf_desc, 0, NULL);
 
     /* check if everything went fine (server may want to renegotiate
@@ -1904,37 +1911,37 @@ schannel_recv(struct Curl_easy *data, int sockindex,
         /* increase buffer in order to fit the received amount of data */
         size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
           inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
-        if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
-           BACKEND->decdata_length < len) {
+        if(backend->decdata_length - backend->decdata_offset < size ||
+           backend->decdata_length < len) {
           /* increase internal decrypted data buffer */
-          reallocated_length = BACKEND->decdata_offset + size;
+          reallocated_length = backend->decdata_offset + size;
           /* make sure that the requested amount of data fits */
           if(reallocated_length < len) {
             reallocated_length = len;
           }
-          reallocated_buffer = realloc(BACKEND->decdata_buffer,
+          reallocated_buffer = realloc(backend->decdata_buffer,
                                        reallocated_length);
           if(!reallocated_buffer) {
             *err = CURLE_OUT_OF_MEMORY;
             failf(data, "schannel: unable to re-allocate memory");
             goto cleanup;
           }
-          BACKEND->decdata_buffer = reallocated_buffer;
-          BACKEND->decdata_length = reallocated_length;
+          backend->decdata_buffer = reallocated_buffer;
+          backend->decdata_length = reallocated_length;
         }
 
         /* copy decrypted data to internal buffer */
         size = inbuf[1].cbBuffer;
         if(size) {
-          memcpy(BACKEND->decdata_buffer + BACKEND->decdata_offset,
+          memcpy(backend->decdata_buffer + backend->decdata_offset,
                  inbuf[1].pvBuffer, size);
-          BACKEND->decdata_offset += size;
+          backend->decdata_offset += size;
         }
 
         DEBUGF(infof(data, "schannel: decrypted data added: %zu", size));
         DEBUGF(infof(data,
                      "schannel: decrypted cached: offset %zu length %zu",
-                     BACKEND->decdata_offset, BACKEND->decdata_length));
+                     backend->decdata_offset, backend->decdata_length));
       }
 
       /* check for remaining encrypted data */
@@ -1945,22 +1952,22 @@ schannel_recv(struct Curl_easy *data, int sockindex,
         /* check if the remaining data is less than the total amount
          * and therefore begins after the already processed data
          */
-        if(BACKEND->encdata_offset > inbuf[3].cbBuffer) {
+        if(backend->encdata_offset > inbuf[3].cbBuffer) {
           /* move remaining encrypted data forward to the beginning of
              buffer */
-          memmove(BACKEND->encdata_buffer,
-                  (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+          memmove(backend->encdata_buffer,
+                  (backend->encdata_buffer + backend->encdata_offset) -
                   inbuf[3].cbBuffer, inbuf[3].cbBuffer);
-          BACKEND->encdata_offset = inbuf[3].cbBuffer;
+          backend->encdata_offset = inbuf[3].cbBuffer;
         }
 
         DEBUGF(infof(data,
                      "schannel: encrypted cached: offset %zu length %zu",
-                     BACKEND->encdata_offset, BACKEND->encdata_length));
+                     backend->encdata_offset, backend->encdata_length));
       }
       else {
         /* reset encrypted buffer offset, because there is no data remaining */
-        BACKEND->encdata_offset = 0;
+        backend->encdata_offset = 0;
       }
 
       /* check if server wants to renegotiate the connection context */
@@ -1970,7 +1977,7 @@ schannel_recv(struct Curl_easy *data, int sockindex,
           infof(data, "schannel: can't renegotiate, an error is pending");
           goto cleanup;
         }
-        if(BACKEND->encdata_offset) {
+        if(backend->encdata_offset) {
           *err = CURLE_RECV_ERROR;
           infof(data, "schannel: can't renegotiate, "
                 "encrypted data available");
@@ -1994,16 +2001,16 @@ schannel_recv(struct Curl_easy *data, int sockindex,
       else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
         /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
            returned so we have to work around that in cleanup. */
-        BACKEND->recv_sspi_close_notify = true;
-        if(!BACKEND->recv_connection_closed) {
-          BACKEND->recv_connection_closed = true;
+        backend->recv_sspi_close_notify = true;
+        if(!backend->recv_connection_closed) {
+          backend->recv_connection_closed = true;
           infof(data, "schannel: server closed the connection");
         }
         goto cleanup;
       }
     }
     else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
-      BACKEND->encdata_is_incomplete = true;
+      backend->encdata_is_incomplete = true;
       if(!*err)
         *err = CURLE_AGAIN;
       infof(data, "schannel: failed to decrypt data, need more data");
@@ -2022,11 +2029,11 @@ schannel_recv(struct Curl_easy *data, int sockindex,
 
   DEBUGF(infof(data,
                "schannel: encrypted data buffer: offset %zu length %zu",
-               BACKEND->encdata_offset, BACKEND->encdata_length));
+               backend->encdata_offset, backend->encdata_length));
 
   DEBUGF(infof(data,
                "schannel: decrypted data buffer: offset %zu length %zu",
-               BACKEND->decdata_offset, BACKEND->decdata_length));
+               backend->decdata_offset, backend->decdata_length));
 
   cleanup:
   /* Warning- there is no guarantee the encdata state is valid at this point */
@@ -2043,13 +2050,13 @@ schannel_recv(struct Curl_easy *data, int sockindex,
      assume it was graceful (close_notify) since there doesn't seem to be a
      way to tell.
   */
-  if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
-     !BACKEND->recv_sspi_close_notify) {
-    bool isWin2k = curlx_verify_windows_version(5, 0, PLATFORM_WINNT,
+  if(len && !backend->decdata_offset && backend->recv_connection_closed &&
+     !backend->recv_sspi_close_notify) {
+    bool isWin2k = curlx_verify_windows_version(5, 0, 0, PLATFORM_WINNT,
                                                 VERSION_EQUAL);
 
     if(isWin2k && sspi_status == SEC_E_OK)
-      BACKEND->recv_sspi_close_notify = true;
+      backend->recv_sspi_close_notify = true;
     else {
       *err = CURLE_RECV_ERROR;
       infof(data, "schannel: server closed abruptly (missing close_notify)");
@@ -2058,23 +2065,23 @@ schannel_recv(struct Curl_easy *data, int sockindex,
 
   /* Any error other than CURLE_AGAIN is an unrecoverable error. */
   if(*err && *err != CURLE_AGAIN)
-    BACKEND->recv_unrecoverable_err = *err;
+    backend->recv_unrecoverable_err = *err;
 
-  size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
+  size = len < backend->decdata_offset ? len : backend->decdata_offset;
   if(size) {
-    memcpy(buf, BACKEND->decdata_buffer, size);
-    memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
-            BACKEND->decdata_offset - size);
-    BACKEND->decdata_offset -= size;
+    memcpy(buf, backend->decdata_buffer, size);
+    memmove(backend->decdata_buffer, backend->decdata_buffer + size,
+            backend->decdata_offset - size);
+    backend->decdata_offset -= size;
     DEBUGF(infof(data, "schannel: decrypted data returned %zu", size));
     DEBUGF(infof(data,
                  "schannel: decrypted data buffer: offset %zu length %zu",
-                 BACKEND->decdata_offset, BACKEND->decdata_length));
+                 backend->decdata_offset, backend->decdata_length));
     *err = CURLE_OK;
     return (ssize_t)size;
   }
 
-  if(!*err && !BACKEND->recv_connection_closed)
+  if(!*err && !backend->recv_connection_closed)
     *err = CURLE_AGAIN;
 
   /* It's debatable what to return when !len. We could return whatever error
@@ -2113,10 +2120,11 @@ static bool schannel_data_pending(const struct connectdata *conn,
                                   int sockindex)
 {
   const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
 
   if(connssl->use) /* SSL/TLS is in use */
-    return (BACKEND->decdata_offset > 0 ||
-            (BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete));
+    return (backend->decdata_offset > 0 ||
+            (backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
   else
     return FALSE;
 }
@@ -2146,6 +2154,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
    */
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
   char * const hostname = SSL_HOST_NAME();
+  struct ssl_backend_data *backend = connssl->backend;
 
   DEBUGASSERT(data);
 
@@ -2154,7 +2163,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
           hostname, conn->remote_port);
   }
 
-  if(connssl->use && BACKEND->cred && BACKEND->ctxt) {
+  if(connssl->use && backend->cred && backend->ctxt) {
     SecBufferDesc BuffDesc;
     SecBuffer Buffer;
     SECURITY_STATUS sspi_status;
@@ -2167,7 +2176,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
     InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
     InitSecBufferDesc(&BuffDesc, &Buffer, 1);
 
-    sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
+    sspi_status = s_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle,
                                               &BuffDesc);
 
     if(sspi_status != SEC_E_OK) {
@@ -2185,18 +2194,18 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
     InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
 
     sspi_status = s_pSecFn->InitializeSecurityContext(
-      &BACKEND->cred->cred_handle,
-      &BACKEND->ctxt->ctxt_handle,
+      &backend->cred->cred_handle,
+      &backend->ctxt->ctxt_handle,
       host_name,
-      BACKEND->req_flags,
+      backend->req_flags,
       0,
       0,
       NULL,
       0,
-      &BACKEND->ctxt->ctxt_handle,
+      &backend->ctxt->ctxt_handle,
       &outbuf_desc,
-      &BACKEND->ret_flags,
-      &BACKEND->ctxt->time_stamp);
+      &backend->ret_flags,
+      &backend->ctxt->time_stamp);
 
     curlx_unicodefree(host_name);
 
@@ -2215,33 +2224,33 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn,
   }
 
   /* free SSPI Schannel API security context handle */
-  if(BACKEND->ctxt) {
+  if(backend->ctxt) {
     DEBUGF(infof(data, "schannel: clear security context handle"));
-    s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
-    Curl_safefree(BACKEND->ctxt);
+    s_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle);
+    Curl_safefree(backend->ctxt);
   }
 
   /* free SSPI Schannel API credential handle */
-  if(BACKEND->cred) {
+  if(backend->cred) {
     Curl_ssl_sessionid_lock(data);
-    schannel_session_free(BACKEND->cred);
+    schannel_session_free(backend->cred);
     Curl_ssl_sessionid_unlock(data);
-    BACKEND->cred = NULL;
+    backend->cred = NULL;
   }
 
   /* free internal buffer for received encrypted data */
-  if(BACKEND->encdata_buffer != NULL) {
-    Curl_safefree(BACKEND->encdata_buffer);
-    BACKEND->encdata_length = 0;
-    BACKEND->encdata_offset = 0;
-    BACKEND->encdata_is_incomplete = false;
+  if(backend->encdata_buffer) {
+    Curl_safefree(backend->encdata_buffer);
+    backend->encdata_length = 0;
+    backend->encdata_offset = 0;
+    backend->encdata_is_incomplete = false;
   }
 
   /* free internal buffer for received decrypted data */
-  if(BACKEND->decdata_buffer != NULL) {
-    Curl_safefree(BACKEND->decdata_buffer);
-    BACKEND->decdata_length = 0;
-    BACKEND->decdata_offset = 0;
+  if(backend->decdata_buffer) {
+    Curl_safefree(backend->decdata_buffer);
+    backend->decdata_length = 0;
+    backend->decdata_offset = 0;
   }
 
   return CURLE_OK;
@@ -2299,6 +2308,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
                                     const char *pinnedpubkey)
 {
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_backend_data *backend = connssl->backend;
   CERT_CONTEXT *pCertContextServer = NULL;
 
   /* Result is returned to caller */
@@ -2316,7 +2326,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
     struct Curl_asn1Element *pubkey;
 
     sspi_status =
-      s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+      s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
                                        SECPKG_ATTR_REMOTE_CERT_CONTEXT,
                                        &pCertContextServer);
 
@@ -2422,8 +2432,9 @@ static CURLcode schannel_sha256sum(const unsigned char *input,
 static void *schannel_get_internals(struct ssl_connect_data *connssl,
                                     CURLINFO info UNUSED_PARAM)
 {
+  struct ssl_backend_data *backend = connssl->backend;
   (void)info;
-  return &BACKEND->ctxt->ctxt_handle;
+  return &backend->ctxt->ctxt_handle;
 }
 
 const struct Curl_ssl Curl_ssl_schannel = {
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index 1b283d0453..4966cd4945 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -355,7 +355,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
   DWORD i;
 
   /* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */
-  if(curlx_verify_windows_version(6, 2, PLATFORM_WINNT,
+  if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT,
                                   VERSION_GREATER_THAN_EQUAL)) {
 #ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
     /* CertGetNameString will provide the 8-bit character string without
@@ -597,7 +597,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data,
      * trusted certificates. This is only supported on Windows 7+.
      */
 
-    if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
+    if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
+                                    VERSION_LESS_THAN)) {
       failf(data, "schannel: this version of Windows is too old to support "
             "certificate verification via CA bundle file.");
       result = CURLE_SSL_CACERT_BADFILE;
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index 0bf515460d..f7a20b20b1 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -997,14 +997,14 @@ CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
 #else
 #if CURL_BUILD_MAC_10_7
   /* Lion & later: Get the long description if we can. */
-  if(SecCertificateCopyLongDescription != NULL)
+  if(SecCertificateCopyLongDescription)
     server_cert_summary =
       SecCertificateCopyLongDescription(NULL, cert, NULL);
   else
 #endif /* CURL_BUILD_MAC_10_7 */
 #if CURL_BUILD_MAC_10_6
   /* Snow Leopard: Get the certificate summary. */
-  if(SecCertificateCopySubjectSummary != NULL)
+  if(SecCertificateCopySubjectSummary)
     server_cert_summary = SecCertificateCopySubjectSummary(cert);
   else
 #endif /* CURL_BUILD_MAC_10_6 */
@@ -1118,7 +1118,7 @@ static OSStatus CopyIdentityWithLabel(char *label,
   /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
      kSecClassIdentity was introduced in Lion. If both exist, let's use them
      to find the certificate. */
-  if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+  if(SecItemCopyMatching && kSecClassIdentity) {
     CFTypeRef keys[5];
     CFTypeRef values[5];
     CFDictionaryRef query_dict;
@@ -1248,7 +1248,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
     CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
       password ? 1L : 0L, NULL, NULL);
 
-    if(options != NULL) {
+    if(options) {
       status = SecPKCS12Import(pkcs_data, options, &items);
       CFRelease(options);
     }
@@ -1406,7 +1406,7 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
   }
 
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-  if(SSLSetProtocolVersionMax != NULL) {
+  if(SSLSetProtocolVersionMax) {
     SSLProtocol darwin_ver_min = kTLSProtocol1;
     SSLProtocol darwin_ver_max = kTLSProtocol1;
     CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
@@ -1608,7 +1608,7 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
       if(tls_name) {
         table_cipher_name = ciphertable[i].name;
       }
-      else if(ciphertable[i].alias_name != NULL) {
+      else if(ciphertable[i].alias_name) {
         table_cipher_name = ciphertable[i].alias_name;
       }
       else {
@@ -1688,7 +1688,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
 #endif /* CURL_BUILD_MAC */
 
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-  if(SSLCreateContext != NULL) {  /* use the newer API if available */
+  if(SSLCreateContext) {  /* use the newer API if available */
     if(backend->ssl_ctx)
       CFRelease(backend->ssl_ctx);
     backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
@@ -1722,7 +1722,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
 
   /* check to see if we've been told to use an explicit SSL/TLS version */
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-  if(SSLSetProtocolVersionMax != NULL) {
+  if(SSLSetProtocolVersionMax) {
     switch(conn->ssl_config.version) {
     case CURL_SSLVERSION_TLSv1:
       (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
@@ -1980,9 +1980,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
   Darwin 15.x.x is El Capitan (10.11)
   */
 #if CURL_BUILD_MAC
-  if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
+  if(SSLSetSessionOption && darwinver_maj >= 13) {
 #else
-  if(SSLSetSessionOption != NULL) {
+  if(SSLSetSessionOption) {
 #endif /* CURL_BUILD_MAC */
     bool break_on_auth = !conn->ssl_config.verifypeer ||
       ssl_cafile || ssl_cablob;
@@ -2065,7 +2065,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
   /* We want to enable 1/n-1 when using a CBC cipher unless the user
      specifically doesn't want us doing that: */
-  if(SSLSetSessionOption != NULL) {
+  if(SSLSetSessionOption) {
     SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
                         !SSL_SET_OPTION(enable_beast));
     SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
@@ -2521,7 +2521,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
   } while(0);
 
   Curl_safefree(realpubkey);
-  if(publicKeyBits != NULL)
+  if(publicKeyBits)
     CFRelease(publicKeyBits);
 
   return result;
@@ -2947,7 +2947,7 @@ collect_server_cert(struct Curl_easy *data,
      private API and doesn't work as expected. So we have to look for
      a different symbol to make sure this code is only executed under
      Lion or later. */
-  if(SecTrustEvaluateAsync != NULL) {
+  if(SecTrustEvaluateAsync) {
 #pragma unused(server_certs)
     err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
     /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
@@ -3165,7 +3165,7 @@ static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
   if(backend->ssl_ctx) {
     (void)SSLClose(backend->ssl_ctx);
 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
-    if(SSLCreateContext != NULL)
+    if(SSLCreateContext)
       CFRelease(backend->ssl_ctx);
 #if CURL_SUPPORT_MAC_10_8
     else
@@ -3329,7 +3329,7 @@ static CURLcode sectransp_sha256sum(const unsigned char *tmp, /* input */
 static bool sectransp_false_start(void)
 {
 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
-  if(SSLSetSessionOption != NULL)
+  if(SSLSetSessionOption)
     return TRUE;
 #endif
   return FALSE;
diff --git a/libs/libcurl/src/x509asn1.c b/libs/libcurl/src/x509asn1.c
index 1bdaeadc80..0341543a2b 100644
--- a/libs/libcurl/src/x509asn1.c
+++ b/libs/libcurl/src/x509asn1.c
@@ -608,7 +608,10 @@ static const char *ASN1tostr(struct Curl_asn1Element *elem, int type)
 
 /*
  * ASCII encode distinguished name at `dn' into the `buflen'-sized buffer at
- * `buf'.  Return the total string length, even if larger than `buflen'.
+ * `buf'.
+ *
+ * Returns the total string length, even if larger than `buflen' or -1 on
+ * error.
  */
 static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn)
 {
@@ -692,7 +695,10 @@ static const char *DNtostr(struct Curl_asn1Element *dn)
   if(buflen >= 0) {
     buf = malloc(buflen + 1);
     if(buf) {
-      encodeDN(buf, buflen + 1, dn);
+      if(encodeDN(buf, buflen + 1, dn) == -1) {
+        free(buf);
+        return NULL;
+      }
       buf[buflen] = '\0';
     }
   }
@@ -855,26 +861,30 @@ static const char *dumpAlgo(struct Curl_asn1Element *param,
   return OID2str(oid.beg, oid.end, TRUE);
 }
 
-static void do_pubkey_field(struct Curl_easy *data, int certnum,
-                            const char *label, struct Curl_asn1Element *elem)
+/* return 0 on success, 1 on error */
+static int do_pubkey_field(struct Curl_easy *data, int certnum,
+                           const char *label, struct Curl_asn1Element *elem)
 {
   const char *output;
+  CURLcode result = CURLE_OK;
 
   /* Generate a certificate information record for the public key. */
 
   output = ASN1tostr(elem, 0);
   if(output) {
     if(data->set.ssl.certinfo)
-      Curl_ssl_push_certinfo(data, certnum, label, output);
-    if(!certnum)
+      result = Curl_ssl_push_certinfo(data, certnum, label, output);
+    if(!certnum && !result)
       infof(data, "   %s: %s", label, output);
     free((char *) output);
   }
+  return result ? 1 : 0;
 }
 
-static void do_pubkey(struct Curl_easy *data, int certnum,
-                      const char *algo, struct Curl_asn1Element *param,
-                      struct Curl_asn1Element *pubkey)
+/* return 0 on success, 1 on error */
+static int do_pubkey(struct Curl_easy *data, int certnum,
+                     const char *algo, struct Curl_asn1Element *param,
+                     struct Curl_asn1Element *pubkey)
 {
   struct Curl_asn1Element elem;
   struct Curl_asn1Element pk;
@@ -884,7 +894,7 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
 
   /* Get the public key (single element). */
   if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end))
-    return;
+    return 1;
 
   if(strcasecompare(algo, "rsaEncryption")) {
     const char *q;
@@ -892,7 +902,7 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
 
     p = getASN1Element(&elem, pk.beg, pk.end);
     if(!p)
-      return;
+      return 1;
 
     /* Compute key length. */
     for(q = elem.beg; !*q && q < elem.end; q++)
@@ -910,26 +920,35 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
     if(data->set.ssl.certinfo) {
       q = curl_maprintf("%lu", len);
       if(q) {
-        Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
+        CURLcode result =
+          Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
         free((char *) q);
+        if(result)
+          return 1;
       }
     }
     /* Generate coefficients. */
-    do_pubkey_field(data, certnum, "rsa(n)", &elem);
+    if(do_pubkey_field(data, certnum, "rsa(n)", &elem))
+      return 1;
     if(!getASN1Element(&elem, p, pk.end))
-      return;
-    do_pubkey_field(data, certnum, "rsa(e)", &elem);
+      return 1;
+    if(do_pubkey_field(data, certnum, "rsa(e)", &elem))
+      return 1;
   }
   else if(strcasecompare(algo, "dsa")) {
     p = getASN1Element(&elem, param->beg, param->end);
     if(p) {
-      do_pubkey_field(data, certnum, "dsa(p)", &elem);
+      if(do_pubkey_field(data, certnum, "dsa(p)", &elem))
+        return 1;
       p = getASN1Element(&elem, p, param->end);
       if(p) {
-        do_pubkey_field(data, certnum, "dsa(q)", &elem);
+        if(do_pubkey_field(data, certnum, "dsa(q)", &elem))
+          return 1;
         if(getASN1Element(&elem, p, param->end)) {
-          do_pubkey_field(data, certnum, "dsa(g)", &elem);
-          do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
+          if(do_pubkey_field(data, certnum, "dsa(g)", &elem))
+            return 1;
+          if(do_pubkey_field(data, certnum, "dsa(pub_key)", &pk))
+            return 1;
         }
       }
     }
@@ -937,13 +956,17 @@ static void do_pubkey(struct Curl_easy *data, int certnum,
   else if(strcasecompare(algo, "dhpublicnumber")) {
     p = getASN1Element(&elem, param->beg, param->end);
     if(p) {
-      do_pubkey_field(data, certnum, "dh(p)", &elem);
+      if(do_pubkey_field(data, certnum, "dh(p)", &elem))
+        return 1;
       if(getASN1Element(&elem, param->beg, param->end)) {
-        do_pubkey_field(data, certnum, "dh(g)", &elem);
-        do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
+        if(do_pubkey_field(data, certnum, "dh(g)", &elem))
+          return 1;
+        if(do_pubkey_field(data, certnum, "dh(pub_key)", &pk))
+          return 1;
       }
     }
   }
+  return 0;
 }
 
 CURLcode Curl_extract_certinfo(struct Curl_easy *data,
@@ -957,7 +980,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   char *cp1;
   size_t cl1;
   char *cp2;
-  CURLcode result;
+  CURLcode result = CURLE_OK;
   unsigned long version;
   size_t i;
   size_t j;
@@ -976,8 +999,11 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   ccp = DNtostr(&cert.subject);
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
-  if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+  if(data->set.ssl.certinfo) {
+    result = Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+    if(result)
+      return result;
+  }
   if(!certnum)
     infof(data, "%2d Subject: %s", certnum, ccp);
   free((char *) ccp);
@@ -986,11 +1012,14 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   ccp = DNtostr(&cert.issuer);
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
-  if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+  if(data->set.ssl.certinfo) {
+    result = Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+  }
   if(!certnum)
     infof(data, "   Issuer: %s", ccp);
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Version (always fits in less than 32 bits). */
   version = 0;
@@ -1000,8 +1029,10 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
     ccp = curl_maprintf("%lx", version);
     if(!ccp)
       return CURLE_OUT_OF_MEMORY;
-    Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
+    result = Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
     free((char *) ccp);
+    if(result)
+      return result;
   }
   if(!certnum)
     infof(data, "   Version: %lu (0x%lx)", version + 1, version);
@@ -1011,10 +1042,12 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
+    result = Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
   if(!certnum)
     infof(data, "   Serial Number: %s", ccp);
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Signature algorithm .*/
   ccp = dumpAlgo(¶m, cert.signatureAlgorithm.beg,
@@ -1022,30 +1055,36 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
+    result = Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
   if(!certnum)
     infof(data, "   Signature Algorithm: %s", ccp);
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Start Date. */
   ccp = ASN1tostr(&cert.notBefore, 0);
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
+    result = Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
   if(!certnum)
     infof(data, "   Start Date: %s", ccp);
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Expire Date. */
   ccp = ASN1tostr(&cert.notAfter, 0);
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
+    result = Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
   if(!certnum)
     infof(data, "   Expire Date: %s", ccp);
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Public Key Algorithm. */
   ccp = dumpAlgo(¶m, cert.subjectPublicKeyAlgorithm.beg,
@@ -1053,21 +1092,31 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
-  if(!certnum)
-    infof(data, "   Public Key Algorithm: %s", ccp);
-  do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey);
+    result = Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm",
+                                    ccp);
+  if(!result) {
+    int ret;
+    if(!certnum)
+      infof(data, "   Public Key Algorithm: %s", ccp);
+    ret = do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey);
+    if(ret)
+      result = CURLE_OUT_OF_MEMORY; /* the most likely error */
+  }
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Signature. */
   ccp = ASN1tostr(&cert.signature, 0);
   if(!ccp)
     return CURLE_OUT_OF_MEMORY;
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
+    result = Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
   if(!certnum)
     infof(data, "   Signature: %s", ccp);
   free((char *) ccp);
+  if(result)
+    return result;
 
   /* Generate PEM certificate. */
   result = Curl_base64_encode(data, cert.certificate.beg,
@@ -1097,11 +1146,11 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
   cp2[i] = '\0';
   free(cp1);
   if(data->set.ssl.certinfo)
-    Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
+    result = Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
   if(!certnum)
     infof(data, "%s", cp2);
   free(cp2);
-  return CURLE_OK;
+  return result;
 }
 
 #endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL
-- 
cgit v1.2.3