From 5aacc593a961fe9ee1427c03d18fba8947a9e33d Mon Sep 17 00:00:00 2001
From: Curl Upstream <curl-library@cool.haxx.se>
Date: Wed, 9 Dec 2020 07:38:24 +0100
Subject: curl 2020-12-09 (e0528597)

Code extracted from:

    https://github.com/curl/curl.git

at commit e052859759b34d0e05ce0f17244873e5cd7b457b (curl-7_74_0).
---
 CMake/CMakeConfigurableFile.in     |   2 +-
 CMake/CurlSymbolHiding.cmake       |   4 +-
 CMake/CurlTests.c                  |   4 +-
 CMake/FindBearSSL.cmake            |   2 +-
 CMake/FindBrotli.cmake             |   2 +-
 CMake/FindCARES.cmake              |   2 +-
 CMake/FindGSS.cmake                |   2 +-
 CMake/FindLibSSH2.cmake            |   2 +-
 CMake/FindMbedTLS.cmake            |   2 +-
 CMake/FindNGHTTP2.cmake            |   2 +-
 CMake/FindNGHTTP3.cmake            |   2 +-
 CMake/FindNGTCP2.cmake             |   2 +-
 CMake/FindNSS.cmake                |   2 +-
 CMake/FindQUICHE.cmake             |   2 +-
 CMake/FindWolfSSL.cmake            |   2 +-
 CMake/FindZstd.cmake               |   2 +-
 CMake/Macros.cmake                 |  13 +-
 CMake/OtherTests.cmake             |   2 +-
 CMake/Platforms/WindowsCache.cmake |   2 +-
 CMake/Utilities.cmake              |   2 +-
 CMake/cmake_uninstall.cmake.in     |   2 +-
 CMake/curl-config.cmake.in         |   2 +-
 CMakeLists.txt                     |  95 +++---
 include/curl/curl.h                | 193 ++++++++---
 include/curl/curlver.h             |   8 +-
 include/curl/easy.h                |   2 +-
 include/curl/mprintf.h             |   4 +-
 include/curl/multi.h               |   2 +-
 include/curl/options.h             |  68 ++++
 include/curl/stdcheaders.h         |   4 +-
 include/curl/system.h              |   4 +-
 include/curl/typecheck-gcc.h       |   8 +-
 include/curl/urlapi.h              |   4 +-
 lib/CMakeLists.txt                 |  17 +-
 lib/Makefile.inc                   |  10 +-
 lib/altsvc.c                       |  36 +-
 lib/altsvc.h                       |  13 +-
 lib/amigaos.c                      |   4 +-
 lib/amigaos.h                      |   4 +-
 lib/arpa_telnet.h                  |   4 +-
 lib/asyn-ares.c                    |  29 +-
 lib/asyn-thread.c                  |  26 +-
 lib/asyn.h                         |   2 +-
 lib/base64.c                       |   7 +-
 lib/conncache.c                    |  36 +-
 lib/conncache.h                    |   6 +-
 lib/connect.c                      | 133 ++++----
 lib/connect.h                      |   4 +-
 lib/content_encoding.c             |   6 +-
 lib/content_encoding.h             |   2 +-
 lib/cookie.c                       |   4 +-
 lib/cookie.h                       |   4 +-
 lib/curl_addrinfo.c                |   2 +-
 lib/curl_addrinfo.h                |   2 +-
 lib/curl_base64.h                  |   4 +-
 lib/curl_config.h.cmake            |  20 +-
 lib/curl_ctype.c                   |   4 +-
 lib/curl_ctype.h                   |   4 +-
 lib/curl_des.c                     |   4 +-
 lib/curl_des.h                     |   4 +-
 lib/curl_endian.c                  |   4 +-
 lib/curl_endian.h                  |   4 +-
 lib/curl_fnmatch.c                 |   4 +-
 lib/curl_fnmatch.h                 |   4 +-
 lib/curl_get_line.c                |   9 +-
 lib/curl_get_line.h                |   4 +-
 lib/curl_gethostname.c             |   6 +-
 lib/curl_gethostname.h             |   6 +-
 lib/curl_gssapi.c                  |   4 +-
 lib/curl_gssapi.h                  |   4 +-
 lib/curl_hmac.h                    |   2 +-
 lib/curl_krb5.h                    |  51 +++
 lib/curl_ldap.h                    |   4 +-
 lib/curl_md4.h                     |   2 +-
 lib/curl_md5.h                     |   2 +-
 lib/curl_memory.h                  |   4 +-
 lib/curl_memrchr.c                 |   4 +-
 lib/curl_memrchr.h                 |   4 +-
 lib/curl_multibyte.c               |   2 +-
 lib/curl_multibyte.h               |   2 +-
 lib/curl_ntlm_core.c               |  18 +-
 lib/curl_ntlm_core.h               |  10 +-
 lib/curl_ntlm_wb.c                 |   2 +-
 lib/curl_ntlm_wb.h                 |   4 +-
 lib/curl_path.c                    |   6 +-
 lib/curl_path.h                    |   4 +-
 lib/curl_printf.h                  |   4 +-
 lib/curl_range.c                   |   4 +-
 lib/curl_range.h                   |   4 +-
 lib/curl_rtmp.c                    |  10 +-
 lib/curl_rtmp.h                    |   4 +-
 lib/curl_sasl.c                    |   2 +-
 lib/curl_sasl.h                    |   4 +-
 lib/curl_sec.h                     |  51 ---
 lib/curl_setup.h                   |  36 +-
 lib/curl_setup_once.h              |   2 +-
 lib/curl_sha256.h                  |   2 +-
 lib/curl_sspi.c                    |   2 +-
 lib/curl_sspi.h                    |   4 +-
 lib/curl_threads.c                 |   8 +-
 lib/curl_threads.h                 |   4 +-
 lib/curlx.h                        |   2 +-
 lib/dict.c                         |  97 ++++--
 lib/dict.h                         |   4 +-
 lib/doh.c                          |  11 +-
 lib/doh.h                          |   2 +-
 lib/dotdot.c                       |   2 +-
 lib/dotdot.h                       |   4 +-
 lib/dynbuf.c                       |  50 ++-
 lib/dynbuf.h                       |  27 +-
 lib/easy.c                         |  46 ++-
 lib/easygetopt.c                   |  96 ++++++
 lib/easyif.h                       |   2 +-
 lib/easyoptions.c                  | 353 +++++++++++++++++++
 lib/easyoptions.h                  |  35 ++
 lib/escape.c                       |   4 +-
 lib/escape.h                       |   2 +-
 lib/file.c                         |  30 +-
 lib/file.h                         |   4 +-
 lib/fileinfo.c                     |   4 +-
 lib/fileinfo.h                     |   6 +-
 lib/formdata.c                     |   2 +-
 lib/formdata.h                     |   2 +-
 lib/ftp.c                          | 670 +++++++++++++++++--------------------
 lib/ftp.h                          |   3 +-
 lib/ftplistparser.c                |  10 +-
 lib/ftplistparser.h                |   4 +-
 lib/getenv.c                       |   2 +-
 lib/getinfo.c                      |   5 +-
 lib/getinfo.h                      |   4 +-
 lib/gopher.c                       |   9 +-
 lib/gopher.h                       |   4 +-
 lib/hash.c                         |  84 ++---
 lib/hash.h                         |  50 +--
 lib/hmac.c                         |   2 +-
 lib/hostasyn.c                     |   2 +-
 lib/hostcheck.c                    |   4 +-
 lib/hostcheck.h                    |   4 +-
 lib/hostip.c                       |   8 +-
 lib/hostip.h                       |  10 +-
 lib/hostip4.c                      |   2 +-
 lib/hostip6.c                      |   2 +-
 lib/hostsyn.c                      |   4 +-
 lib/hsts.c                         | 522 +++++++++++++++++++++++++++++
 lib/hsts.h                         |  65 ++++
 lib/http.c                         |  83 +++--
 lib/http.h                         |   2 +-
 lib/http2.c                        | 178 ++++------
 lib/http2.h                        |   2 +-
 lib/http_chunks.c                  |   2 +-
 lib/http_chunks.h                  |   4 +-
 lib/http_digest.c                  |   2 +-
 lib/http_digest.h                  |   2 +-
 lib/http_negotiate.c               |   2 +-
 lib/http_negotiate.h               |   2 +-
 lib/http_ntlm.c                    |   2 +-
 lib/http_ntlm.h                    |   2 +-
 lib/http_proxy.c                   |  32 +-
 lib/http_proxy.h                   |   2 +-
 lib/idn_win32.c                    |   2 +-
 lib/if2ip.c                        |   2 +-
 lib/if2ip.h                        |   4 +-
 lib/imap.c                         |  65 ++--
 lib/imap.h                         |   7 +-
 lib/inet_ntop.h                    |   4 +-
 lib/inet_pton.c                    |   4 +-
 lib/inet_pton.h                    |   4 +-
 lib/krb5.c                         | 595 +++++++++++++++++++++++++++++++-
 lib/ldap.c                         |  72 ++--
 lib/libcurl.rc                     |   8 +-
 lib/llist.c                        |  14 +-
 lib/llist.h                        |  30 +-
 lib/md4.c                          |   2 +-
 lib/md5.c                          |   2 +-
 lib/memdebug.c                     |  53 +--
 lib/memdebug.h                     |   2 +-
 lib/mime.c                         |   2 +-
 lib/mime.h                         |   2 +-
 lib/mprintf.c                      |  57 ++--
 lib/mqtt.c                         |  40 +--
 lib/mqtt.h                         |   4 +-
 lib/multi.c                        |  94 +++---
 lib/multihandle.h                  |  16 +-
 lib/multiif.h                      |   2 +-
 lib/netrc.c                        |   4 +-
 lib/netrc.h                        |   4 +-
 lib/non-ascii.c                    |   4 +-
 lib/non-ascii.h                    |   4 +-
 lib/nonblock.c                     |   4 +-
 lib/nonblock.h                     |   4 +-
 lib/nwlib.c                        |   2 +-
 lib/nwos.c                         |   4 +-
 lib/openldap.c                     |  14 +-
 lib/parsedate.c                    |  59 +---
 lib/parsedate.h                    |   4 +-
 lib/pingpong.c                     |  61 ++--
 lib/pingpong.h                     |   6 +-
 lib/pop3.c                         |  19 +-
 lib/pop3.h                         |   4 +-
 lib/progress.c                     |  17 +-
 lib/progress.h                     |   6 +-
 lib/psl.c                          |   4 +-
 lib/psl.h                          |   4 +-
 lib/quic.h                         |   4 +-
 lib/rand.c                         |   4 +-
 lib/rand.h                         |   4 +-
 lib/rename.c                       |   6 +-
 lib/rename.h                       |   2 +-
 lib/rtsp.c                         |  46 ++-
 lib/rtsp.h                         |   4 +-
 lib/security.c                     | 579 --------------------------------
 lib/select.c                       | 177 +++-------
 lib/select.h                       |  17 +-
 lib/sendf.c                        | 179 ++++------
 lib/sendf.h                        |   6 +-
 lib/setopt.c                       | 294 +++++++++-------
 lib/setopt.h                       |   2 +-
 lib/setup-os400.h                  |   2 +-
 lib/setup-vms.h                    |   2 +-
 lib/setup-win32.h                  |   5 +-
 lib/sha256.c                       |   2 +-
 lib/share.c                        |   4 +-
 lib/share.h                        |   8 +-
 lib/sigpipe.h                      |   4 +-
 lib/slist.c                        |   4 +-
 lib/slist.h                        |   4 +-
 lib/smb.c                          |  33 +-
 lib/smb.h                          |  11 +-
 lib/smtp.c                         |  27 +-
 lib/smtp.h                         |   2 +-
 lib/sockaddr.h                     |   4 +-
 lib/socketpair.c                   |   6 +-
 lib/socketpair.h                   |   4 +-
 lib/socks.c                        | 169 ++++++----
 lib/socks.h                        |  28 +-
 lib/socks_gssapi.c                 |   6 +-
 lib/socks_sspi.c                   |   2 +-
 lib/speedcheck.c                   |   4 +-
 lib/speedcheck.h                   |   4 +-
 lib/splay.c                        |  10 +-
 lib/splay.h                        |  16 +-
 lib/strcase.c                      |   2 +-
 lib/strcase.h                      |   2 +-
 lib/strdup.c                       |   2 +-
 lib/strdup.h                       |   4 +-
 lib/strerror.c                     |  44 ++-
 lib/strerror.h                     |   2 +-
 lib/strtok.c                       |   2 +-
 lib/strtok.h                       |   4 +-
 lib/strtoofft.c                    |   4 +-
 lib/strtoofft.h                    |   4 +-
 lib/system_win32.c                 |  13 +-
 lib/system_win32.h                 |   2 +-
 lib/telnet.c                       | 164 ++-------
 lib/telnet.h                       |   4 +-
 lib/tftp.c                         |   3 +-
 lib/tftp.h                         |   4 +-
 lib/timeval.c                      |   2 +-
 lib/timeval.h                      |   4 +-
 lib/transfer.c                     |  19 +-
 lib/transfer.h                     |   4 +-
 lib/url.c                          | 223 +++++-------
 lib/url.h                          |   2 +-
 lib/urlapi-int.h                   |   6 +-
 lib/urlapi.c                       |  48 ++-
 lib/urldata.h                      |  91 +++--
 lib/vauth/cleartext.c              |   2 +-
 lib/vauth/cram.c                   |   2 +-
 lib/vauth/digest.c                 |   2 +-
 lib/vauth/digest.h                 |   4 +-
 lib/vauth/digest_sspi.c            |   2 +-
 lib/vauth/krb5_gssapi.c            |   4 +-
 lib/vauth/krb5_sspi.c              |   2 +-
 lib/vauth/ntlm.c                   |   3 +-
 lib/vauth/ntlm.h                   |   4 +-
 lib/vauth/ntlm_sspi.c              |   2 +-
 lib/vauth/oauth2.c                 |   4 +-
 lib/vauth/spnego_gssapi.c          |   4 +-
 lib/vauth/spnego_sspi.c            |   2 +-
 lib/vauth/vauth.c                  |   2 +-
 lib/vauth/vauth.h                  |   4 +-
 lib/version.c                      |  24 +-
 lib/version_win32.c                |   2 +-
 lib/version_win32.h                |   2 +-
 lib/vquic/ngtcp2.c                 |  96 +++---
 lib/vquic/ngtcp2.h                 |   4 +-
 lib/vquic/quiche.c                 |  43 ++-
 lib/vquic/quiche.h                 |   5 +-
 lib/vquic/vquic.c                  |   2 +-
 lib/vquic/vquic.h                  |   2 +-
 lib/vssh/libssh.c                  |  69 ++--
 lib/vssh/libssh2.c                 | 217 +++++++++---
 lib/vssh/ssh.h                     |   8 +-
 lib/vssh/wolfssh.c                 |  10 +-
 lib/vssh/wolfssh.h                 |   2 +-
 lib/vtls/bearssl.c                 |   2 +-
 lib/vtls/bearssl.h                 |   4 +-
 lib/vtls/gskit.c                   |   4 +-
 lib/vtls/gskit.h                   |   4 +-
 lib/vtls/gtls.c                    |  72 ++--
 lib/vtls/gtls.h                    |   4 +-
 lib/vtls/keylog.c                  |   2 +-
 lib/vtls/keylog.h                  |   2 +-
 lib/vtls/mbedtls.c                 |  16 +-
 lib/vtls/mbedtls.h                 |   4 +-
 lib/vtls/mbedtls_threadlock.c      |   2 +-
 lib/vtls/mbedtls_threadlock.h      |   2 +-
 lib/vtls/mesalink.c                |  24 +-
 lib/vtls/mesalink.h                |   6 +-
 lib/vtls/nss.c                     |  67 ++--
 lib/vtls/nssg.h                    |   4 +-
 lib/vtls/openssl.c                 | 253 ++++++++------
 lib/vtls/openssl.h                 |   4 +-
 lib/vtls/schannel.c                |  57 ++--
 lib/vtls/schannel.h                |  12 +-
 lib/vtls/schannel_verify.c         |   2 +-
 lib/vtls/sectransp.c               |  26 +-
 lib/vtls/sectransp.h               |   4 +-
 lib/vtls/vtls.c                    |  17 +-
 lib/vtls/vtls.h                    |  18 +-
 lib/vtls/wolfssl.c                 |  24 +-
 lib/vtls/wolfssl.h                 |   4 +-
 lib/warnless.c                     |   4 +-
 lib/warnless.h                     |   2 +-
 lib/wildcard.c                     |   4 +-
 lib/wildcard.h                     |  14 +-
 lib/x509asn1.c                     |   2 +-
 lib/x509asn1.h                     |   2 +-
 328 files changed, 4853 insertions(+), 3728 deletions(-)
 create mode 100644 include/curl/options.h
 create mode 100644 lib/curl_krb5.h
 delete mode 100644 lib/curl_sec.h
 create mode 100644 lib/easygetopt.c
 create mode 100644 lib/easyoptions.c
 create mode 100644 lib/easyoptions.h
 create mode 100644 lib/hsts.c
 create mode 100644 lib/hsts.h
 delete mode 100644 lib/security.c

diff --git a/CMake/CMakeConfigurableFile.in b/CMake/CMakeConfigurableFile.in
index 2bafe2c..8ccd016 100644
--- a/CMake/CMakeConfigurableFile.in
+++ b/CMake/CMakeConfigurableFile.in
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/CurlSymbolHiding.cmake b/CMake/CurlSymbolHiding.cmake
index aaac9fe..e99ea6f 100644
--- a/CMake/CurlSymbolHiding.cmake
+++ b/CMake/CurlSymbolHiding.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,7 @@ mark_as_advanced(CURL_HIDDEN_SYMBOLS)
 if(CURL_HIDDEN_SYMBOLS)
   set(SUPPORTS_SYMBOL_HIDING FALSE)
 
-  if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+  if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
     set(SUPPORTS_SYMBOL_HIDING TRUE)
     set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
     set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c
index 3ef35f0..949910d 100644
--- a/CMake/CurlTests.c
+++ b/CMake/CurlTests.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindBearSSL.cmake b/CMake/FindBearSSL.cmake
index a8f72c9..9455f4b 100644
--- a/CMake/FindBearSSL.cmake
+++ b/CMake/FindBearSSL.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindBrotli.cmake b/CMake/FindBrotli.cmake
index c43172b..0ed0855 100644
--- a/CMake/FindBrotli.cmake
+++ b/CMake/FindBrotli.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindCARES.cmake b/CMake/FindCARES.cmake
index 9160ae5..7180682 100644
--- a/CMake/FindCARES.cmake
+++ b/CMake/FindCARES.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindGSS.cmake b/CMake/FindGSS.cmake
index 02111a2..4e4747d 100644
--- a/CMake/FindGSS.cmake
+++ b/CMake/FindGSS.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindLibSSH2.cmake b/CMake/FindLibSSH2.cmake
index 4cdf3e3..ce46a40 100644
--- a/CMake/FindLibSSH2.cmake
+++ b/CMake/FindLibSSH2.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindMbedTLS.cmake b/CMake/FindMbedTLS.cmake
index 2ebe721..1746093 100644
--- a/CMake/FindMbedTLS.cmake
+++ b/CMake/FindMbedTLS.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNGHTTP2.cmake b/CMake/FindNGHTTP2.cmake
index e1eba05..8614492 100644
--- a/CMake/FindNGHTTP2.cmake
+++ b/CMake/FindNGHTTP2.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNGHTTP3.cmake b/CMake/FindNGHTTP3.cmake
index 73ce9e1..643b600 100644
--- a/CMake/FindNGHTTP3.cmake
+++ b/CMake/FindNGHTTP3.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNGTCP2.cmake b/CMake/FindNGTCP2.cmake
index a1ed8cd..5757009 100644
--- a/CMake/FindNGTCP2.cmake
+++ b/CMake/FindNGTCP2.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindNSS.cmake b/CMake/FindNSS.cmake
index 5fdb2b7..899c6b0 100644
--- a/CMake/FindNSS.cmake
+++ b/CMake/FindNSS.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindQUICHE.cmake b/CMake/FindQUICHE.cmake
index 01d1758..0247364 100644
--- a/CMake/FindQUICHE.cmake
+++ b/CMake/FindQUICHE.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindWolfSSL.cmake b/CMake/FindWolfSSL.cmake
index 54df1a8..42256b3 100644
--- a/CMake/FindWolfSSL.cmake
+++ b/CMake/FindWolfSSL.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/FindZstd.cmake b/CMake/FindZstd.cmake
index 44c741a..eaba397 100644
--- a/CMake/FindZstd.cmake
+++ b/CMake/FindZstd.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake
index 65a41e4..d57dd6a 100644
--- a/CMake/Macros.cmake
+++ b/CMake/Macros.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
@@ -107,3 +107,14 @@ macro(curl_nroff_check)
     message(WARNING "Found no *nroff program")
   endif()
 endmacro()
+
+macro(optional_dependency DEPENDENCY)
+  set(CURL_${DEPENDENCY} AUTO CACHE STRING "Build curl with ${DEPENDENCY} support (AUTO, ON or OFF)")
+  set_property(CACHE CURL_${DEPENDENCY} PROPERTY STRINGS AUTO ON OFF)
+
+  if(CURL_${DEPENDENCY} STREQUAL AUTO)
+    find_package(${DEPENDENCY})
+  elseif(CURL_${DEPENDENCY})
+    find_package(${DEPENDENCY} REQUIRED)
+  endif()
+endmacro()
diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake
index 7cec6da..80c0b72 100644
--- a/CMake/OtherTests.cmake
+++ b/CMake/OtherTests.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/Platforms/WindowsCache.cmake b/CMake/Platforms/WindowsCache.cmake
index 9ae9b56..12cec52 100644
--- a/CMake/Platforms/WindowsCache.cmake
+++ b/CMake/Platforms/WindowsCache.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake
index 59b17d0..8f9b861 100644
--- a/CMake/Utilities.cmake
+++ b/CMake/Utilities.cmake
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/cmake_uninstall.cmake.in b/CMake/cmake_uninstall.cmake.in
index 4a0de5e..e96c143 100644
--- a/CMake/cmake_uninstall.cmake.in
+++ b/CMake/cmake_uninstall.cmake.in
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMake/curl-config.cmake.in b/CMake/curl-config.cmake.in
index ae8cc30..957148e 100644
--- a/CMake/curl-config.cmake.in
+++ b/CMake/curl-config.cmake.in
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 68842ee..6a1a6fe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
@@ -47,8 +47,6 @@ include(CheckCCompilerFlag)
 
 project(CURL C)
 
-message(WARNING "the curl cmake build system is poorly maintained. Be aware")
-
 file(STRINGS ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )")
 string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
   CURL_VERSION ${CURL_VERSION_H_CONTENTS})
@@ -65,7 +63,7 @@ message(STATUS "curl version=[${CURL_VERSION}]")
 # SET(PACKAGE_NAME "curl")
 # SET(PACKAGE_VERSION "-")
 # SET(PACKAGE_STRING "curl-")
-# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.haxx.se/mail/")
+# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/")
 set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
 set(OS "\"${CMAKE_SYSTEM_NAME}\"")
 
@@ -79,6 +77,7 @@ option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
 if(WIN32)
   option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
   option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
+  option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF)
   set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
   if(CURL_TARGET_WINDOWS_VERSION)
     add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
@@ -92,6 +91,12 @@ if(WIN32)
     add_definitions(-D_WIN32_WINNT=0x0501)
     set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=0x0501")
   endif()
+  if(ENABLE_UNICODE)
+    add_definitions(-DUNICODE -D_UNICODE)
+    if(MINGW)
+      add_compile_options(-municode)
+    endif()
+  endif()
 endif()
 option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF)
 
@@ -183,28 +188,30 @@ option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
 mark_as_advanced(CURL_DISABLE_SMTP)
 option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
 mark_as_advanced(CURL_DISABLE_GOPHER)
-option(CURL_ENABLE_MQTT "to enable MQTT" OFF)
-mark_as_advanced(CURL_ENABLE_MQTT)
+option(CURL_DISABLE_MQTT "to disable MQTT" OFF)
+mark_as_advanced(CURL_DISABLE_MQTT)
 
 if(HTTP_ONLY)
+  set(CURL_DISABLE_DICT ON)
+  set(CURL_DISABLE_FILE ON)
   set(CURL_DISABLE_FTP ON)
+  set(CURL_DISABLE_GOPHER ON)
+  set(CURL_DISABLE_IMAP ON)
   set(CURL_DISABLE_LDAP ON)
   set(CURL_DISABLE_LDAPS ON)
-  set(CURL_DISABLE_TELNET ON)
-  set(CURL_DISABLE_DICT ON)
-  set(CURL_DISABLE_FILE ON)
-  set(CURL_DISABLE_TFTP ON)
-  set(CURL_DISABLE_RTSP ON)
+  set(CURL_DISABLE_MQTT ON)
   set(CURL_DISABLE_POP3 ON)
-  set(CURL_DISABLE_IMAP ON)
+  set(CURL_DISABLE_RTSP ON)
   set(CURL_DISABLE_SMB ON)
   set(CURL_DISABLE_SMTP ON)
-  set(CURL_DISABLE_GOPHER ON)
+  set(CURL_DISABLE_TELNET ON)
+  set(CURL_DISABLE_TFTP ON)
 endif()
 
+option(CURL_DISABLE_ALTSVC "to disable alt-svc support" OFF)
+mark_as_advanced(CURL_DISABLE_ALTSVC)
 option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
 mark_as_advanced(CURL_DISABLE_COOKIES)
-
 option(CURL_DISABLE_CRYPTO_AUTH "to disable cryptographic authentication" OFF)
 mark_as_advanced(CURL_DISABLE_CRYPTO_AUTH)
 option(CURL_DISABLE_VERBOSE_STRINGS "to disable verbose strings" OFF)
@@ -239,10 +246,6 @@ if(ENABLE_MANUAL)
   set(USE_MANUAL ON)
 endif()
 
-# We need ansi c-flags, especially on HP
-set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
-set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS})
-
 if(CURL_STATIC_CRT)
   set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
   set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
@@ -620,28 +623,25 @@ check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
 # Check for symbol dlopen (same as HAVE_LIBDL)
 check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
 
-option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON)
 set(HAVE_LIBZ OFF)
 set(HAVE_ZLIB_H OFF)
 set(USE_ZLIB OFF)
-if(CURL_ZLIB)
-  find_package(ZLIB QUIET)
-  if(ZLIB_FOUND)
-    set(HAVE_ZLIB_H ON)
-    set(HAVE_LIBZ ON)
-    set(USE_ZLIB ON)
-
-    # Depend on ZLIB via imported targets if supported by the running
-    # version of CMake.  This allows our dependents to get our dependencies
-    # transitively.
-    if(NOT CMAKE_VERSION VERSION_LESS 3.4)
-      list(APPEND CURL_LIBS ZLIB::ZLIB)
-    else()
-      list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
-      include_directories(${ZLIB_INCLUDE_DIRS})
-    endif()
-    list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
+optional_dependency(ZLIB)
+if(ZLIB_FOUND)
+  set(HAVE_ZLIB_H ON)
+  set(HAVE_LIBZ ON)
+  set(USE_ZLIB ON)
+
+  # Depend on ZLIB via imported targets if supported by the running
+  # version of CMake.  This allows our dependents to get our dependencies
+  # transitively.
+  if(NOT CMAKE_VERSION VERSION_LESS 3.4)
+    list(APPEND CURL_LIBS ZLIB::ZLIB)
+  else()
+    list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
+    include_directories(${ZLIB_INCLUDE_DIRS})
   endif()
+  list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
 endif()
 
 option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF)
@@ -773,6 +773,7 @@ if(CMAKE_USE_GSSAPI)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
+    set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
     list(APPEND CURL_LIBS ${GSS_LIBRARIES})
 
   else()
@@ -788,8 +789,6 @@ else()
   unset(USE_UNIX_SOCKETS CACHE)
 endif()
 
-option(ENABLE_ALT_SVC "Enable alt-svc support" OFF)
-set(USE_ALTSVC ${ENABLE_ALT_SVC})
 
 #
 # CA handling
@@ -910,6 +909,7 @@ check_include_file_concat("net/if.h"         HAVE_NET_IF_H)
 check_include_file_concat("netdb.h"          HAVE_NETDB_H)
 check_include_file_concat("netinet/in.h"     HAVE_NETINET_IN_H)
 check_include_file_concat("netinet/tcp.h"    HAVE_NETINET_TCP_H)
+check_include_file("linux/tcp.h"      HAVE_LINUX_TCP_H)
 
 check_include_file_concat("pem.h"            HAVE_PEM_H)
 check_include_file_concat("poll.h"           HAVE_POLL_H)
@@ -1323,16 +1323,16 @@ if(BUILD_CURL_EXE)
   add_subdirectory(src)
 endif()
 
-option(BUILD_TESTING "Build tests" "${PERL_FOUND}")
-if(NOT PERL_FOUND)
-  message(STATUS "Perl not found, testing disabled.")
-elseif(BUILD_TESTING)
+cmake_dependent_option(BUILD_TESTING "Build tests"
+  ON "PERL_FOUND;NOT CURL_DISABLE_TESTS"
+  OFF)
+if(BUILD_TESTING)
   add_subdirectory(tests)
 endif()
 
 # NTLM support requires crypto function adaptions from various SSL libs
 # TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
-if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_DARWINSSL OR USE_MBEDTLS OR USE_WIN32_CRYPTO))
+if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_DARWINSSL OR USE_MBEDTLS OR USE_WIN32_CRYPTO))
   set(use_ntlm ON)
 else()
   set(use_ntlm OFF)
@@ -1351,7 +1351,7 @@ endmacro()
 set(_items)
 _add_if("SSL"           SSL_ENABLED)
 _add_if("IPv6"          ENABLE_IPV6)
-_add_if("unix-sockets"  USE_UNIX_SOCKETS)
+_add_if("unixsockets"   USE_UNIX_SOCKETS)
 _add_if("libz"          HAVE_LIBZ)
 _add_if("brotli"        HAVE_BROTLI)
 _add_if("zstd"          HAVE_ZSTD)
@@ -1362,7 +1362,7 @@ _add_if("Largefile"     (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
 # TODO SSP1 (Schannel) check is missing
 _add_if("SSPI"          USE_WINDOWS_SSPI)
 _add_if("GSS-API"       HAVE_GSSAPI)
-_add_if("alt-svc"       ENABLE_ALT_SVC)
+_add_if("alt-svc"       NOT CURL_DISABLE_ALTSVC)
 # TODO SSP1 missing for SPNEGO
 _add_if("SPNEGO"        NOT CURL_DISABLE_CRYPTO_AUTH AND
                         (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
@@ -1370,7 +1370,7 @@ _add_if("Kerberos"      NOT CURL_DISABLE_CRYPTO_AUTH AND
                         (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
 # NTLM support requires crypto function adaptions from various SSL libs
 # TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
-_add_if("NTLM"        use_ntlm)
+_add_if("NTLM"        use_ntlm OR USE_WINDOWS_SSPI)
 # TODO missing option (autoconf: --enable-ntlm-wb)
 _add_if("NTLM_WB"     use_ntlm AND NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
 # TODO missing option (--enable-tls-srp), depends on GNUTLS_SRP/OPENSSL_SRP
@@ -1380,6 +1380,7 @@ _add_if("HTTP2"         USE_NGHTTP2)
 _add_if("HTTP3"         USE_NGTCP2 OR USE_QUICHE)
 _add_if("MultiSSL"      CURL_WITH_MULTI_SSL)
 _add_if("HTTPS-proxy"   SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS OR USE_NSS))
+_add_if("unicode"       ENABLE_UNICODE)
 string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
 message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
 
@@ -1412,7 +1413,7 @@ _add_if("SCP"           USE_LIBSSH2 OR USE_LIBSSH)
 _add_if("SFTP"          USE_LIBSSH2 OR USE_LIBSSH)
 _add_if("RTSP"          NOT CURL_DISABLE_RTSP)
 _add_if("RTMP"          USE_LIBRTMP)
-_add_if("MQTT"          CURL_ENABLE_MQTT)
+_add_if("MQTT"          NOT CURL_DISABLE_MQTT)
 if(_items)
   list(SORT _items)
 endif()
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 5aeaca9..a73418d 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -24,7 +24,7 @@
 
 /*
  * If you have libcurl problems, all docs and details are found here:
- *   https://curl.haxx.se/libcurl/
+ *   https://curl.se/libcurl/
  *
  * curl-library mailing list subscription and unsubscription web interface:
  *   https://cool.haxx.se/mailman/listinfo/curl-library/
@@ -74,7 +74,7 @@
 #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
     defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
     defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
-    defined(__CYGWIN__) || \
+    defined(__CYGWIN__) || defined(AMIGA) || \
    (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
 #include <sys/select.h>
 #endif
@@ -610,6 +610,7 @@ typedef enum {
                                     error */
   CURLE_HTTP3,                   /* 95 - An HTTP/3 layer problem */
   CURLE_QUIC_CONNECT_ERROR,      /* 96 - QUIC connection error */
+  CURLE_PROXY,                   /* 97 - proxy handshake error */
   CURL_LAST /* never use! */
 } CURLcode;
 
@@ -689,6 +690,48 @@ typedef enum {
 
 #endif /*!CURL_NO_OLDIES*/
 
+/*
+ * Proxy error codes. Returned in CURLINFO_PROXY_ERROR if CURLE_PROXY was
+ * return for the transfers.
+ */
+typedef enum {
+  CURLPX_OK,
+  CURLPX_BAD_ADDRESS_TYPE,
+  CURLPX_BAD_VERSION,
+  CURLPX_CLOSED,
+  CURLPX_GSSAPI,
+  CURLPX_GSSAPI_PERMSG,
+  CURLPX_GSSAPI_PROTECTION,
+  CURLPX_IDENTD,
+  CURLPX_IDENTD_DIFFER,
+  CURLPX_LONG_HOSTNAME,
+  CURLPX_LONG_PASSWD,
+  CURLPX_LONG_USER,
+  CURLPX_NO_AUTH,
+  CURLPX_RECV_ADDRESS,
+  CURLPX_RECV_AUTH,
+  CURLPX_RECV_CONNECT,
+  CURLPX_RECV_REQACK,
+  CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+  CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+  CURLPX_REPLY_CONNECTION_REFUSED,
+  CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+  CURLPX_REPLY_HOST_UNREACHABLE,
+  CURLPX_REPLY_NETWORK_UNREACHABLE,
+  CURLPX_REPLY_NOT_ALLOWED,
+  CURLPX_REPLY_TTL_EXPIRED,
+  CURLPX_REPLY_UNASSIGNED,
+  CURLPX_REQUEST_FAILED,
+  CURLPX_RESOLVE_HOST,
+  CURLPX_SEND_AUTH,
+  CURLPX_SEND_CONNECT,
+  CURLPX_SEND_REQUEST,
+  CURLPX_UNKNOWN_FAIL,
+  CURLPX_UNKNOWN_MODE,
+  CURLPX_USER_REJECTED,
+  CURLPX_LAST /* never use */
+} CURLproxycode;
+
 /* This prototype applies to all conversion callbacks */
 typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
 
@@ -789,6 +832,7 @@ enum curl_khstat {
   CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
                         this causes a CURLE_DEFER error but otherwise the
                         connection will be left intact etc */
+  CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/
   CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
 };
 
@@ -905,13 +949,42 @@ typedef enum {
 #define CURLHEADER_SEPARATE (1<<0)
 
 /* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
-#define CURLALTSVC_IMMEDIATELY  (1<<0)
-
 #define CURLALTSVC_READONLYFILE (1<<2)
 #define CURLALTSVC_H1           (1<<3)
 #define CURLALTSVC_H2           (1<<4)
 #define CURLALTSVC_H3           (1<<5)
 
+
+struct curl_hstsentry {
+  char *name;
+  size_t namelen;
+  unsigned int includeSubDomains:1;
+  char expire[18]; /* YYYYMMDD HH:MM:SS [null-terminated] */
+};
+
+struct curl_index {
+  size_t index; /* the provided entry's "index" or count */
+  size_t total; /* total number of entries to save */
+};
+
+typedef enum {
+  CURLSTS_OK,
+  CURLSTS_DONE,
+  CURLSTS_FAIL
+} CURLSTScode;
+
+typedef CURLSTScode (*curl_hstsread_callback)(CURL *easy,
+                                              struct curl_hstsentry *e,
+                                              void *userp);
+typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
+                                               struct curl_hstsentry *e,
+                                               struct curl_index *i,
+                                               void *userp);
+
+/* CURLHSTS_* are bits for the CURLOPT_HSTS option */
+#define CURLHSTS_ENABLE       (long)(1<<0)
+#define CURLHSTS_READONLYFILE (long)(1<<1)
+
 /* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
 #define CURLPROTO_HTTP   (1<<0)
 #define CURLPROTO_HTTPS  (1<<1)
@@ -958,17 +1031,27 @@ typedef enum {
 
 #define CURLOPT(na,t,nu) na = t + nu
 
-/* handy aliases that make no run-time difference */
-#define CURLOPTTYPE_STRINGPOINT  CURLOPTTYPE_OBJECTPOINT
+/* CURLOPT aliases that make no run-time difference */
+
+/* 'char *' argument to a string with a trailing zero */
+#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT
+
+/* 'struct curl_slist *' argument */
 #define CURLOPTTYPE_SLISTPOINT  CURLOPTTYPE_OBJECTPOINT
 
+/* 'void *' argument passed untouched to callback */
+#define CURLOPTTYPE_CBPOINT     CURLOPTTYPE_OBJECTPOINT
+
+/* 'long' argument with a set of values/bitmask */
+#define CURLOPTTYPE_VALUES      CURLOPTTYPE_LONG
+
 /*
  * All CURLOPT_* values.
  */
 
 typedef enum {
   /* This is the FILE * or void * the regular output should be written to. */
-  CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_OBJECTPOINT, 1),
+  CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_CBPOINT, 1),
 
   /* The full URL to get/put */
   CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2),
@@ -991,7 +1074,7 @@ typedef enum {
   /* not used */
 
   /* Specified file stream to upload from (use as input): */
-  CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_OBJECTPOINT, 9),
+  CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_CBPOINT, 9),
 
   /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
    * bytes big. */
@@ -1076,7 +1159,7 @@ typedef enum {
 
   /* send FILE * or void * to store headers to, if you use a callback it
      is simply passed to the callback unmodified */
-  CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_OBJECTPOINT, 29),
+  CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_CBPOINT, 29),
 
   /* point to a file to read the initial cookies from, also enables
      "cookie awareness" */
@@ -1084,10 +1167,10 @@ typedef enum {
 
   /* What version to specifically try to use.
      See CURL_SSLVERSION defines below. */
-  CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_LONG, 32),
+  CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_VALUES, 32),
 
   /* What kind of HTTP time condition to use, see defines */
-  CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_LONG, 33),
+  CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_VALUES, 33),
 
   /* Time to use with the above condition. Specified in number of seconds
      since 1 Jan 1970 */
@@ -1141,7 +1224,7 @@ typedef enum {
 
   /* Specify whether to read the user+password from the .netrc or the URL.
    * This must be one of the CURL_NETRC_* enums below. */
-  CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_LONG, 51),
+  CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_VALUES, 51),
 
   /* use Location: Luke! */
   CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52),
@@ -1162,8 +1245,8 @@ typedef enum {
 
   /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
      callbacks */
-  CURLOPT(CURLOPT_PROGRESSDATA, CURLOPTTYPE_OBJECTPOINT, 57),
-#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
+  CURLOPT(CURLOPT_XFERINFODATA, CURLOPTTYPE_CBPOINT, 57),
+#define CURLOPT_PROGRESSDATA CURLOPT_XFERINFODATA
 
   /* We want the referrer field set automatically when following locations */
   CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58),
@@ -1258,7 +1341,7 @@ typedef enum {
 
   /* Specify which HTTP version to use! This must be set to one of the
      CURL_HTTP_VERSION* enums set below. */
-  CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_LONG, 84),
+  CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_VALUES, 84),
 
   /* Specifically switch on or off the FTP engine's use of the EPSV command. By
      default, that one will always be attempted before the more traditional
@@ -1296,7 +1379,7 @@ typedef enum {
   CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94),
 
   /* set the data for the debug function */
-  CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_OBJECTPOINT, 95),
+  CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_CBPOINT, 95),
 
   /* mark this as start of a cookie session */
   CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96),
@@ -1319,7 +1402,7 @@ typedef enum {
   /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
      CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
      CURLPROXY_SOCKS5. */
-  CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_LONG, 101),
+  CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_VALUES, 101),
 
   /* Set the Accept-Encoding string. Use this to tell a server you would like
      the response to be compressed. Before 7.21.6, this was known as
@@ -1345,7 +1428,7 @@ typedef enum {
   /* Set this to a bitmask value to enable the particular authentications
      methods you like. Use this in combination with CURLOPT_USERPWD.
      Note that setting multiple bits may cause extra network round-trips. */
-  CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_LONG, 107),
+  CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_VALUES, 107),
 
   /* Set the ssl context callback function, currently only for OpenSSL or
      WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument.
@@ -1354,7 +1437,7 @@ typedef enum {
 
   /* Set the userdata for the ssl context callback function's third
      argument */
-  CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_OBJECTPOINT, 109),
+  CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_CBPOINT, 109),
 
   /* FTP Option that causes missing dirs to be created on the remote server.
      In 7.19.4 we introduced the convenience enums for this option using the
@@ -1365,7 +1448,7 @@ typedef enum {
   /* Set this to a bitmask value to enable the particular authentications
      methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
      Note that setting multiple bits may cause extra network round-trips. */
-  CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_LONG, 111),
+  CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111),
 
   /* FTP option that changes the timeout, in seconds, associated with
      getting a response.  This is different from transfer timeout time and
@@ -1377,7 +1460,7 @@ typedef enum {
   /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
      tell libcurl to resolve names to those IP versions only. This only has
      affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
-  CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_LONG, 113),
+  CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113),
 
   /* Set this option to limit the size of a file that will be downloaded from
      an HTTP or FTP server.
@@ -1412,7 +1495,7 @@ typedef enum {
      CURLUSESSL_CONTROL - SSL for the control connection or fail
      CURLUSESSL_ALL     - SSL for all communication or fail
   */
-  CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_LONG, 119),
+  CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_VALUES, 119),
 
   /* The _LARGE version of the standard POSTFIELDSIZE option */
   CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120),
@@ -1438,10 +1521,10 @@ typedef enum {
      CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
      CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
   */
-  CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_LONG, 129),
+  CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_VALUES, 129),
 
   CURLOPT(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130),
-  CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_OBJECTPOINT, 131),
+  CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_CBPOINT, 131),
 
   /* 132 OBSOLETE. Gone in 7.16.0 */
   /* 133 OBSOLETE. Gone in 7.16.0 */
@@ -1464,7 +1547,7 @@ typedef enum {
 
   /* Select "file method" to use when doing FTP, see the curl_ftpmethod
      above. */
-  CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_LONG, 138),
+  CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_VALUES, 138),
 
   /* Local port number to bind the socket to */
   CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139),
@@ -1501,14 +1584,14 @@ typedef enum {
 
   /* callback function for setting socket options */
   CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148),
-  CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_OBJECTPOINT, 149),
+  CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_CBPOINT, 149),
 
   /* set to 0 to disable session ID re-use for this transfer, default is
      enabled (== 1) */
   CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150),
 
   /* allowed SSH authentication methods */
-  CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_LONG, 151),
+  CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_VALUES, 151),
 
   /* Used by scp/sftp to do public/private key authentication */
   CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152),
@@ -1533,7 +1616,7 @@ typedef enum {
 
   /* Set the behaviour of POST when redirecting. Values must be set to one
      of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
-  CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_LONG, 161),
+  CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_VALUES, 161),
 
   /* used by scp/sftp to verify the host's public key */
   CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162),
@@ -1543,7 +1626,7 @@ typedef enum {
      CURL_SOCKET_BAD.  The callback should have type
      curl_opensocket_callback */
   CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163),
-  CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 164),
+  CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_CBPOINT, 164),
 
   /* POST volatile input fields. */
   CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165),
@@ -1553,7 +1636,7 @@ typedef enum {
 
   /* Callback function for seeking in the input stream */
   CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167),
-  CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_OBJECTPOINT, 168),
+  CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_CBPOINT, 168),
 
   /* CRL file */
   CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169),
@@ -1614,7 +1697,7 @@ typedef enum {
   CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184),
 
   /* set the SSH host key callback custom pointer */
-  CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_OBJECTPOINT, 185),
+  CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_CBPOINT, 185),
 
   /* set the SMTP mail originator */
   CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186),
@@ -1626,7 +1709,7 @@ typedef enum {
   CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188),
 
   /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
-  CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_LONG, 189),
+  CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_VALUES, 189),
 
   /* The RTSP session identifier */
   CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190),
@@ -1644,7 +1727,7 @@ typedef enum {
   CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194),
 
   /* The stream to pass to INTERLEAVEFUNCTION. */
-  CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_OBJECTPOINT, 195),
+  CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_CBPOINT, 195),
 
   /* Let the application define a custom write method for RTP data */
   CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196),
@@ -1664,10 +1747,10 @@ typedef enum {
   CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200),
 
   /* Let the application define custom chunk data pointer */
-  CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_OBJECTPOINT, 201),
+  CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_CBPOINT, 201),
 
   /* FNMATCH_FUNCTION user pointer */
-  CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_OBJECTPOINT, 202),
+  CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_CBPOINT, 202),
 
   /* send linked-list of name:port:address sets */
   CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203),
@@ -1696,10 +1779,10 @@ typedef enum {
   /* Callback function for closing socket (instead of close(2)). The callback
      should have type curl_closesocket_callback */
   CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208),
-  CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 209),
+  CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_CBPOINT, 209),
 
   /* allow GSSAPI credential delegation */
-  CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_LONG, 210),
+  CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_VALUES, 210),
 
   /* Set the name servers to use for DNS resolution */
   CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211),
@@ -1716,7 +1799,7 @@ typedef enum {
   CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215),
 
   /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
-  CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_LONG, 216),
+  CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_VALUES, 216),
 
   /* Set the SMTP auth originator */
   CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217),
@@ -1763,7 +1846,7 @@ typedef enum {
   CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228),
 
   /* Pass in a bitmask of "header options" */
-  CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_LONG, 229),
+  CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_VALUES, 229),
 
   /* The public key in DER form used to validate the peer public key
      this option is used only if SSL_VERIFYPEER is true */
@@ -1835,7 +1918,7 @@ typedef enum {
 
   /* What version to specifically try to use for proxy.
      See CURL_SSLVERSION defines below. */
-  CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_LONG, 250),
+  CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_VALUES, 250),
 
   /* Set a username for authenticated TLS for proxy */
   CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251),
@@ -1909,7 +1992,7 @@ typedef enum {
   CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272),
 
   /* User data to pass to the resolver start callback. */
-  CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_OBJECTPOINT, 273),
+  CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_CBPOINT, 273),
 
   /* send HAProxy PROXY protocol header? */
   CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274),
@@ -1940,7 +2023,7 @@ typedef enum {
   CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283),
 
   /* pointer to be passed to HTTP_TRAILER_FUNCTION */
-  CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_OBJECTPOINT, 284),
+  CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_CBPOINT, 284),
 
   /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
   CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285),
@@ -1971,6 +2054,25 @@ typedef enum {
   CURLOPT(CURLOPT_PROXY_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 296),
   CURLOPT(CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOPTTYPE_BLOB, 297),
 
+  /* the EC curves requested by the TLS client (RFC 8422, 5.1);
+   * OpenSSL support via 'set_groups'/'set_curves':
+   * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+   */
+  CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298),
+
+  /* HSTS bitmask */
+  CURLOPT(CURLOPT_HSTS_CTRL, CURLOPTTYPE_LONG, 299),
+  /* HSTS file name */
+  CURLOPT(CURLOPT_HSTS, CURLOPTTYPE_STRINGPOINT, 300),
+
+  /* HSTS read callback */
+  CURLOPT(CURLOPT_HSTSREADFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 301),
+  CURLOPT(CURLOPT_HSTSREADDATA, CURLOPTTYPE_CBPOINT, 302),
+
+  /* HSTS write callback */
+  CURLOPT(CURLOPT_HSTSWRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 303),
+  CURLOPT(CURLOPT_HSTSWRITEDATA, CURLOPTTYPE_CBPOINT, 304),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
@@ -2643,8 +2745,9 @@ typedef enum {
   CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
   CURLINFO_RETRY_AFTER      = CURLINFO_OFF_T + 57,
   CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58,
+  CURLINFO_PROXY_ERROR      = CURLINFO_LONG + 59,
 
-  CURLINFO_LASTONE          = 58
+  CURLINFO_LASTONE          = 59
 } CURLINFO;
 
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@@ -2841,6 +2944,7 @@ typedef struct curl_version_info_data curl_version_info_data;
 #define CURL_VERSION_HTTP3        (1<<25) /* HTTP3 support built-in */
 #define CURL_VERSION_ZSTD         (1<<26) /* zstd features are present */
 #define CURL_VERSION_UNICODE      (1<<27) /* Unicode support on Windows */
+#define CURL_VERSION_HSTS         (1<<28) /* HSTS is supported */
 
  /*
  * NAME curl_version_info()
@@ -2903,6 +3007,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
 #include "easy.h" /* nothing in curl is fun without the easy stuff */
 #include "multi.h"
 #include "urlapi.h"
+#include "options.h"
 
 /* the typechecker doesn't work in C++ (yet) */
 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
diff --git a/include/curl/curlver.h b/include/curl/curlver.h
index b9fd7e6..5990e6c 100644
--- a/include/curl/curlver.h
+++ b/include/curl/curlver.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -30,12 +30,12 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.72.0-DEV"
+#define LIBCURL_VERSION "7.74.0-DEV"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
-#define LIBCURL_VERSION_MINOR 72
+#define LIBCURL_VERSION_MINOR 74
 #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 0x074800
+#define LIBCURL_VERSION_NUM 0x074a00
 
 /*
  * This is the date and time when the full source package was created. The
diff --git a/include/curl/easy.h b/include/curl/easy.h
index 9aef133..2dbfb26 100644
--- a/include/curl/easy.h
+++ b/include/curl/easy.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/include/curl/mprintf.h b/include/curl/mprintf.h
index f615ed7..3549552 100644
--- a/include/curl/mprintf.h
+++ b/include/curl/mprintf.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/include/curl/multi.h b/include/curl/multi.h
index b911ba9..37f9829 100644
--- a/include/curl/multi.h
+++ b/include/curl/multi.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/include/curl/options.h b/include/curl/options.h
new file mode 100644
index 0000000..14373b5
--- /dev/null
+++ b/include/curl/options.h
@@ -0,0 +1,68 @@
+#ifndef CURLINC_OPTIONS_H
+#define CURLINC_OPTIONS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+  CURLOT_LONG,    /* long (a range of values) */
+  CURLOT_VALUES,  /*      (a defined set or bitmask) */
+  CURLOT_OFF_T,   /* curl_off_t (a range of values) */
+  CURLOT_OBJECT,  /* pointer (void *) */
+  CURLOT_STRING,  /*         (char * to zero terminated buffer) */
+  CURLOT_SLIST,   /*         (struct curl_slist *) */
+  CURLOT_CBPTR,   /*         (void * passed as-is to a callback) */
+  CURLOT_BLOB,    /* blob (struct curl_blob *) */
+  CURLOT_FUNCTION /* function pointer */
+} curl_easytype;
+
+/* Flag bits */
+
+/* "alias" means it is provided for old programs to remain functional,
+   we prefer another name */
+#define CURLOT_FLAG_ALIAS (1<<0)
+
+/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
+   to use for curl_easy_setopt() for the given id */
+struct curl_easyoption {
+  const char *name;
+  CURLoption id;
+  curl_easytype type;
+  unsigned int flags;
+};
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_by_name(const char *name);
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_by_id (CURLoption id);
+
+CURL_EXTERN const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+#endif /* CURLINC_OPTIONS_H */
diff --git a/include/curl/stdcheaders.h b/include/curl/stdcheaders.h
index a6bdc1a..60596c7 100644
--- a/include/curl/stdcheaders.h
+++ b/include/curl/stdcheaders.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/include/curl/system.h b/include/curl/system.h
index 867af61..faf8fcf 100644
--- a/include/curl/system.h
+++ b/include/curl/system.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index f8cb921..6d84150 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -273,6 +273,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_FTPPORT ||                                             \
    (option) == CURLOPT_FTP_ACCOUNT ||                                         \
    (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
+   (option) == CURLOPT_HSTS ||                                                \
    (option) == CURLOPT_INTERFACE ||                                           \
    (option) == CURLOPT_ISSUERCERT ||                                          \
    (option) == CURLOPT_KEYPASSWD ||                                           \
@@ -292,6 +293,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_PROXY_CAINFO ||                                        \
    (option) == CURLOPT_PROXY_CAPATH ||                                        \
    (option) == CURLOPT_PROXY_CRLFILE ||                                       \
+   (option) == CURLOPT_PROXY_ISSUERCERT ||                                    \
    (option) == CURLOPT_PROXY_KEYPASSWD ||                                     \
    (option) == CURLOPT_PROXY_PINNEDPUBLICKEY ||                               \
    (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
@@ -334,6 +336,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_USERNAME ||                                            \
    (option) == CURLOPT_USERPWD ||                                             \
    (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
+   (option) == CURLOPT_SSL_EC_CURVES ||                                       \
    0)
 
 /* evaluates to true if option takes a curl_write_callback argument */
@@ -354,10 +357,11 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_DEBUGDATA ||                                           \
    (option) == CURLOPT_FNMATCH_DATA ||                                        \
    (option) == CURLOPT_HEADERDATA ||                                          \
+   (option) == CURLOPT_HSTSREADDATA ||                                        \
+   (option) == CURLOPT_HSTSWRITEDATA ||                                       \
    (option) == CURLOPT_INTERLEAVEDATA ||                                      \
    (option) == CURLOPT_IOCTLDATA ||                                           \
    (option) == CURLOPT_OPENSOCKETDATA ||                                      \
-   (option) == CURLOPT_PRIVATE ||                                             \
    (option) == CURLOPT_PROGRESSDATA ||                                        \
    (option) == CURLOPT_READDATA ||                                            \
    (option) == CURLOPT_SEEKDATA ||                                            \
diff --git a/include/curl/urlapi.h b/include/curl/urlapi.h
index f2d0677..7343cb6 100644
--- a/include/curl/urlapi.h
+++ b/include/curl/urlapi.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 1d71e14..9736e39 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
@@ -39,7 +39,7 @@ list(APPEND HHEADERS
   ${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
   )
 
-if(MSVC)
+if(WIN32)
   list(APPEND CSOURCES libcurl.rc)
 endif()
 
@@ -50,15 +50,6 @@ endif()
 # # strtoofft.c - specify later
 # )
 
-# # if we have Kerberos 4, right now this is never on
-# #OPTION(CURL_KRB4 "Use Kerberos 4" OFF)
-# IF(CURL_KRB4)
-# SET(CSOURCES ${CSOURCES}
-# krb4.c
-# security.c
-# )
-# ENDIF(CURL_KRB4)
-
 # #OPTION(CURL_MALLOC_DEBUG "Debug mallocs in Curl" OFF)
 # MARK_AS_ADVANCED(CURL_MALLOC_DEBUG)
 # IF(CURL_MALLOC_DEBUG)
@@ -97,10 +88,6 @@ add_library(
   ALIAS ${LIB_NAME}
   )
 
-if(MSVC AND NOT BUILD_SHARED_LIBS)
-  set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
-endif()
-
 if(NOT BUILD_SHARED_LIBS)
     set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
 endif()
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index ae3f961..6d35704 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -9,7 +9,7 @@
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
-# are also available at https://curl.haxx.se/docs/copyright.html.
+# are also available at https://curl.se/docs/copyright.html.
 #
 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
 # copies of the Software, and permit persons to whom the Software is
@@ -56,19 +56,19 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c            \
   http_ntlm.c http_proxy.c idn_win32.c if2ip.c imap.c inet_ntop.c inet_pton.c \
   krb5.c ldap.c llist.c md4.c md5.c memdebug.c mime.c mprintf.c mqtt.c        \
   multi.c netrc.c non-ascii.c nonblock.c openldap.c parsedate.c pingpong.c    \
-  pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c security.c select.c    \
+  pop3.c progress.c psl.c doh.c rand.c rename.c rtsp.c select.c               \
   sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
   socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c         \
   strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c    \
   transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c     \
-  version_win32.c
+  version_win32.c easyoptions.c easygetopt.c hsts.c
 
 LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h    \
   content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h      \
   curl_des.h curl_endian.h curl_fnmatch.h curl_get_line.h curl_gethostname.h  \
   curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h   \
   curl_memrchr.h curl_multibyte.h curl_ntlm_core.h curl_ntlm_wb.h curl_path.h \
-  curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_sec.h curl_setup.h  \
+  curl_printf.h curl_range.h curl_rtmp.h curl_sasl.h curl_krb5.h curl_setup.h \
   curl_setup_once.h curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h   \
   dotdot.h easyif.h escape.h file.h fileinfo.h formdata.h ftp.h url.h         \
   ftplistparser.h getinfo.h gopher.h hash.h hostcheck.h hostip.h http.h       \
@@ -80,7 +80,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h    \
   smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
   strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h     \
   timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h           \
-  x509asn1.h dynbuf.h version_win32.h
+  x509asn1.h dynbuf.h version_win32.h easyoptions.h hsts.h
 
 LIB_RCFILES = libcurl.rc
 
diff --git a/lib/altsvc.c b/lib/altsvc.c
index c2ec489..4ab77fd 100644
--- a/lib/altsvc.c
+++ b/lib/altsvc.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -25,7 +25,7 @@
  */
 #include "curl_setup.h"
 
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
 #include <curl/curl.h>
 #include "urldata.h"
 #include "altsvc.h"
@@ -302,11 +302,12 @@ CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
  * Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
  * resources.
  */
-void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
+void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp)
 {
-  struct curl_llist_element *e;
-  struct curl_llist_element *n;
-  if(altsvc) {
+  struct Curl_llist_element *e;
+  struct Curl_llist_element *n;
+  if(*altsvcp) {
+    struct altsvcinfo *altsvc = *altsvcp;
     for(e = altsvc->list.head; e; e = n) {
       struct altsvc *as = e->ptr;
       n = e->next;
@@ -314,6 +315,7 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
     }
     free(altsvc->filename);
     free(altsvc);
+    *altsvcp = NULL; /* clear the pointer */
   }
 }
 
@@ -323,8 +325,8 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
 CURLcode Curl_altsvc_save(struct Curl_easy *data,
                           struct altsvcinfo *altsvc, const char *file)
 {
-  struct curl_llist_element *e;
-  struct curl_llist_element *n;
+  struct Curl_llist_element *e;
+  struct Curl_llist_element *n;
   CURLcode result = CURLE_OK;
   FILE *out;
   char *tempstore;
@@ -353,7 +355,7 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
   if(!out)
     result = CURLE_WRITE_ERROR;
   else {
-    fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
+    fputs("# Your alt-svc cache. https://curl.se/docs/alt-svc.html\n"
           "# This file was generated by libcurl! Edit at your own risk.\n",
           out);
     for(e = altsvc->list.head; e; e = n) {
@@ -399,8 +401,8 @@ static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
 static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
                          const char *srchost, unsigned short srcport)
 {
-  struct curl_llist_element *e;
-  struct curl_llist_element *n;
+  struct Curl_llist_element *e;
+  struct Curl_llist_element *n;
   for(e = asi->list.head; e; e = n) {
     struct altsvc *as = e->ptr;
     n = e->next;
@@ -449,12 +451,14 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
 {
   const char *p = value;
   size_t len;
-  enum alpnid dstalpnid = srcalpnid; /* the same by default */
   char namebuf[MAX_ALTSVC_HOSTLEN] = "";
   char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
   struct altsvc *as;
   unsigned short dstport = srcport; /* the same by default */
   CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  (void)data;
+#endif
   if(result) {
     infof(data, "Excessive alt-svc header, ignoring...\n");
     return CURLE_OK;
@@ -473,7 +477,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
   do {
     if(*p == '=') {
       /* [protocol]="[host][:port]" */
-      dstalpnid = alpn2alpnid(alpnbuf);
+      enum alpnid dstalpnid = alpn2alpnid(alpnbuf); /* the same by default */
       p++;
       if(*p == '\"') {
         const char *dsthost = "";
@@ -612,8 +616,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
                         struct altsvc **dstentry,
                         const int versions) /* one or more bits */
 {
-  struct curl_llist_element *e;
-  struct curl_llist_element *n;
+  struct Curl_llist_element *e;
+  struct Curl_llist_element *n;
   time_t now = time(NULL);
   DEBUGASSERT(asi);
   DEBUGASSERT(srchost);
@@ -640,4 +644,4 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
   return FALSE;
 }
 
-#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
diff --git a/lib/altsvc.h b/lib/altsvc.h
index 578a4fb..2ab89e7 100644
--- a/lib/altsvc.h
+++ b/lib/altsvc.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
  ***************************************************************************/
 #include "curl_setup.h"
 
-#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
 #include <curl/curl.h>
 #include "llist.h"
 
@@ -46,12 +46,12 @@ struct altsvc {
   time_t expires;
   bool persist;
   int prio;
-  struct curl_llist_element node;
+  struct Curl_llist_element node;
 };
 
 struct altsvcinfo {
   char *filename;
-  struct curl_llist list; /* list of entries */
+  struct Curl_llist list; /* list of entries */
   long flags; /* the publicly set bitmask */
 };
 
@@ -61,7 +61,7 @@ CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
 CURLcode Curl_altsvc_save(struct Curl_easy *data,
                           struct altsvcinfo *asi, const char *file);
 CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
-void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
+void Curl_altsvc_cleanup(struct altsvcinfo **altsvc);
 CURLcode Curl_altsvc_parse(struct Curl_easy *data,
                            struct altsvcinfo *altsvc, const char *value,
                            enum alpnid srcalpn, const char *srchost,
@@ -74,5 +74,6 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
 #else
 /* disabled */
 #define Curl_altsvc_save(a,b,c)
-#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
+#define Curl_altsvc_cleanup(x)
+#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
 #endif /* HEADER_CURL_ALTSVC_H */
diff --git a/lib/amigaos.c b/lib/amigaos.c
index cf44bdc..d3b00d9 100644
--- a/lib/amigaos.c
+++ b/lib/amigaos.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/amigaos.h b/lib/amigaos.h
index c776c9c..02e5bb5 100644
--- a/lib/amigaos.h
+++ b/lib/amigaos.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/arpa_telnet.h b/lib/arpa_telnet.h
index 232680e..cbe31de 100644
--- a/lib/arpa_telnet.h
+++ b/lib/arpa_telnet.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c
index e651507..1747571 100644
--- a/lib/asyn-ares.c
+++ b/lib/asyn-ares.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -67,8 +67,8 @@
 #include "select.h"
 #include "progress.h"
 
-#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
-     (defined(WIN32) || defined(__SYMBIAN32__))
+#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) &&   \
+  defined(WIN32)
 #    define CARES_STATICLIB
 #  endif
 #  include <ares.h>
@@ -85,7 +85,7 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
-struct ResolverResults {
+struct thread_data {
   int num_pending; /* number of ares_gethostbyname() requests */
   struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
                                     parts */
@@ -229,8 +229,8 @@ static void destroy_async_data(struct Curl_async *async)
 {
   free(async->hostname);
 
-  if(async->os_specific) {
-    struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
+  if(async->tdata) {
+    struct thread_data *res = async->tdata;
     if(res) {
       if(res->temp_ai) {
         Curl_freeaddrinfo(res->temp_ai);
@@ -238,7 +238,7 @@ static void destroy_async_data(struct Curl_async *async)
       }
       free(res);
     }
-    async->os_specific = NULL;
+    async->tdata = NULL;
   }
 
   async->hostname = NULL;
@@ -349,8 +349,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
                                    struct Curl_dns_entry **dns)
 {
   struct Curl_easy *data = conn->data;
-  struct ResolverResults *res = (struct ResolverResults *)
-    conn->async.os_specific;
+  struct thread_data *res = conn->async.tdata;
   CURLcode result = CURLE_OK;
 
   DEBUGASSERT(dns);
@@ -498,7 +497,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
 }
 
 /* Connects results to the list */
-static void compound_results(struct ResolverResults *res,
+static void compound_results(struct thread_data *res,
                              struct Curl_addrinfo *ai)
 {
   struct Curl_addrinfo *ai_tail;
@@ -527,7 +526,7 @@ static void query_completed_cb(void *arg,  /* (struct connectdata *) */
                                struct hostent *hostent)
 {
   struct connectdata *conn = (struct connectdata *)arg;
-  struct ResolverResults *res;
+  struct thread_data *res;
 
 #ifdef HAVE_CARES_CALLBACK_TIMEOUTS
   (void)timeouts; /* ignored */
@@ -538,7 +537,7 @@ static void query_completed_cb(void *arg,  /* (struct connectdata *) */
        be valid so only defer it when we know the 'status' says its fine! */
     return;
 
-  res = (struct ResolverResults *)conn->async.os_specific;
+  res = conn->async.tdata;
   if(res) {
     res->num_pending--;
 
@@ -653,20 +652,20 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
 
   bufp = strdup(hostname);
   if(bufp) {
-    struct ResolverResults *res = NULL;
+    struct thread_data *res = NULL;
     free(conn->async.hostname);
     conn->async.hostname = bufp;
     conn->async.port = port;
     conn->async.done = FALSE;   /* not done */
     conn->async.status = 0;     /* clear */
     conn->async.dns = NULL;     /* clear */
-    res = calloc(sizeof(struct ResolverResults), 1);
+    res = calloc(sizeof(struct thread_data), 1);
     if(!res) {
       free(conn->async.hostname);
       conn->async.hostname = NULL;
       return NULL;
     }
-    conn->async.os_specific = res;
+    conn->async.tdata = res;
 
     /* initial status - failed */
     res->last_status = ARES_ENOTFOUND;
diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index a60f4f0..7c85982 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -185,7 +185,7 @@ struct thread_data {
 
 static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
 {
-  return &(((struct thread_data *)conn->async.os_specific)->tsd);
+  return &(conn->async.tdata->tsd);
 }
 
 /* Destroy resolver thread synchronization data */
@@ -294,7 +294,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
  */
 static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
 {
-  struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
+  struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
   struct thread_data *td = tsd->td;
   char service[12];
   int rc;
@@ -380,8 +380,8 @@ static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
  */
 static void destroy_async_data(struct Curl_async *async)
 {
-  if(async->os_specific) {
-    struct thread_data *td = (struct thread_data*) async->os_specific;
+  if(async->tdata) {
+    struct thread_data *td = async->tdata;
     int done;
 #ifdef USE_SOCKETPAIR
     curl_socket_t sock_rd = td->tsd.sock_pair[0];
@@ -406,7 +406,7 @@ static void destroy_async_data(struct Curl_async *async)
 
       destroy_thread_sync_data(&td->tsd);
 
-      free(async->os_specific);
+      free(async->tdata);
     }
 #ifdef USE_SOCKETPAIR
     /*
@@ -418,7 +418,7 @@ static void destroy_async_data(struct Curl_async *async)
     sclose(sock_rd);
 #endif
   }
-  async->os_specific = NULL;
+  async->tdata = NULL;
 
   free(async->hostname);
   async->hostname = NULL;
@@ -437,7 +437,7 @@ static bool init_resolve_thread(struct connectdata *conn,
   struct thread_data *td = calloc(1, sizeof(struct thread_data));
   int err = ENOMEM;
 
-  conn->async.os_specific = (void *)td;
+  conn->async.tdata = td;
   if(!td)
     goto errno_exit;
 
@@ -448,7 +448,7 @@ static bool init_resolve_thread(struct connectdata *conn,
   td->thread_hnd = curl_thread_t_null;
 
   if(!init_thread_sync_data(td, hostname, port, hints)) {
-    conn->async.os_specific = NULL;
+    conn->async.tdata = NULL;
     free(td);
     goto errno_exit;
   }
@@ -519,7 +519,7 @@ static CURLcode thread_wait_resolv(struct connectdata *conn,
                                    struct Curl_dns_entry **entry,
                                    bool report)
 {
-  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  struct thread_data *td = conn->async.tdata;
   CURLcode result = CURLE_OK;
 
   DEBUGASSERT(conn && td);
@@ -557,7 +557,7 @@ static CURLcode thread_wait_resolv(struct connectdata *conn,
  */
 void Curl_resolver_kill(struct connectdata *conn)
 {
-  struct thread_data *td = (struct thread_data*) conn->async.os_specific;
+  struct thread_data *td = conn->async.tdata;
 
   /* If we're still resolving, we must wait for the threads to fully clean up,
      unfortunately.  Otherwise, we can simply cancel to clean up any resolver
@@ -596,7 +596,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
                                    struct Curl_dns_entry **entry)
 {
   struct Curl_easy *data = conn->data;
-  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  struct thread_data *td = conn->async.tdata;
   int done = 0;
 
   DEBUGASSERT(entry);
@@ -656,7 +656,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
   struct Curl_easy *data = conn->data;
   struct resdata *reslv = (struct resdata *)data->state.resolver;
 #ifdef USE_SOCKETPAIR
-  struct thread_data *td = (struct thread_data*)conn->async.os_specific;
+  struct thread_data *td = conn->async.tdata;
 #else
   (void)socks;
 #endif
diff --git a/lib/asyn.h b/lib/asyn.h
index bd3c3c1..73a9b72 100644
--- a/lib/asyn.h
+++ b/lib/asyn.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/base64.c b/lib/base64.c
index 643cef6..be6f163 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -26,6 +26,9 @@
 
 #if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_SSH) || \
   !defined(CURL_DISABLE_LDAP) || \
+  !defined(CURL_DISABLE_SMTP) || \
+  !defined(CURL_DISABLE_POP3) || \
+  !defined(CURL_DISABLE_IMAP) || \
   !defined(CURL_DISABLE_DOH) || defined(USE_SSL)
 
 #include "urldata.h" /* for the Curl_easy definition */
diff --git a/lib/conncache.c b/lib/conncache.c
index d21a00c..cb3170c 100644
--- a/lib/conncache.c
+++ b/lib/conncache.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -59,7 +59,7 @@ static CURLcode bundle_create(struct connectbundle **bundlep)
   (*bundlep)->num_connections = 0;
   (*bundlep)->multiuse = BUNDLE_UNKNOWN;
 
-  Curl_llist_init(&(*bundlep)->conn_list, (curl_llist_dtor) conn_llist_dtor);
+  Curl_llist_init(&(*bundlep)->conn_list, (Curl_llist_dtor) conn_llist_dtor);
   return CURLE_OK;
 }
 
@@ -87,7 +87,7 @@ static void bundle_add_conn(struct connectbundle *bundle,
 static int bundle_remove_conn(struct connectbundle *bundle,
                               struct connectdata *conn)
 {
-  struct curl_llist_element *curr;
+  struct Curl_llist_element *curr;
 
   curr = bundle->conn_list.head;
   while(curr) {
@@ -206,8 +206,8 @@ static bool conncache_add_bundle(struct conncache *connc,
 static void conncache_remove_bundle(struct conncache *connc,
                                     struct connectbundle *bundle)
 {
-  struct curl_hash_iterator iter;
-  struct curl_hash_element *he;
+  struct Curl_hash_iterator iter;
+  struct Curl_hash_element *he;
 
   if(!connc)
     return;
@@ -320,9 +320,9 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
                             void *param,
                             int (*func)(struct connectdata *conn, void *param))
 {
-  struct curl_hash_iterator iter;
-  struct curl_llist_element *curr;
-  struct curl_hash_element *he;
+  struct Curl_hash_iterator iter;
+  struct Curl_llist_element *curr;
+  struct Curl_hash_element *he;
 
   if(!connc)
     return FALSE;
@@ -363,15 +363,15 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
 static struct connectdata *
 conncache_find_first_connection(struct conncache *connc)
 {
-  struct curl_hash_iterator iter;
-  struct curl_hash_element *he;
+  struct Curl_hash_iterator iter;
+  struct Curl_hash_element *he;
   struct connectbundle *bundle;
 
   Curl_hash_start_iterate(&connc->hash, &iter);
 
   he = Curl_hash_next_element(&iter);
   while(he) {
-    struct curl_llist_element *curr;
+    struct Curl_llist_element *curr;
     bundle = he->ptr;
 
     curr = bundle->conn_list.head;
@@ -429,7 +429,7 @@ struct connectdata *
 Curl_conncache_extract_bundle(struct Curl_easy *data,
                               struct connectbundle *bundle)
 {
-  struct curl_llist_element *curr;
+  struct Curl_llist_element *curr;
   timediff_t highscore = -1;
   timediff_t score;
   struct curltime now;
@@ -477,9 +477,9 @@ struct connectdata *
 Curl_conncache_extract_oldest(struct Curl_easy *data)
 {
   struct conncache *connc = data->state.conn_cache;
-  struct curl_hash_iterator iter;
-  struct curl_llist_element *curr;
-  struct curl_hash_element *he;
+  struct Curl_hash_iterator iter;
+  struct Curl_llist_element *curr;
+  struct Curl_hash_element *he;
   timediff_t highscore =- 1;
   timediff_t score;
   struct curltime now;
@@ -571,9 +571,9 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
 /* Useful for debugging the connection cache */
 void Curl_conncache_print(struct conncache *connc)
 {
-  struct curl_hash_iterator iter;
-  struct curl_llist_element *curr;
-  struct curl_hash_element *he;
+  struct Curl_hash_iterator iter;
+  struct Curl_llist_element *curr;
+  struct Curl_hash_element *he;
 
   if(!connc)
     return;
diff --git a/lib/conncache.h b/lib/conncache.h
index 3dda21c..ac5460f 100644
--- a/lib/conncache.h
+++ b/lib/conncache.h
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -30,7 +30,7 @@
  */
 
 struct conncache {
-  struct curl_hash hash;
+  struct Curl_hash hash;
   size_t num_conn;
   long next_connection_id;
   struct curltime last_cleanup;
@@ -66,7 +66,7 @@ struct conncache {
 struct connectbundle {
   int multiuse;                 /* supports multi-use */
   size_t num_connections;       /* Number of connections in the bundle */
-  struct curl_llist conn_list;  /* The connectdata members of the bundle */
+  struct Curl_llist conn_list;  /* The connectdata members of the bundle */
 };
 
 /* returns 1 on error, 0 is fine */
diff --git a/lib/connect.c b/lib/connect.c
index b000b1b..e65d24d 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -83,11 +83,6 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
-#ifdef __SYMBIAN32__
-/* This isn't actually supported under Symbian OS */
-#undef SO_NOSIGPIPE
-#endif
-
 static bool verifyconnect(curl_socket_t sockfd, int *error);
 
 #if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
@@ -678,57 +673,69 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
 
 /* retrieves the start/end point information of a socket of an established
    connection */
-void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd)
 {
-  if(conn->transport == TRNSPRT_TCP) {
-#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
-    if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
-      struct Curl_easy *data = conn->data;
-      char buffer[STRERROR_LEN];
-      struct Curl_sockaddr_storage ssrem;
-      struct Curl_sockaddr_storage ssloc;
-      curl_socklen_t plen;
-      curl_socklen_t slen;
-#ifdef HAVE_GETPEERNAME
-      plen = sizeof(struct Curl_sockaddr_storage);
-      if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
-        int error = SOCKERRNO;
-        failf(data, "getpeername() failed with errno %d: %s",
-              error, Curl_strerror(error, buffer, sizeof(buffer)));
-        return;
-      }
-#endif
-#ifdef HAVE_GETSOCKNAME
-      slen = sizeof(struct Curl_sockaddr_storage);
-      memset(&ssloc, 0, sizeof(ssloc));
-      if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
-        int error = SOCKERRNO;
-        failf(data, "getsockname() failed with errno %d: %s",
-              error, Curl_strerror(error, buffer, sizeof(buffer)));
-        return;
-      }
-#endif
 #ifdef HAVE_GETPEERNAME
-      if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
-                           conn->primary_ip, &conn->primary_port)) {
-        failf(data, "ssrem inet_ntop() failed with errno %d: %s",
-              errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-        return;
-      }
-      memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+  char buffer[STRERROR_LEN];
+  struct Curl_sockaddr_storage ssrem;
+  curl_socklen_t plen;
+  plen = sizeof(struct Curl_sockaddr_storage);
+  if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
+    int error = SOCKERRNO;
+    failf(conn->data, "getpeername() failed with errno %d: %s",
+          error, Curl_strerror(error, buffer, sizeof(buffer)));
+    return;
+  }
+  if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+                       conn->primary_ip, &conn->primary_port)) {
+    failf(conn->data, "ssrem inet_ntop() failed with errno %d: %s",
+          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+    return;
+  }
+  memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+#else
+  (void)conn;
+  (void)sockfd;
 #endif
+}
+
+/* retrieves the start/end point information of a socket of an established
+   connection */
+void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd)
+{
 #ifdef HAVE_GETSOCKNAME
-      if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
-                           conn->local_ip, &conn->local_port)) {
-        failf(data, "ssloc inet_ntop() failed with errno %d: %s",
-              errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-        return;
-      }
+  char buffer[STRERROR_LEN];
+  struct Curl_sockaddr_storage ssloc;
+  curl_socklen_t slen;
+  slen = sizeof(struct Curl_sockaddr_storage);
+  memset(&ssloc, 0, sizeof(ssloc));
+  if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
+    int error = SOCKERRNO;
+    failf(conn->data, "getsockname() failed with errno %d: %s",
+          error, Curl_strerror(error, buffer, sizeof(buffer)));
+    return;
+  }
+  if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+                       conn->local_ip, &conn->local_port)) {
+    failf(conn->data, "ssloc inet_ntop() failed with errno %d: %s",
+          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+    return;
+  }
+#else
+  (void)conn;
+  (void)sockfd;
 #endif
+}
+
+/* retrieves the start/end point information of a socket of an established
+   connection */
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+{
+  if(conn->transport == TRNSPRT_TCP) {
+    if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+      Curl_conninfo_remote(conn, sockfd);
+      Curl_conninfo_local(conn, sockfd);
     }
-#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
-    (void)sockfd; /* unused */
-#endif
   } /* end of TCP-only section */
 
   /* persist connection info in session handle */
@@ -746,8 +753,8 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
                               bool *done)
 {
   CURLcode result = CURLE_OK;
-
 #ifndef CURL_DISABLE_PROXY
+  CURLproxycode pxresult = CURLPX_OK;
   if(conn->bits.socksproxy) {
     /* for the secondary socket (FTP), use the "connect to host"
      * but ignore the "connect to port" (use the secondary port)
@@ -767,20 +774,24 @@ static CURLcode connect_SOCKS(struct connectdata *conn, int sockindex,
     switch(conn->socks_proxy.proxytype) {
     case CURLPROXY_SOCKS5:
     case CURLPROXY_SOCKS5_HOSTNAME:
-      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
-                           host, port, sockindex, conn, done);
+      pxresult = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
+                             host, port, sockindex, conn, done);
       break;
 
     case CURLPROXY_SOCKS4:
     case CURLPROXY_SOCKS4A:
-      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
-                           conn, done);
+      pxresult = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
+                             conn, done);
       break;
 
     default:
       failf(conn->data, "unknown proxytype option given");
       result = CURLE_COULDNT_CONNECT;
     } /* switch proxytype */
+    if(pxresult) {
+      result = CURLE_PROXY;
+      conn->data->info.pxcode = pxresult;
+    }
   }
   else
 #else
@@ -1313,10 +1324,9 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
                           const struct Curl_dns_entry *remotehost)
 {
   struct Curl_easy *data = conn->data;
-  struct curltime before = Curl_now();
   CURLcode result = CURLE_COULDNT_CONNECT;
   int i;
-  timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
+  timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
 
   if(timeout_ms < 0) {
     /* a precaution, no need to continue if time already is up */
@@ -1336,8 +1346,12 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
 
   conn->tempfamily[0] = conn->tempaddr[0]?
     conn->tempaddr[0]->ai_family:0;
+#ifdef ENABLE_IPV6
   conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ?
     AF_INET : AF_INET6;
+#else
+  conn->tempfamily[1] = AF_UNSPEC;
+#endif
   ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */
 
   DEBUGF(infof(data, "family0 == %s, family1 == %s\n",
@@ -1416,8 +1430,7 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
     }
     return c->sock[FIRSTSOCKET];
   }
-  else
-    return CURL_SOCKET_BAD;
+  return CURL_SOCKET_BAD;
 }
 
 /*
diff --git a/lib/connect.h b/lib/connect.h
index 6fd9ea8..9b1faf8 100644
--- a/lib/connect.h
+++ b/lib/connect.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -75,6 +75,8 @@ void Curl_sndbufset(curl_socket_t sockfd);
 #endif
 
 void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_conninfo_remote(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_conninfo_local(struct connectdata *conn, curl_socket_t sockfd);
 void Curl_persistconninfo(struct connectdata *conn);
 int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
 
diff --git a/lib/content_encoding.c b/lib/content_encoding.c
index 2fc3d43..82fcc2b 100644
--- a/lib/content_encoding.c
+++ b/lib/content_encoding.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -28,10 +28,6 @@
 
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
-#ifdef __SYMBIAN32__
-/* zlib pollutes the namespace with this definition */
-#undef WIN32
-#endif
 #endif
 
 #ifdef HAVE_BROTLI
diff --git a/lib/content_encoding.h b/lib/content_encoding.h
index bdd3f1c..7031087 100644
--- a/lib/content_encoding.h
+++ b/lib/content_encoding.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/cookie.c b/lib/cookie.c
index cb7d94b..e88678c 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -1539,7 +1539,7 @@ static int cookie_output(struct Curl_easy *data,
   }
 
   fputs("# Netscape HTTP Cookie File\n"
-        "# https://curl.haxx.se/docs/http-cookies.html\n"
+        "# https://curl.se/docs/http-cookies.html\n"
         "# This file was generated by libcurl! Edit at your own risk.\n\n",
         out);
 
diff --git a/lib/cookie.h b/lib/cookie.h
index b3865e6..066396f 100644
--- a/lib/cookie.h
+++ b/lib/cookie.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c
index 947d0d3..872395b 100644
--- a/lib/curl_addrinfo.c
+++ b/lib/curl_addrinfo.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h
index a0cade6..73a8c1b 100644
--- a/lib/curl_addrinfo.h
+++ b/lib/curl_addrinfo.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_base64.h b/lib/curl_base64.h
index cfb6ee7..d48edc4 100644
--- a/lib/curl_base64.h
+++ b/lib/curl_base64.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
index dd87078..082d76b 100644
--- a/lib/curl_config.h.cmake
+++ b/lib/curl_config.h.cmake
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -63,8 +63,8 @@
 /* to disable LDAPS */
 #cmakedefine CURL_DISABLE_LDAPS 1
 
-/* to enable MQTT */
-#undef CURL_ENABLE_MQTT
+/* to disable MQTT */
+#cmakedefine CURL_DISABLE_MQTT 1
 
 /* to disable POP3 */
 #cmakedefine CURL_DISABLE_POP3 1
@@ -395,8 +395,11 @@
 /* Define to 1 if you have the <libgen.h> header file. */
 #cmakedefine HAVE_LIBGEN_H 1
 
-/* Define to 1 if you have the `idn' library (-lidn). */
-#cmakedefine HAVE_LIBIDN 1
+/* Define to 1 if you have the `idn2' library (-lidn2). */
+#cmakedefine HAVE_LIBIDN2 1
+
+/* Define to 1 if you have the idn2.h header file. */
+#cmakedefine HAVE_IDN2_H 1
 
 /* Define to 1 if you have the `resolv' library (-lresolv). */
 #cmakedefine HAVE_LIBRESOLV 1
@@ -470,6 +473,9 @@
 /* Define to 1 if you have the <netinet/tcp.h> header file. */
 #cmakedefine HAVE_NETINET_TCP_H 1
 
+/* Define to 1 if you have the <linux/tcp.h> header file. */
+#cmakedefine HAVE_LINUX_TCP_H 1
+
 /* Define to 1 if you have the <net/if.h> header file. */
 #cmakedefine HAVE_NET_IF_H 1
 
@@ -1014,8 +1020,8 @@ ${SIZEOF_TIME_T_CODE}
 /* if Unix domain sockets are enabled  */
 #cmakedefine USE_UNIX_SOCKETS
 
-/* to enable alt-svc */
-#cmakedefine USE_ALTSVC 1
+/* to disable alt-svc */
+#cmakedefine CURL_DISABLE_ALTSVC 1
 
 /* Define to 1 if you are building a Windows target with large file support. */
 #cmakedefine USE_WIN32_LARGE_FILES 1
diff --git a/lib/curl_ctype.c b/lib/curl_ctype.c
index 1a47fb5..d6cd08a 100644
--- a/lib/curl_ctype.c
+++ b/lib/curl_ctype.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_ctype.h b/lib/curl_ctype.h
index 6e94bb1..17dfaa0 100644
--- a/lib/curl_ctype.h
+++ b/lib/curl_ctype.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_des.c b/lib/curl_des.c
index 39c0f35..8c5af19 100644
--- a/lib/curl_des.c
+++ b/lib/curl_des.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015 - 2020, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_des.h b/lib/curl_des.h
index a42eeb5..438706a 100644
--- a/lib/curl_des.h
+++ b/lib/curl_des.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2015 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2015 - 2020, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_endian.c b/lib/curl_endian.c
index a774d13..2fc25bc 100644
--- a/lib/curl_endian.c
+++ b/lib/curl_endian.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_endian.h b/lib/curl_endian.h
index 9830e58..341dfaf 100644
--- a/lib/curl_endian.h
+++ b/lib/curl_endian.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index ab3e742..4bfa585 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_fnmatch.h b/lib/curl_fnmatch.h
index 34fccae..1c80ea7 100644
--- a/lib/curl_fnmatch.h
+++ b/lib/curl_fnmatch.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_get_line.c b/lib/curl_get_line.c
index c419485..438ede7 100644
--- a/lib/curl_get_line.c
+++ b/lib/curl_get_line.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -22,6 +22,9 @@
 
 #include "curl_setup.h"
 
+#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) ||  \
+  defined(USE_HSTS)
+
 #include "curl_get_line.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -53,3 +56,5 @@ char *Curl_get_line(char *buf, int len, FILE *input)
   }
   return NULL;
 }
+
+#endif /* if not disabled */
diff --git a/lib/curl_get_line.h b/lib/curl_get_line.h
index 532ab08..597aa09 100644
--- a/lib/curl_get_line.h
+++ b/lib/curl_get_line.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_gethostname.c b/lib/curl_gethostname.c
index 8337c72..2d5ff61 100644
--- a/lib/curl_gethostname.c
+++ b/lib/curl_gethostname.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -48,7 +48,7 @@
  * For libcurl static library release builds no overriding takes place.
  */
 
-int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
+int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
 {
 #ifndef HAVE_GETHOSTNAME
 
diff --git a/lib/curl_gethostname.h b/lib/curl_gethostname.h
index 8ae15e6..2161c40 100644
--- a/lib/curl_gethostname.h
+++ b/lib/curl_gethostname.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -26,6 +26,6 @@
 #define HOSTNAME_MAX 1024
 
 /* This returns the local machine's un-qualified hostname */
-int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
+int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen);
 
 #endif /* HEADER_CURL_GETHOSTNAME_H */
diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c
index d854ab0..f72430b 100644
--- a/lib/curl_gssapi.c
+++ b/lib/curl_gssapi.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_gssapi.h b/lib/curl_gssapi.h
index 88f68db..466d09e 100644
--- a/lib/curl_gssapi.h
+++ b/lib/curl_gssapi.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2011 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_hmac.h b/lib/curl_hmac.h
index 9b70c84..84c7312 100644
--- a/lib/curl_hmac.h
+++ b/lib/curl_hmac.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_krb5.h b/lib/curl_krb5.h
new file mode 100644
index 0000000..f0a6fa6
--- /dev/null
+++ b/lib/curl_krb5.h
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_KRB5_H
+#define HEADER_CURL_KRB5_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct Curl_sec_client_mech {
+  const char *name;
+  size_t size;
+  int (*init)(void *);
+  int (*auth)(void *, struct connectdata *);
+  void (*end)(void *);
+  int (*check_prot)(void *, int);
+  int (*overhead)(void *, int, int);
+  int (*encode)(void *, const void *, int, int, void **);
+  int (*decode)(void *, void *, int, int, struct connectdata *);
+};
+
+#define AUTH_OK         0
+#define AUTH_CONTINUE   1
+#define AUTH_ERROR      2
+
+#ifdef HAVE_GSSAPI
+int Curl_sec_read_msg(struct connectdata *conn, char *,
+                      enum protection_level);
+void Curl_sec_end(struct connectdata *);
+CURLcode Curl_sec_login(struct connectdata *);
+int Curl_sec_request_prot(struct connectdata *conn, const char *level);
+#else
+#define Curl_sec_end(x)
+#endif
+
+#endif /* HEADER_CURL_KRB5_H */
diff --git a/lib/curl_ldap.h b/lib/curl_ldap.h
index 912e131..124e18b 100644
--- a/lib/curl_ldap.h
+++ b/lib/curl_ldap.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_md4.h b/lib/curl_md4.h
index c7bb209..f9dafcb 100644
--- a/lib/curl_md4.h
+++ b/lib/curl_md4.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_md5.h b/lib/curl_md5.h
index e06c68e..5739c89 100644
--- a/lib/curl_md5.h
+++ b/lib/curl_md5.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_memory.h b/lib/curl_memory.h
index ce38a08..5806290 100644
--- a/lib/curl_memory.h
+++ b/lib/curl_memory.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_memrchr.c b/lib/curl_memrchr.c
index eeb3044..0bd845f 100644
--- a/lib/curl_memrchr.c
+++ b/lib/curl_memrchr.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_memrchr.h b/lib/curl_memrchr.h
index 90a8a07..c8394bb 100644
--- a/lib/curl_memrchr.h
+++ b/lib/curl_memrchr.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_multibyte.c b/lib/curl_multibyte.c
index 2c8925b5..d327c8b 100644
--- a/lib/curl_multibyte.c
+++ b/lib/curl_multibyte.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_multibyte.h b/lib/curl_multibyte.h
index 5f8c05a..8adaf49 100644
--- a/lib/curl_multibyte.h
+++ b/lib/curl_multibyte.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 0eefb15..9a075ac 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -22,7 +22,7 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NTLM)
+#if defined(USE_CURL_NTLM_CORE)
 
 /*
  * NTLM details:
@@ -50,8 +50,6 @@
      in NTLM type-3 messages.
  */
 
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
 #if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
 
 #ifdef USE_WOLFSSL
@@ -582,15 +580,11 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
   unsigned char *identity;
   CURLcode result = CURLE_OK;
 
-  /* we do the length checks below separately to avoid integer overflow risk
-     on extreme data lengths */
-  if((userlen > SIZE_T_MAX/2) ||
-     (domlen > SIZE_T_MAX/2) ||
-     ((userlen + domlen) > SIZE_T_MAX/2))
+  if((userlen > CURL_MAX_INPUT_LENGTH) || (domlen > CURL_MAX_INPUT_LENGTH))
     return CURLE_OUT_OF_MEMORY;
 
   identity_len = (userlen + domlen) * 2;
-  identity = malloc(identity_len);
+  identity = malloc(identity_len + 1);
 
   if(!identity)
     return CURLE_OUT_OF_MEMORY;
@@ -744,6 +738,4 @@ CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
 
 #endif /* USE_NTRESPONSES */
 
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* USE_NTLM */
+#endif /* USE_CURL_NTLM_CORE */
diff --git a/lib/curl_ntlm_core.h b/lib/curl_ntlm_core.h
index 7895b64..fab628c 100644
--- a/lib/curl_ntlm_core.h
+++ b/lib/curl_ntlm_core.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -24,7 +24,7 @@
 
 #include "curl_setup.h"
 
-#if defined(USE_NTLM)
+#if defined(USE_CURL_NTLM_CORE)
 
 /* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
    then it must be initialized to be used by NTLM. */
@@ -36,8 +36,6 @@
 #define NTLM_NEEDS_NSS_INIT
 #endif
 
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
 #if defined(USE_OPENSSL) || defined(USE_WOLFSSL)
 #ifdef USE_WOLFSSL
 #  include <wolfssl/options.h>
@@ -102,8 +100,6 @@ CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
 
 #endif /* USE_NTRESPONSES */
 
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* USE_NTLM */
+#endif /* USE_CURL_NTLM_CORE */
 
 #endif /* HEADER_CURL_NTLM_CORE_H */
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index 17a92f8..c11757f 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_ntlm_wb.h b/lib/curl_ntlm_wb.h
index 3cf841c..4f847d2 100644
--- a/lib/curl_ntlm_wb.h
+++ b/lib/curl_ntlm_wb.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_path.c b/lib/curl_path.c
index fbd98cb..8c8cbc2 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -168,7 +168,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
     *cpp = cp + i + strspn(cp + i, WHITESPACE);
   }
   else {
-    /* Read to end of filename - either to white space or terminator */
+    /* Read to end of filename - either to whitespace or terminator */
     end = strpbrk(cp, WHITESPACE);
     if(end == NULL)
       end = strchr(cp, '\0');
@@ -184,7 +184,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
       (*path)[pathLength] = '\0';
       cp += 3;
     }
-    /* Copy path name up until first "white space" */
+    /* Copy path name up until first "whitespace" */
     memcpy(&(*path)[pathLength], cp, (int)(end - cp));
     pathLength += (int)(end - cp);
     (*path)[pathLength] = '\0';
diff --git a/lib/curl_path.h b/lib/curl_path.h
index 636c37f..b601b48 100644
--- a/lib/curl_path.h
+++ b/lib/curl_path.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_printf.h b/lib/curl_printf.h
index 0d37b8e..9fa625f 100644
--- a/lib/curl_printf.h
+++ b/lib/curl_printf.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_range.c b/lib/curl_range.c
index aa3c493..0a87b1c 100644
--- a/lib/curl_range.c
+++ b/lib/curl_range.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_range.h b/lib/curl_range.h
index 2350df9..d1f2c6d 100644
--- a/lib/curl_range.h
+++ b/lib/curl_range.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index df8f2b1..ba471a2 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -5,12 +5,12 @@
  *                | (__| |_| |  _ <| |___
  *                 \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -79,6 +79,7 @@ const struct Curl_handler Curl_handler_rtmp = {
   ZERO_NULL,                            /* connection_check */
   PORT_RTMP,                            /* defport */
   CURLPROTO_RTMP,                       /* protocol */
+  CURLPROTO_RTMP,                       /* family */
   PROTOPT_NONE                          /* flags*/
 };
 
@@ -100,6 +101,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
   ZERO_NULL,                            /* connection_check */
   PORT_RTMPT,                           /* defport */
   CURLPROTO_RTMPT,                      /* protocol */
+  CURLPROTO_RTMPT,                      /* family */
   PROTOPT_NONE                          /* flags*/
 };
 
@@ -121,6 +123,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
   ZERO_NULL,                            /* connection_check */
   PORT_RTMP,                            /* defport */
   CURLPROTO_RTMPE,                      /* protocol */
+  CURLPROTO_RTMPE,                      /* family */
   PROTOPT_NONE                          /* flags*/
 };
 
@@ -142,6 +145,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
   ZERO_NULL,                            /* connection_check */
   PORT_RTMPT,                           /* defport */
   CURLPROTO_RTMPTE,                     /* protocol */
+  CURLPROTO_RTMPTE,                     /* family */
   PROTOPT_NONE                          /* flags*/
 };
 
@@ -163,6 +167,7 @@ const struct Curl_handler Curl_handler_rtmps = {
   ZERO_NULL,                            /* connection_check */
   PORT_RTMPS,                           /* defport */
   CURLPROTO_RTMPS,                      /* protocol */
+  CURLPROTO_RTMP,                       /* family */
   PROTOPT_NONE                          /* flags*/
 };
 
@@ -184,6 +189,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
   ZERO_NULL,                            /* connection_check */
   PORT_RTMPS,                           /* defport */
   CURLPROTO_RTMPTS,                     /* protocol */
+  CURLPROTO_RTMPT,                      /* family */
   PROTOPT_NONE                          /* flags*/
 };
 
diff --git a/lib/curl_rtmp.h b/lib/curl_rtmp.h
index 86a0138..f45fa71 100644
--- a/lib/curl_rtmp.h
+++ b/lib/curl_rtmp.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010 - 2019, Howard Chu, <hyc@highlandsun.com>
+ * Copyright (C) 2010 - 2020, Howard Chu, <hyc@highlandsun.com>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 83fe896..94b17a1 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h
index 7647a48..ba40ec4 100644
--- a/lib/curl_sasl.h
+++ b/lib/curl_sasl.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sec.h b/lib/curl_sec.h
deleted file mode 100644
index 7bdde26..0000000
--- a/lib/curl_sec.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef HEADER_CURL_SECURITY_H
-#define HEADER_CURL_SECURITY_H
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-struct Curl_sec_client_mech {
-  const char *name;
-  size_t size;
-  int (*init)(void *);
-  int (*auth)(void *, struct connectdata *);
-  void (*end)(void *);
-  int (*check_prot)(void *, int);
-  int (*overhead)(void *, int, int);
-  int (*encode)(void *, const void *, int, int, void **);
-  int (*decode)(void *, void *, int, int, struct connectdata *);
-};
-
-#define AUTH_OK         0
-#define AUTH_CONTINUE   1
-#define AUTH_ERROR      2
-
-#ifdef HAVE_GSSAPI
-int Curl_sec_read_msg(struct connectdata *conn, char *,
-                      enum protection_level);
-void Curl_sec_end(struct connectdata *);
-CURLcode Curl_sec_login(struct connectdata *);
-int Curl_sec_request_prot(struct connectdata *conn, const char *level);
-
-extern struct Curl_sec_client_mech Curl_krb5_client_mech;
-#endif
-
-#endif /* HEADER_CURL_SECURITY_H */
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 21c3f34..22def2d 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -38,8 +38,7 @@
  * Define WIN32 when build target is Win32 API
  */
 
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
-    !defined(__SYMBIAN32__)
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
 #define WIN32
 #endif
 
@@ -88,10 +87,6 @@
 #  include "config-amigaos.h"
 #endif
 
-#ifdef __SYMBIAN32__
-#  include "config-symbian.h"
-#endif
-
 #ifdef __OS400__
 #  include "config-os400.h"
 #endif
@@ -243,7 +238,7 @@
  * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
  * performing this task will result in a synthesized IPv6 address.
  */
-#ifdef  __APPLE__
+#if defined(__APPLE__) && !defined(USE_ARES)
 #define USE_RESOLVE_ON_IPS 1
 #endif
 
@@ -282,10 +277,16 @@
 #  include <exec/execbase.h>
 #  include <proto/exec.h>
 #  include <proto/dos.h>
+#  include <unistd.h>
 #  ifdef HAVE_PROTO_BSDSOCKET_H
 #    include <proto/bsdsocket.h> /* ensure bsdsocket.library use */
 #    define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
 #  endif
+/*
+ * In clib2 arpa/inet.h warns that some prototypes may clash
+ * with bsdsocket.library. This avoids the definition of those.
+ */
+#  define __NO_NET_API
 #endif
 
 #include <stdio.h>
@@ -560,14 +561,6 @@
 /* ---------------------------------------------------------------- */
 
 /*
- * When using WINSOCK, TELNET protocol requires WINSOCK2 API.
- */
-
-#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
-#  define CURL_DISABLE_TELNET 1
-#endif
-
-/*
  * msvc 6.0 does not have struct sockaddr_storage and
  * does not define IPPROTO_ESP in winsock2.h. But both
  * are available if PSDK is properly installed.
@@ -637,13 +630,12 @@ int netware_init(void);
 
 /* Single point where USE_NTLM definition might be defined */
 #if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
-#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) ||                \
+#if defined(USE_OPENSSL) || defined(USE_MBEDTLS) ||                     \
   defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) ||  \
   defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) ||              \
-  defined(USE_MBEDTLS) ||                                               \
   (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
 
-#define USE_NTLM
+#define USE_CURL_NTLM_CORE
 
 #  if defined(USE_MBEDTLS)
 /* Get definition of MBEDTLS_MD4_C */
@@ -651,6 +643,10 @@ int netware_init(void);
 #  endif
 
 #endif
+
+#if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI)
+#define USE_NTLM
+#endif
 #endif
 
 #ifdef CURL_WANTS_CA_BUNDLE_ENV
@@ -702,7 +698,7 @@ int netware_init(void);
      defined(HAVE_WINSOCK_H) || \
      defined(HAVE_WINSOCK2_H) || \
      defined(HAVE_WS2TCPIP_H)
-#    error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
+#    error "WinSock and lwIP TCP/IP stack definitions shall not coexist!"
 #  endif
 #endif
 
diff --git a/lib/curl_setup_once.h b/lib/curl_setup_once.h
index e7c00de..ef60bc7 100644
--- a/lib/curl_setup_once.h
+++ b/lib/curl_setup_once.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sha256.h b/lib/curl_sha256.h
index 35d286c..0fceb63 100644
--- a/lib/curl_sha256.h
+++ b/lib/curl_sha256.h
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c
index 512ce24..06841dd 100644
--- a/lib/curl_sspi.c
+++ b/lib/curl_sspi.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h
index c09026e..881384d 100644
--- a/lib/curl_sspi.h
+++ b/lib/curl_sspi.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curl_threads.c b/lib/curl_threads.c
index b5f10a2..4146144 100644
--- a/lib/curl_threads.c
+++ b/lib/curl_threads.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -41,14 +41,14 @@
 
 #if defined(USE_THREADS_POSIX)
 
-struct curl_actual_call {
+struct Curl_actual_call {
   unsigned int (*func)(void *);
   void *arg;
 };
 
 static void *curl_thread_create_thunk(void *arg)
 {
-  struct curl_actual_call *ac = arg;
+  struct Curl_actual_call *ac = arg;
   unsigned int (*func)(void *) = ac->func;
   void *real_arg = ac->arg;
 
@@ -62,7 +62,7 @@ static void *curl_thread_create_thunk(void *arg)
 curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg)
 {
   curl_thread_t t = malloc(sizeof(pthread_t));
-  struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
+  struct Curl_actual_call *ac = malloc(sizeof(struct Curl_actual_call));
   if(!(ac && t))
     goto err;
 
diff --git a/lib/curl_threads.h b/lib/curl_threads.h
index 65d1a79..e10b7a1 100644
--- a/lib/curl_threads.h
+++ b/lib/curl_threads.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/curlx.h b/lib/curlx.h
index 98e51bf..9f21f60 100644
--- a/lib/curlx.h
+++ b/lib/curlx.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dict.c b/lib/dict.c
index f529b48..15d3954 100644
--- a/lib/dict.c
+++ b/lib/dict.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -57,6 +57,7 @@
 #include "escape.h"
 #include "progress.h"
 #include "dict.h"
+#include "curl_printf.h"
 #include "strcase.h"
 #include "curl_memory.h"
 /* The last #include file should be: */
@@ -90,7 +91,8 @@ const struct Curl_handler Curl_handler_dict = {
   ZERO_NULL,                            /* connection_check */
   PORT_DICT,                            /* defport */
   CURLPROTO_DICT,                       /* protocol */
-  PROTOPT_NONE | PROTOPT_NOURLQUERY      /* flags */
+  CURLPROTO_DICT,                       /* family */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
 static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
@@ -126,6 +128,51 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
   return dictp;
 }
 
+/* sendf() sends formatted data to the server */
+static CURLcode sendf(curl_socket_t sockfd, struct connectdata *conn,
+                      const char *fmt, ...)
+{
+  struct Curl_easy *data = conn->data;
+  ssize_t bytes_written;
+  size_t write_len;
+  CURLcode result = CURLE_OK;
+  char *s;
+  char *sptr;
+  va_list ap;
+  va_start(ap, fmt);
+  s = vaprintf(fmt, ap); /* returns an allocated string */
+  va_end(ap);
+  if(!s)
+    return CURLE_OUT_OF_MEMORY; /* failure */
+
+  bytes_written = 0;
+  write_len = strlen(s);
+  sptr = s;
+
+  for(;;) {
+    /* Write the buffer to the socket */
+    result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+
+    if(result)
+      break;
+
+    Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
+
+    if((size_t)bytes_written != write_len) {
+      /* if not all was written at once, we must advance the pointer, decrease
+         the size left and try again! */
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+  }
+
+  free(s); /* free the output string */
+
+  return result;
+}
+
 static CURLcode dict_do(struct connectdata *conn, bool *done)
 {
   char *word;
@@ -183,18 +230,16 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
     if(!eword)
       return CURLE_OUT_OF_MEMORY;
 
-    result = Curl_sendf(sockfd, conn,
-                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
-                        "MATCH "
-                        "%s "    /* database */
-                        "%s "    /* strategy */
-                        "%s\r\n" /* word */
-                        "QUIT\r\n",
-
-                        database,
-                        strategy,
-                        eword
-                        );
+    result = sendf(sockfd, conn,
+                   "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                   "MATCH "
+                   "%s "    /* database */
+                   "%s "    /* strategy */
+                   "%s\r\n" /* word */
+                   "QUIT\r\n",
+                   database,
+                   strategy,
+                   eword);
 
     free(eword);
 
@@ -233,14 +278,14 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
     if(!eword)
       return CURLE_OUT_OF_MEMORY;
 
-    result = Curl_sendf(sockfd, conn,
-                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
-                        "DEFINE "
-                        "%s "     /* database */
-                        "%s\r\n"  /* word */
-                        "QUIT\r\n",
-                        database,
-                        eword);
+    result = sendf(sockfd, conn,
+                   "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                   "DEFINE "
+                   "%s "     /* database */
+                   "%s\r\n"  /* word */
+                   "QUIT\r\n",
+                   database,
+                   eword);
 
     free(eword);
 
@@ -261,10 +306,10 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
         if(ppath[i] == ':')
           ppath[i] = ' ';
       }
-      result = Curl_sendf(sockfd, conn,
-                          "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
-                          "%s\r\n"
-                          "QUIT\r\n", ppath);
+      result = sendf(sockfd, conn,
+                     "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                     "%s\r\n"
+                     "QUIT\r\n", ppath);
       if(result) {
         failf(data, "Failed sending DICT request");
         return result;
diff --git a/lib/dict.h b/lib/dict.h
index 38a55ac..6a6c772 100644
--- a/lib/dict.h
+++ b/lib/dict.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/doh.c b/lib/doh.c
index 8bc3428..c2b76de 100644
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -57,12 +57,13 @@ static const char * const errors[]={
   "Unexpected TYPE",
   "Unexpected CLASS",
   "No content",
-  "Bad ID"
+  "Bad ID",
+  "Name too long"
 };
 
 static const char *doh_strerror(DOHcode code)
 {
-  if((code >= DOH_OK) && (code <= DOH_DNS_BAD_ID))
+  if((code >= DOH_OK) && (code <= DOH_DNS_NAME_TOO_LONG))
     return errors[code];
   return "bad error code";
 }
@@ -348,6 +349,10 @@ static CURLcode dohprobe(struct Curl_easy *data,
       ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
     if(data->set.ssl.fsslctxp)
       ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp);
+    if(data->set.str[STRING_SSL_EC_CURVES]) {
+      ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES,
+        data->set.str[STRING_SSL_EC_CURVES]);
+    }
 
     doh->set.fmultidone = Curl_doh_done;
     doh->set.dohfor = data; /* identify for which transfer this is done */
diff --git a/lib/doh.h b/lib/doh.h
index bbd4c1a..0867584 100644
--- a/lib/doh.h
+++ b/lib/doh.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dotdot.c b/lib/dotdot.c
index ce9a052..3a1435f 100644
--- a/lib/dotdot.c
+++ b/lib/dotdot.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dotdot.h b/lib/dotdot.h
index f70b1db..ac1ea36 100644
--- a/lib/dotdot.h
+++ b/lib/dotdot.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/dynbuf.c b/lib/dynbuf.c
index 38d370b..ada7e0c 100644
--- a/lib/dynbuf.c
+++ b/lib/dynbuf.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -21,12 +21,11 @@
  ***************************************************************************/
 
 #include "curl_setup.h"
-#include "strdup.h"
 #include "dynbuf.h"
-
-/* The last 3 #include files should be in this order */
 #include "curl_printf.h"
+#ifdef BUILDING_LIBCURL
 #include "curl_memory.h"
+#endif
 #include "memdebug.h"
 
 #define MIN_FIRST_ALLOC 32
@@ -94,11 +93,15 @@ static CURLcode dyn_nappend(struct dynbuf *s,
   }
 
   if(a != s->allc) {
-    s->bufr = Curl_saferealloc(s->bufr, a);
-    if(!s->bufr) {
+    /* this logic is not using Curl_saferealloc() to make the tool not have to
+       include that as well when it uses this code */
+    void *p = realloc(s->bufr, a);
+    if(!p) {
+      Curl_safefree(s->bufr);
       s->leng = s->allc = 0;
       return CURLE_OUT_OF_MEMORY;
     }
+    s->bufr = p;
     s->allc = a;
   }
 
@@ -143,6 +146,7 @@ CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail)
   else {
     memmove(&s->bufr[0], &s->bufr[s->leng - trail], trail);
     s->leng = trail;
+    s->bufr[s->leng] = 0;
   }
   return CURLE_OK;
 
@@ -173,15 +177,22 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
 }
 
 /*
- * Append a string printf()-style
+ * Append a string vprintf()-style
  */
-CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
 {
+#ifdef BUILDING_LIBCURL
+  int rc;
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  rc = Curl_dyn_vprintf(s, fmt, ap);
+
+  if(!rc)
+    return CURLE_OK;
+#else
   char *str;
-  va_list ap;
-  va_start(ap, fmt);
   str = vaprintf(fmt, ap); /* this allocs a new string to append */
-  va_end(ap);
 
   if(str) {
     CURLcode result = dyn_nappend(s, (unsigned char *)str, strlen(str));
@@ -190,10 +201,27 @@ CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
   }
   /* If we failed, we cleanup the whole buffer and return error */
   Curl_dyn_free(s);
+#endif
   return CURLE_OUT_OF_MEMORY;
 }
 
 /*
+ * Append a string printf()-style
+ */
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
+{
+  CURLcode result;
+  va_list ap;
+  DEBUGASSERT(s);
+  DEBUGASSERT(s->init == DYNINIT);
+  DEBUGASSERT(!s->leng || s->bufr);
+  va_start(ap, fmt);
+  result = Curl_dyn_vaddf(s, fmt, ap);
+  va_end(ap);
+  return result;
+}
+
+/*
  * Returns a pointer to the buffer.
  */
 char *Curl_dyn_ptr(const struct dynbuf *s)
diff --git a/lib/dynbuf.h b/lib/dynbuf.h
index ecc9957..484e40c 100644
--- a/lib/dynbuf.h
+++ b/lib/dynbuf.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -22,6 +22,23 @@
  *
  ***************************************************************************/
 
+#ifndef BUILDING_LIBCURL
+/* this renames the functions so that the tool code can use the same code
+   without getting symbol collisions */
+#define Curl_dyn_init(a,b) curlx_dyn_init(a,b)
+#define Curl_dyn_add(a,b) curlx_dyn_add(a,b)
+#define Curl_dyn_addn(a,b,c) curlx_dyn_addn(a,b,c)
+#define Curl_dyn_addf curlx_dyn_addf
+#define Curl_dyn_vaddf curlx_dyn_vaddf
+#define Curl_dyn_free(a) curlx_dyn_free(a)
+#define Curl_dyn_ptr(a) curlx_dyn_ptr(a)
+#define Curl_dyn_uptr(a) curlx_dyn_uptr(a)
+#define Curl_dyn_len(a) curlx_dyn_len(a)
+#define Curl_dyn_reset(a) curlx_dyn_reset(a)
+#define Curl_dyn_tail(a,b) curlx_dyn_tail(a,b)
+#define curlx_dynbuf dynbuf /* for the struct name */
+#endif
+
 struct dynbuf {
   char *bufr;    /* point to a null-terminated allocated buffer */
   size_t leng;   /* number of bytes *EXCLUDING* the zero terminator */
@@ -40,12 +57,18 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
   WARN_UNUSED_RESULT;
 CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
   WARN_UNUSED_RESULT;
+CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
+  WARN_UNUSED_RESULT;
 void Curl_dyn_reset(struct dynbuf *s);
 CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail);
 char *Curl_dyn_ptr(const struct dynbuf *s);
 unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
 size_t Curl_dyn_len(const struct dynbuf *s);
 
+/* returns 0 on success, -1 on error */
+/* The implementation of this function exists in mprintf.c */
+int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
+
 /* Dynamic buffer max sizes */
 #define DYN_DOH_RESPONSE    3000
 #define DYN_DOH_CNAME       256
@@ -60,4 +83,6 @@ size_t Curl_dyn_len(const struct dynbuf *s);
 #define DYN_PROXY_CONNECT_HEADERS 16384
 #define DYN_QLOG_NAME       1024
 #define DYN_H1_TRAILER      4096
+#define DYN_PINGPPONG_CMD   (64*1024)
+#define DYN_IMAP_CMD        (64*1024)
 #endif
diff --git a/lib/easy.c b/lib/easy.c
index a69eb9e..dc790b0 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -78,6 +78,8 @@
 #include "system_win32.h"
 #include "http2.h"
 #include "dynbuf.h"
+#include "altsvc.h"
+#include "hsts.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -105,7 +107,6 @@ static long          init_flags;
 #  pragma warning(disable:4232) /* MSVC extension, dllimport identity */
 #endif
 
-#ifndef __SYMBIAN32__
 /*
  * If a memory-using function (like curl_getenv) is used before
  * curl_global_init() is called, we need to have these pointers set already.
@@ -118,17 +119,6 @@ curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
 #if defined(WIN32) && defined(UNICODE)
 curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
 #endif
-#else
-/*
- * Symbian OS doesn't support initialization to code in writable static data.
- * Initialization will occur in the curl_global_init() call.
- */
-curl_malloc_callback Curl_cmalloc;
-curl_free_callback Curl_cfree;
-curl_realloc_callback Curl_crealloc;
-curl_strdup_callback Curl_cstrdup;
-curl_calloc_callback Curl_ccalloc;
-#endif
 
 #if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
 #  pragma warning(default:4232) /* MSVC extension, dllimport identity */
@@ -883,6 +873,26 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
       goto fail;
   }
 
+#ifdef USE_ALTSVC
+  if(data->asi) {
+    outcurl->asi = Curl_altsvc_init();
+    if(!outcurl->asi)
+      goto fail;
+    if(outcurl->set.str[STRING_ALTSVC])
+      (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]);
+  }
+#endif
+#ifdef USE_HSTS
+  if(data->hsts) {
+    outcurl->hsts = Curl_hsts_init();
+    if(!outcurl->hsts)
+      goto fail;
+    if(outcurl->set.str[STRING_HSTS])
+      (void)Curl_hsts_loadfile(outcurl,
+                               outcurl->hsts, outcurl->set.str[STRING_HSTS]);
+    (void)Curl_hsts_loadcb(outcurl, outcurl->hsts);
+  }
+#endif
   /* Clone the resolver handle, if present, for the new handle */
   if(Curl_resolver_duphandle(outcurl,
                              &outcurl->state.resolver,
@@ -930,6 +940,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
     Curl_dyn_free(&outcurl->state.headerb);
     Curl_safefree(outcurl->change.url);
     Curl_safefree(outcurl->change.referer);
+    Curl_altsvc_cleanup(&outcurl->asi);
+    Curl_hsts_cleanup(&outcurl->hsts);
     Curl_freeset(outcurl);
     free(outcurl);
   }
@@ -958,6 +970,7 @@ void curl_easy_reset(struct Curl_easy *data)
 
   data->progress.flags |= PGRS_HIDE;
   data->state.current_speed = -1; /* init to negative == impossible */
+  data->state.retrycount = 0;     /* reset the retry counter */
 
   /* zero out authentication data: */
   memset(&data->state.authhost, 0, sizeof(struct auth));
@@ -1067,9 +1080,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
      (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) {
     Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going 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->state.tempcount)
+      /* 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);
   }
diff --git a/lib/easygetopt.c b/lib/easygetopt.c
new file mode 100644
index 0000000..7b2213f
--- /dev/null
+++ b/lib/easygetopt.c
@@ -0,0 +1,96 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ | |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             ___|___/|_| ______|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "strcase.h"
+#include "easyoptions.h"
+
+#ifndef CURL_DISABLE_GETOPTIONS
+
+/* Lookups easy options at runtime */
+static struct curl_easyoption *lookup(const char *name, CURLoption id)
+{
+  DEBUGASSERT(name || id);
+  DEBUGASSERT(!Curl_easyopts_check());
+  if(name || id) {
+    struct curl_easyoption *o = &Curl_easyopts[0];
+    do {
+      if(name) {
+        if(strcasecompare(o->name, name))
+          return o;
+      }
+      else {
+        if((o->id == id) && !(o->flags & CURLOT_FLAG_ALIAS))
+          /* don't match alias options */
+          return o;
+      }
+      o++;
+    } while(o->name);
+  }
+  return NULL;
+}
+
+const struct curl_easyoption *curl_easy_option_by_name(const char *name)
+{
+  /* when name is used, the id argument is ignored */
+  return lookup(name, CURLOPT_LASTENTRY);
+}
+
+const struct curl_easyoption *curl_easy_option_by_id(CURLoption id)
+{
+  return lookup(NULL, id);
+}
+
+/* Iterates over available options */
+const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev)
+{
+  if(prev && prev->name) {
+    prev++;
+    if(prev->name)
+      return prev;
+  }
+  else if(!prev)
+    return &Curl_easyopts[0];
+  return NULL;
+}
+
+#else
+const struct curl_easyoption *curl_easy_option_by_name(const char *name)
+{
+  (void)name;
+  return NULL;
+}
+
+const struct curl_easyoption *curl_easy_option_by_id (CURLoption id)
+{
+  (void)id;
+  return NULL;
+}
+
+const struct curl_easyoption *
+curl_easy_option_next(const struct curl_easyoption *prev)
+{
+  (void)prev;
+  return NULL;
+}
+#endif
diff --git a/lib/easyif.h b/lib/easyif.h
index eda0d62..3364418 100644
--- a/lib/easyif.h
+++ b/lib/easyif.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/easyoptions.c b/lib/easyoptions.c
new file mode 100644
index 0000000..f236da2
--- /dev/null
+++ b/lib/easyoptions.c
@@ -0,0 +1,353 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ | |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             ___|___/|_| ______|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This source code is generated by optiontable.pl - DO NOT EDIT BY HAND */
+
+#include "curl_setup.h"
+#include "easyoptions.h"
+
+/* all easy setopt options listed in alphabetical order */
+struct curl_easyoption Curl_easyopts[] = {
+  {"ABSTRACT_UNIX_SOCKET", CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOT_STRING, 0},
+  {"ACCEPTTIMEOUT_MS", CURLOPT_ACCEPTTIMEOUT_MS, CURLOT_LONG, 0},
+  {"ACCEPT_ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, 0},
+  {"ADDRESS_SCOPE", CURLOPT_ADDRESS_SCOPE, CURLOT_LONG, 0},
+  {"ALTSVC", CURLOPT_ALTSVC, CURLOT_STRING, 0},
+  {"ALTSVC_CTRL", CURLOPT_ALTSVC_CTRL, CURLOT_LONG, 0},
+  {"APPEND", CURLOPT_APPEND, CURLOT_LONG, 0},
+  {"AUTOREFERER", CURLOPT_AUTOREFERER, CURLOT_LONG, 0},
+  {"BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0},
+  {"CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0},
+  {"CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0},
+  {"CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0},
+  {"CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0},
+  {"CHUNK_DATA", CURLOPT_CHUNK_DATA, CURLOT_CBPTR, 0},
+  {"CHUNK_END_FUNCTION", CURLOPT_CHUNK_END_FUNCTION, CURLOT_FUNCTION, 0},
+  {"CLOSESOCKETDATA", CURLOPT_CLOSESOCKETDATA, CURLOT_CBPTR, 0},
+  {"CLOSESOCKETFUNCTION", CURLOPT_CLOSESOCKETFUNCTION, CURLOT_FUNCTION, 0},
+  {"CONNECTTIMEOUT", CURLOPT_CONNECTTIMEOUT, CURLOT_LONG, 0},
+  {"CONNECTTIMEOUT_MS", CURLOPT_CONNECTTIMEOUT_MS, CURLOT_LONG, 0},
+  {"CONNECT_ONLY", CURLOPT_CONNECT_ONLY, CURLOT_LONG, 0},
+  {"CONNECT_TO", CURLOPT_CONNECT_TO, CURLOT_SLIST, 0},
+  {"CONV_FROM_NETWORK_FUNCTION", CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+   CURLOT_FUNCTION, 0},
+  {"CONV_FROM_UTF8_FUNCTION", CURLOPT_CONV_FROM_UTF8_FUNCTION,
+   CURLOT_FUNCTION, 0},
+  {"CONV_TO_NETWORK_FUNCTION", CURLOPT_CONV_TO_NETWORK_FUNCTION,
+   CURLOT_FUNCTION, 0},
+  {"COOKIE", CURLOPT_COOKIE, CURLOT_STRING, 0},
+  {"COOKIEFILE", CURLOPT_COOKIEFILE, CURLOT_STRING, 0},
+  {"COOKIEJAR", CURLOPT_COOKIEJAR, CURLOT_STRING, 0},
+  {"COOKIELIST", CURLOPT_COOKIELIST, CURLOT_STRING, 0},
+  {"COOKIESESSION", CURLOPT_COOKIESESSION, CURLOT_LONG, 0},
+  {"COPYPOSTFIELDS", CURLOPT_COPYPOSTFIELDS, CURLOT_OBJECT, 0},
+  {"CRLF", CURLOPT_CRLF, CURLOT_LONG, 0},
+  {"CRLFILE", CURLOPT_CRLFILE, CURLOT_STRING, 0},
+  {"CURLU", CURLOPT_CURLU, CURLOT_OBJECT, 0},
+  {"CUSTOMREQUEST", CURLOPT_CUSTOMREQUEST, CURLOT_STRING, 0},
+  {"DEBUGDATA", CURLOPT_DEBUGDATA, CURLOT_CBPTR, 0},
+  {"DEBUGFUNCTION", CURLOPT_DEBUGFUNCTION, CURLOT_FUNCTION, 0},
+  {"DEFAULT_PROTOCOL", CURLOPT_DEFAULT_PROTOCOL, CURLOT_STRING, 0},
+  {"DIRLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, 0},
+  {"DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL,
+   CURLOT_LONG, 0},
+  {"DNS_CACHE_TIMEOUT", CURLOPT_DNS_CACHE_TIMEOUT, CURLOT_LONG, 0},
+  {"DNS_INTERFACE", CURLOPT_DNS_INTERFACE, CURLOT_STRING, 0},
+  {"DNS_LOCAL_IP4", CURLOPT_DNS_LOCAL_IP4, CURLOT_STRING, 0},
+  {"DNS_LOCAL_IP6", CURLOPT_DNS_LOCAL_IP6, CURLOT_STRING, 0},
+  {"DNS_SERVERS", CURLOPT_DNS_SERVERS, CURLOT_STRING, 0},
+  {"DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOT_LONG, 0},
+  {"DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOT_LONG, 0},
+  {"DOH_URL", CURLOPT_DOH_URL, CURLOT_STRING, 0},
+  {"EGDSOCKET", CURLOPT_EGDSOCKET, CURLOT_STRING, 0},
+  {"ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+  {"ERRORBUFFER", CURLOPT_ERRORBUFFER, CURLOT_OBJECT, 0},
+  {"EXPECT_100_TIMEOUT_MS", CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOT_LONG, 0},
+  {"FAILONERROR", CURLOPT_FAILONERROR, CURLOT_LONG, 0},
+  {"FILE", CURLOPT_WRITEDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+  {"FILETIME", CURLOPT_FILETIME, CURLOT_LONG, 0},
+  {"FNMATCH_DATA", CURLOPT_FNMATCH_DATA, CURLOT_CBPTR, 0},
+  {"FNMATCH_FUNCTION", CURLOPT_FNMATCH_FUNCTION, CURLOT_FUNCTION, 0},
+  {"FOLLOWLOCATION", CURLOPT_FOLLOWLOCATION, CURLOT_LONG, 0},
+  {"FORBID_REUSE", CURLOPT_FORBID_REUSE, CURLOT_LONG, 0},
+  {"FRESH_CONNECT", CURLOPT_FRESH_CONNECT, CURLOT_LONG, 0},
+  {"FTPAPPEND", CURLOPT_APPEND, CURLOT_LONG, CURLOT_FLAG_ALIAS},
+  {"FTPLISTONLY", CURLOPT_DIRLISTONLY, CURLOT_LONG, CURLOT_FLAG_ALIAS},
+  {"FTPPORT", CURLOPT_FTPPORT, CURLOT_STRING, 0},
+  {"FTPSSLAUTH", CURLOPT_FTPSSLAUTH, CURLOT_VALUES, 0},
+  {"FTP_ACCOUNT", CURLOPT_FTP_ACCOUNT, CURLOT_STRING, 0},
+  {"FTP_ALTERNATIVE_TO_USER", CURLOPT_FTP_ALTERNATIVE_TO_USER,
+   CURLOT_STRING, 0},
+  {"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS,
+   CURLOT_LONG, 0},
+  {"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0},
+  {"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOT_LONG, 0},
+  {"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0},
+  {"FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS},
+  {"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0},
+  {"FTP_USE_EPRT", CURLOPT_FTP_USE_EPRT, CURLOT_LONG, 0},
+  {"FTP_USE_EPSV", CURLOPT_FTP_USE_EPSV, CURLOT_LONG, 0},
+  {"FTP_USE_PRET", CURLOPT_FTP_USE_PRET, CURLOT_LONG, 0},
+  {"GSSAPI_DELEGATION", CURLOPT_GSSAPI_DELEGATION, CURLOT_VALUES, 0},
+  {"HAPPY_EYEBALLS_TIMEOUT_MS", CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS,
+   CURLOT_LONG, 0},
+  {"HAPROXYPROTOCOL", CURLOPT_HAPROXYPROTOCOL, CURLOT_LONG, 0},
+  {"HEADER", CURLOPT_HEADER, CURLOT_LONG, 0},
+  {"HEADERDATA", CURLOPT_HEADERDATA, CURLOT_CBPTR, 0},
+  {"HEADERFUNCTION", CURLOPT_HEADERFUNCTION, CURLOT_FUNCTION, 0},
+  {"HEADEROPT", CURLOPT_HEADEROPT, CURLOT_VALUES, 0},
+  {"HSTS", CURLOPT_HSTS, CURLOT_STRING, 0},
+  {"HSTSREADDATA", CURLOPT_HSTSREADDATA, CURLOT_CBPTR, 0},
+  {"HSTSREADFUNCTION", CURLOPT_HSTSREADFUNCTION, CURLOT_FUNCTION, 0},
+  {"HSTSWRITEDATA", CURLOPT_HSTSWRITEDATA, CURLOT_CBPTR, 0},
+  {"HSTSWRITEFUNCTION", CURLOPT_HSTSWRITEFUNCTION, CURLOT_FUNCTION, 0},
+  {"HSTS_CTRL", CURLOPT_HSTS_CTRL, CURLOT_LONG, 0},
+  {"HTTP09_ALLOWED", CURLOPT_HTTP09_ALLOWED, CURLOT_LONG, 0},
+  {"HTTP200ALIASES", CURLOPT_HTTP200ALIASES, CURLOT_SLIST, 0},
+  {"HTTPAUTH", CURLOPT_HTTPAUTH, CURLOT_VALUES, 0},
+  {"HTTPGET", CURLOPT_HTTPGET, CURLOT_LONG, 0},
+  {"HTTPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, 0},
+  {"HTTPPOST", CURLOPT_HTTPPOST, CURLOT_OBJECT, 0},
+  {"HTTPPROXYTUNNEL", CURLOPT_HTTPPROXYTUNNEL, CURLOT_LONG, 0},
+  {"HTTP_CONTENT_DECODING", CURLOPT_HTTP_CONTENT_DECODING, CURLOT_LONG, 0},
+  {"HTTP_TRANSFER_DECODING", CURLOPT_HTTP_TRANSFER_DECODING, CURLOT_LONG, 0},
+  {"HTTP_VERSION", CURLOPT_HTTP_VERSION, CURLOT_VALUES, 0},
+  {"IGNORE_CONTENT_LENGTH", CURLOPT_IGNORE_CONTENT_LENGTH, CURLOT_LONG, 0},
+  {"INFILE", CURLOPT_READDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+  {"INFILESIZE", CURLOPT_INFILESIZE, CURLOT_LONG, 0},
+  {"INFILESIZE_LARGE", CURLOPT_INFILESIZE_LARGE, CURLOT_OFF_T, 0},
+  {"INTERFACE", CURLOPT_INTERFACE, CURLOT_STRING, 0},
+  {"INTERLEAVEDATA", CURLOPT_INTERLEAVEDATA, CURLOT_CBPTR, 0},
+  {"INTERLEAVEFUNCTION", CURLOPT_INTERLEAVEFUNCTION, CURLOT_FUNCTION, 0},
+  {"IOCTLDATA", CURLOPT_IOCTLDATA, CURLOT_CBPTR, 0},
+  {"IOCTLFUNCTION", CURLOPT_IOCTLFUNCTION, CURLOT_FUNCTION, 0},
+  {"IPRESOLVE", CURLOPT_IPRESOLVE, CURLOT_VALUES, 0},
+  {"ISSUERCERT", CURLOPT_ISSUERCERT, CURLOT_STRING, 0},
+  {"ISSUERCERT_BLOB", CURLOPT_ISSUERCERT_BLOB, CURLOT_BLOB, 0},
+  {"KEEP_SENDING_ON_ERROR", CURLOPT_KEEP_SENDING_ON_ERROR, CURLOT_LONG, 0},
+  {"KEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, 0},
+  {"KRB4LEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+  {"KRBLEVEL", CURLOPT_KRBLEVEL, CURLOT_STRING, 0},
+  {"LOCALPORT", CURLOPT_LOCALPORT, CURLOT_LONG, 0},
+  {"LOCALPORTRANGE", CURLOPT_LOCALPORTRANGE, CURLOT_LONG, 0},
+  {"LOGIN_OPTIONS", CURLOPT_LOGIN_OPTIONS, CURLOT_STRING, 0},
+  {"LOW_SPEED_LIMIT", CURLOPT_LOW_SPEED_LIMIT, CURLOT_LONG, 0},
+  {"LOW_SPEED_TIME", CURLOPT_LOW_SPEED_TIME, CURLOT_LONG, 0},
+  {"MAIL_AUTH", CURLOPT_MAIL_AUTH, CURLOT_STRING, 0},
+  {"MAIL_FROM", CURLOPT_MAIL_FROM, CURLOT_STRING, 0},
+  {"MAIL_RCPT", CURLOPT_MAIL_RCPT, CURLOT_SLIST, 0},
+  {"MAIL_RCPT_ALLLOWFAILS", CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOT_LONG, 0},
+  {"MAXAGE_CONN", CURLOPT_MAXAGE_CONN, CURLOT_LONG, 0},
+  {"MAXCONNECTS", CURLOPT_MAXCONNECTS, CURLOT_LONG, 0},
+  {"MAXFILESIZE", CURLOPT_MAXFILESIZE, CURLOT_LONG, 0},
+  {"MAXFILESIZE_LARGE", CURLOPT_MAXFILESIZE_LARGE, CURLOT_OFF_T, 0},
+  {"MAXREDIRS", CURLOPT_MAXREDIRS, CURLOT_LONG, 0},
+  {"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},
+  {"NETRC", CURLOPT_NETRC, CURLOT_VALUES, 0},
+  {"NETRC_FILE", CURLOPT_NETRC_FILE, CURLOT_STRING, 0},
+  {"NEW_DIRECTORY_PERMS", CURLOPT_NEW_DIRECTORY_PERMS, CURLOT_LONG, 0},
+  {"NEW_FILE_PERMS", CURLOPT_NEW_FILE_PERMS, CURLOT_LONG, 0},
+  {"NOBODY", CURLOPT_NOBODY, CURLOT_LONG, 0},
+  {"NOPROGRESS", CURLOPT_NOPROGRESS, CURLOT_LONG, 0},
+  {"NOPROXY", CURLOPT_NOPROXY, CURLOT_STRING, 0},
+  {"NOSIGNAL", CURLOPT_NOSIGNAL, CURLOT_LONG, 0},
+  {"OPENSOCKETDATA", CURLOPT_OPENSOCKETDATA, CURLOT_CBPTR, 0},
+  {"OPENSOCKETFUNCTION", CURLOPT_OPENSOCKETFUNCTION, CURLOT_FUNCTION, 0},
+  {"PASSWORD", CURLOPT_PASSWORD, CURLOT_STRING, 0},
+  {"PATH_AS_IS", CURLOPT_PATH_AS_IS, CURLOT_LONG, 0},
+  {"PINNEDPUBLICKEY", CURLOPT_PINNEDPUBLICKEY, CURLOT_STRING, 0},
+  {"PIPEWAIT", CURLOPT_PIPEWAIT, CURLOT_LONG, 0},
+  {"PORT", CURLOPT_PORT, CURLOT_LONG, 0},
+  {"POST", CURLOPT_POST, CURLOT_LONG, 0},
+  {"POST301", CURLOPT_POSTREDIR, CURLOT_VALUES, CURLOT_FLAG_ALIAS},
+  {"POSTFIELDS", CURLOPT_POSTFIELDS, CURLOT_OBJECT, 0},
+  {"POSTFIELDSIZE", CURLOPT_POSTFIELDSIZE, CURLOT_LONG, 0},
+  {"POSTFIELDSIZE_LARGE", CURLOPT_POSTFIELDSIZE_LARGE, CURLOT_OFF_T, 0},
+  {"POSTQUOTE", CURLOPT_POSTQUOTE, CURLOT_SLIST, 0},
+  {"POSTREDIR", CURLOPT_POSTREDIR, CURLOT_VALUES, 0},
+  {"PREQUOTE", CURLOPT_PREQUOTE, CURLOT_SLIST, 0},
+  {"PRE_PROXY", CURLOPT_PRE_PROXY, CURLOT_STRING, 0},
+  {"PRIVATE", CURLOPT_PRIVATE, CURLOT_OBJECT, 0},
+  {"PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+  {"PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0},
+  {"PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0},
+  {"PROXY", CURLOPT_PROXY, CURLOT_STRING, 0},
+  {"PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0},
+  {"PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0},
+  {"PROXYPASSWORD", CURLOPT_PROXYPASSWORD, CURLOT_STRING, 0},
+  {"PROXYPORT", CURLOPT_PROXYPORT, CURLOT_LONG, 0},
+  {"PROXYTYPE", CURLOPT_PROXYTYPE, CURLOT_VALUES, 0},
+  {"PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0},
+  {"PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0},
+  {"PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0},
+  {"PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0},
+  {"PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0},
+  {"PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0},
+  {"PROXY_ISSUERCERT_BLOB", CURLOPT_PROXY_ISSUERCERT_BLOB, CURLOT_BLOB, 0},
+  {"PROXY_KEYPASSWD", CURLOPT_PROXY_KEYPASSWD, CURLOT_STRING, 0},
+  {"PROXY_PINNEDPUBLICKEY", CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOT_STRING, 0},
+  {"PROXY_SERVICE_NAME", CURLOPT_PROXY_SERVICE_NAME, CURLOT_STRING, 0},
+  {"PROXY_SSLCERT", CURLOPT_PROXY_SSLCERT, CURLOT_STRING, 0},
+  {"PROXY_SSLCERTTYPE", CURLOPT_PROXY_SSLCERTTYPE, CURLOT_STRING, 0},
+  {"PROXY_SSLCERT_BLOB", CURLOPT_PROXY_SSLCERT_BLOB, CURLOT_BLOB, 0},
+  {"PROXY_SSLKEY", CURLOPT_PROXY_SSLKEY, CURLOT_STRING, 0},
+  {"PROXY_SSLKEYTYPE", CURLOPT_PROXY_SSLKEYTYPE, CURLOT_STRING, 0},
+  {"PROXY_SSLKEY_BLOB", CURLOPT_PROXY_SSLKEY_BLOB, CURLOT_BLOB, 0},
+  {"PROXY_SSLVERSION", CURLOPT_PROXY_SSLVERSION, CURLOT_VALUES, 0},
+  {"PROXY_SSL_CIPHER_LIST", CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOT_STRING, 0},
+  {"PROXY_SSL_OPTIONS", CURLOPT_PROXY_SSL_OPTIONS, CURLOT_LONG, 0},
+  {"PROXY_SSL_VERIFYHOST", CURLOPT_PROXY_SSL_VERIFYHOST, CURLOT_LONG, 0},
+  {"PROXY_SSL_VERIFYPEER", CURLOPT_PROXY_SSL_VERIFYPEER, CURLOT_LONG, 0},
+  {"PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CURLOT_STRING, 0},
+  {"PROXY_TLSAUTH_PASSWORD", CURLOPT_PROXY_TLSAUTH_PASSWORD,
+   CURLOT_STRING, 0},
+  {"PROXY_TLSAUTH_TYPE", CURLOPT_PROXY_TLSAUTH_TYPE, CURLOT_STRING, 0},
+  {"PROXY_TLSAUTH_USERNAME", CURLOPT_PROXY_TLSAUTH_USERNAME,
+   CURLOT_STRING, 0},
+  {"PROXY_TRANSFER_MODE", CURLOPT_PROXY_TRANSFER_MODE, CURLOT_LONG, 0},
+  {"PUT", CURLOPT_PUT, CURLOT_LONG, 0},
+  {"QUOTE", CURLOPT_QUOTE, CURLOT_SLIST, 0},
+  {"RANDOM_FILE", CURLOPT_RANDOM_FILE, CURLOT_STRING, 0},
+  {"RANGE", CURLOPT_RANGE, CURLOT_STRING, 0},
+  {"READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0},
+  {"READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0},
+  {"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0},
+  {"REFERER", CURLOPT_REFERER, CURLOT_STRING, 0},
+  {"REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0},
+  {"RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0},
+  {"RESOLVER_START_DATA", CURLOPT_RESOLVER_START_DATA, CURLOT_CBPTR, 0},
+  {"RESOLVER_START_FUNCTION", CURLOPT_RESOLVER_START_FUNCTION,
+   CURLOT_FUNCTION, 0},
+  {"RESUME_FROM", CURLOPT_RESUME_FROM, CURLOT_LONG, 0},
+  {"RESUME_FROM_LARGE", CURLOPT_RESUME_FROM_LARGE, CURLOT_OFF_T, 0},
+  {"RTSPHEADER", CURLOPT_HTTPHEADER, CURLOT_SLIST, CURLOT_FLAG_ALIAS},
+  {"RTSP_CLIENT_CSEQ", CURLOPT_RTSP_CLIENT_CSEQ, CURLOT_LONG, 0},
+  {"RTSP_REQUEST", CURLOPT_RTSP_REQUEST, CURLOT_VALUES, 0},
+  {"RTSP_SERVER_CSEQ", CURLOPT_RTSP_SERVER_CSEQ, CURLOT_LONG, 0},
+  {"RTSP_SESSION_ID", CURLOPT_RTSP_SESSION_ID, CURLOT_STRING, 0},
+  {"RTSP_STREAM_URI", CURLOPT_RTSP_STREAM_URI, CURLOT_STRING, 0},
+  {"RTSP_TRANSPORT", CURLOPT_RTSP_TRANSPORT, CURLOT_STRING, 0},
+  {"SASL_AUTHZID", CURLOPT_SASL_AUTHZID, CURLOT_STRING, 0},
+  {"SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0},
+  {"SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0},
+  {"SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0},
+  {"SERVER_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT,
+   CURLOT_LONG, CURLOT_FLAG_ALIAS},
+  {"SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0},
+  {"SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0},
+  {"SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0},
+  {"SOCKOPTFUNCTION", CURLOPT_SOCKOPTFUNCTION, CURLOT_FUNCTION, 0},
+  {"SOCKS5_AUTH", CURLOPT_SOCKS5_AUTH, CURLOT_LONG, 0},
+  {"SOCKS5_GSSAPI_NEC", CURLOPT_SOCKS5_GSSAPI_NEC, CURLOT_LONG, 0},
+  {"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOT_STRING, 0},
+  {"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0},
+  {"SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0},
+  {"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
+   CURLOT_STRING, 0},
+  {"SSH_KEYDATA", CURLOPT_SSH_KEYDATA, CURLOT_CBPTR, 0},
+  {"SSH_KEYFUNCTION", CURLOPT_SSH_KEYFUNCTION, CURLOT_FUNCTION, 0},
+  {"SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS, CURLOT_STRING, 0},
+  {"SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE, CURLOT_STRING, 0},
+  {"SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE, CURLOT_STRING, 0},
+  {"SSLCERT", CURLOPT_SSLCERT, CURLOT_STRING, 0},
+  {"SSLCERTPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+  {"SSLCERTTYPE", CURLOPT_SSLCERTTYPE, CURLOT_STRING, 0},
+  {"SSLCERT_BLOB", CURLOPT_SSLCERT_BLOB, CURLOT_BLOB, 0},
+  {"SSLENGINE", CURLOPT_SSLENGINE, CURLOT_STRING, 0},
+  {"SSLENGINE_DEFAULT", CURLOPT_SSLENGINE_DEFAULT, CURLOT_LONG, 0},
+  {"SSLKEY", CURLOPT_SSLKEY, CURLOT_STRING, 0},
+  {"SSLKEYPASSWD", CURLOPT_KEYPASSWD, CURLOT_STRING, CURLOT_FLAG_ALIAS},
+  {"SSLKEYTYPE", CURLOPT_SSLKEYTYPE, CURLOT_STRING, 0},
+  {"SSLKEY_BLOB", CURLOPT_SSLKEY_BLOB, CURLOT_BLOB, 0},
+  {"SSLVERSION", CURLOPT_SSLVERSION, CURLOT_VALUES, 0},
+  {"SSL_CIPHER_LIST", CURLOPT_SSL_CIPHER_LIST, CURLOT_STRING, 0},
+  {"SSL_CTX_DATA", CURLOPT_SSL_CTX_DATA, CURLOT_CBPTR, 0},
+  {"SSL_CTX_FUNCTION", CURLOPT_SSL_CTX_FUNCTION, CURLOT_FUNCTION, 0},
+  {"SSL_EC_CURVES", CURLOPT_SSL_EC_CURVES, CURLOT_STRING, 0},
+  {"SSL_ENABLE_ALPN", CURLOPT_SSL_ENABLE_ALPN, CURLOT_LONG, 0},
+  {"SSL_ENABLE_NPN", CURLOPT_SSL_ENABLE_NPN, CURLOT_LONG, 0},
+  {"SSL_FALSESTART", CURLOPT_SSL_FALSESTART, CURLOT_LONG, 0},
+  {"SSL_OPTIONS", CURLOPT_SSL_OPTIONS, CURLOT_VALUES, 0},
+  {"SSL_SESSIONID_CACHE", CURLOPT_SSL_SESSIONID_CACHE, CURLOT_LONG, 0},
+  {"SSL_VERIFYHOST", CURLOPT_SSL_VERIFYHOST, CURLOT_LONG, 0},
+  {"SSL_VERIFYPEER", CURLOPT_SSL_VERIFYPEER, CURLOT_LONG, 0},
+  {"SSL_VERIFYSTATUS", CURLOPT_SSL_VERIFYSTATUS, CURLOT_LONG, 0},
+  {"STDERR", CURLOPT_STDERR, CURLOT_OBJECT, 0},
+  {"STREAM_DEPENDS", CURLOPT_STREAM_DEPENDS, CURLOT_OBJECT, 0},
+  {"STREAM_DEPENDS_E", CURLOPT_STREAM_DEPENDS_E, CURLOT_OBJECT, 0},
+  {"STREAM_WEIGHT", CURLOPT_STREAM_WEIGHT, CURLOT_LONG, 0},
+  {"SUPPRESS_CONNECT_HEADERS", CURLOPT_SUPPRESS_CONNECT_HEADERS,
+   CURLOT_LONG, 0},
+  {"TCP_FASTOPEN", CURLOPT_TCP_FASTOPEN, CURLOT_LONG, 0},
+  {"TCP_KEEPALIVE", CURLOPT_TCP_KEEPALIVE, CURLOT_LONG, 0},
+  {"TCP_KEEPIDLE", CURLOPT_TCP_KEEPIDLE, CURLOT_LONG, 0},
+  {"TCP_KEEPINTVL", CURLOPT_TCP_KEEPINTVL, CURLOT_LONG, 0},
+  {"TCP_NODELAY", CURLOPT_TCP_NODELAY, CURLOT_LONG, 0},
+  {"TELNETOPTIONS", CURLOPT_TELNETOPTIONS, CURLOT_SLIST, 0},
+  {"TFTP_BLKSIZE", CURLOPT_TFTP_BLKSIZE, CURLOT_LONG, 0},
+  {"TFTP_NO_OPTIONS", CURLOPT_TFTP_NO_OPTIONS, CURLOT_LONG, 0},
+  {"TIMECONDITION", CURLOPT_TIMECONDITION, CURLOT_VALUES, 0},
+  {"TIMEOUT", CURLOPT_TIMEOUT, CURLOT_LONG, 0},
+  {"TIMEOUT_MS", CURLOPT_TIMEOUT_MS, CURLOT_LONG, 0},
+  {"TIMEVALUE", CURLOPT_TIMEVALUE, CURLOT_LONG, 0},
+  {"TIMEVALUE_LARGE", CURLOPT_TIMEVALUE_LARGE, CURLOT_OFF_T, 0},
+  {"TLS13_CIPHERS", CURLOPT_TLS13_CIPHERS, CURLOT_STRING, 0},
+  {"TLSAUTH_PASSWORD", CURLOPT_TLSAUTH_PASSWORD, CURLOT_STRING, 0},
+  {"TLSAUTH_TYPE", CURLOPT_TLSAUTH_TYPE, CURLOT_STRING, 0},
+  {"TLSAUTH_USERNAME", CURLOPT_TLSAUTH_USERNAME, CURLOT_STRING, 0},
+  {"TRAILERDATA", CURLOPT_TRAILERDATA, CURLOT_CBPTR, 0},
+  {"TRAILERFUNCTION", CURLOPT_TRAILERFUNCTION, CURLOT_FUNCTION, 0},
+  {"TRANSFERTEXT", CURLOPT_TRANSFERTEXT, CURLOT_LONG, 0},
+  {"TRANSFER_ENCODING", CURLOPT_TRANSFER_ENCODING, CURLOT_LONG, 0},
+  {"UNIX_SOCKET_PATH", CURLOPT_UNIX_SOCKET_PATH, CURLOT_STRING, 0},
+  {"UNRESTRICTED_AUTH", CURLOPT_UNRESTRICTED_AUTH, CURLOT_LONG, 0},
+  {"UPKEEP_INTERVAL_MS", CURLOPT_UPKEEP_INTERVAL_MS, CURLOT_LONG, 0},
+  {"UPLOAD", CURLOPT_UPLOAD, CURLOT_LONG, 0},
+  {"UPLOAD_BUFFERSIZE", CURLOPT_UPLOAD_BUFFERSIZE, CURLOT_LONG, 0},
+  {"URL", CURLOPT_URL, CURLOT_STRING, 0},
+  {"USERAGENT", CURLOPT_USERAGENT, CURLOT_STRING, 0},
+  {"USERNAME", CURLOPT_USERNAME, CURLOT_STRING, 0},
+  {"USERPWD", CURLOPT_USERPWD, CURLOT_STRING, 0},
+  {"USE_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, 0},
+  {"VERBOSE", CURLOPT_VERBOSE, CURLOT_LONG, 0},
+  {"WILDCARDMATCH", CURLOPT_WILDCARDMATCH, CURLOT_LONG, 0},
+  {"WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0},
+  {"WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0},
+  {"WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS},
+  {"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0},
+  {"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0},
+  {"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0},
+  {NULL, CURLOPT_LASTENTRY, 0, 0} /* end of table */
+};
+
+#ifdef DEBUGBUILD
+/*
+ * Curl_easyopts_check() is a debug-only function that returns non-zero
+ * if this source file is not in sync with the options listed in curl/curl.h
+ */
+int Curl_easyopts_check(void)
+{
+  return (CURLOPT_LASTENTRY != (304 + 1));
+}
+#endif
diff --git a/lib/easyoptions.h b/lib/easyoptions.h
new file mode 100644
index 0000000..91e1190
--- /dev/null
+++ b/lib/easyoptions.h
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_EASYOPTIONS_H
+#define HEADER_CURL_EASYOPTIONS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* should probably go into the public header */
+
+#include <curl/curl.h>
+
+/* generated table with all easy options */
+extern struct curl_easyoption Curl_easyopts[];
+
+#ifdef DEBUGBUILD
+int Curl_easyopts_check(void);
+#endif
+#endif
diff --git a/lib/escape.c b/lib/escape.c
index 2bea145..683b6fc 100644
--- a/lib/escape.c
+++ b/lib/escape.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -86,7 +86,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
   if(inlength < 0)
     return NULL;
 
-  Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH);
+  Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH * 3);
 
   length = (inlength?(size_t)inlength:strlen(string));
   if(!length)
diff --git a/lib/escape.h b/lib/escape.h
index 586db7e..46cb590 100644
--- a/lib/escape.h
+++ b/lib/escape.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/file.c b/lib/file.c
index cd3e49c..a65eb77 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -67,8 +67,7 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
-#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
-  defined(__SYMBIAN32__)
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__)
 #define DOS_FILESYSTEM 1
 #endif
 
@@ -112,6 +111,7 @@ const struct Curl_handler Curl_handler_file = {
   ZERO_NULL,                            /* connection_check */
   0,                                    /* defport */
   CURLPROTO_FILE,                       /* protocol */
+  CURLPROTO_FILE,                       /* family */
   PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
 };
 
@@ -119,8 +119,8 @@ const struct Curl_handler Curl_handler_file = {
 static CURLcode file_setup_connection(struct connectdata *conn)
 {
   /* allocate the FILE specific struct */
-  conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
-  if(!conn->data->req.protop)
+  conn->data->req.p.file = calloc(1, sizeof(struct FILEPROTO));
+  if(!conn->data->req.p.file)
     return CURLE_OUT_OF_MEMORY;
 
   return CURLE_OK;
@@ -135,7 +135,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
 {
   struct Curl_easy *data = conn->data;
   char *real_path;
-  struct FILEPROTO *file = data->req.protop;
+  struct FILEPROTO *file = data->req.p.file;
   int fd;
 #ifdef DOS_FILESYSTEM
   size_t i;
@@ -209,7 +209,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
 static CURLcode file_done(struct connectdata *conn,
                                CURLcode status, bool premature)
 {
-  struct FILEPROTO *file = conn->data->req.protop;
+  struct FILEPROTO *file = conn->data->req.p.file;
   (void)status; /* not used */
   (void)premature; /* not used */
 
@@ -227,18 +227,8 @@ static CURLcode file_done(struct connectdata *conn,
 static CURLcode file_disconnect(struct connectdata *conn,
                                 bool dead_connection)
 {
-  struct FILEPROTO *file = conn->data->req.protop;
   (void)dead_connection; /* not used */
-
-  if(file) {
-    Curl_safefree(file->freepath);
-    file->path = NULL;
-    if(file->fd != -1)
-      close(file->fd);
-    file->fd = -1;
-  }
-
-  return CURLE_OK;
+  return file_done(conn, 0, 0);
 }
 
 #ifdef DOS_FILESYSTEM
@@ -249,7 +239,7 @@ static CURLcode file_disconnect(struct connectdata *conn,
 
 static CURLcode file_upload(struct connectdata *conn)
 {
-  struct FILEPROTO *file = conn->data->req.protop;
+  struct FILEPROTO *file = conn->data->req.p.file;
   const char *dir = strchr(file->path, DIRSEP);
   int fd;
   int mode;
@@ -391,7 +381,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
   if(data->set.upload)
     return file_upload(conn);
 
-  file = conn->data->req.protop;
+  file = conn->data->req.p.file;
 
   /* get the fd from the connection phase */
   fd = file->fd;
diff --git a/lib/file.h b/lib/file.h
index f6b74a7..338f92e 100644
--- a/lib/file.h
+++ b/lib/file.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/fileinfo.c b/lib/fileinfo.c
index 2630c9e..b7e9f0f 100644
--- a/lib/fileinfo.c
+++ b/lib/fileinfo.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/fileinfo.h b/lib/fileinfo.h
index f4d8f3b..5ae23ad 100644
--- a/lib/fileinfo.h
+++ b/lib/fileinfo.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,7 @@
 
 struct fileinfo {
   struct curl_fileinfo info;
-  struct curl_llist_element list;
+  struct Curl_llist_element list;
 };
 
 struct fileinfo *Curl_fileinfo_alloc(void);
diff --git a/lib/formdata.c b/lib/formdata.c
index 1cab2c5..769f06a 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/formdata.h b/lib/formdata.h
index 3766d38..5a021ce 100644
--- a/lib/formdata.h
+++ b/lib/formdata.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/ftp.c b/lib/ftp.c
index 9fadac5..bc35574 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -59,7 +59,7 @@
 #include "fileinfo.h"
 #include "ftplistparser.h"
 #include "curl_range.h"
-#include "curl_sec.h"
+#include "curl_krb5.h"
 #include "strtoofft.h"
 #include "strcase.h"
 #include "vtls/vtls.h"
@@ -137,14 +137,10 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks);
 static CURLcode ftp_doing(struct connectdata *conn,
                           bool *dophase_done);
 static CURLcode ftp_setup_connection(struct connectdata *conn);
-
 static CURLcode init_wc_data(struct connectdata *conn);
 static CURLcode wc_statemach(struct connectdata *conn);
-
 static void wc_data_dtor(void *ptr);
-
 static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
-
 static CURLcode ftp_readresp(curl_socket_t sockfd,
                              struct pingpong *pp,
                              int *ftpcode,
@@ -152,12 +148,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
 static CURLcode ftp_dophase_done(struct connectdata *conn,
                                  bool connected);
 
-/* easy-to-use macro: */
-#define PPSENDF(x,y,z)  result = Curl_pp_sendf(x,y,z); \
-                        if(result)                     \
-                          return result
-
-
 /*
  * FTP protocol handler.
  */
@@ -180,6 +170,7 @@ const struct Curl_handler Curl_handler_ftp = {
   ZERO_NULL,                       /* connection_check */
   PORT_FTP,                        /* defport */
   CURLPROTO_FTP,                   /* protocol */
+  CURLPROTO_FTP,                   /* family */
   PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
   PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
   PROTOPT_WILDCARD /* flags */
@@ -209,6 +200,7 @@ const struct Curl_handler Curl_handler_ftps = {
   ZERO_NULL,                       /* connection_check */
   PORT_FTPS,                       /* defport */
   CURLPROTO_FTPS,                  /* protocol */
+  CURLPROTO_FTP,                   /* family */
   PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
   PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */
 };
@@ -775,25 +767,22 @@ static void _state(struct connectdata *conn,
 
 static CURLcode ftp_state_user(struct connectdata *conn)
 {
-  CURLcode result;
-  /* send USER */
-  PPSENDF(&conn->proto.ftpc.pp, "USER %s", conn->user?conn->user:"");
-
-  state(conn, FTP_USER);
-  conn->data->state.ftp_trying_alternative = FALSE;
-
-  return CURLE_OK;
+  CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "USER %s",
+                                  conn->user?conn->user:"");
+  if(!result) {
+    state(conn, FTP_USER);
+    conn->data->state.ftp_trying_alternative = FALSE;
+  }
+  return result;
 }
 
 static CURLcode ftp_state_pwd(struct connectdata *conn)
 {
-  CURLcode result;
-
-  /* send PWD to discover our entry point */
-  PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
-  state(conn, FTP_PWD);
+  CURLcode result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PWD");
+  if(!result)
+    state(conn, FTP_PWD);
 
-  return CURLE_OK;
+  return result;
 }
 
 /* For the FTP "protocol connect" and "doing" phases only */
@@ -881,16 +870,19 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
          where we ended up after login: */
       ftpc->cwdcount = 0; /* we count this as the first path, then we add one
                              for all upcoming ones in the ftp->dirs[] array */
-      PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath);
-      state(conn, FTP_CWD);
+      result = Curl_pp_sendf(&ftpc->pp, "CWD %s", ftpc->entrypath);
+      if(!result)
+        state(conn, FTP_CWD);
     }
     else {
       if(ftpc->dirdepth) {
         ftpc->cwdcount = 1;
         /* issue the first CWD, the rest is sent when the CWD responses are
            received... */
-        PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->cwdcount -1]);
-        state(conn, FTP_CWD);
+        result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+                               ftpc->dirs[ftpc->cwdcount -1]);
+        if(!result)
+          state(conn, FTP_CWD);
       }
       else {
         /* No CWD necessary */
@@ -909,7 +901,6 @@ typedef enum {
 
 static CURLcode ftp_state_use_port(struct connectdata *conn,
                                    ftpport fcmd) /* start with this */
-
 {
   CURLcode result = CURLE_OK;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -1326,12 +1317,12 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
 
   modeoff = conn->bits.ftp_use_epsv?0:1;
 
-  PPSENDF(&ftpc->pp, "%s", mode[modeoff]);
-
-  ftpc->count1 = modeoff;
-  state(conn, FTP_PASV);
-  infof(conn->data, "Connect data stream passively\n");
-
+  result = Curl_pp_sendf(&ftpc->pp, "%s", mode[modeoff]);
+  if(!result) {
+    ftpc->count1 = modeoff;
+    state(conn, FTP_PASV);
+    infof(conn->data, "Connect data stream passively\n");
+  }
   return result;
 }
 
@@ -1345,7 +1336,7 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
 static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   struct Curl_easy *data = conn->data;
 
   if(ftp->transfer != FTPTRANSFER_BODY) {
@@ -1364,23 +1355,23 @@ static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
     if(data->set.ftp_use_pret) {
       /* The user has requested that we send a PRET command
          to prepare the server for the upcoming PASV */
-      if(!conn->proto.ftpc.file) {
-        PPSENDF(&conn->proto.ftpc.pp, "PRET %s",
-                data->set.str[STRING_CUSTOMREQUEST]?
-                data->set.str[STRING_CUSTOMREQUEST]:
-                (data->set.ftp_list_only?"NLST":"LIST"));
-      }
-      else if(data->set.upload) {
-        PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
-      }
-      else {
-        PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
-      }
-      state(conn, FTP_PRET);
+      struct ftp_conn *ftpc = &conn->proto.ftpc;
+      if(!conn->proto.ftpc.file)
+        result = Curl_pp_sendf(&ftpc->pp, "PRET %s",
+                               data->set.str[STRING_CUSTOMREQUEST]?
+                               data->set.str[STRING_CUSTOMREQUEST]:
+                               (data->set.ftp_list_only?"NLST":"LIST"));
+      else if(data->set.upload)
+        result = Curl_pp_sendf(&ftpc->pp, "PRET STOR %s",
+                               conn->proto.ftpc.file);
+      else
+        result = Curl_pp_sendf(&ftpc->pp, "PRET RETR %s",
+                               conn->proto.ftpc.file);
+      if(!result)
+        state(conn, FTP_PRET);
     }
-    else {
+    else
       result = ftp_state_use_pasv(conn);
-    }
   }
   return result;
 }
@@ -1388,7 +1379,7 @@ static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
 static CURLcode ftp_state_rest(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
@@ -1396,9 +1387,9 @@ static CURLcode ftp_state_rest(struct connectdata *conn)
 
     /* Determine if server can respond to REST command and therefore
        whether it supports range */
-    PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0);
-
-    state(conn, FTP_REST);
+    result = Curl_pp_sendf(&ftpc->pp, "REST %d", 0);
+    if(!result)
+      state(conn, FTP_REST);
   }
   else
     result = ftp_state_prepare_transfer(conn);
@@ -1409,16 +1400,16 @@ static CURLcode ftp_state_rest(struct connectdata *conn)
 static CURLcode ftp_state_size(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
     /* if a "head"-like request is being made (on a file) */
 
     /* we know ftpc->file is a valid pointer to a file name */
-    PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
-
-    state(conn, FTP_SIZE);
+    result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+    if(!result)
+      state(conn, FTP_SIZE);
   }
   else
     result = ftp_state_rest(conn);
@@ -1430,7 +1421,7 @@ static CURLcode ftp_state_list(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
 
   /* If this output is to be machine-parsed, the NLST command might be better
      to use, since the LIST command output is not specified or standard in any
@@ -1485,10 +1476,8 @@ static CURLcode ftp_state_list(struct connectdata *conn)
   result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
   free(cmd);
 
-  if(result)
-    return result;
-
-  state(conn, FTP_LIST);
+  if(!result)
+    state(conn, FTP_LIST);
 
   return result;
 }
@@ -1508,7 +1497,7 @@ static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
 static CURLcode ftp_state_type(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   struct Curl_easy *data = conn->data;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
@@ -1549,9 +1538,10 @@ static CURLcode ftp_state_mdtm(struct connectdata *conn)
 
     /* we have requested to get the modified-time of the file, this is a white
        spot as the MDTM is not mentioned in RFC959 */
-    PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file);
+    result = Curl_pp_sendf(&ftpc->pp, "MDTM %s", ftpc->file);
 
-    state(conn, FTP_MDTM);
+    if(!result)
+      state(conn, FTP_MDTM);
   }
   else
     result = ftp_state_type(conn);
@@ -1565,7 +1555,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
                                    bool sizechecked)
 {
   CURLcode result = CURLE_OK;
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   struct Curl_easy *data = conn->data;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
@@ -1587,8 +1577,9 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
 
     if(data->state.resume_from < 0) {
       /* Got no given size to start from, figure it out */
-      PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
-      state(conn, FTP_STOR_SIZE);
+      result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+      if(!result)
+        state(conn, FTP_STOR_SIZE);
       return result;
     }
 
@@ -1650,10 +1641,10 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
     /* we've passed, proceed as normal */
   } /* resume_from */
 
-  PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
-          ftpc->file);
-
-  state(conn, FTP_STOR);
+  result = Curl_pp_sendf(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
+                         ftpc->file);
+  if(!result)
+    state(conn, FTP_STOR);
 
   return result;
 }
@@ -1664,7 +1655,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   bool quote = FALSE;
   struct curl_slist *item;
@@ -1711,7 +1702,9 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
       else
         ftpc->count2 = 0; /* failure means cancel operation */
 
-      PPSENDF(&ftpc->pp, "%s", cmd);
+      result = Curl_pp_sendf(&ftpc->pp, "%s", cmd);
+      if(result)
+        return result;
       state(conn, instate);
       quote = TRUE;
     }
@@ -1740,12 +1733,14 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
                the server terminates it, otherwise the client stops if the
                received byte count exceeds the reported file size.  Set option
                CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/
-            PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
-            state(conn, FTP_RETR);
+            result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+            if(!result)
+              state(conn, FTP_RETR);
           }
           else {
-            PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
-            state(conn, FTP_RETR_SIZE);
+            result = Curl_pp_sendf(&ftpc->pp, "SIZE %s", ftpc->file);
+            if(!result)
+              state(conn, FTP_RETR_SIZE);
           }
         }
       }
@@ -1782,10 +1777,12 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
   conn->bits.ftp_use_epsv = FALSE;
   conn->data->state.errorbuf = FALSE; /* allow error message to get
                                          rewritten */
-  PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
-  conn->proto.ftpc.count1++;
-  /* remain in/go to the FTP_PASV state */
-  state(conn, FTP_PASV);
+  result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "PASV");
+  if(!result) {
+    conn->proto.ftpc.count1++;
+    /* remain in/go to the FTP_PASV state */
+    state(conn, FTP_PASV);
+  }
   return result;
 }
 
@@ -1864,8 +1861,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
   else if((ftpc->count1 == 1) &&
           (ftpcode == 227)) {
     /* positive PASV response */
-    unsigned int ip[4];
-    unsigned int port[2];
+    unsigned int ip[4] = {0, 0, 0, 0};
+    unsigned int port[2] = {0, 0};
 
     /*
      * Scan for a sequence of six comma-separated numbers and use them as
@@ -1943,6 +1940,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
 #endif
   {
     /* normal, direct, ftp connection */
+    DEBUGASSERT(ftpc->newhost);
+
+    /* postponed address resolution in case of tcp fastopen */
+    if(conn->bits.tcp_fastopen && !conn->bits.reuse && !ftpc->newhost[0]) {
+      Curl_conninfo_remote(conn, conn->sock[FIRSTSOCKET]);
+      Curl_safefree(ftpc->newhost);
+      ftpc->newhost = strdup(control_address(conn));
+      if(!ftpc->newhost)
+        return CURLE_OUT_OF_MEMORY;
+    }
+
     rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
     if(rc == CURLRESOLV_PENDING)
       /* BLOCKING */
@@ -2033,7 +2041,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   switch(ftpcode) {
@@ -2092,7 +2100,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
     break;
   case 550: /* "No such file or directory" */
     failf(data, "Given file does not exist");
-    result = CURLE_FTP_COULDNT_RETR_FILE;
+    result = CURLE_REMOTE_FILE_NOT_FOUND;
     break;
   }
 
@@ -2166,7 +2174,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
@@ -2229,15 +2237,16 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
     infof(data, "Instructs server to resume from offset %"
           CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
 
-    PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
-            data->state.resume_from);
-
-    state(conn, FTP_RETR_REST);
+    result = Curl_pp_sendf(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
+                           data->state.resume_from);
+    if(!result)
+      state(conn, FTP_RETR_REST);
   }
   else {
     /* no resume */
-    PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
-    state(conn, FTP_RETR);
+    result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+    if(!result)
+      state(conn, FTP_RETR);
   }
 
   return result;
@@ -2272,6 +2281,10 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
     (void)curlx_strtoofft(fdigit, NULL, 0, &filesize);
 
   }
+  else if(ftpcode == 550) { /* "No such file or directory" */
+    failf(data, "The file does not exist");
+    return CURLE_REMOTE_FILE_NOT_FOUND;
+  }
 
   if(instate == FTP_SIZE) {
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
@@ -2326,8 +2339,9 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
       result = CURLE_FTP_COULDNT_USE_REST;
     }
     else {
-      PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
-      state(conn, FTP_RETR);
+      result = Curl_pp_sendf(&ftpc->pp, "RETR %s", ftpc->file);
+      if(!result)
+        state(conn, FTP_RETR);
     }
     break;
   }
@@ -2378,7 +2392,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
 
   if((ftpcode == 150) || (ftpcode == 125)) {
 
@@ -2504,7 +2518,7 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
 
-  if(conn->ssl[FIRSTSOCKET].use) {
+  if(conn->bits.ftp_use_control_ssl) {
     /* PBSZ = PROTECTION BUFFER SIZE.
 
     The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
@@ -2519,8 +2533,9 @@ static CURLcode ftp_state_loggedin(struct connectdata *conn)
     parameter of '0' to indicate that no buffering is taking place
     and the data connection should not be encapsulated.
     */
-    PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0);
-    state(conn, FTP_PBSZ);
+    result = Curl_pp_sendf(&conn->proto.ftpc.pp, "PBSZ %d", 0);
+    if(!result)
+      state(conn, FTP_PBSZ);
   }
   else {
     result = ftp_state_pwd(conn);
@@ -2542,8 +2557,9 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
   if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
     /* 331 Password required for ...
        (the server requires to send the user's password too) */
-    PPSENDF(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
-    state(conn, FTP_PASS);
+    result = Curl_pp_sendf(&ftpc->pp, "PASS %s", conn->passwd?conn->passwd:"");
+    if(!result)
+      state(conn, FTP_PASS);
   }
   else if(ftpcode/100 == 2) {
     /* 230 User ... logged in.
@@ -2552,8 +2568,10 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
   }
   else if(ftpcode == 332) {
     if(data->set.str[STRING_FTP_ACCOUNT]) {
-      PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]);
-      state(conn, FTP_ACCT);
+      result = Curl_pp_sendf(&ftpc->pp, "ACCT %s",
+                             data->set.str[STRING_FTP_ACCOUNT]);
+      if(!result)
+        state(conn, FTP_ACCT);
     }
     else {
       failf(data, "ACCT requested but none available");
@@ -2569,11 +2587,13 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
     if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
         !conn->data->state.ftp_trying_alternative) {
       /* Ok, USER failed.  Let's try the supplied command. */
-      PPSENDF(&conn->proto.ftpc.pp, "%s",
-              conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
-      conn->data->state.ftp_trying_alternative = TRUE;
-      state(conn, FTP_USER);
-      result = CURLE_OK;
+      result =
+        Curl_pp_sendf(&ftpc->pp, "%s",
+                      conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+      if(!result) {
+        conn->data->state.ftp_trying_alternative = TRUE;
+        state(conn, FTP_USER);
+      }
     }
     else {
       failf(data, "Access denied: %03d", ftpcode);
@@ -2649,14 +2669,8 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
       }
 #endif
 
-      if(data->set.use_ssl &&
-         (!conn->ssl[FIRSTSOCKET].use
-#ifndef CURL_DISABLE_PROXY
-          || (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
-              !conn->proxy_ssl[FIRSTSOCKET].use)
-#endif
-           )) {
-        /* We don't have a SSL/TLS connection yet, but FTPS is
+      if(data->set.use_ssl && !conn->bits.ftp_use_control_ssl) {
+        /* We don't have a SSL/TLS control connection yet, but FTPS is
            requested. Try a FTPS connection now */
 
         ftpc->count3 = 0;
@@ -2675,15 +2689,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
                 (int)data->set.ftpsslauth);
           return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
         }
-        PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
-        state(conn, FTP_AUTH);
+        result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+        if(!result)
+          state(conn, FTP_AUTH);
       }
-      else {
+      else
         result = ftp_state_user(conn);
-        if(result)
-          return result;
-      }
-
       break;
 
     case FTP_AUTH:
@@ -2701,6 +2712,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
         result = Curl_ssl_connect(conn, FIRSTSOCKET);
         if(!result) {
           conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
+          conn->bits.ftp_use_control_ssl = TRUE; /* SSL on control */
           result = ftp_state_user(conn);
         }
       }
@@ -2718,9 +2730,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
           /* ignore the failure and continue */
           result = ftp_state_user(conn);
       }
-
-      if(result)
-        return result;
       break;
 
     case FTP_USER:
@@ -2733,10 +2742,11 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
       break;
 
     case FTP_PBSZ:
-      PPSENDF(&ftpc->pp, "PROT %c",
-              data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
-      state(conn, FTP_PROT);
-
+      result =
+        Curl_pp_sendf(&ftpc->pp, "PROT %c",
+                      data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
+      if(!result)
+        state(conn, FTP_PROT);
       break;
 
     case FTP_PROT:
@@ -2753,14 +2763,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
       if(data->set.ftp_ccc) {
         /* CCC - Clear Command Channel
          */
-        PPSENDF(&ftpc->pp, "%s", "CCC");
-        state(conn, FTP_CCC);
+        result = Curl_pp_sendf(&ftpc->pp, "%s", "CCC");
+        if(!result)
+          state(conn, FTP_CCC);
       }
-      else {
+      else
         result = ftp_state_pwd(conn);
-        if(result)
-          return result;
-      }
       break;
 
     case FTP_CCC:
@@ -2768,16 +2776,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
         /* First shut down the SSL layer (note: this call will block) */
         result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
 
-        if(result) {
+        if(result)
           failf(conn->data, "Failed to clear the command channel (CCC)");
-          return result;
-        }
       }
-
-      /* Then continue as normal */
-      result = ftp_state_pwd(conn);
-      if(result)
-        return result;
+      if(!result)
+        /* Then continue as normal */
+        result = ftp_state_pwd(conn);
       break;
 
     case FTP_PWD:
@@ -2843,7 +2847,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
              systems. */
 
           if(!ftpc->server_os && dir[0] != '/') {
-
             result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
             if(result) {
               free(dir);
@@ -2939,12 +2942,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
       if((ftpcode >= 400) && !ftpc->count2) {
         /* failure response code, and not allowed to fail */
         failf(conn->data, "QUOT command failed with %03d", ftpcode);
-        return CURLE_QUOTE_ERROR;
+        result = CURLE_QUOTE_ERROR;
       }
-      result = ftp_state_quote(conn, FALSE, ftpc->state);
-      if(result)
-        return result;
-
+      else
+        result = ftp_state_quote(conn, FALSE, ftpc->state);
       break;
 
     case FTP_CWD:
@@ -2954,29 +2955,28 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
            ftpc->cwdcount && !ftpc->count2) {
           /* try making it */
           ftpc->count2++; /* counter to prevent CWD-MKD loops */
-          PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->cwdcount - 1]);
-          state(conn, FTP_MKD);
+          result = Curl_pp_sendf(&ftpc->pp, "MKD %s",
+                                 ftpc->dirs[ftpc->cwdcount - 1]);
+          if(!result)
+            state(conn, FTP_MKD);
         }
         else {
           /* return failure */
           failf(data, "Server denied you to change to the given directory");
           ftpc->cwdfail = TRUE; /* don't remember this path as we failed
                                    to enter it */
-          return CURLE_REMOTE_ACCESS_DENIED;
+          result = CURLE_REMOTE_ACCESS_DENIED;
         }
       }
       else {
         /* success */
         ftpc->count2 = 0;
-        if(++ftpc->cwdcount <= ftpc->dirdepth) {
+        if(++ftpc->cwdcount <= ftpc->dirdepth)
           /* send next CWD */
-          PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]);
-        }
-        else {
+          result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+                                 ftpc->dirs[ftpc->cwdcount - 1]);
+        else
           result = ftp_state_mdtm(conn);
-          if(result)
-            return result;
-        }
       }
       break;
 
@@ -2984,11 +2984,14 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
       if((ftpcode/100 != 2) && !ftpc->count3--) {
         /* failure to MKD the dir */
         failf(data, "Failed to MKD dir: %03d", ftpcode);
-        return CURLE_REMOTE_ACCESS_DENIED;
+        result = CURLE_REMOTE_ACCESS_DENIED;
+      }
+      else {
+        state(conn, FTP_CWD);
+        /* send CWD */
+        result = Curl_pp_sendf(&ftpc->pp, "CWD %s",
+                               ftpc->dirs[ftpc->cwdcount - 1]);
       }
-      state(conn, FTP_CWD);
-      /* send CWD */
-      PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]);
       break;
 
     case FTP_MDTM:
@@ -3091,7 +3094,7 @@ static CURLcode ftp_block_statemach(struct connectdata *conn)
  *
  */
 static CURLcode ftp_connect(struct connectdata *conn,
-                                 bool *done) /* see description above */
+                            bool *done) /* see description above */
 {
   CURLcode result;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
@@ -3112,8 +3115,10 @@ static CURLcode ftp_connect(struct connectdata *conn,
     result = Curl_ssl_connect(conn, FIRSTSOCKET);
     if(result)
       return result;
+    conn->bits.ftp_use_control_ssl = TRUE;
   }
 
+  Curl_pp_setup(pp); /* once per transfer */
   Curl_pp_init(pp); /* init the generic pingpong data */
 
   /* When we connect, we start in the state where we await the 220
@@ -3138,7 +3143,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
                          bool premature)
 {
   struct Curl_easy *data = conn->data;
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct pingpong *pp = &ftpc->pp;
   ssize_t nread;
@@ -3297,9 +3302,18 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
 
     if(!ftpc->dont_check) {
       /* 226 Transfer complete, 250 Requested file action okay, completed. */
-      if((ftpcode != 226) && (ftpcode != 250)) {
+      switch(ftpcode) {
+      case 226:
+      case 250:
+        break;
+      case 552:
+        failf(data, "Exceeded storage allocation");
+        result = CURLE_REMOTE_DISK_FULL;
+        break;
+      default:
         failf(data, "server did not report OK, got %d", ftpcode);
         result = CURLE_PARTIAL_FILE;
+        break;
       }
     }
   }
@@ -3368,17 +3382,17 @@ static
 CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
 {
   struct curl_slist *item;
-  ssize_t nread;
-  int ftpcode;
-  CURLcode result;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct pingpong *pp = &ftpc->pp;
 
   item = quote;
   while(item) {
     if(item->data) {
+      ssize_t nread;
       char *cmd = item->data;
       bool acceptfail = FALSE;
+      CURLcode result;
+      int ftpcode = 0;
 
       /* if a command starts with an asterisk, which a legal FTP command never
          can, the command will be allowed to fail without it causing any
@@ -3390,11 +3404,11 @@ CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
         acceptfail = TRUE;
       }
 
-      PPSENDF(&conn->proto.ftpc.pp, "%s", cmd);
-
-      pp->response = Curl_now(); /* timeout relative now */
-
-      result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+      result = Curl_pp_sendf(&ftpc->pp, "%s", cmd);
+      if(!result) {
+        pp->response = Curl_now(); /* timeout relative now */
+        result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+      }
       if(result)
         return result;
 
@@ -3442,12 +3456,14 @@ static CURLcode ftp_nb_type(struct connectdata *conn,
     return ftp_state_type_resp(conn, 200, newstate);
   }
 
-  PPSENDF(&ftpc->pp, "TYPE %c", want);
-  state(conn, newstate);
+  result = Curl_pp_sendf(&ftpc->pp, "TYPE %c", want);
+  if(!result) {
+    state(conn, newstate);
 
-  /* keep track of our current transfer type */
-  ftpc->transfertype = want;
-  return CURLE_OK;
+    /* keep track of our current transfer type */
+    ftpc->transfertype = want;
+  }
+  return result;
 }
 
 /***************************************************************************
@@ -3492,7 +3508,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
   bool complete = FALSE;
 
   /* the ftp struct is inited in ftp_connect() */
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
 
   /* if the second connection isn't done yet, wait for it */
   if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
@@ -3657,7 +3673,7 @@ CURLcode ftp_perform(struct connectdata *conn,
 
   if(conn->data->set.opt_no_body) {
     /* requested no body means no transfer... */
-    struct FTP *ftp = conn->data->req.protop;
+    struct FTP *ftp = conn->data->req.p.ftp;
     ftp->transfer = FTPTRANSFER_INFO;
   }
 
@@ -3692,7 +3708,7 @@ static void wc_data_dtor(void *ptr)
 static CURLcode init_wc_data(struct connectdata *conn)
 {
   char *last_slash;
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   char *path = ftp->path;
   struct WildcardData *wildcard = &(conn->data->wildcard);
   CURLcode result = CURLE_OK;
@@ -3784,129 +3800,131 @@ static CURLcode init_wc_data(struct connectdata *conn)
   return result;
 }
 
-/* This is called recursively */
 static CURLcode wc_statemach(struct connectdata *conn)
 {
   struct WildcardData * const wildcard = &(conn->data->wildcard);
   CURLcode result = CURLE_OK;
 
-  switch(wildcard->state) {
-  case CURLWC_INIT:
-    result = init_wc_data(conn);
-    if(wildcard->state == CURLWC_CLEAN)
-      /* only listing! */
-      break;
-    wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
-    break;
+  for(;;) {
+    switch(wildcard->state) {
+    case CURLWC_INIT:
+      result = init_wc_data(conn);
+      if(wildcard->state == CURLWC_CLEAN)
+        /* only listing! */
+        return result;
+      wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
+      return result;
 
-  case CURLWC_MATCHING: {
-    /* In this state is LIST response successfully parsed, so lets restore
-       previous WRITEFUNCTION callback and WRITEDATA pointer */
-    struct ftp_wc *ftpwc = wildcard->protdata;
-    conn->data->set.fwrite_func = ftpwc->backup.write_function;
-    conn->data->set.out = ftpwc->backup.file_descriptor;
-    ftpwc->backup.write_function = ZERO_NULL;
-    ftpwc->backup.file_descriptor = NULL;
-    wildcard->state = CURLWC_DOWNLOADING;
-
-    if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
-      /* error found in LIST parsing */
-      wildcard->state = CURLWC_CLEAN;
-      return wc_statemach(conn);
-    }
-    if(wildcard->filelist.size == 0) {
-      /* no corresponding file */
-      wildcard->state = CURLWC_CLEAN;
-      return CURLE_REMOTE_FILE_NOT_FOUND;
+    case CURLWC_MATCHING: {
+      /* In this state is LIST response successfully parsed, so lets restore
+         previous WRITEFUNCTION callback and WRITEDATA pointer */
+      struct ftp_wc *ftpwc = wildcard->protdata;
+      conn->data->set.fwrite_func = ftpwc->backup.write_function;
+      conn->data->set.out = ftpwc->backup.file_descriptor;
+      ftpwc->backup.write_function = ZERO_NULL;
+      ftpwc->backup.file_descriptor = NULL;
+      wildcard->state = CURLWC_DOWNLOADING;
+
+      if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
+        /* error found in LIST parsing */
+        wildcard->state = CURLWC_CLEAN;
+        continue;
+      }
+      if(wildcard->filelist.size == 0) {
+        /* no corresponding file */
+        wildcard->state = CURLWC_CLEAN;
+        return CURLE_REMOTE_FILE_NOT_FOUND;
+      }
+      continue;
     }
-    return wc_statemach(conn);
-  }
 
-  case CURLWC_DOWNLOADING: {
-    /* filelist has at least one file, lets get first one */
-    struct ftp_conn *ftpc = &conn->proto.ftpc;
-    struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
-    struct FTP *ftp = conn->data->req.protop;
+    case CURLWC_DOWNLOADING: {
+      /* filelist has at least one file, lets get first one */
+      struct ftp_conn *ftpc = &conn->proto.ftpc;
+      struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
+      struct FTP *ftp = conn->data->req.p.ftp;
 
-    char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
-    if(!tmp_path)
-      return CURLE_OUT_OF_MEMORY;
+      char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
+      if(!tmp_path)
+        return CURLE_OUT_OF_MEMORY;
 
-    /* switch default ftp->path and tmp_path */
-    free(ftp->pathalloc);
-    ftp->pathalloc = ftp->path = tmp_path;
-
-    infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
-    if(conn->data->set.chunk_bgn) {
-      long userresponse;
-      Curl_set_in_callback(conn->data, true);
-      userresponse = conn->data->set.chunk_bgn(
-        finfo, wildcard->customptr, (int)wildcard->filelist.size);
-      Curl_set_in_callback(conn->data, false);
-      switch(userresponse) {
-      case CURL_CHUNK_BGN_FUNC_SKIP:
-        infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
-              finfo->filename);
-        wildcard->state = CURLWC_SKIP;
-        return wc_statemach(conn);
-      case CURL_CHUNK_BGN_FUNC_FAIL:
-        return CURLE_CHUNK_FAILED;
+      /* switch default ftp->path and tmp_path */
+      free(ftp->pathalloc);
+      ftp->pathalloc = ftp->path = tmp_path;
+
+      infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
+      if(conn->data->set.chunk_bgn) {
+        long userresponse;
+        Curl_set_in_callback(conn->data, true);
+        userresponse = conn->data->set.chunk_bgn(
+          finfo, wildcard->customptr, (int)wildcard->filelist.size);
+        Curl_set_in_callback(conn->data, false);
+        switch(userresponse) {
+        case CURL_CHUNK_BGN_FUNC_SKIP:
+          infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
+                finfo->filename);
+          wildcard->state = CURLWC_SKIP;
+          continue;
+        case CURL_CHUNK_BGN_FUNC_FAIL:
+          return CURLE_CHUNK_FAILED;
+        }
       }
-    }
 
-    if(finfo->filetype != CURLFILETYPE_FILE) {
-      wildcard->state = CURLWC_SKIP;
-      return wc_statemach(conn);
-    }
+      if(finfo->filetype != CURLFILETYPE_FILE) {
+        wildcard->state = CURLWC_SKIP;
+        continue;
+      }
 
-    if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
-      ftpc->known_filesize = finfo->size;
+      if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
+        ftpc->known_filesize = finfo->size;
 
-    result = ftp_parse_url_path(conn);
-    if(result)
-      return result;
+      result = ftp_parse_url_path(conn);
+      if(result)
+        return result;
 
-    /* we don't need the Curl_fileinfo of first file anymore */
-    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+      /* we don't need the Curl_fileinfo of first file anymore */
+      Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
 
-    if(wildcard->filelist.size == 0) { /* remains only one file to down. */
-      wildcard->state = CURLWC_CLEAN;
-      /* after that will be ftp_do called once again and no transfer
-         will be done because of CURLWC_CLEAN state */
-      return CURLE_OK;
+      if(wildcard->filelist.size == 0) { /* remains only one file to down. */
+        wildcard->state = CURLWC_CLEAN;
+        /* after that will be ftp_do called once again and no transfer
+           will be done because of CURLWC_CLEAN state */
+        return CURLE_OK;
+      }
+      return result;
     }
-  } break;
 
-  case CURLWC_SKIP: {
-    if(conn->data->set.chunk_end) {
-      Curl_set_in_callback(conn->data, true);
-      conn->data->set.chunk_end(conn->data->wildcard.customptr);
-      Curl_set_in_callback(conn->data, false);
+    case CURLWC_SKIP: {
+      if(conn->data->set.chunk_end) {
+        Curl_set_in_callback(conn->data, true);
+        conn->data->set.chunk_end(conn->data->wildcard.customptr);
+        Curl_set_in_callback(conn->data, false);
+      }
+      Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+      wildcard->state = (wildcard->filelist.size == 0) ?
+        CURLWC_CLEAN : CURLWC_DOWNLOADING;
+      continue;
     }
-    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
-    wildcard->state = (wildcard->filelist.size == 0) ?
-                      CURLWC_CLEAN : CURLWC_DOWNLOADING;
-    return wc_statemach(conn);
-  }
 
-  case CURLWC_CLEAN: {
-    struct ftp_wc *ftpwc = wildcard->protdata;
-    result = CURLE_OK;
-    if(ftpwc)
-      result = Curl_ftp_parselist_geterror(ftpwc->parser);
+    case CURLWC_CLEAN: {
+      struct ftp_wc *ftpwc = wildcard->protdata;
+      result = CURLE_OK;
+      if(ftpwc)
+        result = Curl_ftp_parselist_geterror(ftpwc->parser);
 
-    wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
-  } break;
+      wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
+      return result;
+    }
 
-  case CURLWC_DONE:
-  case CURLWC_ERROR:
-  case CURLWC_CLEAR:
-    if(wildcard->dtor)
-      wildcard->dtor(wildcard->protdata);
-    break;
+    case CURLWC_DONE:
+    case CURLWC_ERROR:
+    case CURLWC_CLEAR:
+      if(wildcard->dtor)
+        wildcard->dtor(wildcard->protdata);
+      return result;
+    }
   }
-
-  return result;
+  /* UNREACHABLE */
 }
 
 /***********************************************************************
@@ -3947,64 +3965,6 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done)
   return result;
 }
 
-
-CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
-{
-  ssize_t bytes_written;
-#define SBUF_SIZE 1024
-  char s[SBUF_SIZE];
-  size_t write_len;
-  char *sptr = s;
-  CURLcode result = CURLE_OK;
-#ifdef HAVE_GSSAPI
-  enum protection_level data_sec = conn->data_prot;
-#endif
-
-  if(!cmd)
-    return CURLE_BAD_FUNCTION_ARGUMENT;
-
-  write_len = strlen(cmd);
-  if(!write_len || write_len > (sizeof(s) -3))
-    return CURLE_BAD_FUNCTION_ARGUMENT;
-
-  memcpy(&s, cmd, write_len);
-  strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
-  write_len += 2;
-  bytes_written = 0;
-
-  result = Curl_convert_to_network(conn->data, s, write_len);
-  /* Curl_convert_to_network calls failf if unsuccessful */
-  if(result)
-    return result;
-
-  for(;;) {
-#ifdef HAVE_GSSAPI
-    conn->data_prot = PROT_CMD;
-#endif
-    result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
-                        &bytes_written);
-#ifdef HAVE_GSSAPI
-    DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
-    conn->data_prot = data_sec;
-#endif
-
-    if(result)
-      break;
-
-    if(conn->data->set.verbose)
-      Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
-
-    if(bytes_written != (ssize_t)write_len) {
-      write_len -= bytes_written;
-      sptr += bytes_written;
-    }
-    else
-      break;
-  }
-
-  return result;
-}
-
 /***********************************************************************
  *
  * ftp_quit()
@@ -4068,22 +4028,14 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
     if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
       data->state.most_recent_ftp_entrypath = NULL;
     }
-    free(ftpc->entrypath);
-    ftpc->entrypath = NULL;
+    Curl_safefree(ftpc->entrypath);
   }
 
   freedirs(ftpc);
-  free(ftpc->prevpath);
-  ftpc->prevpath = NULL;
-  free(ftpc->server_os);
-  ftpc->server_os = NULL;
-
+  Curl_safefree(ftpc->prevpath);
+  Curl_safefree(ftpc->server_os);
   Curl_pp_disconnect(pp);
-
-#ifdef HAVE_GSSAPI
   Curl_sec_end(conn);
-#endif
-
   return CURLE_OK;
 }
 
@@ -4099,7 +4051,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
 {
   struct Curl_easy *data = conn->data;
   /* the ftp struct is already inited in ftp_connect() */
-  struct FTP *ftp = data->req.protop;
+  struct FTP *ftp = data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   const char *slashPos = NULL;
   const char *fileName = NULL;
@@ -4244,7 +4196,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
 static CURLcode ftp_dophase_done(struct connectdata *conn,
                                  bool connected)
 {
-  struct FTP *ftp = conn->data->req.protop;
+  struct FTP *ftp = conn->data->req.p.ftp;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
 
   if(connected) {
@@ -4341,7 +4293,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
   char *type;
   struct FTP *ftp;
 
-  conn->data->req.protop = ftp = calloc(sizeof(struct FTP), 1);
+  conn->data->req.p.ftp = ftp = calloc(sizeof(struct FTP), 1);
   if(NULL == ftp)
     return CURLE_OUT_OF_MEMORY;
 
diff --git a/lib/ftp.h b/lib/ftp.h
index 06421c6..3ca1458 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -31,7 +31,6 @@ extern const struct Curl_handler Curl_handler_ftp;
 extern const struct Curl_handler Curl_handler_ftps;
 #endif
 
-CURLcode Curl_ftpsend(struct connectdata *, const char *cmd);
 CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
                              int *ftpcode);
 #endif /* CURL_DISABLE_FTP */
diff --git a/lib/ftplistparser.c b/lib/ftplistparser.c
index f399a4c..85b8a78 100644
--- a/lib/ftplistparser.c
+++ b/lib/ftplistparser.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -274,7 +274,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
   curl_fnmatch_callback compare;
   struct WildcardData *wc = &conn->data->wildcard;
   struct ftp_wc *ftpwc = wc->protdata;
-  struct curl_llist *llist = &wc->filelist;
+  struct Curl_llist *llist = &wc->filelist;
   struct ftp_parselist_data *parser = ftpwc->parser;
   bool add = TRUE;
   struct curl_fileinfo *finfo = &infop->info;
@@ -418,8 +418,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
             finfo->b_data[parser->item_length - 1] = 0;
             if(strncmp("total ", finfo->b_data, 6) == 0) {
               char *endptr = finfo->b_data + 6;
-              /* here we can deal with directory size, pass the leading white
-                 spaces and then the digits */
+              /* here we can deal with directory size, pass the leading
+                 whitespace and then the digits */
               while(ISSPACE(*endptr))
                 endptr++;
               while(ISDIGIT(*endptr))
diff --git a/lib/ftplistparser.h b/lib/ftplistparser.h
index b34ae9b..e4cd820 100644
--- a/lib/ftplistparser.h
+++ b/lib/ftplistparser.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/getenv.c b/lib/getenv.c
index 9385b8f..92c5350 100644
--- a/lib/getenv.c
+++ b/lib/getenv.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/getinfo.c b/lib/getinfo.c
index 82691dc..fd8f4e8 100644
--- a/lib/getinfo.c
+++ b/lib/getinfo.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -269,6 +269,9 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
     /* Return the local port of the most recent (primary) connection */
     *param_longp = data->info.conn_local_port;
     break;
+  case CURLINFO_PROXY_ERROR:
+    *param_longp = (long)data->info.pxcode;
+    break;
   case CURLINFO_CONDITION_UNMET:
     if(data->info.httpcode == 304)
       *param_longp = 1L;
diff --git a/lib/getinfo.h b/lib/getinfo.h
index 8d2af42..f35d1b4 100644
--- a/lib/getinfo.h
+++ b/lib/getinfo.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/gopher.c b/lib/gopher.c
index b4811b2..b101c0a 100644
--- a/lib/gopher.c
+++ b/lib/gopher.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -71,6 +71,7 @@ const struct Curl_handler Curl_handler_gopher = {
   ZERO_NULL,                            /* connection_check */
   PORT_GOPHER,                          /* defport */
   CURLPROTO_GOPHER,                     /* protocol */
+  CURLPROTO_GOPHER,                     /* family */
   PROTOPT_NONE                          /* flags */
 };
 
@@ -123,8 +124,6 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
     sel_org = sel;
   }
 
-  /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
-     sent, which could be sizeable with long selectors. */
   k = curlx_uztosz(len);
 
   for(;;) {
@@ -170,9 +169,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
   free(sel_org);
 
   if(!result)
-    /* We can use Curl_sendf to send the terminal \r\n relatively safely and
-       save allocing another string/doing another _write loop. */
-    result = Curl_sendf(sockfd, conn, "\r\n");
+    result = Curl_write(conn, sockfd, "\r\n", 2, &amount);
   if(result) {
     failf(data, "Failed sending Gopher request");
     return result;
diff --git a/lib/gopher.h b/lib/gopher.h
index dec2557..b35fa45 100644
--- a/lib/gopher.h
+++ b/lib/gopher.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hash.c b/lib/hash.c
index 421d68f..051c176 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -34,8 +34,8 @@
 static void
 hash_element_dtor(void *user, void *element)
 {
-  struct curl_hash *h = (struct curl_hash *) user;
-  struct curl_hash_element *e = (struct curl_hash_element *) element;
+  struct Curl_hash *h = (struct Curl_hash *) user;
+  struct Curl_hash_element *e = (struct Curl_hash_element *) element;
 
   if(e->ptr) {
     h->dtor(e->ptr);
@@ -54,11 +54,11 @@ hash_element_dtor(void *user, void *element)
  * @unittest: 1603
  */
 int
-Curl_hash_init(struct curl_hash *h,
+Curl_hash_init(struct Curl_hash *h,
                int slots,
                hash_function hfunc,
                comp_function comparator,
-               curl_hash_dtor dtor)
+               Curl_hash_dtor dtor)
 {
   if(!slots || !hfunc || !comparator ||!dtor) {
     return 1; /* failure */
@@ -70,22 +70,22 @@ Curl_hash_init(struct curl_hash *h,
   h->size = 0;
   h->slots = slots;
 
-  h->table = malloc(slots * sizeof(struct curl_llist));
+  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);
+      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 *
+static struct Curl_hash_element *
 mk_hash_element(const void *key, size_t key_len, const void *p)
 {
   /* allocate the struct plus memory after it to store the key */
-  struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) +
+  struct Curl_hash_element *he = malloc(sizeof(struct Curl_hash_element) +
                                         key_len);
   if(he) {
     /* copy the key */
@@ -106,14 +106,14 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
  * @unittest: 1603
  */
 void *
-Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
+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_hash_element  *he;
+  struct Curl_llist_element *le;
+  struct Curl_llist *l = FETCH_LIST(h, key, key_len);
 
   for(le = l->head; le; le = le->next) {
-    he = (struct curl_hash_element *) le->ptr;
+    he = (struct Curl_hash_element *) le->ptr;
     if(h->comp_func(he->key, he->key_len, key, key_len)) {
       Curl_llist_remove(l, le, (void *)h);
       --h->size;
@@ -136,13 +136,13 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
  *
  * @unittest: 1603
  */
-int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
+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_element *le;
+  struct Curl_llist *l = FETCH_LIST(h, key, key_len);
 
   for(le = l->head; le; le = le->next) {
-    struct curl_hash_element *he = le->ptr;
+    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;
@@ -157,15 +157,15 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
  * @unittest: 1603
  */
 void *
-Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
+Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
 {
-  struct curl_llist_element *le;
-  struct curl_llist *l;
+  struct Curl_llist_element *le;
+  struct Curl_llist *l;
 
   if(h) {
     l = FETCH_LIST(h, key, key_len);
     for(le = l->head; le; le = le->next) {
-      struct curl_hash_element *he = le->ptr;
+      struct Curl_hash_element *he = le->ptr;
       if(h->comp_func(he->key, he->key_len, key, key_len)) {
         return he->ptr;
       }
@@ -177,17 +177,17 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
 
 #if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST)
 void
-Curl_hash_apply(curl_hash *h, void *user,
+Curl_hash_apply(Curl_hash *h, void *user,
                 void (*cb)(void *user, void *ptr))
 {
-  struct curl_llist_element  *le;
+  struct Curl_llist_element  *le;
   int                  i;
 
   for(i = 0; i < h->slots; ++i) {
     for(le = (h->table[i])->head;
         le;
         le = le->next) {
-      curl_hash_element *el = le->ptr;
+      Curl_hash_element *el = le->ptr;
       cb(user, el->ptr);
     }
   }
@@ -202,7 +202,7 @@ Curl_hash_apply(curl_hash *h, void *user,
  * @unittest: 1603
  */
 void
-Curl_hash_destroy(struct curl_hash *h)
+Curl_hash_destroy(struct Curl_hash *h)
 {
   int i;
 
@@ -220,19 +220,19 @@ Curl_hash_destroy(struct curl_hash *h)
  * @unittest: 1602
  */
 void
-Curl_hash_clean(struct curl_hash *h)
+Curl_hash_clean(struct Curl_hash *h)
 {
   Curl_hash_clean_with_criterium(h, NULL, NULL);
 }
 
 /* Cleans all entries that pass the comp function criteria. */
 void
-Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
                                int (*comp)(void *, void *))
 {
-  struct curl_llist_element *le;
-  struct curl_llist_element *lnext;
-  struct curl_llist *list;
+  struct Curl_llist_element *le;
+  struct Curl_llist_element *lnext;
+  struct Curl_llist *list;
   int i;
 
   if(!h)
@@ -242,7 +242,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
     list = &h->table[i];
     le = list->head; /* get first list entry */
     while(le) {
-      struct curl_hash_element *he = le->ptr;
+      struct Curl_hash_element *he = le->ptr;
       lnext = le->next;
       /* ask the callback function if we shall remove this entry or not */
       if(comp == NULL || comp(user, he->ptr)) {
@@ -277,18 +277,18 @@ size_t Curl_str_key_compare(void *k1, size_t key1_len,
   return 0;
 }
 
-void Curl_hash_start_iterate(struct curl_hash *hash,
-                             struct curl_hash_iterator *iter)
+void Curl_hash_start_iterate(struct Curl_hash *hash,
+                             struct Curl_hash_iterator *iter)
 {
   iter->hash = hash;
   iter->slot_index = 0;
   iter->current_element = NULL;
 }
 
-struct curl_hash_element *
-Curl_hash_next_element(struct curl_hash_iterator *iter)
+struct Curl_hash_element *
+Curl_hash_next_element(struct Curl_hash_iterator *iter)
 {
-  struct curl_hash *h = iter->hash;
+  struct Curl_hash *h = iter->hash;
 
   /* Get the next element in the current list, if any */
   if(iter->current_element)
@@ -307,7 +307,7 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
   }
 
   if(iter->current_element) {
-    struct curl_hash_element *he = iter->current_element->ptr;
+    struct Curl_hash_element *he = iter->current_element->ptr;
     return he;
   }
   iter->current_element = NULL;
@@ -315,11 +315,11 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
 }
 
 #if 0 /* useful function for debugging hashes and their contents */
-void Curl_hash_print(struct curl_hash *h,
+void Curl_hash_print(struct Curl_hash *h,
                      void (*func)(void *))
 {
-  struct curl_hash_iterator iter;
-  struct curl_hash_element *he;
+  struct Curl_hash_iterator iter;
+  struct Curl_hash_element *he;
   int last_index = -1;
 
   if(!h)
diff --git a/lib/hash.h b/lib/hash.h
index 558d0f4..b7f828e 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -41,59 +41,59 @@ typedef size_t (*comp_function) (void *key1,
                                  void *key2,
                                  size_t key2_len);
 
-typedef void (*curl_hash_dtor)(void *);
+typedef void (*Curl_hash_dtor)(void *);
 
-struct curl_hash {
-  struct curl_llist *table;
+struct Curl_hash {
+  struct Curl_llist *table;
 
   /* Hash function to be used for this hash table */
   hash_function hash_func;
 
   /* Comparator function to compare keys */
   comp_function comp_func;
-  curl_hash_dtor   dtor;
+  Curl_hash_dtor   dtor;
   int slots;
   size_t size;
 };
 
-struct curl_hash_element {
-  struct curl_llist_element list;
+struct Curl_hash_element {
+  struct Curl_llist_element list;
   void   *ptr;
   size_t key_len;
   char   key[1]; /* allocated memory following the struct */
 };
 
-struct curl_hash_iterator {
-  struct curl_hash *hash;
+struct Curl_hash_iterator {
+  struct Curl_hash *hash;
   int slot_index;
-  struct curl_llist_element *current_element;
+  struct Curl_llist_element *current_element;
 };
 
-int Curl_hash_init(struct curl_hash *h,
+int Curl_hash_init(struct Curl_hash *h,
                    int slots,
                    hash_function hfunc,
                    comp_function comparator,
-                   curl_hash_dtor dtor);
+                   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);
-void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
-void Curl_hash_apply(struct curl_hash *h, void *user,
+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);
+void *Curl_hash_pick(struct Curl_hash *, void *key, size_t key_len);
+void Curl_hash_apply(struct Curl_hash *h, void *user,
                      void (*cb)(void *user, void *ptr));
 #define Curl_hash_count(h) ((h)->size)
-void Curl_hash_destroy(struct curl_hash *h);
-void Curl_hash_clean(struct curl_hash *h);
-void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+void Curl_hash_destroy(struct Curl_hash *h);
+void Curl_hash_clean(struct Curl_hash *h);
+void Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
                                     int (*comp)(void *, void *));
 size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num);
 size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2,
                             size_t key2_len);
-void Curl_hash_start_iterate(struct curl_hash *hash,
-                             struct curl_hash_iterator *iter);
-struct curl_hash_element *
-Curl_hash_next_element(struct curl_hash_iterator *iter);
+void Curl_hash_start_iterate(struct Curl_hash *hash,
+                             struct Curl_hash_iterator *iter);
+struct Curl_hash_element *
+Curl_hash_next_element(struct Curl_hash_iterator *iter);
 
-void Curl_hash_print(struct curl_hash *h,
+void Curl_hash_print(struct Curl_hash *h,
                      void (*func)(void *));
 
 
diff --git a/lib/hmac.c b/lib/hmac.c
index e4fea8a..590abe6 100644
--- a/lib/hmac.c
+++ b/lib/hmac.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostasyn.c b/lib/hostasyn.c
index ed9190f..56a6fc2 100644
--- a/lib/hostasyn.c
+++ b/lib/hostasyn.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostcheck.c b/lib/hostcheck.c
index 9e0db05..0fef98b 100644
--- a/lib/hostcheck.c
+++ b/lib/hostcheck.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostcheck.h b/lib/hostcheck.h
index 9c18085..52155f4 100644
--- a/lib/hostcheck.h
+++ b/lib/hostcheck.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostip.c b/lib/hostip.c
index dd5916e..ab1f6df 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -206,7 +206,7 @@ hostcache_timestamp_remove(void *datap, void *hc)
  * Prune the DNS cache. This assumes that a lock has already been taken.
  */
 static void
-hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now)
+hostcache_prune(struct Curl_hash *hostcache, long cache_timeout, time_t now)
 {
   struct hostcache_prune_data user;
 
@@ -843,7 +843,7 @@ static void freednsentry(void *freethis)
 /*
  * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
  */
-int Curl_mk_dnscache(struct curl_hash *hash)
+int Curl_mk_dnscache(struct Curl_hash *hash)
 {
   return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
                         freednsentry);
@@ -857,7 +857,7 @@ int Curl_mk_dnscache(struct curl_hash *hash)
  */
 
 void Curl_hostcache_clean(struct Curl_easy *data,
-                          struct curl_hash *hash)
+                          struct Curl_hash *hash)
 {
   if(data && data->share)
     Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
diff --git a/lib/hostip.h b/lib/hostip.h
index 374b06c..724a03d 100644
--- a/lib/hostip.h
+++ b/lib/hostip.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -59,9 +59,9 @@ struct connectdata;
  * Global DNS cache is general badness. Do not use. This will be removed in
  * a future version. Use the share interface instead!
  *
- * Returns a struct curl_hash pointer on success, NULL on failure.
+ * Returns a struct Curl_hash pointer on success, NULL on failure.
  */
-struct curl_hash *Curl_global_host_cache_init(void);
+struct Curl_hash *Curl_global_host_cache_init(void);
 
 struct Curl_dns_entry {
   struct Curl_addrinfo *addr;
@@ -128,7 +128,7 @@ 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);
+int Curl_mk_dnscache(struct Curl_hash *hash);
 
 /* prune old entries from the DNS cache */
 void Curl_hostcache_prune(struct Curl_easy *data);
@@ -234,7 +234,7 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
 /*
  * Clean off entries from the cache
  */
-void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash);
+void Curl_hostcache_clean(struct Curl_easy *data, struct Curl_hash *hash);
 
 /*
  * Populate the cache with specified entries from CURLOPT_RESOLVE.
diff --git a/lib/hostip4.c b/lib/hostip4.c
index eae9416..df83a2f 100644
--- a/lib/hostip4.c
+++ b/lib/hostip4.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostip6.c b/lib/hostip6.c
index 1121575..02b0ca2 100644
--- a/lib/hostip6.c
+++ b/lib/hostip6.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hostsyn.c b/lib/hostsyn.c
index 9e31008..550b43a 100644
--- a/lib/hostsyn.c
+++ b/lib/hostsyn.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/hsts.c b/lib/hsts.c
new file mode 100644
index 0000000..6f77128
--- /dev/null
+++ b/lib/hsts.c
@@ -0,0 +1,522 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ * The Strict-Transport-Security header is defined in RFC 6797:
+ * https://tools.ietf.org/html/rfc6797
+ */
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS)
+#include <curl/curl.h>
+#include "urldata.h"
+#include "llist.h"
+#include "hsts.h"
+#include "curl_get_line.h"
+#include "strcase.h"
+#include "sendf.h"
+#include "strtoofft.h"
+#include "parsedate.h"
+#include "rand.h"
+#include "rename.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MAX_HSTS_LINE 4095
+#define MAX_HSTS_HOSTLEN 256
+#define MAX_HSTS_HOSTLENSTR "256"
+#define MAX_HSTS_SUBLEN 4
+#define MAX_HSTS_SUBLENSTR "4"
+#define MAX_HSTS_DATELEN 64
+#define MAX_HSTS_DATELENSTR "64"
+
+#ifdef DEBUGBUILD
+/* to play well with debug builds, we can *set* a fixed time this will
+   return */
+time_t deltatime; /* allow for "adjustments" for unit test purposes */
+static time_t debugtime(void *unused)
+{
+  char *timestr = getenv("CURL_TIME");
+  (void)unused;
+  if(timestr) {
+    unsigned long val = strtol(timestr, NULL, 10) + deltatime;
+    return (time_t)val;
+  }
+  return time(NULL);
+}
+#define time(x) debugtime(x)
+#endif
+
+struct hsts *Curl_hsts_init(void)
+{
+  struct hsts *h = calloc(sizeof(struct hsts), 1);
+  if(h) {
+    Curl_llist_init(&h->list, NULL);
+  }
+  return h;
+}
+
+static void hsts_free(struct stsentry *e)
+{
+  free((char *)e->host);
+  free(e);
+}
+
+void Curl_hsts_cleanup(struct hsts **hp)
+{
+  struct hsts *h = *hp;
+  if(h) {
+    struct Curl_llist_element *e;
+    struct Curl_llist_element *n;
+    for(e = h->list.head; e; e = n) {
+      struct stsentry *sts = e->ptr;
+      n = e->next;
+      hsts_free(sts);
+    }
+    free(h->filename);
+    free(h);
+    *hp = NULL;
+  }
+}
+
+static struct stsentry *hsts_entry(void)
+{
+  return calloc(sizeof(struct stsentry), 1);
+}
+
+static CURLcode hsts_create(struct hsts *h,
+                            const char *hostname,
+                            bool subdomains,
+                            curl_off_t expires)
+{
+  struct stsentry *sts = hsts_entry();
+  if(!sts)
+    return CURLE_OUT_OF_MEMORY;
+
+  sts->expires = expires;
+  sts->includeSubDomains = subdomains;
+  sts->host = strdup(hostname);
+  if(!sts->host) {
+    free(sts);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  Curl_llist_insert_next(&h->list, h->list.tail, sts, &sts->node);
+  return CURLE_OK;
+}
+
+CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
+                         const char *header)
+{
+  const char *p = header;
+  curl_off_t expires = 0;
+  bool gotma = FALSE;
+  bool gotinc = FALSE;
+  bool subdomains = FALSE;
+  struct stsentry *sts;
+  time_t now = time(NULL);
+
+  do {
+    while(*p && ISSPACE(*p))
+      p++;
+    if(Curl_strncasecompare("max-age=", p, 8)) {
+      bool quoted = FALSE;
+      CURLofft offt;
+      char *endp;
+
+      if(gotma)
+        return CURLE_BAD_FUNCTION_ARGUMENT;
+
+      p += 8;
+      while(*p && ISSPACE(*p))
+        p++;
+      if(*p == '\"') {
+        p++;
+        quoted = TRUE;
+      }
+      offt = curlx_strtoofft(p, &endp, 10, &expires);
+      if(offt == CURL_OFFT_FLOW)
+        expires = CURL_OFF_T_MAX;
+      else if(offt)
+        /* invalid max-age */
+        return CURLE_BAD_FUNCTION_ARGUMENT;
+      p = endp;
+      if(quoted) {
+        if(*p != '\"')
+          return CURLE_BAD_FUNCTION_ARGUMENT;
+        p++;
+      }
+      gotma = TRUE;
+    }
+    else if(Curl_strncasecompare("includesubdomains", p, 17)) {
+      if(gotinc)
+        return CURLE_BAD_FUNCTION_ARGUMENT;
+      subdomains = TRUE;
+      p += 17;
+      gotinc = TRUE;
+    }
+    else {
+      /* unknown directive, do a lame attempt to skip */
+      while(*p && (*p != ';'))
+        p++;
+    }
+
+    while(*p && ISSPACE(*p))
+      p++;
+    if(*p == ';')
+      p++;
+  } while (*p);
+
+  if(!gotma)
+    /* max-age is mandatory */
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  if(!expires) {
+    /* remove the entry if present verbatim (without subdomain match) */
+    sts = Curl_hsts(h, hostname, FALSE);
+    if(sts) {
+      Curl_llist_remove(&h->list, &sts->node, NULL);
+      hsts_free(sts);
+    }
+    return CURLE_OK;
+  }
+
+  if(CURL_OFF_T_MAX - now < expires)
+    /* would overflow, use maximum value */
+    expires = CURL_OFF_T_MAX;
+  else
+    expires += now;
+
+  /* check if it already exists */
+  sts = Curl_hsts(h, hostname, FALSE);
+  if(sts) {
+    /* just update these fields */
+    sts->expires = expires;
+    sts->includeSubDomains = subdomains;
+  }
+  else
+    return hsts_create(h, hostname, subdomains, expires);
+
+  return CURLE_OK;
+}
+
+/*
+ * Return TRUE if the given host name is currently an HSTS one.
+ *
+ * The 'subdomain' argument tells the function if subdomain matching should be
+ * attempted.
+ */
+struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
+                           bool subdomain)
+{
+  if(h) {
+    time_t now = time(NULL);
+    size_t hlen = strlen(hostname);
+    struct Curl_llist_element *e;
+    struct Curl_llist_element *n;
+    for(e = h->list.head; e; e = n) {
+      struct stsentry *sts = e->ptr;
+      n = e->next;
+      if(sts->expires <= now) {
+        /* remove expired entries */
+        Curl_llist_remove(&h->list, &sts->node, NULL);
+        hsts_free(sts);
+        continue;
+      }
+      if(subdomain && sts->includeSubDomains) {
+        size_t ntail = strlen(sts->host);
+        if(ntail < hlen) {
+          size_t offs = hlen - ntail;
+          if((hostname[offs-1] == '.') &&
+             Curl_strncasecompare(&hostname[offs], sts->host, ntail))
+            return sts;
+        }
+      }
+      if(Curl_strcasecompare(hostname, sts->host))
+        return sts;
+    }
+  }
+  return NULL; /* no match */
+}
+
+/*
+ * Send this HSTS entry to the write callback.
+ */
+static CURLcode hsts_push(struct Curl_easy *data,
+                          struct curl_index *i,
+                          struct stsentry *sts,
+                          bool *stop)
+{
+  struct curl_hstsentry e;
+  CURLSTScode sc;
+  struct tm stamp;
+  CURLcode result;
+
+  e.name = (char *)sts->host;
+  e.namelen = strlen(sts->host);
+  e.includeSubDomains = sts->includeSubDomains;
+
+  result = Curl_gmtime(sts->expires, &stamp);
+  if(result)
+    return result;
+
+  msnprintf(e.expire, sizeof(e.expire), "%d%02d%02d %02d:%02d:%02d",
+            stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+            stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
+
+  sc = data->set.hsts_write(data, &e, i,
+                            data->set.hsts_write_userp);
+  *stop = (sc != CURLSTS_OK);
+  return sc == CURLSTS_FAIL ? CURLE_BAD_FUNCTION_ARGUMENT : CURLE_OK;
+}
+
+/*
+ * Write this single hsts entry to a single output line
+ */
+static CURLcode hsts_out(struct stsentry *sts, FILE *fp)
+{
+  struct tm stamp;
+  CURLcode result = Curl_gmtime(sts->expires, &stamp);
+  if(result)
+    return result;
+
+  fprintf(fp, "%s%s \"%d%02d%02d %02d:%02d:%02d\"\n",
+          sts->includeSubDomains ? ".": "", sts->host,
+          stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
+          stamp.tm_hour, stamp.tm_min, stamp.tm_sec);
+  return CURLE_OK;
+}
+
+
+/*
+ * Curl_https_save() writes the HSTS cache to file and callback.
+ */
+CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
+                        const char *file)
+{
+  struct Curl_llist_element *e;
+  struct Curl_llist_element *n;
+  CURLcode result = CURLE_OK;
+  FILE *out;
+  char *tempstore;
+  unsigned char randsuffix[9];
+
+  if(!h)
+    /* no cache activated */
+    return CURLE_OK;
+
+  /* if not new name is given, use the one we stored from the load */
+  if(!file && h->filename)
+    file = h->filename;
+
+  if((h->flags & CURLHSTS_READONLYFILE) || !file || !file[0])
+    /* marked as read-only, no file or zero length file name */
+    goto skipsave;
+
+  if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+    return CURLE_FAILED_INIT;
+
+  tempstore = aprintf("%s.%s.tmp", file, randsuffix);
+  if(!tempstore)
+    return CURLE_OUT_OF_MEMORY;
+
+  out = fopen(tempstore, FOPEN_WRITETEXT);
+  if(!out)
+    result = CURLE_WRITE_ERROR;
+  else {
+    fputs("# Your HSTS cache. https://curl.se/docs/hsts.html\n"
+          "# This file was generated by libcurl! Edit at your own risk.\n",
+          out);
+    for(e = h->list.head; e; e = n) {
+      struct stsentry *sts = e->ptr;
+      n = e->next;
+      result = hsts_out(sts, out);
+      if(result)
+        break;
+    }
+    fclose(out);
+    if(!result && Curl_rename(tempstore, file))
+      result = CURLE_WRITE_ERROR;
+
+    if(result)
+      unlink(tempstore);
+  }
+  free(tempstore);
+  skipsave:
+  if(data->set.hsts_write) {
+    /* if there's a write callback */
+    struct curl_index i; /* count */
+    i.total = h->list.size;
+    i.index = 0;
+    for(e = h->list.head; e; e = n) {
+      struct stsentry *sts = e->ptr;
+      bool stop;
+      n = e->next;
+      result = hsts_push(data, &i, sts, &stop);
+      if(result || stop)
+        break;
+      i.index++;
+    }
+  }
+  return result;
+}
+
+/* only returns SERIOUS errors */
+static CURLcode hsts_add(struct hsts *h, char *line)
+{
+  /* Example lines:
+     example.com "20191231 10:00:00"
+     .example.net "20191231 10:00:00"
+   */
+  char host[MAX_HSTS_HOSTLEN + 1];
+  char date[MAX_HSTS_DATELEN + 1];
+  int rc;
+
+  rc = sscanf(line,
+              "%" MAX_HSTS_HOSTLENSTR "s \"%" MAX_HSTS_DATELENSTR "[^\"]\"",
+              host, date);
+  if(2 == rc) {
+    time_t expires = Curl_getdate_capped(date);
+    CURLcode result;
+    char *p = host;
+    bool subdomain = FALSE;
+    if(p[0] == '.') {
+      p++;
+      subdomain = TRUE;
+    }
+    result = hsts_create(h, p, subdomain, expires);
+    if(result)
+      return result;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Load HSTS data from callback.
+ *
+ */
+static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h)
+{
+  /* if the HSTS read callback is set, use it */
+  if(data->set.hsts_read) {
+    CURLSTScode sc;
+    DEBUGASSERT(h);
+    do {
+      char buffer[257];
+      struct curl_hstsentry e;
+      e.name = buffer;
+      e.namelen = sizeof(buffer)-1;
+      e.includeSubDomains = FALSE; /* default */
+      e.expire[0] = 0;
+      e.name[0] = 0; /* just to make it clean */
+      sc = data->set.hsts_read(data, &e, data->set.hsts_read_userp);
+      if(sc == CURLSTS_OK) {
+        time_t expires;
+        CURLcode result;
+        if(!e.name[0])
+          /* bail out if no name was stored */
+          return CURLE_BAD_FUNCTION_ARGUMENT;
+        if(e.expire[0])
+          expires = Curl_getdate_capped(e.expire);
+        else
+          expires = TIME_T_MAX; /* the end of time */
+        result = hsts_create(h, e.name, e.includeSubDomains, expires);
+        if(result)
+          return result;
+      }
+      else if(sc == CURLSTS_FAIL)
+        return CURLE_BAD_FUNCTION_ARGUMENT;
+    } while(sc == CURLSTS_OK);
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Load the HSTS cache from the given file. The text based line-oriented file
+ * format is documented here:
+ * https://github.com/curl/curl/wiki/HSTS
+ *
+ * This function only returns error on major problems that prevents hsts
+ * handling to work completely. It will ignore individual syntactical errors
+ * etc.
+ */
+static CURLcode hsts_load(struct hsts *h, const char *file)
+{
+  CURLcode result = CURLE_OK;
+  char *line = NULL;
+  FILE *fp;
+
+  /* we need a private copy of the file name so that the hsts cache file
+     name survives an easy handle reset */
+  free(h->filename);
+  h->filename = strdup(file);
+  if(!h->filename)
+    return CURLE_OUT_OF_MEMORY;
+
+  fp = fopen(file, FOPEN_READTEXT);
+  if(fp) {
+    line = malloc(MAX_HSTS_LINE);
+    if(!line)
+      goto fail;
+    while(Curl_get_line(line, MAX_HSTS_LINE, fp)) {
+      char *lineptr = line;
+      while(*lineptr && ISBLANK(*lineptr))
+        lineptr++;
+      if(*lineptr == '#')
+        /* skip commented lines */
+        continue;
+
+      hsts_add(h, lineptr);
+    }
+    free(line); /* free the line buffer */
+    fclose(fp);
+  }
+  return result;
+
+  fail:
+  Curl_safefree(h->filename);
+  fclose(fp);
+  return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * Curl_hsts_loadfile() loads HSTS from file
+ */
+CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
+                            struct hsts *h, const char *file)
+{
+  DEBUGASSERT(h);
+  (void)data;
+  return hsts_load(h, file);
+}
+
+/*
+ * Curl_hsts_loadcb() loads HSTS from callback
+ */
+CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h)
+{
+  return hsts_pull(data, h);
+}
+
+#endif /* CURL_DISABLE_HTTP || USE_HSTS */
diff --git a/lib/hsts.h b/lib/hsts.h
new file mode 100644
index 0000000..ae5db74
--- /dev/null
+++ b/lib/hsts.h
@@ -0,0 +1,65 @@
+#ifndef HEADER_CURL_HSTS_H
+#define HEADER_CURL_HSTS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS)
+#include <curl/curl.h>
+#include "llist.h"
+
+#ifdef DEBUGBUILD
+extern time_t deltatime;
+#endif
+
+struct stsentry {
+  struct Curl_llist_element node;
+  const char *host;
+  bool includeSubDomains;
+  time_t expires; /* the timestamp of this entry's expiry */
+};
+
+/* The HSTS cache. Needs to be able to tailmatch host names. */
+struct hsts {
+  struct Curl_llist list;
+  char *filename;
+  unsigned int flags;
+};
+
+struct hsts *Curl_hsts_init(void);
+void Curl_hsts_cleanup(struct hsts **hp);
+CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
+                         const char *sts);
+struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
+                           bool subdomain);
+CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
+                        const char *file);
+CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
+                            struct hsts *h, const char *file);
+CURLcode Curl_hsts_loadcb(struct Curl_easy *data,
+                          struct hsts *h);
+#else
+#define Curl_hsts_cleanup(x)
+#define Curl_hsts_loadcb(x,y)
+#define Curl_hsts_save(x,y,z)
+#endif /* CURL_DISABLE_HTTP || USE_HSTS */
+#endif /* HEADER_CURL_HSTS_H */
diff --git a/lib/http.c b/lib/http.c
index 8fcdd43..c232ed4 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -77,6 +77,7 @@
 #include "connect.h"
 #include "strdup.h"
 #include "altsvc.h"
+#include "hsts.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -125,6 +126,7 @@ const struct Curl_handler Curl_handler_http = {
   ZERO_NULL,                            /* connection_check */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
+  CURLPROTO_HTTP,                       /* family */
   PROTOPT_CREDSPERREQUEST |             /* flags */
   PROTOPT_USERPWDCTRL
 };
@@ -151,6 +153,7 @@ const struct Curl_handler Curl_handler_https = {
   ZERO_NULL,                            /* connection_check */
   PORT_HTTPS,                           /* defport */
   CURLPROTO_HTTPS,                      /* protocol */
+  CURLPROTO_HTTP,                       /* family */
   PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
   PROTOPT_USERPWDCTRL
 };
@@ -162,14 +165,14 @@ static CURLcode http_setup_conn(struct connectdata *conn)
      during this request */
   struct HTTP *http;
   struct Curl_easy *data = conn->data;
-  DEBUGASSERT(data->req.protop == NULL);
+  DEBUGASSERT(data->req.p.http == NULL);
 
   http = calloc(1, sizeof(struct HTTP));
   if(!http)
     return CURLE_OUT_OF_MEMORY;
 
   Curl_mime_initpart(&http->form, conn->data);
-  data->req.protop = http;
+  data->req.p.http = http;
 
   if(data->set.httpversion == CURL_HTTP_VERSION_3) {
     if(conn->handler->flags & PROTOPT_SSL)
@@ -425,7 +428,7 @@ static bool pickoneauth(struct auth *pick, unsigned long mask)
 static CURLcode http_perhapsrewind(struct connectdata *conn)
 {
   struct Curl_easy *data = conn->data;
-  struct HTTP *http = data->req.protop;
+  struct HTTP *http = data->req.p.http;
   curl_off_t bytessent;
   curl_off_t expectsend = -1; /* default is unknown */
 
@@ -1109,7 +1112,7 @@ static size_t readmoredata(char *buffer,
                            void *userp)
 {
   struct connectdata *conn = (struct connectdata *)userp;
-  struct HTTP *http = conn->data->req.protop;
+  struct HTTP *http = conn->data->req.p.http;
   size_t fullsize = size * nitems;
 
   if(!http->postsize)
@@ -1167,7 +1170,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
   char *ptr;
   size_t size;
   struct Curl_easy *data = conn->data;
-  struct HTTP *http = data->req.protop;
+  struct HTTP *http = data->req.p.http;
   size_t sendsize;
   curl_socket_t sockfd;
   size_t headersize;
@@ -1252,16 +1255,12 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
     size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
     size_t bodylen = amount - headlen;
 
-    if(data->set.verbose) {
-      /* this data _may_ contain binary stuff */
-      Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
-      if(bodylen) {
-        /* there was body data sent beyond the initial header part, pass that
-           on to the debug callback too */
-        Curl_debug(data, CURLINFO_DATA_OUT,
-                   ptr + headlen, bodylen);
-      }
-    }
+    /* this data _may_ contain binary stuff */
+    Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
+    if(bodylen)
+      /* there was body data sent beyond the initial header part, pass that on
+         to the debug callback too */
+      Curl_debug(data, CURLINFO_DATA_OUT, ptr + headlen, bodylen);
 
     /* 'amount' can never be a very large value here so typecasting it so a
        signed 31 bit value should not cause problems even if ssize_t is
@@ -1353,7 +1352,7 @@ Curl_compareheader(const char *headerline, /* line to check */
   /* pass the header */
   start = &headerline[hlen];
 
-  /* pass all white spaces */
+  /* pass all whitespace */
   while(*start && ISSPACE(*start))
     start++;
 
@@ -1517,7 +1516,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
                         CURLcode status, bool premature)
 {
   struct Curl_easy *data = conn->data;
-  struct HTTP *http = data->req.protop;
+  struct HTTP *http = data->req.p.http;
 
   /* Clear multipass flag. If authentication isn't done yet, then it will get
    * a chance to be set back to true when we output the next auth header */
@@ -1978,7 +1977,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
         return result;
     }
   }
-  http = data->req.protop;
+  http = data->req.p.http;
   DEBUGASSERT(http);
 
   if(!data->state.this_is_a_follow) {
@@ -2516,7 +2515,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
   if(result)
     return result;
 
-#ifdef USE_ALTSVC
+#ifndef CURL_DISABLE_ALTSVC
   if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
     altused = aprintf("Alt-Used: %s:%d\r\n",
                       conn->conn_to_host.name, conn->conn_to_port);
@@ -2871,20 +2870,24 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
         }
         else {
           if(postsize) {
+            char chunk[16];
             /* Append the POST data chunky-style */
-            result = Curl_dyn_addf(&req, "%x\r\n", (int)postsize);
+            msnprintf(chunk, sizeof(chunk), "%x\r\n", (int)postsize);
+            result = Curl_dyn_add(&req, chunk);
             if(!result) {
+              included_body = postsize + strlen(chunk);
               result = Curl_dyn_addn(&req, data->set.postfields,
                                      (size_t)postsize);
               if(!result)
                 result = Curl_dyn_add(&req, "\r\n");
-              included_body = postsize + 2;
+              included_body += 2;
             }
           }
-          if(!result)
+          if(!result) {
             result = Curl_dyn_add(&req, "\x30\x0d\x0a\x0d\x0a");
-          /* 0  CR  LF  CR  LF */
-          included_body += 5;
+            /* 0  CR  LF  CR  LF */
+            included_body += 5;
+          }
         }
         if(result)
           return result;
@@ -3531,10 +3534,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
           k->keepon &= ~KEEP_RECV;
         }
 
-        if(data->set.verbose)
-          Curl_debug(data, CURLINFO_HEADER_IN,
-                     str_start, headerlen);
-        break;          /* exit header line loop */
+        Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen);
+        break; /* exit header line loop */
       }
 
       /* We continue reading headers, reset the line-based header */
@@ -3990,7 +3991,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
         }
       }
     }
-#ifdef USE_ALTSVC
+
+#ifdef USE_HSTS
+    /* If enabled, the header is incoming and this is over HTTPS */
+    else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) &&
+            (conn->handler->flags & PROTOPT_SSL)) {
+      CURLcode check =
+        Curl_hsts_parse(data->hsts, data->state.up.hostname,
+                        &headp[ sizeof("Strict-Transport-Security:") -1 ]);
+      if(check)
+        infof(data, "Illegal STS header skipped\n");
+#ifdef DEBUGBUILD
+      else
+        infof(data, "Parsed STS header fine (%zu entries)\n",
+              data->hsts->list.size);
+#endif
+    }
+#endif
+#ifndef CURL_DISABLE_ALTSVC
     /* If enabled, the header is incoming and this is over HTTPS */
     else if(data->asi && checkprefix("Alt-Svc:", headp) &&
             ((conn->handler->flags & PROTOPT_SSL) ||
@@ -4025,9 +4043,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
     if(data->set.include_header)
       writetype |= CLIENTWRITE_BODY;
 
-    if(data->set.verbose)
-      Curl_debug(data, CURLINFO_HEADER_IN, headp,
-                 Curl_dyn_len(&data->state.headerb));
+    Curl_debug(data, CURLINFO_HEADER_IN, headp,
+               Curl_dyn_len(&data->state.headerb));
 
     result = Curl_client_write(conn, writetype, headp,
                                Curl_dyn_len(&data->state.headerb));
diff --git a/lib/http.h b/lib/http.h
index 9ea3eb2..1aaec22 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http2.c b/lib/http2.c
index d316da8..b138fb4 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -257,7 +257,7 @@ static unsigned int http2_conncheck(struct connectdata *check,
 /* called from http_setup_conn */
 void Curl_http2_setup_req(struct Curl_easy *data)
 {
-  struct HTTP *http = data->req.protop;
+  struct HTTP *http = data->req.p.http;
   http->bodystarted = FALSE;
   http->status_code = -1;
   http->pausedata = NULL;
@@ -300,6 +300,7 @@ static const struct Curl_handler Curl_handler_http2 = {
   http2_conncheck,                      /* connection_check */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTP,                       /* protocol */
+  CURLPROTO_HTTP,                       /* family */
   PROTOPT_STREAM                        /* flags */
 };
 
@@ -321,6 +322,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
   http2_conncheck,                      /* connection_check */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTPS,                      /* protocol */
+  CURLPROTO_HTTP,                       /* family */
   PROTOPT_SSL | PROTOPT_STREAM          /* flags */
 };
 
@@ -391,7 +393,7 @@ char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
   if(!h || !GOOD_EASY_HANDLE(h->data))
     return NULL;
   else {
-    struct HTTP *stream = h->data->req.protop;
+    struct HTTP *stream = h->data->req.p.http;
     if(num < stream->push_headers_used)
       return stream->push_headers[num];
   }
@@ -413,7 +415,7 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
      !strcmp(header, ":") || strchr(header + 1, ':'))
     return NULL;
   else {
-    struct HTTP *stream = h->data->req.protop;
+    struct HTTP *stream = h->data->req.p.http;
     size_t len = strlen(header);
     size_t i;
     for(i = 0; i<stream->push_headers_used; i++) {
@@ -460,7 +462,7 @@ static struct Curl_easy *duphandle(struct Curl_easy *data)
       (void)Curl_close(&second);
     }
     else {
-      second->req.protop = http;
+      second->req.p.http = http;
       Curl_dyn_init(&http->header_recvbuf, DYN_H2_HEADERS);
       Curl_http2_setup_req(second);
       second->state.stream_weight = data->state.stream_weight;
@@ -537,7 +539,7 @@ static int push_promise(struct Curl_easy *data,
     /* ask the application */
     H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
 
-    stream = data->req.protop;
+    stream = data->req.p.http;
     if(!stream) {
       failf(data, "Internal NULL stream!\n");
       (void)Curl_close(&newhandle);
@@ -567,13 +569,13 @@ static int push_promise(struct Curl_easy *data,
     if(rv) {
       DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
       /* denied, kill off the new handle again */
-      http2_stream_free(newhandle->req.protop);
-      newhandle->req.protop = NULL;
+      http2_stream_free(newhandle->req.p.http);
+      newhandle->req.p.http = NULL;
       (void)Curl_close(&newhandle);
       goto fail;
     }
 
-    newstream = newhandle->req.protop;
+    newstream = newhandle->req.p.http;
     newstream->stream_id = frame->promised_stream_id;
     newhandle->req.maxdownload = -1;
     newhandle->req.size = -1;
@@ -583,8 +585,8 @@ static int push_promise(struct Curl_easy *data,
     rc = Curl_multi_add_perform(data->multi, newhandle, conn);
     if(rc) {
       infof(data, "failed to add handle to multi\n");
-      http2_stream_free(newhandle->req.protop);
-      newhandle->req.protop = NULL;
+      http2_stream_free(newhandle->req.p.http);
+      newhandle->req.p.http = NULL;
       Curl_close(&newhandle);
       rv = CURL_PUSH_DENY;
       goto fail;
@@ -667,7 +669,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
     return 0;
   }
 
-  stream = data_s->req.protop;
+  stream = data_s->req.p.http;
   if(!stream) {
     H2BUGF(infof(data_s, "No proto pointer for stream: %x\n",
                  stream_id));
@@ -783,7 +785,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
        internal error more than anything else! */
     return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-  stream = data_s->req.protop;
+  stream = data_s->req.p.http;
   if(!stream)
     return NGHTTP2_ERR_CALLBACK_FAILURE;
 
@@ -849,7 +851,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
     }
     H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
                  nghttp2_http2_strerror(error_code), error_code, stream_id));
-    stream = data_s->req.protop;
+    stream = data_s->req.p.http;
     if(!stream)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
 
@@ -894,7 +896,7 @@ static int on_begin_headers(nghttp2_session *session,
     return 0;
   }
 
-  stream = data_s->req.protop;
+  stream = data_s->req.p.http;
   if(!stream || !stream->bodystarted) {
     return 0;
   }
@@ -952,7 +954,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
        internal error more than anything else! */
     return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-  stream = data_s->req.protop;
+  stream = data_s->req.p.http;
   if(!stream) {
     failf(data_s, "Internal NULL stream! 5\n");
     return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -1100,7 +1102,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
          internal error more than anything else! */
       return NGHTTP2_ERR_CALLBACK_FAILURE;
 
-    stream = data_s->req.protop;
+    stream = data_s->req.p.http;
     if(!stream)
       return NGHTTP2_ERR_CALLBACK_FAILURE;
   }
@@ -1161,7 +1163,7 @@ static void populate_settings(struct connectdata *conn,
 
 void Curl_http2_done(struct Curl_easy *data, bool premature)
 {
-  struct HTTP *http = data->req.protop;
+  struct HTTP *http = data->req.p.http;
   struct http_conn *httpc = &data->conn->proto.httpc;
 
   /* there might be allocated resources done before this got the 'h2' pointer
@@ -1207,13 +1209,6 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
     }
     http->stream_id = 0;
   }
-
-  if(0 == nghttp2_session_check_request_allowed(httpc->h2)) {
-    /* No more requests are allowed in the current session, so the connection
-       may not be reused. This is set when a GOAWAY frame has been received or
-       when the limit of stream identifiers has been reached. */
-    connclose(data->conn, "http/2: No new requests allowed");
-  }
 }
 
 /*
@@ -1288,7 +1283,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
   binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
                                          httpc->local_settings,
                                          httpc->local_settings_num);
-  if(!binlen) {
+  if(binlen <= 0) {
     failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
     Curl_dyn_free(req);
     return CURLE_FAILED_INIT;
@@ -1371,6 +1366,14 @@ static int h2_process_pending_input(struct connectdata *conn,
     return -1;
   }
 
+  if(nghttp2_session_check_request_allowed(httpc->h2) == 0) {
+    /* No more requests are allowed in the current session, so
+       the connection may not be reused. This is set when a
+       GOAWAY frame has been received or when the limit of stream
+       identifiers has been reached. */
+    connclose(conn, "http/2: No new requests allowed");
+  }
+
   if(should_close_session(httpc)) {
     H2BUGF(infof(data,
                  "h2_process_pending_input: nothing to do in this session\n"));
@@ -1383,7 +1386,6 @@ static int h2_process_pending_input(struct connectdata *conn,
     }
     return -1;
   }
-
   return 0;
 }
 
@@ -1398,7 +1400,7 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
      (conn->handler == &Curl_handler_http2)) {
     /* make sure this is only attempted for HTTP/2 transfers */
 
-    struct HTTP *stream = conn->data->req.protop;
+    struct HTTP *stream = conn->data->req.p.http;
 
     struct http_conn *httpc = &conn->proto.httpc;
     nghttp2_session *h2 = httpc->h2;
@@ -1494,8 +1496,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
         break;
       len = lf + 1 - trailp;
 
-      if(data->set.verbose)
-        Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
+      Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
       /* pass the trailers one by one to the callback */
       result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailp, len);
       if(result) {
@@ -1522,7 +1523,7 @@ static void h2_pri_spec(struct Curl_easy *data,
                         nghttp2_priority_spec *pri_spec)
 {
   struct HTTP *depstream = (data->set.stream_depends_on?
-                            data->set.stream_depends_on->req.protop:NULL);
+                            data->set.stream_depends_on->req.p.http:NULL);
   int32_t depstream_id = depstream? depstream->stream_id:0;
   nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight,
                              data->set.stream_depends_e);
@@ -1539,7 +1540,7 @@ static void h2_pri_spec(struct Curl_easy *data,
 static int h2_session_send(struct Curl_easy *data,
                            nghttp2_session *h2)
 {
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   if((data->set.stream_weight != data->state.stream_weight) ||
      (data->set.stream_depends_e != data->state.stream_depends_e) ||
      (data->set.stream_depends_on != data->state.stream_depends_on) ) {
@@ -1564,12 +1565,10 @@ static int h2_session_send(struct Curl_easy *data,
 static ssize_t http2_recv(struct connectdata *conn, int sockindex,
                           char *mem, size_t len, CURLcode *err)
 {
-  CURLcode result = CURLE_OK;
-  ssize_t rv;
   ssize_t nread;
   struct http_conn *httpc = &conn->proto.httpc;
   struct Curl_easy *data = conn->data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
 
   (void)sockindex; /* we always do HTTP2 on sockindex 0 */
 
@@ -1632,8 +1631,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
       /* We have paused nghttp2, but we have no pause data (see
          on_data_chunk_recv). */
       httpc->pause_stream_id = 0;
-      if(h2_process_pending_input(conn, httpc, &result) != 0) {
-        *err = result;
+      if(h2_process_pending_input(conn, httpc, err) != 0) {
         return -1;
       }
     }
@@ -1661,8 +1659,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
          frames, then we have to call it again with 0-length data.
          Without this, on_stream_close callback will not be called,
          and stream could be hanged. */
-      if(h2_process_pending_input(conn, httpc, &result) != 0) {
-        *err = result;
+      if(h2_process_pending_input(conn, httpc, err) != 0) {
         return -1;
       }
     }
@@ -1688,7 +1685,6 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
     return -1;
   }
   else {
-    char *inbuf;
     /* remember where to store incoming data for this stream and how big the
        buffer is */
     stream->mem = mem;
@@ -1697,16 +1693,15 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
 
     if(httpc->inbuflen == 0) {
       nread = ((Curl_recv *)httpc->recv_underlying)(
-          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
 
       if(nread == -1) {
-        if(result != CURLE_AGAIN)
+        if(*err != CURLE_AGAIN)
           failf(data, "Failed receiving HTTP2 data");
         else if(stream->closed)
           /* received when the stream was already closed! */
           return http2_handle_stream_close(conn, data, stream, err);
 
-        *err = result;
         return -1;
       }
 
@@ -1719,47 +1714,18 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
       H2BUGF(infof(data, "nread=%zd\n", nread));
 
       httpc->inbuflen = nread;
-      inbuf = httpc->inbuf;
+
+      DEBUGASSERT(httpc->nread_inbuf == 0);
     }
     else {
       nread = httpc->inbuflen - httpc->nread_inbuf;
-      inbuf = httpc->inbuf + httpc->nread_inbuf;
-
+      (void)nread;  /* silence warning, used in debug */
       H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
                    nread));
     }
-    rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
 
-    if(nghttp2_is_fatal((int)rv)) {
-      failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
-            rv, nghttp2_strerror((int)rv));
-      *err = CURLE_RECV_ERROR;
-      return -1;
-    }
-    H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
-    if(nread == rv) {
-      H2BUGF(infof(data, "All data in connection buffer processed\n"));
-      httpc->inbuflen = 0;
-      httpc->nread_inbuf = 0;
-    }
-    else {
-      httpc->nread_inbuf += rv;
-      H2BUGF(infof(data, "%zu bytes left in connection buffer\n",
-                   httpc->inbuflen - httpc->nread_inbuf));
-    }
-    /* Always send pending frames in nghttp2 session, because
-       nghttp2_session_mem_recv() may queue new frame */
-    rv = h2_session_send(data, httpc->h2);
-    if(rv != 0) {
-      *err = CURLE_SEND_ERROR;
-      return -1;
-    }
-
-    if(should_close_session(httpc)) {
-      H2BUGF(infof(data, "http2_recv: nothing to do in this session\n"));
-      *err = CURLE_HTTP2;
+    if(h2_process_pending_input(conn, httpc, err) != 0)
       return -1;
-    }
   }
   if(stream->memlen) {
     ssize_t retlen = stream->memlen;
@@ -1874,7 +1840,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
    */
   int rv;
   struct http_conn *httpc = &conn->proto.httpc;
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
   nghttp2_nv *nva = NULL;
   size_t nheader;
   size_t i;
@@ -2104,7 +2070,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
 
     if(acc > MAX_ACC) {
       infof(conn->data, "http2_send: Warning: The cumulative length of all "
-            "headers exceeds %zu bytes and that could cause the "
+            "headers exceeds %d bytes and that could cause the "
             "stream to be rejected.\n", MAX_ACC);
     }
   }
@@ -2112,7 +2078,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   h2_pri_spec(conn->data, &pri_spec);
 
   H2BUGF(infof(conn->data, "http2_send request allowed %d (easy handle %p)\n",
-               nghttp2_session_check_request_allowed(h2), (void *)conn->data));
+         nghttp2_session_check_request_allowed(h2), (void *)conn->data));
 
   switch(conn->data->state.httpreq) {
   case HTTPREQ_POST:
@@ -2138,7 +2104,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   Curl_safefree(nva);
 
   if(stream_id < 0) {
-    H2BUGF(infof(conn->data, "http2_send() send error\n"));
+    H2BUGF(infof(conn->data,
+                 "http2_send() nghttp2_submit_request error (%s)%d\n",
+                 nghttp2_strerror(stream_id), stream_id));
     *err = CURLE_SEND_ERROR;
     return -1;
   }
@@ -2148,10 +2116,13 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
   stream->stream_id = stream_id;
 
   /* this does not call h2_session_send() since there can not have been any
-   * priority upodate since the nghttp2_submit_request() call above */
+   * priority update since the nghttp2_submit_request() call above */
   rv = nghttp2_session_send(h2);
-
   if(rv != 0) {
+    H2BUGF(infof(conn->data,
+                 "http2_send() nghttp2_session_send error (%s)%d\n",
+                 nghttp2_strerror(rv), rv));
+
     *err = CURLE_SEND_ERROR;
     return -1;
   }
@@ -2183,7 +2154,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
 {
   CURLcode result;
   struct http_conn *httpc = &conn->proto.httpc;
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
 
   DEBUGASSERT(conn->data->state.buffer);
 
@@ -2236,9 +2207,8 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
   CURLcode result;
   struct http_conn *httpc = &conn->proto.httpc;
   int rv;
-  ssize_t nproc;
   struct Curl_easy *data = conn->data;
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
 
   result = Curl_http2_setup(conn);
   if(result)
@@ -2299,7 +2269,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
      data into stream->mem, overwriting data already there. */
   if(H2_BUFSIZE < nread) {
     failf(data, "connection buffer size is too small to store data following "
-                "HTTP Upgrade response header: buflen=%zu, datalen=%zu",
+                "HTTP Upgrade response header: buflen=%d, datalen=%zu",
           H2_BUFSIZE, nread);
     return CURLE_HTTP2;
   }
@@ -2310,41 +2280,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
 
   if(nread)
     memcpy(httpc->inbuf, mem, nread);
-  httpc->inbuflen = nread;
-
-  nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
-                                   httpc->inbuflen);
-
-  if(nghttp2_is_fatal((int)nproc)) {
-    failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
-          nghttp2_strerror((int)nproc), (int)nproc);
-    return CURLE_HTTP2;
-  }
-
-  H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
-
-  if((ssize_t)nread == nproc) {
-    httpc->inbuflen = 0;
-    httpc->nread_inbuf = 0;
-  }
-  else {
-    httpc->nread_inbuf += nproc;
-  }
 
-  /* Try to send some frames since we may read SETTINGS already. */
-  rv = h2_session_send(data, httpc->h2);
+  httpc->inbuflen = nread;
 
-  if(rv != 0) {
-    failf(data, "nghttp2_session_send() failed: %s(%d)",
-          nghttp2_strerror(rv), rv);
-    return CURLE_HTTP2;
-  }
+  DEBUGASSERT(httpc->nread_inbuf == 0);
 
-  if(should_close_session(httpc)) {
-    H2BUGF(infof(data,
-                 "nghttp2_session_send(): nothing to do in this session\n"));
+  if(-1 == h2_process_pending_input(conn, httpc, &result))
     return CURLE_HTTP2;
-  }
 
   return CURLE_OK;
 }
@@ -2358,7 +2300,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause)
     return CURLE_OK;
 #ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
   else {
-    struct HTTP *stream = data->req.protop;
+    struct HTTP *stream = data->req.p.http;
     struct http_conn *httpc = &data->conn->proto.httpc;
     uint32_t window = !pause * HTTP2_HUGE_WINDOW_SIZE;
     int rv = nghttp2_session_set_local_window_size(httpc->h2,
diff --git a/lib/http2.h b/lib/http2.h
index e82b212..43a6863 100644
--- a/lib/http2.h
+++ b/lib/http2.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_chunks.c b/lib/http_chunks.c
index 767f806..4984814 100644
--- a/lib/http_chunks.c
+++ b/lib/http_chunks.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_chunks.h b/lib/http_chunks.h
index 8f4a33c..c8f072a 100644
--- a/lib/http_chunks.h
+++ b/lib/http_chunks.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_digest.c b/lib/http_digest.c
index b06dc0d..dfa40dc 100644
--- a/lib/http_digest.c
+++ b/lib/http_digest.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_digest.h b/lib/http_digest.h
index 96e39a7..f7001ed 100644
--- a/lib/http_digest.h
+++ b/lib/http_digest.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 0a19ec2..872d172 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h
index a737f6f..cf1d007 100644
--- a/lib/http_negotiate.h
+++ b/lib/http_negotiate.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index cab543c..91e1d1f 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h
index 3ebdf97..5ddf538 100644
--- a/lib/http_ntlm.h
+++ b/lib/http_ntlm.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index f188cbf..4242251 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -102,9 +102,9 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
      * This function might be called several times in the multi interface case
      * if the proxy's CONNECT response is not instant.
      */
-    prot_save = conn->data->req.protop;
+    prot_save = conn->data->req.p.http;
     memset(&http_proxy, 0, sizeof(http_proxy));
-    conn->data->req.protop = &http_proxy;
+    conn->data->req.p.http = &http_proxy;
     connkeep(conn, "HTTP proxy CONNECT");
 
     /* for the secondary socket (FTP), use the "connect to host"
@@ -125,7 +125,7 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
     else
       remote_port = conn->remote_port;
     result = Curl_proxyCONNECT(conn, sockindex, hostname, remote_port);
-    conn->data->req.protop = prot_save;
+    conn->data->req.p.http = prot_save;
     if(CURLE_OK != result)
       return result;
     Curl_safefree(data->state.aptr.proxyuserpwd);
@@ -167,7 +167,7 @@ static CURLcode connect_init(struct connectdata *conn, bool reinit)
     Curl_dyn_reset(&s->rcvbuf);
   }
   s->tunnel_state = TUNNEL_INIT;
-  s->keepon = TRUE;
+  s->keepon = KEEPON_CONNECT;
   s->cl = 0;
   s->close_connection = FALSE;
   return CURLE_OK;
@@ -339,7 +339,7 @@ static CURLcode CONNECT(struct connectdata *conn,
           return CURLE_ABORTED_BY_CALLBACK;
 
         if(result) {
-          s->keepon = FALSE;
+          s->keepon = KEEPON_DONE;
           break;
         }
         else if(gotbytes <= 0) {
@@ -353,11 +353,11 @@ static CURLcode CONNECT(struct connectdata *conn,
             error = SELECT_ERROR;
             failf(data, "Proxy CONNECT aborted");
           }
-          s->keepon = FALSE;
+          s->keepon = KEEPON_DONE;
           break;
         }
 
-        if(s->keepon > TRUE) {
+        if(s->keepon == KEEPON_IGNORE) {
           /* This means we are currently ignoring a response-body */
 
           if(s->cl) {
@@ -365,7 +365,7 @@ static CURLcode CONNECT(struct connectdata *conn,
                and make sure to break out of the loop when we're done! */
             s->cl--;
             if(s->cl <= 0) {
-              s->keepon = FALSE;
+              s->keepon = KEEPON_DONE;
               s->tunnel_state = TUNNEL_COMPLETE;
               break;
             }
@@ -383,7 +383,7 @@ static CURLcode CONNECT(struct connectdata *conn,
             if(r == CHUNKE_STOP) {
               /* we're done reading chunks! */
               infof(data, "chunk reading DONE\n");
-              s->keepon = FALSE;
+              s->keepon = KEEPON_DONE;
               /* we did the full CONNECT treatment, go COMPLETE */
               s->tunnel_state = TUNNEL_COMPLETE;
             }
@@ -410,8 +410,7 @@ static CURLcode CONNECT(struct connectdata *conn,
           return result;
 
         /* output debug if that is requested */
-        if(data->set.verbose)
-          Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
+        Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);
 
         if(!data->set.suppress_connect_headers) {
           /* send the header to the callback */
@@ -425,7 +424,6 @@ static CURLcode CONNECT(struct connectdata *conn,
         }
 
         data->info.header_size += (long)perline;
-        data->req.headerbytecount += (long)perline;
 
         /* Newlines are CRLF, so the CR is ignored as the line isn't
            really terminated until the LF comes. Treat a following CR
@@ -439,7 +437,7 @@ static CURLcode CONNECT(struct connectdata *conn,
             /* If we get a 407 response code with content length
                when we have no auth problem, we must ignore the
                whole response-body */
-            s->keepon = 2;
+            s->keepon = KEEPON_IGNORE;
 
             if(s->cl) {
               infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
@@ -467,7 +465,7 @@ static CURLcode CONNECT(struct connectdata *conn,
               if(r == CHUNKE_STOP) {
                 /* we're done reading chunks! */
                 infof(data, "chunk reading DONE\n");
-                s->keepon = FALSE;
+                s->keepon = KEEPON_DONE;
                 /* we did the full CONNECT treatment, go to COMPLETE */
                 s->tunnel_state = TUNNEL_COMPLETE;
               }
@@ -476,11 +474,11 @@ static CURLcode CONNECT(struct connectdata *conn,
               /* without content-length or chunked encoding, we
                  can't keep the connection alive since the close is
                  the end signal so we bail out at once instead */
-              s->keepon = FALSE;
+              s->keepon = KEEPON_DONE;
             }
           }
           else
-            s->keepon = FALSE;
+            s->keepon = KEEPON_DONE;
           if(!s->cl)
             /* we did the full CONNECT treatment, go to COMPLETE */
             s->tunnel_state = TUNNEL_COMPLETE;
diff --git a/lib/http_proxy.h b/lib/http_proxy.h
index 29988a6..a595e8b 100644
--- a/lib/http_proxy.h
+++ b/lib/http_proxy.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/idn_win32.c b/lib/idn_win32.c
index 2f5850d..1d475a4 100644
--- a/lib/idn_win32.c
+++ b/lib/idn_win32.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/if2ip.c b/lib/if2ip.c
index 3938869..21e00b1 100644
--- a/lib/if2ip.c
+++ b/lib/if2ip.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/if2ip.h b/lib/if2ip.h
index f193d42..e074e47 100644
--- a/lib/if2ip.h
+++ b/lib/if2ip.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/imap.c b/lib/imap.c
index cad0e59..c6dd7a2 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -132,6 +132,7 @@ const struct Curl_handler Curl_handler_imap = {
   ZERO_NULL,                        /* connection_check */
   PORT_IMAP,                        /* defport */
   CURLPROTO_IMAP,                   /* protocol */
+  CURLPROTO_IMAP,                   /* family */
   PROTOPT_CLOSEACTION|              /* flags */
   PROTOPT_URLOPTIONS
 };
@@ -159,6 +160,7 @@ const struct Curl_handler Curl_handler_imaps = {
   ZERO_NULL,                        /* connection_check */
   PORT_IMAPS,                       /* defport */
   CURLPROTO_IMAPS,                  /* protocol */
+  CURLPROTO_IMAP,                   /* family */
   PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
   PROTOPT_URLOPTIONS
 };
@@ -244,7 +246,7 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd)
 static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
                            int *resp)
 {
-  struct IMAP *imap = conn->data->req.protop;
+  struct IMAP *imap = conn->data->req.p.imap;
   struct imap_conn *imapc = &conn->proto.imapc;
   const char *id = imapc->resptag;
   size_t id_len = strlen(id);
@@ -605,7 +607,7 @@ static CURLcode imap_perform_list(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
 
   if(imap->custom)
     /* Send the custom request */
@@ -640,7 +642,7 @@ static CURLcode imap_perform_select(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
   struct imap_conn *imapc = &conn->proto.imapc;
   char *mailbox;
 
@@ -679,7 +681,7 @@ static CURLcode imap_perform_select(struct connectdata *conn)
 static CURLcode imap_perform_fetch(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct IMAP *imap = conn->data->req.protop;
+  struct IMAP *imap = conn->data->req.p.imap;
   /* Check we have a UID */
   if(imap->uid) {
 
@@ -727,7 +729,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
   char *mailbox;
 
   /* Check we have a mailbox */
@@ -797,7 +799,7 @@ static CURLcode imap_perform_append(struct connectdata *conn)
 static CURLcode imap_perform_search(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
-  struct IMAP *imap = conn->data->req.protop;
+  struct IMAP *imap = conn->data->req.p.imap;
 
   /* Check we have a query string */
   if(!imap->query) {
@@ -1051,7 +1053,7 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = conn->data->req.protop;
+  struct IMAP *imap = conn->data->req.p.imap;
   struct imap_conn *imapc = &conn->proto.imapc;
   const char *line = data->state.buffer;
 
@@ -1176,6 +1178,9 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
     else {
       /* IMAP download */
       data->req.maxdownload = size;
+      /* 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_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1);
     }
   }
@@ -1380,7 +1385,7 @@ static CURLcode imap_init(struct connectdata *conn)
   struct Curl_easy *data = conn->data;
   struct IMAP *imap;
 
-  imap = data->req.protop = calloc(sizeof(struct IMAP), 1);
+  imap = data->req.p.imap = calloc(sizeof(struct IMAP), 1);
   if(!imap)
     result = CURLE_OUT_OF_MEMORY;
 
@@ -1424,7 +1429,9 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
   imapc->preftype = IMAP_TYPE_ANY;
   Curl_sasl_init(&imapc->sasl, &saslimap);
 
+  Curl_dyn_init(&imapc->dyn, DYN_IMAP_CMD);
   /* Initialise the pingpong layer */
+  Curl_pp_setup(pp);
   Curl_pp_init(pp);
 
   /* Parse the URL options */
@@ -1457,7 +1464,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
 
   (void)premature;
 
@@ -1517,7 +1524,7 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected,
   /* This is IMAP and no proxy */
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
   struct imap_conn *imapc = &conn->proto.imapc;
   bool selected = FALSE;
 
@@ -1626,6 +1633,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
 
   /* Disconnect from the server */
   Curl_pp_disconnect(&imapc->pp);
+  Curl_dyn_free(&imapc->dyn);
 
   /* Cleanup the SASL module */
   Curl_sasl_cleanup(conn, imapc->sasl.authused);
@@ -1640,7 +1648,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
 /* Call this when the DO phase has completed */
 static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
 {
-  struct IMAP *imap = conn->data->req.protop;
+  struct IMAP *imap = conn->data->req.p.imap;
 
   (void)connected;
 
@@ -1727,30 +1735,25 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
 {
   CURLcode result = CURLE_OK;
   struct imap_conn *imapc = &conn->proto.imapc;
-  char *taggedfmt;
-  va_list ap;
 
   DEBUGASSERT(fmt);
 
-  /* Calculate the next command ID wrapping at 3 digits */
-  imapc->cmdid = (imapc->cmdid + 1) % 1000;
-
   /* Calculate the tag based on the connection ID and command ID */
   msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
-            'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
-
-  /* Prefix the format with the tag */
-  taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
-  if(!taggedfmt)
-    return CURLE_OUT_OF_MEMORY;
+            'A' + curlx_sltosi(conn->connection_id % 26),
+            (++imapc->cmdid)%1000);
 
-  /* Send the data with the tag */
-  va_start(ap, fmt);
-  result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
-  va_end(ap);
-
-  free(taggedfmt);
+  /* start with a blank buffer */
+  Curl_dyn_reset(&imapc->dyn);
 
+  /* append tag + space + fmt */
+  result = Curl_dyn_addf(&imapc->dyn, "%s %s", imapc->resptag, fmt);
+  if(!result) {
+    va_list ap;
+    va_start(ap, fmt);
+    result = Curl_pp_vsendf(&imapc->pp, Curl_dyn_ptr(&imapc->dyn), ap);
+    va_end(ap);
+  }
   return result;
 }
 
@@ -1942,7 +1945,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
   /* The imap struct is already initialised in imap_connect() */
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
   const char *begin = &data->state.up.path[1]; /* skip leading slash */
   const char *ptr = begin;
 
@@ -2074,7 +2077,7 @@ static CURLcode imap_parse_custom_request(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct IMAP *imap = data->req.protop;
+  struct IMAP *imap = data->req.p.imap;
   const char *custom = data->set.str[STRING_CUSTOMREQUEST];
 
   if(custom) {
diff --git a/lib/imap.h b/lib/imap.h
index 4786f56..ef6515d 100644
--- a/lib/imap.h
+++ b/lib/imap.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -75,13 +75,14 @@ struct imap_conn {
   bool preauth;               /* Is this connection PREAUTH? */
   struct SASL sasl;           /* SASL-related parameters */
   unsigned int preftype;      /* Preferred authentication type */
-  int cmdid;                  /* Last used command ID */
+  unsigned int cmdid;         /* Last used command ID */
   char resptag[5];            /* Response tag to wait for */
   bool tls_supported;         /* StartTLS capability supported by server */
   bool login_disabled;        /* LOGIN command disabled by server */
   bool ir_supported;          /* Initial response supported by server */
   char *mailbox;              /* The last selected mailbox */
   char *mailbox_uidvalidity;  /* UIDVALIDITY parsed from select response */
+  struct dynbuf dyn;          /* for the IMAP commands */
 };
 
 extern const struct Curl_handler Curl_handler_imap;
diff --git a/lib/inet_ntop.h b/lib/inet_ntop.h
index 9d3f237..067632a 100644
--- a/lib/inet_ntop.h
+++ b/lib/inet_ntop.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/inet_pton.c b/lib/inet_pton.c
index 9c87a05..4923cae 100644
--- a/lib/inet_pton.c
+++ b/lib/inet_pton.c
@@ -1,6 +1,6 @@
 /* This is from the BIND 4.9.4 release, modified to compile by itself */
 
-/* Copyright (c) 1996 - 2019 by Internet Software Consortium.
+/* Copyright (c) 1996 - 2020 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
@@ -112,7 +112,7 @@ inet_pton4(const char *src, unsigned char *dst)
       if(val > 255)
         return (0);
       *tp = (unsigned char)val;
-      if(! saw_digit) {
+      if(!saw_digit) {
         if(++octets > 4)
           return (0);
         saw_digit = 1;
diff --git a/lib/inet_pton.h b/lib/inet_pton.h
index e695af9..ec12373 100644
--- a/lib/inet_pton.h
+++ b/lib/inet_pton.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/krb5.c b/lib/krb5.c
index 5bd8e71..1f32943 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -2,7 +2,7 @@
  *
  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
- * Copyright (c) 2004 - 2019 Daniel Stenberg
+ * Copyright (c) 2004 - 2020 Daniel Stenberg
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,14 +45,73 @@
 #include "ftp.h"
 #include "curl_gssapi.h"
 #include "sendf.h"
-#include "curl_sec.h"
+#include "curl_krb5.h"
 #include "warnless.h"
+#include "non-ascii.h"
+#include "strcase.h"
+#include "strdup.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 
+static CURLcode ftpsend(struct connectdata *conn, const char *cmd)
+{
+  ssize_t bytes_written;
+#define SBUF_SIZE 1024
+  char s[SBUF_SIZE];
+  size_t write_len;
+  char *sptr = s;
+  CURLcode result = CURLE_OK;
+#ifdef HAVE_GSSAPI
+  enum protection_level data_sec = conn->data_prot;
+#endif
+
+  if(!cmd)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  write_len = strlen(cmd);
+  if(!write_len || write_len > (sizeof(s) -3))
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  memcpy(&s, cmd, write_len);
+  strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
+  write_len += 2;
+  bytes_written = 0;
+
+  result = Curl_convert_to_network(conn->data, s, write_len);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result)
+    return result;
+
+  for(;;) {
+#ifdef HAVE_GSSAPI
+    conn->data_prot = PROT_CMD;
+#endif
+    result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+                        &bytes_written);
+#ifdef HAVE_GSSAPI
+    DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+    conn->data_prot = data_sec;
+#endif
+
+    if(result)
+      break;
+
+    Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
+
+    if(bytes_written != (ssize_t)write_len) {
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+  }
+
+  return result;
+}
+
 static int
 krb5_init(void *app_data)
 {
@@ -183,7 +242,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
   for(;;) {
     /* this really shouldn't be repeated here, but can't help it */
     if(service == srv_host) {
-      result = Curl_ftpsend(conn, "AUTH GSSAPI");
+      result = ftpsend(conn, "AUTH GSSAPI");
       if(result)
         return -2;
 
@@ -260,7 +319,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
 
         cmd = aprintf("ADAT %s", p);
         if(cmd)
-          result = Curl_ftpsend(conn, cmd);
+          result = ftpsend(conn, cmd);
         else
           result = CURLE_OUT_OF_MEMORY;
 
@@ -326,16 +385,524 @@ static void krb5_end(void *app_data)
     }
 }
 
-struct Curl_sec_client_mech Curl_krb5_client_mech = {
-    "GSSAPI",
-    sizeof(gss_ctx_id_t),
-    krb5_init,
-    krb5_auth,
-    krb5_end,
-    krb5_check_prot,
-    krb5_overhead,
-    krb5_encode,
-    krb5_decode
+static struct Curl_sec_client_mech Curl_krb5_client_mech = {
+  "GSSAPI",
+  sizeof(gss_ctx_id_t),
+  krb5_init,
+  krb5_auth,
+  krb5_end,
+  krb5_check_prot,
+  krb5_overhead,
+  krb5_encode,
+  krb5_decode
+};
+
+static const struct {
+  enum protection_level level;
+  const char *name;
+} level_names[] = {
+  { PROT_CLEAR, "clear" },
+  { PROT_SAFE, "safe" },
+  { PROT_CONFIDENTIAL, "confidential" },
+  { PROT_PRIVATE, "private" }
 };
 
+static enum protection_level
+name_to_level(const char *name)
+{
+  int i;
+  for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
+    if(checkprefix(name, level_names[i].name))
+      return level_names[i].level;
+  return PROT_NONE;
+}
+
+/* Convert a protocol |level| to its char representation.
+   We take an int to catch programming mistakes. */
+static char level_to_char(int level)
+{
+  switch(level) {
+  case PROT_CLEAR:
+    return 'C';
+  case PROT_SAFE:
+    return 'S';
+  case PROT_CONFIDENTIAL:
+    return 'E';
+  case PROT_PRIVATE:
+    return 'P';
+  case PROT_CMD:
+    /* Fall through */
+  default:
+    /* Those 2 cases should not be reached! */
+    break;
+  }
+  DEBUGASSERT(0);
+  /* Default to the most secure alternative. */
+  return 'P';
+}
+
+/* Send an FTP command defined by |message| and the optional arguments. The
+   function returns the ftp_code. If an error occurs, -1 is returned. */
+static int ftp_send_command(struct connectdata *conn, const char *message, ...)
+{
+  int ftp_code;
+  ssize_t nread = 0;
+  va_list args;
+  char print_buffer[50];
+
+  va_start(args, message);
+  mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
+  va_end(args);
+
+  if(ftpsend(conn, print_buffer)) {
+    ftp_code = -1;
+  }
+  else {
+    if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
+      ftp_code = -1;
+  }
+
+  (void)nread; /* Unused */
+  return ftp_code;
+}
+
+/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
+   saying whether an error occurred or CURLE_OK if |len| was read. */
+static CURLcode
+socket_read(curl_socket_t fd, void *to, size_t len)
+{
+  char *to_p = to;
+  CURLcode result;
+  ssize_t nread = 0;
+
+  while(len > 0) {
+    result = Curl_read_plain(fd, to_p, len, &nread);
+    if(!result) {
+      len -= nread;
+      to_p += nread;
+    }
+    else {
+      if(result == CURLE_AGAIN)
+        continue;
+      return result;
+    }
+  }
+  return CURLE_OK;
+}
+
+
+/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
+   CURLcode saying whether an error occurred or CURLE_OK if |len| was
+   written. */
+static CURLcode
+socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
+             size_t len)
+{
+  const char *to_p = to;
+  CURLcode result;
+  ssize_t written;
+
+  while(len > 0) {
+    result = Curl_write_plain(conn, fd, to_p, len, &written);
+    if(!result) {
+      len -= written;
+      to_p += written;
+    }
+    else {
+      if(result == CURLE_AGAIN)
+        continue;
+      return result;
+    }
+  }
+  return CURLE_OK;
+}
+
+static CURLcode read_data(struct connectdata *conn,
+                          curl_socket_t fd,
+                          struct krb5buffer *buf)
+{
+  int len;
+  CURLcode result;
+
+  result = socket_read(fd, &len, sizeof(len));
+  if(result)
+    return result;
+
+  if(len) {
+    /* only realloc if there was a length */
+    len = ntohl(len);
+    buf->data = Curl_saferealloc(buf->data, len);
+  }
+  if(!len || !buf->data)
+    return CURLE_OUT_OF_MEMORY;
+
+  result = socket_read(fd, buf->data, len);
+  if(result)
+    return result;
+  buf->size = conn->mech->decode(conn->app_data, buf->data, len,
+                                 conn->data_prot, conn);
+  buf->index = 0;
+  return CURLE_OK;
+}
+
+static size_t
+buffer_read(struct krb5buffer *buf, void *data, size_t len)
+{
+  if(buf->size - buf->index < len)
+    len = buf->size - buf->index;
+  memcpy(data, (char *)buf->data + buf->index, len);
+  buf->index += len;
+  return len;
+}
+
+/* Matches Curl_recv signature */
+static ssize_t sec_recv(struct connectdata *conn, int sockindex,
+                        char *buffer, size_t len, CURLcode *err)
+{
+  size_t bytes_read;
+  size_t total_read = 0;
+  curl_socket_t fd = conn->sock[sockindex];
+
+  *err = CURLE_OK;
+
+  /* Handle clear text response. */
+  if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
+      return sread(fd, buffer, len);
+
+  if(conn->in_buffer.eof_flag) {
+    conn->in_buffer.eof_flag = 0;
+    return 0;
+  }
+
+  bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+  len -= bytes_read;
+  total_read += bytes_read;
+  buffer += bytes_read;
+
+  while(len > 0) {
+    if(read_data(conn, fd, &conn->in_buffer))
+      return -1;
+    if(conn->in_buffer.size == 0) {
+      if(bytes_read > 0)
+        conn->in_buffer.eof_flag = 1;
+      return bytes_read;
+    }
+    bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+    len -= bytes_read;
+    total_read += bytes_read;
+    buffer += bytes_read;
+  }
+  return total_read;
+}
+
+/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
+   and negotiating with the server. |from| can be NULL. */
+static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
+                        const char *from, int length)
+{
+  int bytes, htonl_bytes; /* 32-bit integers for htonl */
+  char *buffer = NULL;
+  char *cmd_buffer;
+  size_t cmd_size = 0;
+  CURLcode error;
+  enum protection_level prot_level = conn->data_prot;
+  bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
+
+  DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
+
+  if(iscmd) {
+    if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
+      prot_level = PROT_PRIVATE;
+    else
+      prot_level = conn->command_prot;
+  }
+  bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
+                             (void **)&buffer);
+  if(!buffer || bytes <= 0)
+    return; /* error */
+
+  if(iscmd) {
+    error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
+                               &cmd_buffer, &cmd_size);
+    if(error) {
+      free(buffer);
+      return; /* error */
+    }
+    if(cmd_size > 0) {
+      static const char *enc = "ENC ";
+      static const char *mic = "MIC ";
+      if(prot_level == PROT_PRIVATE)
+        socket_write(conn, fd, enc, 4);
+      else
+        socket_write(conn, fd, mic, 4);
+
+      socket_write(conn, fd, cmd_buffer, cmd_size);
+      socket_write(conn, fd, "\r\n", 2);
+      infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
+            cmd_buffer);
+      free(cmd_buffer);
+    }
+  }
+  else {
+    htonl_bytes = htonl(bytes);
+    socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
+    socket_write(conn, fd, buffer, curlx_sitouz(bytes));
+  }
+  free(buffer);
+}
+
+static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
+                         const char *buffer, size_t length)
+{
+  ssize_t tx = 0, len = conn->buffer_size;
+
+  len -= conn->mech->overhead(conn->app_data, conn->data_prot,
+                              curlx_sztosi(len));
+  if(len <= 0)
+    len = length;
+  while(length) {
+    if(length < (size_t)len)
+      len = length;
+
+    do_sec_send(conn, fd, buffer, curlx_sztosi(len));
+    length -= len;
+    buffer += len;
+    tx += len;
+  }
+  return tx;
+}
+
+/* Matches Curl_send signature */
+static ssize_t sec_send(struct connectdata *conn, int sockindex,
+                        const void *buffer, size_t len, CURLcode *err)
+{
+  curl_socket_t fd = conn->sock[sockindex];
+  *err = CURLE_OK;
+  return sec_write(conn, fd, buffer, len);
+}
+
+int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
+                      enum protection_level level)
+{
+  /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
+     int */
+  int decoded_len;
+  char *buf;
+  int ret_code = 0;
+  size_t decoded_sz = 0;
+  CURLcode error;
+
+  if(!conn->mech)
+    /* not inititalized, return error */
+    return -1;
+
+  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+  error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
+  if(error || decoded_sz == 0)
+    return -1;
+
+  if(decoded_sz > (size_t)INT_MAX) {
+    free(buf);
+    return -1;
+  }
+  decoded_len = curlx_uztosi(decoded_sz);
+
+  decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
+                                   level, conn);
+  if(decoded_len <= 0) {
+    free(buf);
+    return -1;
+  }
+
+  {
+    buf[decoded_len] = '\n';
+    Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
+  }
+
+  buf[decoded_len] = '\0';
+  if(decoded_len <= 3)
+    /* suspiciously short */
+    return 0;
+
+  if(buf[3] != '-')
+    /* safe to ignore return code */
+    (void)sscanf(buf, "%d", &ret_code);
+
+  if(buf[decoded_len - 1] == '\n')
+    buf[decoded_len - 1] = '\0';
+  strcpy(buffer, buf);
+  free(buf);
+  return ret_code;
+}
+
+static int sec_set_protection_level(struct connectdata *conn)
+{
+  int code;
+  enum protection_level level = conn->request_data_prot;
+
+  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+  if(!conn->sec_complete) {
+    infof(conn->data, "Trying to change the protection level after the"
+                      " completion of the data exchange.\n");
+    return -1;
+  }
+
+  /* Bail out if we try to set up the same level */
+  if(conn->data_prot == level)
+    return 0;
+
+  if(level) {
+    char *pbsz;
+    static unsigned int buffer_size = 1 << 20; /* 1048576 */
+
+    code = ftp_send_command(conn, "PBSZ %u", buffer_size);
+    if(code < 0)
+      return -1;
+
+    if(code/100 != 2) {
+      failf(conn->data, "Failed to set the protection's buffer size.");
+      return -1;
+    }
+    conn->buffer_size = buffer_size;
+
+    pbsz = strstr(conn->data->state.buffer, "PBSZ=");
+    if(pbsz) {
+      /* ignore return code, use default value if it fails */
+      (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
+      if(buffer_size < conn->buffer_size)
+        conn->buffer_size = buffer_size;
+    }
+  }
+
+  /* Now try to negiociate the protection level. */
+  code = ftp_send_command(conn, "PROT %c", level_to_char(level));
+
+  if(code < 0)
+    return -1;
+
+  if(code/100 != 2) {
+    failf(conn->data, "Failed to set the protection level.");
+    return -1;
+  }
+
+  conn->data_prot = level;
+  if(level == PROT_PRIVATE)
+    conn->command_prot = level;
+
+  return 0;
+}
+
+int
+Curl_sec_request_prot(struct connectdata *conn, const char *level)
+{
+  enum protection_level l = name_to_level(level);
+  if(l == PROT_NONE)
+    return -1;
+  DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
+  conn->request_data_prot = l;
+  return 0;
+}
+
+static CURLcode choose_mech(struct connectdata *conn)
+{
+  int ret;
+  struct Curl_easy *data = conn->data;
+  void *tmp_allocation;
+  const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
+
+  tmp_allocation = realloc(conn->app_data, mech->size);
+  if(tmp_allocation == NULL) {
+    failf(data, "Failed realloc of size %zu", mech->size);
+    mech = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+  conn->app_data = tmp_allocation;
+
+  if(mech->init) {
+    ret = mech->init(conn->app_data);
+    if(ret) {
+      infof(data, "Failed initialization for %s. Skipping it.\n",
+            mech->name);
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  infof(data, "Trying mechanism %s...\n", mech->name);
+  ret = ftp_send_command(conn, "AUTH %s", mech->name);
+  if(ret < 0)
+    return CURLE_COULDNT_CONNECT;
+
+  if(ret/100 != 3) {
+    switch(ret) {
+    case 504:
+      infof(data, "Mechanism %s is not supported by the server (server "
+            "returned ftp code: 504).\n", mech->name);
+      break;
+    case 534:
+      infof(data, "Mechanism %s was rejected by the server (server returned "
+            "ftp code: 534).\n", mech->name);
+      break;
+    default:
+      if(ret/100 == 5) {
+        infof(data, "server does not support the security extensions\n");
+        return CURLE_USE_SSL_FAILED;
+      }
+      break;
+    }
+    return CURLE_LOGIN_DENIED;
+  }
+
+  /* Authenticate */
+  ret = mech->auth(conn->app_data, conn);
+
+  if(ret != AUTH_CONTINUE) {
+    if(ret != AUTH_OK) {
+      /* Mechanism has dumped the error to stderr, don't error here. */
+      return CURLE_USE_SSL_FAILED;
+    }
+    DEBUGASSERT(ret == AUTH_OK);
+
+    conn->mech = mech;
+    conn->sec_complete = 1;
+    conn->recv[FIRSTSOCKET] = sec_recv;
+    conn->send[FIRSTSOCKET] = sec_send;
+    conn->recv[SECONDARYSOCKET] = sec_recv;
+    conn->send[SECONDARYSOCKET] = sec_send;
+    conn->command_prot = PROT_SAFE;
+    /* Set the requested protection level */
+    /* BLOCKING */
+    (void)sec_set_protection_level(conn);
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_sec_login(struct connectdata *conn)
+{
+  return choose_mech(conn);
+}
+
+
+void
+Curl_sec_end(struct connectdata *conn)
+{
+  if(conn->mech != NULL && conn->mech->end)
+    conn->mech->end(conn->app_data);
+  free(conn->app_data);
+  conn->app_data = NULL;
+  if(conn->in_buffer.data) {
+    free(conn->in_buffer.data);
+    conn->in_buffer.data = NULL;
+    conn->in_buffer.size = 0;
+    conn->in_buffer.index = 0;
+    conn->in_buffer.eof_flag = 0;
+  }
+  conn->sec_complete = 0;
+  conn->data_prot = PROT_CLEAR;
+  conn->mech = NULL;
+}
+
 #endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */
diff --git a/lib/ldap.c b/lib/ldap.c
index 512def6..0a1f02d 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -150,6 +150,7 @@ const struct Curl_handler Curl_handler_ldap = {
   ZERO_NULL,                            /* connection_check */
   PORT_LDAP,                            /* defport */
   CURLPROTO_LDAP,                       /* protocol */
+  CURLPROTO_LDAP,                       /* family */
   PROTOPT_NONE                          /* flags */
 };
 
@@ -176,6 +177,7 @@ const struct Curl_handler Curl_handler_ldaps = {
   ZERO_NULL,                            /* connection_check */
   PORT_LDAPS,                           /* defport */
   CURLPROTO_LDAPS,                      /* protocol */
+  CURLPROTO_LDAP,                       /* family */
   PROTOPT_SSL                           /* flags */
 };
 #endif
@@ -257,6 +259,13 @@ static int ldap_win_bind(struct connectdata *conn, LDAP *server,
 }
 #endif /* #if defined(USE_WIN32_LDAP) */
 
+#if defined(USE_WIN32_LDAP)
+#define FREE_ON_WINLDAP(x) curlx_unicodefree(x)
+#else
+#define FREE_ON_WINLDAP(x)
+#endif
+
+
 static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 {
   CURLcode result = CURLE_OK;
@@ -463,9 +472,6 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
   }
 #ifdef USE_WIN32_LDAP
   ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
-#endif
-
-#ifdef USE_WIN32_LDAP
   rc = ldap_win_bind(conn, server, user, passwd);
 #else
   rc = ldap_simple_bind_s(server, user, passwd);
@@ -507,7 +513,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 #if defined(USE_WIN32_LDAP)
     TCHAR *attribute;
 #else
-    char  *attribute;       /*! suspicious that this isn't 'const' */
+    char *attribute;
 #endif
     int i;
 
@@ -532,30 +538,22 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 
       result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
       if(result) {
-#if defined(USE_WIN32_LDAP)
-        curlx_unicodefree(name);
-#endif
+        FREE_ON_WINLDAP(name);
         ldap_memfree(dn);
-
         goto quit;
       }
 
       result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
                                  name_len);
       if(result) {
-#if defined(USE_WIN32_LDAP)
-        curlx_unicodefree(name);
-#endif
+        FREE_ON_WINLDAP(name);
         ldap_memfree(dn);
-
         goto quit;
       }
 
       result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
       if(result) {
-#if defined(USE_WIN32_LDAP)
-        curlx_unicodefree(name);
-#endif
+        FREE_ON_WINLDAP(name);
         ldap_memfree(dn);
 
         goto quit;
@@ -563,9 +561,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
 
       dlsize += name_len + 5;
 
-#if defined(USE_WIN32_LDAP)
-      curlx_unicodefree(name);
-#endif
+      FREE_ON_WINLDAP(name);
       ldap_memfree(dn);
     }
 
@@ -596,9 +592,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
           result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
           if(result) {
             ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-            curlx_unicodefree(attr);
-#endif
+            FREE_ON_WINLDAP(attr);
             ldap_memfree(attribute);
             if(ber)
               ber_free(ber, 0);
@@ -610,9 +604,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
                                      (char *) attr, attr_len);
           if(result) {
             ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-            curlx_unicodefree(attr);
-#endif
+            FREE_ON_WINLDAP(attr);
             ldap_memfree(attribute);
             if(ber)
               ber_free(ber, 0);
@@ -623,9 +615,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
           result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
           if(result) {
             ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-            curlx_unicodefree(attr);
-#endif
+            FREE_ON_WINLDAP(attr);
             ldap_memfree(attribute);
             if(ber)
               ber_free(ber, 0);
@@ -645,9 +635,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
                                         &val_b64_sz);
             if(result) {
               ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-              curlx_unicodefree(attr);
-#endif
+              FREE_ON_WINLDAP(attr);
               ldap_memfree(attribute);
               if(ber)
                 ber_free(ber, 0);
@@ -661,9 +649,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
               free(val_b64);
               if(result) {
                 ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-                curlx_unicodefree(attr);
-#endif
+                FREE_ON_WINLDAP(attr);
                 ldap_memfree(attribute);
                 if(ber)
                   ber_free(ber, 0);
@@ -679,9 +665,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
                                        vals[i]->bv_len);
             if(result) {
               ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-              curlx_unicodefree(attr);
-#endif
+              FREE_ON_WINLDAP(attr);
               ldap_memfree(attribute);
               if(ber)
                 ber_free(ber, 0);
@@ -695,9 +679,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
           result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
           if(result) {
             ldap_value_free_len(vals);
-#if defined(USE_WIN32_LDAP)
-            curlx_unicodefree(attr);
-#endif
+            FREE_ON_WINLDAP(attr);
             ldap_memfree(attribute);
             if(ber)
               ber_free(ber, 0);
@@ -713,9 +695,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
       }
 
       /* Free the attribute as we are done with it */
-#if defined(USE_WIN32_LDAP)
-      curlx_unicodefree(attr);
-#endif
+      FREE_ON_WINLDAP(attr);
       ldap_memfree(attribute);
 
       result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
@@ -745,9 +725,7 @@ quit:
     ldapssl_client_deinit();
 #endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
 
-#if defined(USE_WIN32_LDAP)
-  curlx_unicodefree(host);
-#endif
+  FREE_ON_WINLDAP(host);
 
   /* no data to transfer */
   Curl_setup_transfer(data, -1, -1, FALSE, -1);
@@ -945,7 +923,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
       char *unescaped;
       CURLcode result;
 
-      LDAP_TRACE(("attr[%d] '%s'\n", i, attributes[i]));
+      LDAP_TRACE(("attr[%zu] '%s'\n", i, attributes[i]));
 
       /* Unescape the attribute */
       result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
diff --git a/lib/libcurl.rc b/lib/libcurl.rc
index 4839d0a..3f7ae16 100644
--- a/lib/libcurl.rc
+++ b/lib/libcurl.rc
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -44,7 +44,7 @@ BEGIN
   BEGIN
     BLOCK "040904b0"
     BEGIN
-      VALUE "CompanyName",      "The curl library, https://curl.haxx.se/\0"
+      VALUE "CompanyName",      "The curl library, https://curl.se/\0"
       VALUE "FileDescription",  "libcurl Shared Library\0"
       VALUE "FileVersion",      LIBCURL_VERSION "\0"
       VALUE "InternalName",     "libcurl\0"
@@ -52,7 +52,7 @@ BEGIN
       VALUE "ProductName",      "The curl library\0"
       VALUE "ProductVersion",   LIBCURL_VERSION "\0"
       VALUE "LegalCopyright",   "\xa9 " LIBCURL_COPYRIGHT "\0"  /* a9: Copyright symbol */
-      VALUE "License",          "https://curl.haxx.se/docs/copyright.html\0"
+      VALUE "License",          "https://curl.se/docs/copyright.html\0"
     END
   END
 
diff --git a/lib/llist.c b/lib/llist.c
index e7c6f51..17a7be1 100644
--- a/lib/llist.c
+++ b/lib/llist.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -34,7 +34,7 @@
  * @unittest: 1300
  */
 void
-Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
+Curl_llist_init(struct Curl_llist *l, Curl_llist_dtor dtor)
 {
   l->size = 0;
   l->dtor = dtor;
@@ -54,9 +54,9 @@ Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
  * @unittest: 1300
  */
 void
-Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
+Curl_llist_insert_next(struct Curl_llist *list, struct Curl_llist_element *e,
                        const void *p,
-                       struct curl_llist_element *ne)
+                       struct Curl_llist_element *ne)
 {
   ne->ptr = (void *) p;
   if(list->size == 0) {
@@ -90,7 +90,7 @@ Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
  * @unittest: 1300
  */
 void
-Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
+Curl_llist_remove(struct Curl_llist *list, struct Curl_llist_element *e,
                   void *user)
 {
   void *ptr;
@@ -131,7 +131,7 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
 }
 
 void
-Curl_llist_destroy(struct curl_llist *list, void *user)
+Curl_llist_destroy(struct Curl_llist *list, void *user)
 {
   if(list) {
     while(list->size > 0)
@@ -140,7 +140,7 @@ Curl_llist_destroy(struct curl_llist *list, void *user)
 }
 
 size_t
-Curl_llist_count(struct curl_llist *list)
+Curl_llist_count(struct Curl_llist *list)
 {
   return list->size;
 }
diff --git a/lib/llist.h b/lib/llist.h
index 0178c42..ceae2dd 100644
--- a/lib/llist.h
+++ b/lib/llist.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -25,26 +25,26 @@
 #include "curl_setup.h"
 #include <stddef.h>
 
-typedef void (*curl_llist_dtor)(void *, void *);
+typedef void (*Curl_llist_dtor)(void *, void *);
 
-struct curl_llist_element {
+struct Curl_llist_element {
   void *ptr;
-  struct curl_llist_element *prev;
-  struct curl_llist_element *next;
+  struct Curl_llist_element *prev;
+  struct Curl_llist_element *next;
 };
 
-struct curl_llist {
-  struct curl_llist_element *head;
-  struct curl_llist_element *tail;
-  curl_llist_dtor dtor;
+struct Curl_llist {
+  struct Curl_llist_element *head;
+  struct Curl_llist_element *tail;
+  Curl_llist_dtor dtor;
   size_t size;
 };
 
-void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
-void Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
-                            const void *, struct curl_llist_element *node);
-void Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
+void Curl_llist_init(struct Curl_llist *, Curl_llist_dtor);
+void Curl_llist_insert_next(struct Curl_llist *, struct Curl_llist_element *,
+                            const void *, struct Curl_llist_element *node);
+void Curl_llist_remove(struct Curl_llist *, struct Curl_llist_element *,
                        void *);
-size_t Curl_llist_count(struct curl_llist *);
-void Curl_llist_destroy(struct curl_llist *, void *);
+size_t Curl_llist_count(struct Curl_llist *);
+void Curl_llist_destroy(struct Curl_llist *, void *);
 #endif /* HEADER_CURL_LLIST_H */
diff --git a/lib/md4.c b/lib/md4.c
index 67119cd..8ae6ac3 100644
--- a/lib/md4.c
+++ b/lib/md4.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/md5.c b/lib/md5.c
index d21625f..513ffb2 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/memdebug.c b/lib/memdebug.c
index da75c9f..881ee85 100644
--- a/lib/memdebug.c
+++ b/lib/memdebug.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -35,52 +35,6 @@
 #include "curl_memory.h"
 #include "memdebug.h"
 
-/*
- * Until 2011-08-17 libcurl's Memory Tracking feature also performed
- * automatic malloc and free filling operations using 0xA5 and 0x13
- * values. Our own preinitialization of dynamically allocated memory
- * might be useful when not using third party memory debuggers, but
- * on the other hand this would fool memory debuggers into thinking
- * that all dynamically allocated memory is properly initialized.
- *
- * As a default setting, libcurl's Memory Tracking feature no longer
- * performs preinitialization of dynamically allocated memory on its
- * own. If you know what you are doing, and really want to retain old
- * behavior, you can achieve this compiling with preprocessor symbols
- * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate
- * values.
- */
-
-#ifdef CURL_MT_MALLOC_FILL
-# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff)
-#   error "invalid CURL_MT_MALLOC_FILL or out of range"
-# endif
-#endif
-
-#ifdef CURL_MT_FREE_FILL
-# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff)
-#   error "invalid CURL_MT_FREE_FILL or out of range"
-# endif
-#endif
-
-#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL)
-# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL)
-#   error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL"
-# endif
-#endif
-
-#ifdef CURL_MT_MALLOC_FILL
-#  define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len))
-#else
-#  define mt_malloc_fill(buf,len) Curl_nop_stmt
-#endif
-
-#ifdef CURL_MT_FREE_FILL
-#  define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len))
-#else
-#  define mt_free_fill(buf,len) Curl_nop_stmt
-#endif
-
 struct memdebug {
   size_t size;
   union {
@@ -173,8 +127,6 @@ void *curl_dbg_malloc(size_t wantedsize, int line, const char *source)
 
   mem = (Curl_cmalloc)(size);
   if(mem) {
-    /* fill memory with junk */
-    mt_malloc_fill(mem->mem, wantedsize);
     mem->size = wantedsize;
   }
 
@@ -321,9 +273,6 @@ void curl_dbg_free(void *ptr, int line, const char *source)
 #  pragma warning(pop)
 #endif
 
-    /* destroy */
-    mt_free_fill(mem->mem, mem->size);
-
     /* free for real */
     (Curl_cfree)(mem);
   }
diff --git a/lib/memdebug.h b/lib/memdebug.h
index 4edafdf..8e88cea 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mime.c b/lib/mime.c
index 6a9b64a..2ddd9b8 100644
--- a/lib/mime.c
+++ b/lib/mime.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mime.h b/lib/mime.h
index 50b7ea6..ab89d52 100644
--- a/lib/mime.h
+++ b/lib/mime.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/mprintf.c b/lib/mprintf.c
index 80735be..c681248 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -99,12 +99,12 @@ static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
 /* Upper-case digits.  */
 static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
-#define OUTCHAR(x) \
-  do{ \
+#define OUTCHAR(x)                                     \
+  do {                                                 \
     if(stream((unsigned char)(x), (FILE *)data) != -1) \
-      done++; \
-    else \
-     return done; /* return immediately on failure */ \
+      done++;                                          \
+    else                                               \
+      return done; /* return immediately on failure */ \
   } while(0)
 
 /* Data type to read from the arglist */
@@ -169,7 +169,7 @@ struct nsprintf {
 };
 
 struct asprintf {
-  struct dynbuf b;
+  struct dynbuf *b;
   bool fail; /* if an alloc has failed and thus the output is not the complete
                 data */
 };
@@ -878,7 +878,7 @@ static int dprintf_formatf(
               OUTCHAR(' ');
           for(point = strnil; *point != '\0'; ++point)
             OUTCHAR(*point);
-          if(! (p->flags & FLAGS_LEFT))
+          if(!(p->flags & FLAGS_LEFT))
             while(width-- > 0)
               OUTCHAR(' ');
         }
@@ -1042,50 +1042,61 @@ static int alloc_addbyter(int output, FILE *data)
   struct asprintf *infop = (struct asprintf *)data;
   unsigned char outc = (unsigned char)output;
 
-  if(Curl_dyn_addn(&infop->b, &outc, 1)) {
+  if(Curl_dyn_addn(infop->b, &outc, 1)) {
     infop->fail = 1;
     return -1; /* fail */
   }
   return outc; /* fputc() returns like this on success */
 }
 
-char *curl_maprintf(const char *format, ...)
+extern int Curl_dyn_vprintf(struct dynbuf *dyn,
+                            const char *format, va_list ap_save);
+
+/* appends the formatted string, returns 0 on success, 1 on error */
+int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save)
 {
-  va_list ap_save; /* argument pointer */
   int retcode;
   struct asprintf info;
-  Curl_dyn_init(&info.b, DYN_APRINTF);
+  info.b = dyn;
   info.fail = 0;
 
-  va_start(ap_save, format);
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
-  va_end(ap_save);
   if((-1 == retcode) || info.fail) {
-    Curl_dyn_free(&info.b);
-    return NULL;
+    Curl_dyn_free(info.b);
+    return 1;
   }
-  if(Curl_dyn_len(&info.b))
-    return Curl_dyn_ptr(&info.b);
-  return strdup("");
+  return 0;
 }
 
 char *curl_mvaprintf(const char *format, va_list ap_save)
 {
   int retcode;
   struct asprintf info;
-  Curl_dyn_init(&info.b, DYN_APRINTF);
+  struct dynbuf dyn;
+  info.b = &dyn;
+  Curl_dyn_init(info.b, DYN_APRINTF);
   info.fail = 0;
 
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
   if((-1 == retcode) || info.fail) {
-    Curl_dyn_free(&info.b);
+    Curl_dyn_free(info.b);
     return NULL;
   }
-  if(Curl_dyn_len(&info.b))
-    return Curl_dyn_ptr(&info.b);
+  if(Curl_dyn_len(info.b))
+    return Curl_dyn_ptr(info.b);
   return strdup("");
 }
 
+char *curl_maprintf(const char *format, ...)
+{
+  va_list ap_save;
+  char *s;
+  va_start(ap_save, format);
+  s = curl_mvaprintf(format, ap_save);
+  va_end(ap_save);
+  return s;
+}
+
 static int storebuffer(int output, FILE *data)
 {
   char **buffer = (char **)data;
diff --git a/lib/mqtt.c b/lib/mqtt.c
index f6f4416..e324ec3 100644
--- a/lib/mqtt.c
+++ b/lib/mqtt.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
 
 #include "curl_setup.h"
 
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
 
 #include "urldata.h"
 #include <curl/curl.h>
@@ -86,6 +86,7 @@ const struct Curl_handler Curl_handler_mqtt = {
   ZERO_NULL,                          /* connection_check */
   PORT_MQTT,                          /* defport */
   CURLPROTO_MQTT,                     /* protocol */
+  CURLPROTO_MQTT,                     /* family */
   PROTOPT_NONE                        /* flags */
 };
 
@@ -95,12 +96,12 @@ static CURLcode mqtt_setup_conn(struct connectdata *conn)
      during this request */
   struct MQTT *mq;
   struct Curl_easy *data = conn->data;
-  DEBUGASSERT(data->req.protop == NULL);
+  DEBUGASSERT(data->req.p.mqtt == NULL);
 
   mq = calloc(1, sizeof(struct MQTT));
   if(!mq)
     return CURLE_OUT_OF_MEMORY;
-  data->req.protop = mq;
+  data->req.p.mqtt = mq;
   return CURLE_OK;
 }
 
@@ -110,10 +111,10 @@ static CURLcode mqtt_send(struct connectdata *conn,
   CURLcode result = CURLE_OK;
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
   struct Curl_easy *data = conn->data;
-  struct MQTT *mq = data->req.protop;
+  struct MQTT *mq = data->req.p.mqtt;
   ssize_t n;
   result = Curl_write(conn, sockfd, buf, len, &n);
-  if(!result && data->set.verbose)
+  if(!result)
     Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)n);
   if(len != (size_t)n) {
     size_t nsend = len - n;
@@ -142,7 +143,7 @@ static CURLcode mqtt_connect(struct connectdata *conn)
   const size_t client_id_offset = 14;
   const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN;
   char client_id[MQTT_CLIENTID_LEN + 1] = "curl";
-  const size_t curl_len = strlen("curl");
+  const size_t clen = strlen("curl");
   char packet[32] = {
     MQTT_MSG_CONNECT,  /* packet type */
     0x00,              /* remaining length */
@@ -156,8 +157,8 @@ static CURLcode mqtt_connect(struct connectdata *conn)
   packet[1] = (packetlen - 2) & 0x7f;
   packet[client_id_offset - 1] = MQTT_CLIENTID_LEN;
 
-  result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[curl_len],
-                         MQTT_CLIENTID_LEN - curl_len + 1);
+  result = Curl_rand_hex(conn->data, (unsigned char *)&client_id[clen],
+                         MQTT_CLIENTID_LEN - clen + 1);
   memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN);
   infof(conn->data, "Using client id '%s'\n", client_id);
   if(!result)
@@ -184,8 +185,7 @@ static CURLcode mqtt_verify_connack(struct connectdata *conn)
   if(result)
     goto fail;
 
-  if(data->set.verbose)
-    Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+  Curl_debug(data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
 
   /* fixme */
   if(nread < MQTT_CONNACK_LEN) {
@@ -297,8 +297,7 @@ static CURLcode mqtt_verify_suback(struct connectdata *conn)
   if(result)
     goto fail;
 
-  if(conn->data->set.verbose)
-    Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
+  Curl_debug(conn->data, CURLINFO_HEADER_IN, (char *)readbuf, (size_t)nread);
 
   /* fixme */
   if(nread < MQTT_SUBACK_LEN) {
@@ -426,7 +425,7 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
   unsigned char *pkt = (unsigned char *)data->state.buffer;
   size_t remlen;
   struct mqtt_conn *mqtt = &conn->proto.mqtt;
-  struct MQTT *mq = data->req.protop;
+  struct MQTT *mq = data->req.p.mqtt;
   unsigned char packet;
 
   switch(mqtt->state) {
@@ -485,8 +484,7 @@ static CURLcode mqtt_read_publish(struct connectdata *conn,
       result = CURLE_PARTIAL_FILE;
       goto end;
     }
-    if(data->set.verbose)
-      Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread);
+    Curl_debug(data, CURLINFO_DATA_IN, (char *)pkt, (size_t)nread);
 
     mq->npacket -= nread;
     k->bytecount += nread;
@@ -533,7 +531,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
   CURLcode result = CURLE_OK;
   struct mqtt_conn *mqtt = &conn->proto.mqtt;
   struct Curl_easy *data = conn->data;
-  struct MQTT *mq = data->req.protop;
+  struct MQTT *mq = data->req.p.mqtt;
   ssize_t nread;
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
   unsigned char *pkt = (unsigned char *)data->state.buffer;
@@ -557,8 +555,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
     result = Curl_read(conn, sockfd, (char *)&mq->firstbyte, 1, &nread);
     if(result)
       break;
-    if(data->set.verbose)
-      Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
+    Curl_debug(data, CURLINFO_HEADER_IN, (char *)&mq->firstbyte, 1);
     /* remember the first byte */
     mq->npacket = 0;
     mqstate(conn, MQTT_REMAINING_LENGTH, MQTT_NOSTATE);
@@ -568,8 +565,7 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
       result = Curl_read(conn, sockfd, (char *)&byte, 1, &nread);
       if(result)
         break;
-      if(data->set.verbose)
-        Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
+      Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1);
       pkt[mq->npacket++] = byte;
     } while((byte & 0x80) && (mq->npacket < 4));
     if(result)
@@ -625,4 +621,4 @@ static CURLcode mqtt_doing(struct connectdata *conn, bool *done)
   return result;
 }
 
-#endif /* CURL_ENABLE_MQTT */
+#endif /* CURL_DISABLE_MQTT */
diff --git a/lib/mqtt.h b/lib/mqtt.h
index 37463d5..fb52c72 100644
--- a/lib/mqtt.h
+++ b/lib/mqtt.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -22,7 +22,7 @@
  *
  ***************************************************************************/
 
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
 extern const struct Curl_handler Curl_handler_mqtt;
 #endif
 
diff --git a/lib/multi.c b/lib/multi.c
index 3c7fb85..86e36be 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -190,7 +190,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state
  */
 
 struct Curl_sh_entry {
-  struct curl_hash transfers; /* hash of transfers using this socket */
+  struct Curl_hash transfers; /* hash of transfers using this socket */
   unsigned int action;  /* what combined action READ/WRITE this socket waits
                            for */
   void *socketp; /* settable by users with curl_multi_assign() */
@@ -204,7 +204,7 @@ struct Curl_sh_entry {
 #define SH_WRITE 2
 
 /* look up a given socket in the socket hash, skip invalid sockets */
-static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
+static struct Curl_sh_entry *sh_getentry(struct Curl_hash *sh,
                                          curl_socket_t s)
 {
   if(s != CURL_SOCKET_BAD) {
@@ -238,7 +238,7 @@ static void trhash_dtor(void *nada)
 
 
 /* make sure this socket is present in the hash for this handle */
-static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+static struct Curl_sh_entry *sh_addentry(struct Curl_hash *sh,
                                          curl_socket_t s)
 {
   struct Curl_sh_entry *there = sh_getentry(sh, s);
@@ -273,7 +273,7 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
 
 /* delete the given socket + handle from the hash */
 static void sh_delentry(struct Curl_sh_entry *entry,
-                        struct curl_hash *sh, curl_socket_t s)
+                        struct Curl_hash *sh, curl_socket_t s)
 {
   Curl_hash_destroy(&entry->transfers);
 
@@ -325,7 +325,7 @@ 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 int sh_init(struct Curl_hash *hash, int hashsize)
 {
   return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
                         sh_freeentry);
@@ -716,7 +716,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
   struct Curl_easy *easy = data;
   bool premature;
   bool easy_owns_conn;
-  struct curl_llist_element *e;
+  struct Curl_llist_element *e;
 
   /* First, make some basic checks that the CURLM handle is a good handle */
   if(!GOOD_MULTI_HANDLE(multi))
@@ -1081,11 +1081,11 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
   unsigned int i;
   unsigned int nfds = 0;
   unsigned int curlfds;
-  bool ufds_malloc = FALSE;
   long timeout_internal;
   int retcode = 0;
   struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
   struct pollfd *ufds = &a_few_on_stack[0];
+  bool ufds_malloc = FALSE;
 
   if(!GOOD_MULTI_HANDLE(multi))
     return CURLM_BAD_HANDLE;
@@ -1157,7 +1157,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
     while(data) {
       bitmap = multi_getsock(data, sockbunch);
 
-      for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+      for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) {
         curl_socket_t s = CURL_SOCKET_BAD;
 
         if(bitmap & GETSOCK_READSOCK(i)) {
@@ -1203,10 +1203,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
 #endif
 
   if(nfds) {
-    int pollrc;
     /* wait... */
-    pollrc = Curl_poll(ufds, nfds, timeout_ms);
-
+    int pollrc = Curl_poll(ufds, nfds, timeout_ms);
     if(pollrc > 0) {
       retcode = pollrc;
       /* copy revents results from the poll to the curl_multi_wait poll
@@ -1222,7 +1220,6 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
           mask |= CURL_WAIT_POLLOUT;
         if(r & POLLPRI)
           mask |= CURL_WAIT_POLLPRI;
-
         extra_fds[i].revents = mask;
       }
 
@@ -1562,7 +1559,7 @@ CURLcode Curl_preconnect(struct Curl_easy *data)
 
 
 static CURLMcode multi_runsingle(struct Curl_multi *multi,
-                                 struct curltime now,
+                                 struct curltime *nowp,
                                  struct Curl_easy *data)
 {
   struct Curl_message *msg = NULL;
@@ -1603,7 +1600,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
        (data->mstate < CURLM_STATE_COMPLETED)) {
       /* we need to wait for the connect state as only then is the start time
          stored, but we must not check already completed handles */
-      timeout_ms = Curl_timeleft(data, &now,
+      timeout_ms = Curl_timeleft(data, nowp,
                                  (data->mstate <= CURLM_STATE_DO)?
                                  TRUE:FALSE);
 
@@ -1612,25 +1609,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
         if(data->mstate == CURLM_STATE_WAITRESOLVE)
           failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
                 " milliseconds",
-                Curl_timediff(now, data->progress.t_startsingle));
+                Curl_timediff(*nowp, data->progress.t_startsingle));
         else if(data->mstate == CURLM_STATE_WAITCONNECT)
           failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
                 " milliseconds",
-                Curl_timediff(now, data->progress.t_startsingle));
+                Curl_timediff(*nowp, data->progress.t_startsingle));
         else {
           struct SingleRequest *k = &data->req;
           if(k->size != -1) {
             failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
                   " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
                   CURL_FORMAT_CURL_OFF_T " bytes received",
-                  Curl_timediff(now, data->progress.t_startsingle),
+                  Curl_timediff(*nowp, data->progress.t_startsingle),
                   k->bytecount, k->size);
           }
           else {
             failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
                   " milliseconds with %" CURL_FORMAT_CURL_OFF_T
                   " bytes received",
-                  Curl_timediff(now, data->progress.t_startsingle),
+                  Curl_timediff(*nowp, data->progress.t_startsingle),
                   k->bytecount);
           }
         }
@@ -1655,7 +1652,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       if(!result) {
         /* after init, go CONNECT */
         multistate(data, CURLM_STATE_CONNECT);
-        Curl_pgrsTime(data, TIMER_STARTOP);
+        *nowp = Curl_pgrsTime(data, TIMER_STARTOP);
         rc = CURLM_CALL_MULTI_PERFORM;
       }
       break;
@@ -1672,7 +1669,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       if(result)
         break;
 
-      Curl_pgrsTime(data, TIMER_STARTSINGLE);
+      *nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
       if(data->set.timeout)
         Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
 
@@ -2080,7 +2077,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
       if(Curl_pgrsUpdate(data->conn))
         result = CURLE_ABORTED_BY_CALLBACK;
       else
-        result = Curl_speedcheck(data, now);
+        result = Curl_speedcheck(data, *nowp);
 
       if(!result) {
         send_timeout_ms = 0;
@@ -2090,7 +2087,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                    data->progress.ul_limit_size,
                                    data->set.max_send_speed,
                                    data->progress.ul_limit_start,
-                                   now);
+                                   *nowp);
 
         recv_timeout_ms = 0;
         if(data->set.max_recv_speed > 0)
@@ -2099,11 +2096,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                    data->progress.dl_limit_size,
                                    data->set.max_recv_speed,
                                    data->progress.dl_limit_start,
-                                   now);
+                                   *nowp);
 
         if(!send_timeout_ms && !recv_timeout_ms) {
           multistate(data, CURLM_STATE_PERFORM);
-          Curl_ratelimit(data, now);
+          Curl_ratelimit(data, *nowp);
         }
         else if(send_timeout_ms >= recv_timeout_ms)
           Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
@@ -2125,7 +2122,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                                  data->progress.ul_limit_size,
                                                  data->set.max_send_speed,
                                                  data->progress.ul_limit_start,
-                                                 now);
+                                                 *nowp);
 
       /* check if over recv speed */
       recv_timeout_ms = 0;
@@ -2134,10 +2131,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
                                                  data->progress.dl_limit_size,
                                                  data->set.max_recv_speed,
                                                  data->progress.dl_limit_start,
-                                                 now);
+                                                 *nowp);
 
       if(send_timeout_ms || recv_timeout_ms) {
-        Curl_ratelimit(data, now);
+        Curl_ratelimit(data, *nowp);
         multistate(data, CURLM_STATE_TOOFAST);
         if(send_timeout_ms >= recv_timeout_ms)
           Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
@@ -2417,7 +2414,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
     SIGPIPE_VARIABLE(pipe_st);
 
     sigpipe_ignore(data, &pipe_st);
-    result = multi_runsingle(multi, now, data);
+    result = multi_runsingle(multi, &now, data);
     sigpipe_restore(&pipe_st);
 
     if(result)
@@ -2531,7 +2528,7 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
      !multi->in_callback &&
      Curl_llist_count(&multi->msglist)) {
     /* there is one or more messages in the list */
-    struct curl_llist_element *e;
+    struct Curl_llist_element *e;
 
     /* extract the head of the list to return */
     e = multi->msglist.head;
@@ -2761,15 +2758,15 @@ static CURLMcode add_next_timeout(struct curltime now,
                                   struct Curl_easy *d)
 {
   struct curltime *tv = &d->state.expiretime;
-  struct curl_llist *list = &d->state.timeoutlist;
-  struct curl_llist_element *e;
+  struct Curl_llist *list = &d->state.timeoutlist;
+  struct Curl_llist_element *e;
   struct time_node *node = NULL;
 
   /* move over the timeout list for this specific handle and remove all
      timeouts that are now passed tense and store the next pending
      timeout in *tv */
   for(e = list->head; e;) {
-    struct curl_llist_element *n = e->next;
+    struct Curl_llist_element *n = e->next;
     timediff_t diff;
     node = (struct time_node *)e->ptr;
     diff = Curl_timediff(node->time, now);
@@ -2839,8 +2836,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
          and just move on. */
       ;
     else {
-      struct curl_hash_iterator iter;
-      struct curl_hash_element *he;
+      struct Curl_hash_iterator iter;
+      struct Curl_hash_element *he;
 
       /* the socket can be shared by many transfers, iterate */
       Curl_hash_start_iterate(&entry->transfers, &iter);
@@ -2887,7 +2884,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
       SIGPIPE_VARIABLE(pipe_st);
 
       sigpipe_ignore(data, &pipe_st);
-      result = multi_runsingle(multi, now, data);
+      result = multi_runsingle(multi, &now, data);
       sigpipe_restore(&pipe_st);
 
       if(CURLM_OK >= result) {
@@ -3015,7 +3012,6 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
 }
 
 CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
-
 {
   CURLMcode result;
   if(multi->in_callback)
@@ -3123,8 +3119,8 @@ void Curl_update_timer(struct Curl_multi *multi)
 static void
 multi_deltimeout(struct Curl_easy *data, expire_id eid)
 {
-  struct curl_llist_element *e;
-  struct curl_llist *timeoutlist = &data->state.timeoutlist;
+  struct Curl_llist_element *e;
+  struct Curl_llist *timeoutlist = &data->state.timeoutlist;
   /* find and remove the specific node from the list */
   for(e = timeoutlist->head; e; e = e->next) {
     struct time_node *n = (struct time_node *)e->ptr;
@@ -3147,11 +3143,11 @@ multi_addtimeout(struct Curl_easy *data,
                  struct curltime *stamp,
                  expire_id eid)
 {
-  struct curl_llist_element *e;
+  struct Curl_llist_element *e;
   struct time_node *node;
-  struct curl_llist_element *prev = NULL;
+  struct Curl_llist_element *prev = NULL;
   size_t n;
-  struct curl_llist *timeoutlist = &data->state.timeoutlist;
+  struct Curl_llist *timeoutlist = &data->state.timeoutlist;
 
   node = &data->state.expires[eid];
 
@@ -3233,9 +3229,8 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id)
 
     /* Since this is an updated time, we must remove the previous entry from
        the splay tree first and then re-add the new value */
-    rc = Curl_splayremovebyaddr(multi->timetree,
-                                &data->state.timenode,
-                                &multi->timetree);
+    rc = Curl_splayremove(multi->timetree, &data->state.timenode,
+                          &multi->timetree);
     if(rc)
       infof(data, "Internal error removing splay node = %d\n", rc);
   }
@@ -3278,12 +3273,11 @@ void Curl_expire_clear(struct Curl_easy *data)
   if(nowp->tv_sec || nowp->tv_usec) {
     /* Since this is an cleared time, we must remove the previous entry from
        the splay tree */
-    struct curl_llist *list = &data->state.timeoutlist;
+    struct Curl_llist *list = &data->state.timeoutlist;
     int rc;
 
-    rc = Curl_splayremovebyaddr(multi->timetree,
-                                &data->state.timenode,
-                                &multi->timetree);
+    rc = Curl_splayremove(multi->timetree, &data->state.timenode,
+                          &multi->timetree);
     if(rc)
       infof(data, "Internal error clearing splay node = %d\n", rc);
 
@@ -3349,7 +3343,7 @@ void Curl_multiuse_state(struct connectdata *conn,
 
 static void process_pending_handles(struct Curl_multi *multi)
 {
-  struct curl_llist_element *e = multi->pending.head;
+  struct Curl_llist_element *e = multi->pending.head;
   if(e) {
     struct Curl_easy *data = e->ptr;
 
diff --git a/lib/multihandle.h b/lib/multihandle.h
index 9d73df0..de4f740 100644
--- a/lib/multihandle.h
+++ b/lib/multihandle.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -27,7 +27,7 @@
 #include "socketpair.h"
 
 struct Curl_message {
-  struct curl_llist_element list;
+  struct Curl_llist_element list;
   /* the 'CURLMsg' is the part that is visible to the external user */
   struct CURLMsg extmsg;
 };
@@ -67,11 +67,11 @@ typedef enum {
 
 #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
 
-#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS)
+#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) &&        \
+  !defined(CURL_DISABLE_SOCKETPAIR)
 #define ENABLE_WAKEUP
 #endif
 
-
 /* value for MAXIMUM CONCURRENT STREAMS upper limit */
 #define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1)
 
@@ -89,9 +89,9 @@ struct Curl_multi {
   int num_alive; /* amount of easy handles that are added but have not yet
                     reached COMPLETE state */
 
-  struct curl_llist msglist; /* a list of messages from completed transfers */
+  struct Curl_llist msglist; /* a list of messages from completed transfers */
 
-  struct curl_llist pending; /* Curl_easys that are in the
+  struct Curl_llist pending; /* Curl_easys that are in the
                                 CURLM_STATE_CONNECT_PEND state */
 
   /* callback function and user data pointer for the *socket() API */
@@ -103,7 +103,7 @@ struct Curl_multi {
   void *push_userp;
 
   /* Hostname cache */
-  struct curl_hash hostcache;
+  struct Curl_hash hostcache;
 
 #ifdef USE_LIBPSL
   /* PSL cache. */
@@ -117,7 +117,7 @@ struct Curl_multi {
   /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
      the pluralis form, there can be more than one easy handle waiting on the
      same actual socket) */
-  struct curl_hash sockhash;
+  struct Curl_hash sockhash;
 
   /* Shared connection cache (bundles)*/
   struct conncache conn_cache;
diff --git a/lib/multiif.h b/lib/multiif.h
index 7d574df..f0a57d9 100644
--- a/lib/multiif.h
+++ b/lib/multiif.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/netrc.c b/lib/netrc.c
index 1c9da31..13610bb 100644
--- a/lib/netrc.c
+++ b/lib/netrc.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/netrc.h b/lib/netrc.h
index 7f56c4b..4938a59 100644
--- a/lib/netrc.h
+++ b/lib/netrc.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/non-ascii.c b/lib/non-ascii.c
index a48e67d..30c240b 100644
--- a/lib/non-ascii.c
+++ b/lib/non-ascii.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/non-ascii.h b/lib/non-ascii.h
index 5fb5771..458e8ef 100644
--- a/lib/non-ascii.h
+++ b/lib/non-ascii.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nonblock.c b/lib/nonblock.c
index abeb659..4a7bde5 100644
--- a/lib/nonblock.c
+++ b/lib/nonblock.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nonblock.h b/lib/nonblock.h
index d50d315..761dab4 100644
--- a/lib/nonblock.h
+++ b/lib/nonblock.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nwlib.c b/lib/nwlib.c
index beec0b3..7693268 100644
--- a/lib/nwlib.c
+++ b/lib/nwlib.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/nwos.c b/lib/nwos.c
index c6c22cc..8894031 100644
--- a/lib/nwos.c
+++ b/lib/nwos.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/openldap.c b/lib/openldap.c
index 782d6a0..24892ff 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -107,6 +107,7 @@ const struct Curl_handler Curl_handler_ldap = {
   ZERO_NULL,                            /* connection_check */
   PORT_LDAP,                            /* defport */
   CURLPROTO_LDAP,                       /* protocol */
+  CURLPROTO_LDAP,                       /* family */
   PROTOPT_NONE                          /* flags */
 };
 
@@ -132,7 +133,8 @@ const struct Curl_handler Curl_handler_ldaps = {
   ZERO_NULL,                            /* readwrite */
   ZERO_NULL,                            /* connection_check */
   PORT_LDAPS,                           /* defport */
-  CURLPROTO_LDAP,                       /* protocol */
+  CURLPROTO_LDAPS,                      /* protocol */
+  CURLPROTO_LDAP,                       /* family */
   PROTOPT_SSL                           /* flags */
 };
 #endif
@@ -410,7 +412,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
   if(!lr)
     return CURLE_OUT_OF_MEMORY;
   lr->msgid = msgid;
-  data->req.protop = lr;
+  data->req.p.ldap = lr;
   Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
   *done = TRUE;
   return CURLE_OK;
@@ -419,7 +421,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
 static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
                           bool premature)
 {
-  struct ldapreqinfo *lr = conn->data->req.protop;
+  struct ldapreqinfo *lr = conn->data->req.p.ldap;
 
   (void)res;
   (void)premature;
@@ -431,7 +433,7 @@ static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
       ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
       lr->msgid = 0;
     }
-    conn->data->req.protop = NULL;
+    conn->data->req.p.ldap = NULL;
     free(lr);
   }
 
@@ -443,7 +445,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
 {
   struct ldapconninfo *li = conn->proto.ldapc;
   struct Curl_easy *data = conn->data;
-  struct ldapreqinfo *lr = data->req.protop;
+  struct ldapreqinfo *lr = data->req.p.ldap;
   int rc, ret;
   LDAPMessage *msg = NULL;
   LDAPMessage *ent;
diff --git a/lib/parsedate.c b/lib/parsedate.c
index 4c7a40c..3c38f2c 100644
--- a/lib/parsedate.c
+++ b/lib/parsedate.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -275,48 +275,21 @@ enum assume {
   DATE_TIME
 };
 
-/* this is a clone of 'struct tm' but with all fields we don't need or use
-   cut out */
-struct my_tm {
-  int tm_sec;
-  int tm_min;
-  int tm_hour;
-  int tm_mday;
-  int tm_mon;
-  int tm_year; /* full year */
-};
-
-/* struct tm to time since epoch in GMT time zone.
- * This is similar to the standard mktime function but for GMT only, and
- * doesn't suffer from the various bugs and portability problems that
- * some systems' implementations have.
- *
- * Returns 0 on success, otherwise non-zero.
+/*
+ * time2epoch: time stamp to seconds since epoch in GMT time zone.  Similar to
+ * mktime but for GMT only.
  */
-static void my_timegm(struct my_tm *tm, time_t *t)
+static time_t time2epoch(int sec, int min, int hour,
+                         int mday, int mon, int year)
 {
   static const int month_days_cumulative [12] =
     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-  int month, year, leap_days;
-
-  year = tm->tm_year;
-  month = tm->tm_mon;
-  if(month < 0) {
-    year += (11 - month) / 12;
-    month = 11 - (11 - month) % 12;
-  }
-  else if(month >= 12) {
-    year -= month / 12;
-    month = month % 12;
-  }
-
-  leap_days = year - (tm->tm_mon <= 1);
+  int leap_days = year - (mon <= 1);
   leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
                - (1969 / 4) + (1969 / 100) - (1969 / 400));
-
-  *t = ((((time_t) (year - 1970) * 365
-          + leap_days + month_days_cumulative[month] + tm->tm_mday - 1) * 24
-         + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
+  return ((((time_t) (year - 1970) * 365
+            + leap_days + month_days_cumulative[mon] + mday - 1) * 24
+           + hour) * 60 + min) * 60 + sec;
 }
 
 /*
@@ -341,7 +314,6 @@ static int parsedate(const char *date, time_t *output)
   int secnum = -1;
   int yearnum = -1;
   int tzoff = -1;
-  struct my_tm tm;
   enum assume dignext = DATE_MDAY;
   const char *indate = date; /* save the original pointer */
   int part = 0; /* max 6 parts */
@@ -533,18 +505,11 @@ static int parsedate(const char *date, time_t *output)
      (hournum > 23) || (minnum > 59) || (secnum > 60))
     return PARSEDATE_FAIL; /* clearly an illegal date */
 
-  tm.tm_sec = secnum;
-  tm.tm_min = minnum;
-  tm.tm_hour = hournum;
-  tm.tm_mday = mdaynum;
-  tm.tm_mon = monnum;
-  tm.tm_year = yearnum;
-
-  /* my_timegm() returns a time_t. time_t is often 32 bits, sometimes even on
+  /* time2epoch() returns a time_t. time_t is often 32 bits, sometimes even on
      architectures that feature 64 bit 'long' but ultimately time_t is the
      correct data type to use.
   */
-  my_timegm(&tm, &t);
+  t = time2epoch(secnum, minnum, hournum, mdaynum, monnum, yearnum);
 
   /* Add the time zone diff between local time zone and GMT. */
   if(tzoff == -1)
diff --git a/lib/parsedate.h b/lib/parsedate.h
index 8c7ae94..a99faf9 100644
--- a/lib/parsedate.h
+++ b/lib/parsedate.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/pingpong.c b/lib/pingpong.c
index 3143315..5d6109a 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -146,7 +146,11 @@ void Curl_pp_init(struct pingpong *pp)
   pp->response = Curl_now(); /* start response time-out now! */
 }
 
-
+/* setup for the coming transfer */
+void Curl_pp_setup(struct pingpong *pp)
+{
+  Curl_dyn_init(&pp->sendbuf, DYN_PINGPPONG_CMD);
+}
 
 /***********************************************************************
  *
@@ -162,9 +166,8 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
                         const char *fmt,
                         va_list args)
 {
-  ssize_t bytes_written;
+  ssize_t bytes_written = 0;
   size_t write_len;
-  char *fmt_crlf;
   char *s;
   CURLcode result;
   struct connectdata *conn = pp->conn;
@@ -181,48 +184,41 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
   if(!conn)
     /* can't send without a connection! */
     return CURLE_SEND_ERROR;
-
   data = conn->data;
 
-  fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
-  if(!fmt_crlf)
-    return CURLE_OUT_OF_MEMORY;
-
-  s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */
-  free(fmt_crlf);
-  if(!s)
-    return CURLE_OUT_OF_MEMORY;
+  Curl_dyn_reset(&pp->sendbuf);
+  result = Curl_dyn_vaddf(&pp->sendbuf, fmt, args);
+  if(result)
+    return result;
 
-  bytes_written = 0;
-  write_len = strlen(s);
+  /* append CRLF */
+  result = Curl_dyn_addn(&pp->sendbuf, "\r\n", 2);
+  if(result)
+    return result;
 
+  write_len = Curl_dyn_len(&pp->sendbuf);
+  s = Curl_dyn_ptr(&pp->sendbuf);
   Curl_pp_init(pp);
 
   result = Curl_convert_to_network(data, s, write_len);
   /* Curl_convert_to_network calls failf if unsuccessful */
-  if(result) {
-    free(s);
+  if(result)
     return result;
-  }
 
 #ifdef HAVE_GSSAPI
   conn->data_prot = PROT_CMD;
 #endif
   result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
-                     &bytes_written);
+                      &bytes_written);
+  if(result)
+    return result;
 #ifdef HAVE_GSSAPI
   data_sec = conn->data_prot;
   DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
   conn->data_prot = data_sec;
 #endif
 
-  if(result) {
-    free(s);
-    return result;
-  }
-
-  if(conn->data->set.verbose)
-    Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
+  Curl_debug(data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
 
   if(bytes_written != (ssize_t)write_len) {
     /* the whole chunk was not sent, keep it around and adjust sizes */
@@ -231,7 +227,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
     pp->sendleft = write_len - bytes_written;
   }
   else {
-    free(s);
     pp->sendthis = NULL;
     pp->sendleft = pp->sendsize = 0;
     pp->response = Curl_now();
@@ -368,9 +363,8 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
 #ifdef HAVE_GSSAPI
           if(!conn->sec_complete)
 #endif
-            if(data->set.verbose)
-              Curl_debug(data, CURLINFO_HEADER_IN,
-                         pp->linestart_resp, (size_t)perline);
+            Curl_debug(data, CURLINFO_HEADER_IN,
+                       pp->linestart_resp, (size_t)perline);
 
           /*
            * We pass all response-lines to the callback function registered
@@ -493,7 +487,6 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
     pp->sendleft -= written;
   }
   else {
-    free(pp->sendthis);
     pp->sendthis = NULL;
     pp->sendleft = pp->sendsize = 0;
     pp->response = Curl_now();
@@ -503,15 +496,15 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp)
 
 CURLcode Curl_pp_disconnect(struct pingpong *pp)
 {
-  free(pp->cache);
-  pp->cache = NULL;
+  Curl_dyn_free(&pp->sendbuf);
+  Curl_safefree(pp->cache);
   return CURLE_OK;
 }
 
 bool Curl_pp_moredata(struct pingpong *pp)
 {
   return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ?
-         TRUE : FALSE;
+    TRUE : FALSE;
 }
 
 #endif
diff --git a/lib/pingpong.h b/lib/pingpong.h
index e874799..0d0c74a 100644
--- a/lib/pingpong.h
+++ b/lib/pingpong.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -64,6 +64,7 @@ struct pingpong {
                                milliseconds we await for a server response. */
   struct connectdata *conn; /* points to the connectdata struct that this
                                belongs to */
+  struct dynbuf sendbuf;
 
   /* Function pointers the protocols MUST implement and provide for the
      pingpong layer to function */
@@ -86,6 +87,9 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block,
 /* initialize stuff to prepare for reading a fresh new response */
 void Curl_pp_init(struct pingpong *pp);
 
+/* setup for the transfer */
+void Curl_pp_setup(struct pingpong *pp);
+
 /* Returns timeout in ms. 0 or negative number means the timeout has already
    triggered */
 timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting);
diff --git a/lib/pop3.c b/lib/pop3.c
index 9ff5c78..e71860e 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -128,6 +128,7 @@ const struct Curl_handler Curl_handler_pop3 = {
   ZERO_NULL,                        /* connection_check */
   PORT_POP3,                        /* defport */
   CURLPROTO_POP3,                   /* protocol */
+  CURLPROTO_POP3,                   /* family */
   PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
   PROTOPT_URLOPTIONS
 };
@@ -155,6 +156,7 @@ const struct Curl_handler Curl_handler_pop3s = {
   ZERO_NULL,                        /* connection_check */
   PORT_POP3S,                       /* defport */
   CURLPROTO_POP3S,                  /* protocol */
+  CURLPROTO_POP3,                   /* family */
   PROTOPT_CLOSEACTION | PROTOPT_SSL
   | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
 };
@@ -551,7 +553,7 @@ static CURLcode pop3_perform_command(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct POP3 *pop3 = data->req.protop;
+  struct POP3 *pop3 = data->req.p.pop3;
   const char *command = NULL;
 
   /* Calculate the default command */
@@ -884,7 +886,7 @@ static CURLcode pop3_state_command_resp(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct POP3 *pop3 = data->req.protop;
+  struct POP3 *pop3 = data->req.p.pop3;
   struct pop3_conn *pop3c = &conn->proto.pop3c;
   struct pingpong *pp = &pop3c->pp;
 
@@ -1046,7 +1048,7 @@ static CURLcode pop3_init(struct connectdata *conn)
   struct Curl_easy *data = conn->data;
   struct POP3 *pop3;
 
-  pop3 = data->req.protop = calloc(sizeof(struct POP3), 1);
+  pop3 = data->req.p.pop3 = calloc(sizeof(struct POP3), 1);
   if(!pop3)
     result = CURLE_OUT_OF_MEMORY;
 
@@ -1091,6 +1093,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
   Curl_sasl_init(&pop3c->sasl, &saslpop3);
 
   /* Initialise the pingpong layer */
+  Curl_pp_setup(pp);
   Curl_pp_init(pp);
 
   /* Parse the URL options */
@@ -1120,7 +1123,7 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct POP3 *pop3 = data->req.protop;
+  struct POP3 *pop3 = data->req.p.pop3;
 
   (void)premature;
 
@@ -1154,7 +1157,7 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
 {
   /* This is POP3 and no proxy */
   CURLcode result = CURLE_OK;
-  struct POP3 *pop3 = conn->data->req.protop;
+  struct POP3 *pop3 = conn->data->req.p.pop3;
 
   DEBUGF(infof(conn->data, "DO phase starts\n"));
 
@@ -1386,7 +1389,7 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
 {
   /* The POP3 struct is already initialised in pop3_connect() */
   struct Curl_easy *data = conn->data;
-  struct POP3 *pop3 = data->req.protop;
+  struct POP3 *pop3 = data->req.p.pop3;
   const char *path = &data->state.up.path[1]; /* skip leading path */
 
   /* URL decode the path for the message ID */
@@ -1403,7 +1406,7 @@ static CURLcode pop3_parse_custom_request(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct POP3 *pop3 = data->req.protop;
+  struct POP3 *pop3 = data->req.p.pop3;
   const char *custom = data->set.str[STRING_CUSTOMREQUEST];
 
   /* URL decode the custom request */
diff --git a/lib/pop3.h b/lib/pop3.h
index 3ba7999..6ca3fd5 100644
--- a/lib/pop3.h
+++ b/lib/pop3.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2009 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/progress.c b/lib/progress.c
index 8951384..658d05a 100644
--- a/lib/progress.c
+++ b/lib/progress.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -164,9 +164,13 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
 }
 
 /*
+ *
+ * Curl_pgrsTime(). Store the current time at the given label. This fetches a
+ * fresh "now" and returns it.
+ *
  * @unittest: 1399
  */
-void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
+struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer)
 {
   struct curltime now = Curl_now();
   timediff_t *delta = NULL;
@@ -209,7 +213,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
      * changing the t_starttransfer time.
      */
     if(data->progress.is_t_startransfer_set) {
-      return;
+      return now;
     }
     else {
       data->progress.is_t_startransfer_set = true;
@@ -228,6 +232,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
       us = 1; /* make sure at least one microsecond passed */
     *delta += us;
   }
+  return now;
 }
 
 void Curl_pgrsStartNow(struct Curl_easy *data)
@@ -235,10 +240,8 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
   data->progress.speeder_c = 0; /* reset the progress meter display */
   data->progress.start = Curl_now();
   data->progress.is_t_startransfer_set = false;
-  data->progress.ul_limit_start.tv_sec = 0;
-  data->progress.ul_limit_start.tv_usec = 0;
-  data->progress.dl_limit_start.tv_sec = 0;
-  data->progress.dl_limit_start.tv_usec = 0;
+  data->progress.ul_limit_start = data->progress.start;
+  data->progress.dl_limit_start = data->progress.start;
   data->progress.downloaded = 0;
   data->progress.uploaded = 0;
   /* clear all bits except HIDE and HEADERS_OUT */
diff --git a/lib/progress.h b/lib/progress.h
index 3515ac6..7468009 100644
--- a/lib/progress.h
+++ b/lib/progress.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -49,7 +49,7 @@ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
 void Curl_ratelimit(struct Curl_easy *data, struct curltime now);
 int Curl_pgrsUpdate(struct connectdata *);
 void Curl_pgrsResetTransferSizes(struct Curl_easy *data);
-void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
+struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer);
 timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
                                   curl_off_t startsize,
                                   curl_off_t limit,
diff --git a/lib/psl.c b/lib/psl.c
index 568baff..e460918 100644
--- a/lib/psl.c
+++ b/lib/psl.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/psl.h b/lib/psl.h
index e9f99d0..c103674 100644
--- a/lib/psl.h
+++ b/lib/psl.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/quic.h b/lib/quic.h
index 8e7df90..f04662e 100644
--- a/lib/quic.h
+++ b/lib/quic.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -41,7 +41,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
                            const struct sockaddr *addr,
                            socklen_t addrlen);
 CURLcode Curl_quic_is_connected(struct connectdata *conn,
-                                curl_socket_t sockfd,
+                                int sockindex,
                                 bool *connected);
 int Curl_quic_ver(char *p, size_t len);
 CURLcode Curl_quic_done_sending(struct connectdata *conn);
diff --git a/lib/rand.c b/lib/rand.c
index c415048..951fedb 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/rand.h b/lib/rand.h
index 3c8e2b8..02d95d8 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/rename.c b/lib/rename.c
index fe5f95d..f858d43 100644
--- a/lib/rename.c
+++ b/lib/rename.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -24,8 +24,8 @@
 
 #include "curl_setup.h"
 
-#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) ||  \
-  defined(USE_ALTSVC)
+#if (!defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_COOKIES)) || \
+  !defined(CURL_DISABLE_ALTSVC)
 
 #include "curl_multibyte.h"
 #include "timeval.h"
diff --git a/lib/rename.h b/lib/rename.h
index d7442c8..534f747 100644
--- a/lib/rename.h
+++ b/lib/rename.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/rtsp.c b/lib/rtsp.c
index dbd7dc6..151ff4a 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -106,6 +106,7 @@ const struct Curl_handler Curl_handler_rtsp = {
   rtsp_conncheck,                       /* connection_check */
   PORT_RTSP,                            /* defport */
   CURLPROTO_RTSP,                       /* protocol */
+  CURLPROTO_RTSP,                       /* family */
   PROTOPT_NONE                          /* flags */
 };
 
@@ -114,7 +115,7 @@ static CURLcode rtsp_setup_connection(struct connectdata *conn)
 {
   struct RTSP *rtsp;
 
-  conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP));
+  conn->data->req.p.rtsp = rtsp = calloc(1, sizeof(struct RTSP));
   if(!rtsp)
     return CURLE_OUT_OF_MEMORY;
 
@@ -199,7 +200,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
                           CURLcode status, bool premature)
 {
   struct Curl_easy *data = conn->data;
-  struct RTSP *rtsp = data->req.protop;
+  struct RTSP *rtsp = data->req.p.rtsp;
   CURLcode httpStatus;
 
   /* Bypass HTTP empty-reply checks on receive */
@@ -232,7 +233,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_OK;
   Curl_RtspReq rtspreq = data->set.rtspreq;
-  struct RTSP *rtsp = data->req.protop;
+  struct RTSP *rtsp = data->req.p.rtsp;
   struct dynbuf req_buffer;
   curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
   curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
@@ -764,7 +765,7 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
     /* Store the received CSeq. Match is verified in rtsp_done */
     int nc = sscanf(&header[4], ": %ld", &CSeq);
     if(nc == 1) {
-      struct RTSP *rtsp = data->req.protop;
+      struct RTSP *rtsp = data->req.p.rtsp;
       rtsp->CSeq_recv = CSeq; /* mark the request */
       data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
     }
@@ -775,6 +776,8 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
   }
   else if(checkprefix("Session:", header)) {
     char *start;
+    char *end;
+    size_t idlen;
 
     /* Find the first non-space letter */
     start = header + 8;
@@ -783,11 +786,25 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
 
     if(!*start) {
       failf(data, "Got a blank Session ID");
+      return CURLE_RTSP_SESSION_ERROR;
     }
-    else if(data->set.str[STRING_RTSP_SESSION_ID]) {
+
+    /* Find the end of Session ID
+     *
+     * Allow any non whitespace content, up to the field separator or end of
+     * line. RFC 2326 isn't 100% clear on the session ID and for example
+     * gstreamer does url-encoded session ID's not covered by the standard.
+     */
+    end = start;
+    while(*end && *end != ';' && !ISSPACE(*end))
+      end++;
+    idlen = end - start;
+
+    if(data->set.str[STRING_RTSP_SESSION_ID]) {
+
       /* If the Session ID is set, then compare */
-      if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID],
-                 strlen(data->set.str[STRING_RTSP_SESSION_ID]))  != 0) {
+      if(strlen(data->set.str[STRING_RTSP_SESSION_ID]) != idlen ||
+         strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], idlen) != 0) {
         failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]",
               start, data->set.str[STRING_RTSP_SESSION_ID]);
         return CURLE_RTSP_SESSION_ERROR;
@@ -796,21 +813,14 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
     else {
       /* If the Session ID is not set, and we find it in a response, then set
        * it.
-       *
-       * Allow any non whitespace content, up to the field separator or end of
-       * line. RFC 2326 isn't 100% clear on the session ID and for example
-       * gstreamer does url-encoded session ID's not covered by the standard.
        */
-      char *end = start;
-      while(*end && *end != ';' && !ISSPACE(*end))
-        end++;
 
       /* Copy the id substring into a new buffer */
-      data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1);
+      data->set.str[STRING_RTSP_SESSION_ID] = malloc(idlen + 1);
       if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
         return CURLE_OUT_OF_MEMORY;
-      memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start);
-      (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0';
+      memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, idlen);
+      (data->set.str[STRING_RTSP_SESSION_ID])[idlen] = '\0';
     }
   }
   return CURLE_OK;
diff --git a/lib/rtsp.h b/lib/rtsp.h
index 1aae864..bf7f0bc 100644
--- a/lib/rtsp.h
+++ b/lib/rtsp.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/security.c b/lib/security.c
deleted file mode 100644
index 3b9c20a..0000000
--- a/lib/security.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
- * use in Curl. His latest changes were done 2000-09-18.
- *
- * It has since been patched and modified a lot by Daniel Stenberg
- * <daniel@haxx.se> to make it better applied to curl conditions, and to make
- * it not use globals, pollute name space and more. This source code awaits a
- * rewrite to work around the paragraph 2 in the BSD licenses as explained
- * below.
- *
- * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- *
- * Copyright (C) 2001 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.  */
-
-#include "curl_setup.h"
-
-#ifndef CURL_DISABLE_FTP
-#ifdef HAVE_GSSAPI
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#include <limits.h>
-
-#include "urldata.h"
-#include "curl_base64.h"
-#include "curl_memory.h"
-#include "curl_sec.h"
-#include "ftp.h"
-#include "sendf.h"
-#include "strcase.h"
-#include "warnless.h"
-#include "strdup.h"
-/* The last 3 #include files should be in this order */
-#include "curl_printf.h"
-#include "curl_memory.h"
-#include "memdebug.h"
-
-static const struct {
-  enum protection_level level;
-  const char *name;
-} level_names[] = {
-  { PROT_CLEAR, "clear" },
-  { PROT_SAFE, "safe" },
-  { PROT_CONFIDENTIAL, "confidential" },
-  { PROT_PRIVATE, "private" }
-};
-
-static enum protection_level
-name_to_level(const char *name)
-{
-  int i;
-  for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
-    if(checkprefix(name, level_names[i].name))
-      return level_names[i].level;
-  return PROT_NONE;
-}
-
-/* Convert a protocol |level| to its char representation.
-   We take an int to catch programming mistakes. */
-static char level_to_char(int level)
-{
-  switch(level) {
-  case PROT_CLEAR:
-    return 'C';
-  case PROT_SAFE:
-    return 'S';
-  case PROT_CONFIDENTIAL:
-    return 'E';
-  case PROT_PRIVATE:
-    return 'P';
-  case PROT_CMD:
-    /* Fall through */
-  default:
-    /* Those 2 cases should not be reached! */
-    break;
-  }
-  DEBUGASSERT(0);
-  /* Default to the most secure alternative. */
-  return 'P';
-}
-
-/* Send an FTP command defined by |message| and the optional arguments. The
-   function returns the ftp_code. If an error occurs, -1 is returned. */
-static int ftp_send_command(struct connectdata *conn, const char *message, ...)
-{
-  int ftp_code;
-  ssize_t nread = 0;
-  va_list args;
-  char print_buffer[50];
-
-  va_start(args, message);
-  mvsnprintf(print_buffer, sizeof(print_buffer), message, args);
-  va_end(args);
-
-  if(Curl_ftpsend(conn, print_buffer)) {
-    ftp_code = -1;
-  }
-  else {
-    if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
-      ftp_code = -1;
-  }
-
-  (void)nread; /* Unused */
-  return ftp_code;
-}
-
-/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
-   saying whether an error occurred or CURLE_OK if |len| was read. */
-static CURLcode
-socket_read(curl_socket_t fd, void *to, size_t len)
-{
-  char *to_p = to;
-  CURLcode result;
-  ssize_t nread = 0;
-
-  while(len > 0) {
-    result = Curl_read_plain(fd, to_p, len, &nread);
-    if(!result) {
-      len -= nread;
-      to_p += nread;
-    }
-    else {
-      if(result == CURLE_AGAIN)
-        continue;
-      return result;
-    }
-  }
-  return CURLE_OK;
-}
-
-
-/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
-   CURLcode saying whether an error occurred or CURLE_OK if |len| was
-   written. */
-static CURLcode
-socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
-             size_t len)
-{
-  const char *to_p = to;
-  CURLcode result;
-  ssize_t written;
-
-  while(len > 0) {
-    result = Curl_write_plain(conn, fd, to_p, len, &written);
-    if(!result) {
-      len -= written;
-      to_p += written;
-    }
-    else {
-      if(result == CURLE_AGAIN)
-        continue;
-      return result;
-    }
-  }
-  return CURLE_OK;
-}
-
-static CURLcode read_data(struct connectdata *conn,
-                          curl_socket_t fd,
-                          struct krb5buffer *buf)
-{
-  int len;
-  CURLcode result;
-
-  result = socket_read(fd, &len, sizeof(len));
-  if(result)
-    return result;
-
-  if(len) {
-    /* only realloc if there was a length */
-    len = ntohl(len);
-    buf->data = Curl_saferealloc(buf->data, len);
-  }
-  if(!len || !buf->data)
-    return CURLE_OUT_OF_MEMORY;
-
-  result = socket_read(fd, buf->data, len);
-  if(result)
-    return result;
-  buf->size = conn->mech->decode(conn->app_data, buf->data, len,
-                                 conn->data_prot, conn);
-  buf->index = 0;
-  return CURLE_OK;
-}
-
-static size_t
-buffer_read(struct krb5buffer *buf, void *data, size_t len)
-{
-  if(buf->size - buf->index < len)
-    len = buf->size - buf->index;
-  memcpy(data, (char *)buf->data + buf->index, len);
-  buf->index += len;
-  return len;
-}
-
-/* Matches Curl_recv signature */
-static ssize_t sec_recv(struct connectdata *conn, int sockindex,
-                        char *buffer, size_t len, CURLcode *err)
-{
-  size_t bytes_read;
-  size_t total_read = 0;
-  curl_socket_t fd = conn->sock[sockindex];
-
-  *err = CURLE_OK;
-
-  /* Handle clear text response. */
-  if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
-      return sread(fd, buffer, len);
-
-  if(conn->in_buffer.eof_flag) {
-    conn->in_buffer.eof_flag = 0;
-    return 0;
-  }
-
-  bytes_read = buffer_read(&conn->in_buffer, buffer, len);
-  len -= bytes_read;
-  total_read += bytes_read;
-  buffer += bytes_read;
-
-  while(len > 0) {
-    if(read_data(conn, fd, &conn->in_buffer))
-      return -1;
-    if(conn->in_buffer.size == 0) {
-      if(bytes_read > 0)
-        conn->in_buffer.eof_flag = 1;
-      return bytes_read;
-    }
-    bytes_read = buffer_read(&conn->in_buffer, buffer, len);
-    len -= bytes_read;
-    total_read += bytes_read;
-    buffer += bytes_read;
-  }
-  return total_read;
-}
-
-/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
-   and negotiating with the server. |from| can be NULL. */
-static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
-                        const char *from, int length)
-{
-  int bytes, htonl_bytes; /* 32-bit integers for htonl */
-  char *buffer = NULL;
-  char *cmd_buffer;
-  size_t cmd_size = 0;
-  CURLcode error;
-  enum protection_level prot_level = conn->data_prot;
-  bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
-
-  DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
-
-  if(iscmd) {
-    if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
-      prot_level = PROT_PRIVATE;
-    else
-      prot_level = conn->command_prot;
-  }
-  bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
-                             (void **)&buffer);
-  if(!buffer || bytes <= 0)
-    return; /* error */
-
-  if(iscmd) {
-    error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
-                               &cmd_buffer, &cmd_size);
-    if(error) {
-      free(buffer);
-      return; /* error */
-    }
-    if(cmd_size > 0) {
-      static const char *enc = "ENC ";
-      static const char *mic = "MIC ";
-      if(prot_level == PROT_PRIVATE)
-        socket_write(conn, fd, enc, 4);
-      else
-        socket_write(conn, fd, mic, 4);
-
-      socket_write(conn, fd, cmd_buffer, cmd_size);
-      socket_write(conn, fd, "\r\n", 2);
-      infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
-            cmd_buffer);
-      free(cmd_buffer);
-    }
-  }
-  else {
-    htonl_bytes = htonl(bytes);
-    socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
-    socket_write(conn, fd, buffer, curlx_sitouz(bytes));
-  }
-  free(buffer);
-}
-
-static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
-                         const char *buffer, size_t length)
-{
-  ssize_t tx = 0, len = conn->buffer_size;
-
-  len -= conn->mech->overhead(conn->app_data, conn->data_prot,
-                              curlx_sztosi(len));
-  if(len <= 0)
-    len = length;
-  while(length) {
-    if(length < (size_t)len)
-      len = length;
-
-    do_sec_send(conn, fd, buffer, curlx_sztosi(len));
-    length -= len;
-    buffer += len;
-    tx += len;
-  }
-  return tx;
-}
-
-/* Matches Curl_send signature */
-static ssize_t sec_send(struct connectdata *conn, int sockindex,
-                        const void *buffer, size_t len, CURLcode *err)
-{
-  curl_socket_t fd = conn->sock[sockindex];
-  *err = CURLE_OK;
-  return sec_write(conn, fd, buffer, len);
-}
-
-int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
-                      enum protection_level level)
-{
-  /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
-     int */
-  int decoded_len;
-  char *buf;
-  int ret_code = 0;
-  size_t decoded_sz = 0;
-  CURLcode error;
-
-  if(!conn->mech)
-    /* not inititalized, return error */
-    return -1;
-
-  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
-
-  error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
-  if(error || decoded_sz == 0)
-    return -1;
-
-  if(decoded_sz > (size_t)INT_MAX) {
-    free(buf);
-    return -1;
-  }
-  decoded_len = curlx_uztosi(decoded_sz);
-
-  decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
-                                   level, conn);
-  if(decoded_len <= 0) {
-    free(buf);
-    return -1;
-  }
-
-  if(conn->data->set.verbose) {
-    buf[decoded_len] = '\n';
-    Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
-  }
-
-  buf[decoded_len] = '\0';
-  if(decoded_len <= 3)
-    /* suspiciously short */
-    return 0;
-
-  if(buf[3] != '-')
-    /* safe to ignore return code */
-    (void)sscanf(buf, "%d", &ret_code);
-
-  if(buf[decoded_len - 1] == '\n')
-    buf[decoded_len - 1] = '\0';
-  strcpy(buffer, buf);
-  free(buf);
-  return ret_code;
-}
-
-static int sec_set_protection_level(struct connectdata *conn)
-{
-  int code;
-  enum protection_level level = conn->request_data_prot;
-
-  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
-
-  if(!conn->sec_complete) {
-    infof(conn->data, "Trying to change the protection level after the"
-                      " completion of the data exchange.\n");
-    return -1;
-  }
-
-  /* Bail out if we try to set up the same level */
-  if(conn->data_prot == level)
-    return 0;
-
-  if(level) {
-    char *pbsz;
-    static unsigned int buffer_size = 1 << 20; /* 1048576 */
-
-    code = ftp_send_command(conn, "PBSZ %u", buffer_size);
-    if(code < 0)
-      return -1;
-
-    if(code/100 != 2) {
-      failf(conn->data, "Failed to set the protection's buffer size.");
-      return -1;
-    }
-    conn->buffer_size = buffer_size;
-
-    pbsz = strstr(conn->data->state.buffer, "PBSZ=");
-    if(pbsz) {
-      /* ignore return code, use default value if it fails */
-      (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
-      if(buffer_size < conn->buffer_size)
-        conn->buffer_size = buffer_size;
-    }
-  }
-
-  /* Now try to negiociate the protection level. */
-  code = ftp_send_command(conn, "PROT %c", level_to_char(level));
-
-  if(code < 0)
-    return -1;
-
-  if(code/100 != 2) {
-    failf(conn->data, "Failed to set the protection level.");
-    return -1;
-  }
-
-  conn->data_prot = level;
-  if(level == PROT_PRIVATE)
-    conn->command_prot = level;
-
-  return 0;
-}
-
-int
-Curl_sec_request_prot(struct connectdata *conn, const char *level)
-{
-  enum protection_level l = name_to_level(level);
-  if(l == PROT_NONE)
-    return -1;
-  DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
-  conn->request_data_prot = l;
-  return 0;
-}
-
-static CURLcode choose_mech(struct connectdata *conn)
-{
-  int ret;
-  struct Curl_easy *data = conn->data;
-  void *tmp_allocation;
-  const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
-
-  tmp_allocation = realloc(conn->app_data, mech->size);
-  if(tmp_allocation == NULL) {
-    failf(data, "Failed realloc of size %zu", mech->size);
-    mech = NULL;
-    return CURLE_OUT_OF_MEMORY;
-  }
-  conn->app_data = tmp_allocation;
-
-  if(mech->init) {
-    ret = mech->init(conn->app_data);
-    if(ret) {
-      infof(data, "Failed initialization for %s. Skipping it.\n",
-            mech->name);
-      return CURLE_FAILED_INIT;
-    }
-  }
-
-  infof(data, "Trying mechanism %s...\n", mech->name);
-  ret = ftp_send_command(conn, "AUTH %s", mech->name);
-  if(ret < 0)
-    return CURLE_COULDNT_CONNECT;
-
-  if(ret/100 != 3) {
-    switch(ret) {
-    case 504:
-      infof(data, "Mechanism %s is not supported by the server (server "
-            "returned ftp code: 504).\n", mech->name);
-      break;
-    case 534:
-      infof(data, "Mechanism %s was rejected by the server (server returned "
-            "ftp code: 534).\n", mech->name);
-      break;
-    default:
-      if(ret/100 == 5) {
-        infof(data, "server does not support the security extensions\n");
-        return CURLE_USE_SSL_FAILED;
-      }
-      break;
-    }
-    return CURLE_LOGIN_DENIED;
-  }
-
-  /* Authenticate */
-  ret = mech->auth(conn->app_data, conn);
-
-  if(ret != AUTH_CONTINUE) {
-    if(ret != AUTH_OK) {
-      /* Mechanism has dumped the error to stderr, don't error here. */
-      return -1;
-    }
-    DEBUGASSERT(ret == AUTH_OK);
-
-    conn->mech = mech;
-    conn->sec_complete = 1;
-    conn->recv[FIRSTSOCKET] = sec_recv;
-    conn->send[FIRSTSOCKET] = sec_send;
-    conn->recv[SECONDARYSOCKET] = sec_recv;
-    conn->send[SECONDARYSOCKET] = sec_send;
-    conn->command_prot = PROT_SAFE;
-    /* Set the requested protection level */
-    /* BLOCKING */
-    (void)sec_set_protection_level(conn);
-  }
-
-  return CURLE_OK;
-}
-
-CURLcode
-Curl_sec_login(struct connectdata *conn)
-{
-  return choose_mech(conn);
-}
-
-
-void
-Curl_sec_end(struct connectdata *conn)
-{
-  if(conn->mech != NULL && conn->mech->end)
-    conn->mech->end(conn->app_data);
-  free(conn->app_data);
-  conn->app_data = NULL;
-  if(conn->in_buffer.data) {
-    free(conn->in_buffer.data);
-    conn->in_buffer.data = NULL;
-    conn->in_buffer.size = 0;
-    conn->in_buffer.index = 0;
-    conn->in_buffer.eof_flag = 0;
-  }
-  conn->sec_complete = 0;
-  conn->data_prot = PROT_CLEAR;
-  conn->mech = NULL;
-}
-
-#endif /* HAVE_GSSAPI */
-
-#endif /* CURL_DISABLE_FTP */
diff --git a/lib/select.c b/lib/select.c
index abb124a..7d1f944 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -149,15 +149,14 @@ int Curl_select(curl_socket_t maxfd,   /* highest socket number */
 {
   struct timeval pending_tv;
   struct timeval *ptimeout;
-  int r;
 
 #ifdef USE_WINSOCK
   /* WinSock select() can't handle zero events.  See the comment below. */
   if((!fds_read || fds_read->fd_count == 0) &&
      (!fds_write || fds_write->fd_count == 0) &&
      (!fds_err || fds_err->fd_count == 0)) {
-    r = Curl_wait_ms(timeout_ms);
-    return r;
+    /* no sockets, just wait */
+    return Curl_wait_ms(timeout_ms);
   }
 #endif
 
@@ -209,17 +208,16 @@ int Curl_select(curl_socket_t maxfd,   /* highest socket number */
     descriptor set must contain at least one handle to a socket.
 
     It is unclear why WinSock doesn't just handle this for us instead of
-    calling this an error.
+    calling this an error. Luckily, with WinSock, we can _also_ ask how
+    many bits are set on an fd_set. So, let's just check it beforehand.
   */
-  r = select((int)maxfd + 1,
-             fds_read && fds_read->fd_count ? fds_read : NULL,
-             fds_write && fds_write->fd_count ? fds_write : NULL,
-             fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
+  return select((int)maxfd + 1,
+                fds_read && fds_read->fd_count ? fds_read : NULL,
+                fds_write && fds_write->fd_count ? fds_write : NULL,
+                fds_err && fds_err->fd_count ? fds_err : NULL, ptimeout);
 #else
-  r = select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
+  return select((int)maxfd + 1, fds_read, fds_write, fds_err, ptimeout);
 #endif
-
-  return r;
 }
 
 /*
@@ -247,23 +245,14 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
                       curl_socket_t writefd, /* socket to write to */
                       timediff_t timeout_ms) /* milliseconds to wait */
 {
-#ifdef HAVE_POLL_FINE
   struct pollfd pfd[3];
   int num;
-#else
-  fd_set fds_read;
-  fd_set fds_write;
-  fd_set fds_err;
-  curl_socket_t maxfd;
-#endif
   int r;
-  int ret;
 
   if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
      (writefd == CURL_SOCKET_BAD)) {
     /* no sockets, just wait */
-    r = Curl_wait_ms(timeout_ms);
-    return r;
+    return Curl_wait_ms(timeout_ms);
   }
 
   /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
@@ -271,8 +260,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
 
-#ifdef HAVE_POLL_FINE
-
   num = 0;
   if(readfd0 != CURL_SOCKET_BAD) {
     pfd[num].fd = readfd0;
@@ -288,7 +275,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   }
   if(writefd != CURL_SOCKET_BAD) {
     pfd[num].fd = writefd;
-    pfd[num].events = POLLWRNORM|POLLOUT;
+    pfd[num].events = POLLWRNORM|POLLOUT|POLLPRI;
     pfd[num].revents = 0;
     num++;
   }
@@ -297,101 +284,30 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
   if(r <= 0)
     return r;
 
-  ret = 0;
+  r = 0;
   num = 0;
   if(readfd0 != CURL_SOCKET_BAD) {
     if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
-      ret |= CURL_CSELECT_IN;
+      r |= CURL_CSELECT_IN;
     if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
-      ret |= CURL_CSELECT_ERR;
+      r |= CURL_CSELECT_ERR;
     num++;
   }
   if(readfd1 != CURL_SOCKET_BAD) {
     if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
-      ret |= CURL_CSELECT_IN2;
+      r |= CURL_CSELECT_IN2;
     if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
-      ret |= CURL_CSELECT_ERR;
+      r |= CURL_CSELECT_ERR;
     num++;
   }
   if(writefd != CURL_SOCKET_BAD) {
     if(pfd[num].revents & (POLLWRNORM|POLLOUT))
-      ret |= CURL_CSELECT_OUT;
-    if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
-      ret |= CURL_CSELECT_ERR;
-  }
-
-  return ret;
-
-#else  /* HAVE_POLL_FINE */
-
-  FD_ZERO(&fds_err);
-  maxfd = (curl_socket_t)-1;
-
-  FD_ZERO(&fds_read);
-  if(readfd0 != CURL_SOCKET_BAD) {
-    VERIFY_SOCK(readfd0);
-    FD_SET(readfd0, &fds_read);
-    FD_SET(readfd0, &fds_err);
-    maxfd = readfd0;
-  }
-  if(readfd1 != CURL_SOCKET_BAD) {
-    VERIFY_SOCK(readfd1);
-    FD_SET(readfd1, &fds_read);
-    FD_SET(readfd1, &fds_err);
-    if(readfd1 > maxfd)
-      maxfd = readfd1;
-  }
-
-  FD_ZERO(&fds_write);
-  if(writefd != CURL_SOCKET_BAD) {
-    VERIFY_SOCK(writefd);
-    FD_SET(writefd, &fds_write);
-    FD_SET(writefd, &fds_err);
-    if(writefd > maxfd)
-      maxfd = writefd;
-  }
-
-  /* We know that we have at least one bit set in at least two fd_sets in
-     this case, but we may have no bits set in either fds_read or fd_write,
-     so check for that and handle it.  Luckily, with WinSock, we can _also_
-     ask how many bits are set on an fd_set.
-
-     Note also that WinSock ignores the first argument, so we don't worry
-     about the fact that maxfd is computed incorrectly with WinSock (since
-     curl_socket_t is unsigned in such cases and thus -1 is the largest
-     value).
-  */
-  r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
-
-  if(r < 0)
-    return -1;
-  if(r == 0)
-    return 0;
-
-  ret = 0;
-  if(readfd0 != CURL_SOCKET_BAD) {
-    if(FD_ISSET(readfd0, &fds_read))
-      ret |= CURL_CSELECT_IN;
-    if(FD_ISSET(readfd0, &fds_err))
-      ret |= CURL_CSELECT_ERR;
-  }
-  if(readfd1 != CURL_SOCKET_BAD) {
-    if(FD_ISSET(readfd1, &fds_read))
-      ret |= CURL_CSELECT_IN2;
-    if(FD_ISSET(readfd1, &fds_err))
-      ret |= CURL_CSELECT_ERR;
-  }
-  if(writefd != CURL_SOCKET_BAD) {
-    if(FD_ISSET(writefd, &fds_write))
-      ret |= CURL_CSELECT_OUT;
-    if(FD_ISSET(writefd, &fds_err))
-      ret |= CURL_CSELECT_ERR;
+      r |= CURL_CSELECT_OUT;
+    if(pfd[num].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL))
+      r |= CURL_CSELECT_ERR;
   }
 
-  return ret;
-
-#endif  /* HAVE_POLL_FINE */
-
+  return r;
 }
 
 /*
@@ -431,8 +347,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
   }
   if(fds_none) {
     /* no sockets, just wait */
-    r = Curl_wait_ms(timeout_ms);
-    return r;
+    return Curl_wait_ms(timeout_ms);
   }
 
   /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
@@ -454,11 +369,8 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
   else
     pending_ms = 0;
   r = poll(ufds, nfds, pending_ms);
-
-  if(r < 0)
-    return -1;
-  if(r == 0)
-    return 0;
+  if(r <= 0)
+    return r;
 
   for(i = 0; i < nfds; i++) {
     if(ufds[i].fd == CURL_SOCKET_BAD)
@@ -466,7 +378,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
     if(ufds[i].revents & POLLHUP)
       ufds[i].revents |= POLLIN;
     if(ufds[i].revents & POLLERR)
-      ufds[i].revents |= (POLLIN|POLLOUT);
+      ufds[i].revents |= POLLIN|POLLOUT;
   }
 
 #else  /* HAVE_POLL_FINE */
@@ -482,7 +394,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
       continue;
     VERIFY_SOCK(ufds[i].fd);
     if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
-                          POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
+                         POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
       if(ufds[i].fd > maxfd)
         maxfd = ufds[i].fd;
       if(ufds[i].events & (POLLRDNORM|POLLIN))
@@ -494,24 +406,39 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms)
     }
   }
 
+  /*
+     Note also that WinSock ignores the first argument, so we don't worry
+     about the fact that maxfd is computed incorrectly with WinSock (since
+     curl_socket_t is unsigned in such cases and thus -1 is the largest
+     value).
+  */
   r = Curl_select(maxfd, &fds_read, &fds_write, &fds_err, timeout_ms);
-
-  if(r < 0)
-    return -1;
-  if(r == 0)
-    return 0;
+  if(r <= 0)
+    return r;
 
   r = 0;
   for(i = 0; i < nfds; i++) {
     ufds[i].revents = 0;
     if(ufds[i].fd == CURL_SOCKET_BAD)
       continue;
-    if(FD_ISSET(ufds[i].fd, &fds_read))
-      ufds[i].revents |= POLLIN;
-    if(FD_ISSET(ufds[i].fd, &fds_write))
-      ufds[i].revents |= POLLOUT;
-    if(FD_ISSET(ufds[i].fd, &fds_err))
-      ufds[i].revents |= POLLPRI;
+    if(FD_ISSET(ufds[i].fd, &fds_read)) {
+      if(ufds[i].events & POLLRDNORM)
+        ufds[i].revents |= POLLRDNORM;
+      if(ufds[i].events & POLLIN)
+        ufds[i].revents |= POLLIN;
+    }
+    if(FD_ISSET(ufds[i].fd, &fds_write)) {
+      if(ufds[i].events & POLLWRNORM)
+        ufds[i].revents |= POLLWRNORM;
+      if(ufds[i].events & POLLOUT)
+        ufds[i].revents |= POLLOUT;
+    }
+    if(FD_ISSET(ufds[i].fd, &fds_err)) {
+      if(ufds[i].events & POLLRDBAND)
+        ufds[i].revents |= POLLRDBAND;
+      if(ufds[i].events & POLLPRI)
+        ufds[i].revents |= POLLPRI;
+    }
     if(ufds[i].revents != 0)
       r++;
   }
diff --git a/lib/select.h b/lib/select.h
index 95181f4..1350950 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -94,12 +94,23 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
                        fd_set* excepts, struct timeval *tv);
 #endif
 
-/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
+/* TPF sockets are not in range [0..FD_SETSIZE-1], which
    unfortunately makes it impossible for us to easily check if they're valid
+
+   With Winsock the valid range is [0..INVALID_SOCKET-1] according to
+   https://docs.microsoft.com/en-us/windows/win32/winsock/socket-data-type-2
 */
-#if defined(USE_WINSOCK) || defined(TPF)
+#if defined(TPF)
 #define VALID_SOCK(x) 1
 #define VERIFY_SOCK(x) Curl_nop_stmt
+#elif defined(USE_WINSOCK)
+#define VALID_SOCK(s) ((s) < INVALID_SOCKET)
+#define VERIFY_SOCK(x) do { \
+  if(!VALID_SOCK(x)) { \
+    SET_SOCKERRNO(WSAEINVAL); \
+    return -1; \
+  } \
+} while(0)
 #else
 #define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
 #define VERIFY_SOCK(x) do { \
diff --git a/lib/sendf.c b/lib/sendf.c
index 6943fa8..04cc725 100644
--- a/lib/sendf.c
+++ b/lib/sendf.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -28,6 +28,8 @@
 
 #ifdef HAVE_LINUX_TCP_H
 #include <linux/tcp.h>
+#elif defined(HAVE_NETINET_TCP_H)
+#include <netinet/tcp.h>
 #endif
 
 #include <curl/curl.h>
@@ -140,7 +142,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
          psnd->recv_size > psnd->recv_processed;
 }
 
-static void pre_receive_plain(struct connectdata *conn, int num)
+static CURLcode pre_receive_plain(struct connectdata *conn, int num)
 {
   const curl_socket_t sockfd = conn->sock[num];
   struct postponed_data * const psnd = &(conn->postponed[num]);
@@ -161,6 +163,8 @@ static void pre_receive_plain(struct connectdata *conn, int num)
         /* Use buffer double default size for intermediate buffer */
         psnd->allocated_size = 2 * conn->data->set.buffer_size;
         psnd->buffer = malloc(psnd->allocated_size);
+        if(!psnd->buffer)
+          return CURLE_OUT_OF_MEMORY;
         psnd->recv_size = 0;
         psnd->recv_processed = 0;
 #ifdef DEBUGBUILD
@@ -180,6 +184,7 @@ static void pre_receive_plain(struct connectdata *conn, int num)
         psnd->allocated_size = 0;
     }
   }
+  return CURLE_OK;
 }
 
 static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
@@ -225,7 +230,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
   (void)sockindex;
   return false;
 }
-#define pre_receive_plain(c,n) do {} while(0)
+#define pre_receive_plain(c,n) CURLE_OK
 #define get_pre_recved(c,n,b,l) 0
 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
 
@@ -274,61 +279,12 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
       strcpy(data->set.errorbuffer, error);
       data->state.errorbuf = TRUE; /* wrote error string */
     }
-    if(data->set.verbose) {
-      error[len] = '\n';
-      error[++len] = '\0';
-      Curl_debug(data, CURLINFO_TEXT, error, len);
-    }
+    error[len++] = '\n';
+    Curl_debug(data, CURLINFO_TEXT, error, len);
     va_end(ap);
   }
 }
 
-/* Curl_sendf() sends formatted data to the server */
-CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
-                    const char *fmt, ...)
-{
-  struct Curl_easy *data = conn->data;
-  ssize_t bytes_written;
-  size_t write_len;
-  CURLcode result = CURLE_OK;
-  char *s;
-  char *sptr;
-  va_list ap;
-  va_start(ap, fmt);
-  s = vaprintf(fmt, ap); /* returns an allocated string */
-  va_end(ap);
-  if(!s)
-    return CURLE_OUT_OF_MEMORY; /* failure */
-
-  bytes_written = 0;
-  write_len = strlen(s);
-  sptr = s;
-
-  for(;;) {
-    /* Write the buffer to the socket */
-    result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
-
-    if(result)
-      break;
-
-    if(data->set.verbose)
-      Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
-
-    if((size_t)bytes_written != write_len) {
-      /* if not all was written at once, we must advance the pointer, decrease
-         the size left and try again! */
-      write_len -= bytes_written;
-      sptr += bytes_written;
-    }
-    else
-      break;
-  }
-
-  free(s); /* free the output string */
-
-  return result;
-}
-
 /*
  * Curl_write() is an internal write function that sends data to the
  * server. Works with plain sockets, SCP, SSL or kerberos.
@@ -379,7 +335,10 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
      To avoid lossage of received data, recv() must be
      performed before every send() if any incoming data is
      available. */
-  pre_receive_plain(conn, num);
+  if(pre_receive_plain(conn, num)) {
+    *code = CURLE_OUT_OF_MEMORY;
+    return -1;
+  }
 
 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
   if(conn->bits.tcp_fastopen) {
@@ -733,72 +692,74 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
 int Curl_debug(struct Curl_easy *data, curl_infotype type,
                char *ptr, size_t size)
 {
-  static const char s_infotype[CURLINFO_END][3] = {
-    "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
   int rc = 0;
+  if(data->set.verbose) {
+    static const char s_infotype[CURLINFO_END][3] = {
+      "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
 
 #ifdef CURL_DOES_CONVERSIONS
-  char *buf = NULL;
-  size_t conv_size = 0;
-
-  switch(type) {
-  case CURLINFO_HEADER_OUT:
-    buf = Curl_memdup(ptr, size);
-    if(!buf)
-      return 1;
-    conv_size = size;
-
-    /* Special processing is needed for this block if it
-     * contains both headers and data (separated by CRLFCRLF).
-     * We want to convert just the headers, leaving the data as-is.
-     */
-    if(size > 4) {
-      size_t i;
-      for(i = 0; i < size-4; i++) {
-        if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
-          /* convert everything through this CRLFCRLF but no further */
-          conv_size = i + 4;
-          break;
+    char *buf = NULL;
+    size_t conv_size = 0;
+
+    switch(type) {
+    case CURLINFO_HEADER_OUT:
+      buf = Curl_memdup(ptr, size);
+      if(!buf)
+        return 1;
+      conv_size = size;
+
+      /* Special processing is needed for this block if it
+       * contains both headers and data (separated by CRLFCRLF).
+       * We want to convert just the headers, leaving the data as-is.
+       */
+      if(size > 4) {
+        size_t i;
+        for(i = 0; i < size-4; i++) {
+          if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
+            /* convert everything through this CRLFCRLF but no further */
+            conv_size = i + 4;
+            break;
+          }
         }
       }
-    }
 
-    Curl_convert_from_network(data, buf, conv_size);
-    /* Curl_convert_from_network calls failf if unsuccessful */
-    /* we might as well continue even if it fails...   */
-    ptr = buf; /* switch pointer to use my buffer instead */
-    break;
-  default:
-    /* leave everything else as-is */
-    break;
-  }
+      Curl_convert_from_network(data, buf, conv_size);
+      /* Curl_convert_from_network calls failf if unsuccessful */
+      /* we might as well continue even if it fails...   */
+      ptr = buf; /* switch pointer to use my buffer instead */
+      break;
+    default:
+      /* leave everything else as-is */
+      break;
+    }
 #endif /* CURL_DOES_CONVERSIONS */
 
-  if(data->set.fdebug) {
-    Curl_set_in_callback(data, true);
-    rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
-    Curl_set_in_callback(data, false);
-  }
-  else {
-    switch(type) {
-    case CURLINFO_TEXT:
-    case CURLINFO_HEADER_OUT:
-    case CURLINFO_HEADER_IN:
-      fwrite(s_infotype[type], 2, 1, data->set.err);
-      fwrite(ptr, size, 1, data->set.err);
+    if(data->set.fdebug) {
+      Curl_set_in_callback(data, true);
+      rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
+      Curl_set_in_callback(data, false);
+    }
+    else {
+      switch(type) {
+      case CURLINFO_TEXT:
+      case CURLINFO_HEADER_OUT:
+      case CURLINFO_HEADER_IN:
+        fwrite(s_infotype[type], 2, 1, data->set.err);
+        fwrite(ptr, size, 1, data->set.err);
 #ifdef CURL_DOES_CONVERSIONS
-      if(size != conv_size) {
-        /* we had untranslated data so we need an explicit newline */
-        fwrite("\n", 1, 1, data->set.err);
-      }
+        if(size != conv_size) {
+          /* we had untranslated data so we need an explicit newline */
+          fwrite("\n", 1, 1, data->set.err);
+        }
 #endif
-      break;
-    default: /* nada */
-      break;
+        break;
+      default: /* nada */
+        break;
+      }
     }
-  }
 #ifdef CURL_DOES_CONVERSIONS
-  free(buf);
+    free(buf);
 #endif
+  }
   return rc;
 }
diff --git a/lib/sendf.h b/lib/sendf.h
index c68b017..c7e67c7 100644
--- a/lib/sendf.h
+++ b/lib/sendf.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -24,8 +24,6 @@
 
 #include "curl_setup.h"
 
-CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
-                    const char *fmt, ...);
 void Curl_infof(struct Curl_easy *, const char *fmt, ...);
 void Curl_failf(struct Curl_easy *, const char *fmt, ...);
 
diff --git a/lib/setopt.c b/lib/setopt.c
index d621335..58956c1 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -30,6 +30,8 @@
 
 #ifdef HAVE_LINUX_TCP_H
 #include <linux/tcp.h>
+#elif defined(HAVE_NETINET_TCP_H)
+#include <netinet/tcp.h>
 #endif
 
 #include "urldata.h"
@@ -45,6 +47,7 @@
 #include "setopt.h"
 #include "multiif.h"
 #include "altsvc.h"
+#include "hsts.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -430,104 +433,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
       primary->version_max = version_max;
     }
 #else
-    result = CURLE_UNKNOWN_OPTION;
+    result = CURLE_NOT_BUILT_IN;
 #endif
     break;
 
-#ifndef CURL_DISABLE_HTTP
-  case CURLOPT_AUTOREFERER:
-    /*
-     * Switch on automatic referer that gets set if curl follows locations.
-     */
-    data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
-    break;
-
-  case CURLOPT_ACCEPT_ENCODING:
-    /*
-     * String to use at the value of Accept-Encoding header.
-     *
-     * If the encoding is set to "" we use an Accept-Encoding header that
-     * encompasses all the encodings we support.
-     * If the encoding is set to NULL we don't send an Accept-Encoding header
-     * and ignore an received Content-Encoding header.
-     *
-     */
-    argptr = va_arg(param, char *);
-    if(argptr && !*argptr) {
-      argptr = Curl_all_content_encodings();
-      if(!argptr)
-        result = CURLE_OUT_OF_MEMORY;
-      else {
-        result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
-        free(argptr);
-      }
-    }
-    else
-      result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
-    break;
-
-  case CURLOPT_TRANSFER_ENCODING:
-    data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
-      TRUE : FALSE;
-    break;
-
-  case CURLOPT_FOLLOWLOCATION:
-    /*
-     * Follow Location: header hints on a HTTP-server.
-     */
-    data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
-    break;
-
-  case CURLOPT_UNRESTRICTED_AUTH:
-    /*
-     * Send authentication (user+password) when following locations, even when
-     * hostname changed.
-     */
-    data->set.allow_auth_to_other_hosts =
-      (0 != va_arg(param, long)) ? TRUE : FALSE;
-    break;
-
-  case CURLOPT_MAXREDIRS:
-    /*
-     * The maximum amount of hops you allow curl to follow Location:
-     * headers. This should mostly be used to detect never-ending loops.
-     */
-    arg = va_arg(param, long);
-    if(arg < -1)
-      return CURLE_BAD_FUNCTION_ARGUMENT;
-    data->set.maxredirs = arg;
-    break;
-
-  case CURLOPT_POSTREDIR:
-    /*
-     * Set the behaviour of POST when redirecting
-     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
-     * CURL_REDIR_POST_301 - POST is kept as POST after 301
-     * CURL_REDIR_POST_302 - POST is kept as POST after 302
-     * CURL_REDIR_POST_303 - POST is kept as POST after 303
-     * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
-     * other - POST is kept as POST after 301 and 302
-     */
-    arg = va_arg(param, long);
-    if(arg < CURL_REDIR_GET_ALL)
-      /* no return error on too high numbers since the bitmask could be
-         extended in a future */
-      return CURLE_BAD_FUNCTION_ARGUMENT;
-    data->set.keep_post = arg & CURL_REDIR_POST_ALL;
-    break;
-
-  case CURLOPT_POST:
-    /* Does this option serve a purpose anymore? Yes it does, when
-       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
-       callback! */
-    if(va_arg(param, long)) {
-      data->set.method = HTTPREQ_POST;
-      data->set.opt_no_body = FALSE; /* this is implied */
-    }
-    else
-      data->set.method = HTTPREQ_GET;
-    break;
-
+    /* MQTT "borrows" some of the HTTP options */
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT)
   case CURLOPT_COPYPOSTFIELDS:
     /*
      * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
@@ -622,6 +533,100 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
 
     data->set.postfieldsize = bigsize;
     break;
+#endif
+#ifndef CURL_DISABLE_HTTP
+  case CURLOPT_AUTOREFERER:
+    /*
+     * Switch on automatic referer that gets set if curl follows locations.
+     */
+    data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_ACCEPT_ENCODING:
+    /*
+     * String to use at the value of Accept-Encoding header.
+     *
+     * If the encoding is set to "" we use an Accept-Encoding header that
+     * encompasses all the encodings we support.
+     * If the encoding is set to NULL we don't send an Accept-Encoding header
+     * and ignore an received Content-Encoding header.
+     *
+     */
+    argptr = va_arg(param, char *);
+    if(argptr && !*argptr) {
+      argptr = Curl_all_content_encodings();
+      if(!argptr)
+        result = CURLE_OUT_OF_MEMORY;
+      else {
+        result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
+        free(argptr);
+      }
+    }
+    else
+      result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
+    break;
+
+  case CURLOPT_TRANSFER_ENCODING:
+    data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+    break;
+
+  case CURLOPT_FOLLOWLOCATION:
+    /*
+     * Follow Location: header hints on a HTTP-server.
+     */
+    data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_UNRESTRICTED_AUTH:
+    /*
+     * Send authentication (user+password) when following locations, even when
+     * hostname changed.
+     */
+    data->set.allow_auth_to_other_hosts =
+      (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_MAXREDIRS:
+    /*
+     * The maximum amount of hops you allow curl to follow Location:
+     * headers. This should mostly be used to detect never-ending loops.
+     */
+    arg = va_arg(param, long);
+    if(arg < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.maxredirs = arg;
+    break;
+
+  case CURLOPT_POSTREDIR:
+    /*
+     * Set the behaviour of POST when redirecting
+     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
+     * CURL_REDIR_POST_301 - POST is kept as POST after 301
+     * CURL_REDIR_POST_302 - POST is kept as POST after 302
+     * CURL_REDIR_POST_303 - POST is kept as POST after 303
+     * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
+     * other - POST is kept as POST after 301 and 302
+     */
+    arg = va_arg(param, long);
+    if(arg < CURL_REDIR_GET_ALL)
+      /* no return error on too high numbers since the bitmask could be
+         extended in a future */
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.keep_post = arg & CURL_REDIR_POST_ALL;
+    break;
+
+  case CURLOPT_POST:
+    /* Does this option serve a purpose anymore? Yes it does, when
+       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
+       callback! */
+    if(va_arg(param, long)) {
+      data->set.method = HTTPREQ_POST;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    else
+      data->set.method = HTTPREQ_GET;
+    break;
 
   case CURLOPT_HTTPPOST:
     /*
@@ -720,6 +725,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     argptr = (char *)va_arg(param, void *);
     if(argptr) {
       struct curl_slist *cl;
+      /* general protection against mistakes and abuse */
+      if(strlen(argptr) > CURL_MAX_INPUT_LENGTH)
+        return CURLE_BAD_FUNCTION_ARGUMENT;
       /* append the cookie file name to the list of file names, and deal with
          them later */
       cl = curl_slist_append(data->change.cookielist, argptr);
@@ -804,6 +812,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
         /* if cookie engine was not running, activate it */
         data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
 
+      /* general protection against mistakes and abuse */
+      if(strlen(argptr) > CURL_MAX_INPUT_LENGTH)
+        return CURLE_BAD_FUNCTION_ARGUMENT;
       argptr = strdup(argptr);
       if(!argptr || !data->cookies) {
         result = CURLE_OUT_OF_MEMORY;
@@ -1069,7 +1080,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
       break;
     default:
       /* reserve other values for future use */
-      result = CURLE_UNKNOWN_OPTION;
+      result = CURLE_BAD_FUNCTION_ARGUMENT;
       break;
     }
     break;
@@ -1222,21 +1233,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
      * An FTP/SFTP option that modifies an upload to create missing
      * directories on the server.
      */
-    switch(va_arg(param, long)) {
-    case 0:
-      data->set.ftp_create_missing_dirs = 0;
-      break;
-    case 1:
-      data->set.ftp_create_missing_dirs = 1;
-      break;
-    case 2:
-      data->set.ftp_create_missing_dirs = 2;
-      break;
-    default:
-      /* reserve other values for future use */
-      result = CURLE_UNKNOWN_OPTION;
-      break;
-    }
+    arg = va_arg(param, long);
+    /* reserve other values for future use */
+    if((arg < CURLFTP_CREATE_DIR_NONE) ||
+       (arg > CURLFTP_CREATE_DIR_RETRY))
+      result = CURLE_BAD_FUNCTION_ARGUMENT;
+    else
+      data->set.ftp_create_missing_dirs = (int)arg;
     break;
   case CURLOPT_READDATA:
     /*
@@ -2075,6 +2078,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
      * The application kindly asks for a differently sized receive buffer.
      * If it seems reasonable, we'll use it.
      */
+    if(data->state.buffer)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+
     arg = va_arg(param, long);
 
     if(arg > READBUFFER_MAX)
@@ -2084,18 +2090,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     else if(arg < READBUFFER_MIN)
       arg = READBUFFER_MIN;
 
-    /* Resize if new size */
-    if((arg != data->set.buffer_size) && data->state.buffer) {
-      char *newbuff = realloc(data->state.buffer, arg + 1);
-      if(!newbuff) {
-        DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
-        result = CURLE_OUT_OF_MEMORY;
-      }
-      else
-        data->state.buffer = newbuff;
-    }
     data->set.buffer_size = arg;
-
     break;
 
   case CURLOPT_UPLOAD_BUFFERSIZE:
@@ -2243,6 +2238,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     break;
 #endif
 
+  case CURLOPT_SSL_EC_CURVES:
+    /*
+     * Set accepted curves in SSL connection setup.
+     * Specify colon-delimited list of curve algorithm names.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_EC_CURVES],
+                            va_arg(param, char *));
+    break;
 #endif
   case CURLOPT_IPRESOLVE:
     arg = va_arg(param, long);
@@ -2513,9 +2516,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
      * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
      * Would this be better if the RTSPREQ_* were just moved into here?
      */
-    long curl_rtspreq = va_arg(param, long);
+    long in_rtspreq = va_arg(param, long);
     Curl_RtspReq rtspreq = RTSPREQ_NONE;
-    switch(curl_rtspreq) {
+    switch(in_rtspreq) {
     case CURL_RTSPREQ_OPTIONS:
       rtspreq = RTSPREQ_OPTIONS;
       break;
@@ -2839,7 +2842,46 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     data->set.trailer_data = va_arg(param, void *);
 #endif
     break;
-#ifdef USE_ALTSVC
+#ifdef USE_HSTS
+  case CURLOPT_HSTSREADFUNCTION:
+    data->set.hsts_read = va_arg(param, curl_hstsread_callback);
+    break;
+  case CURLOPT_HSTSREADDATA:
+    data->set.hsts_read_userp = va_arg(param, void *);
+    break;
+  case CURLOPT_HSTSWRITEFUNCTION:
+    data->set.hsts_write = va_arg(param, curl_hstswrite_callback);
+    break;
+  case CURLOPT_HSTSWRITEDATA:
+    data->set.hsts_write_userp = va_arg(param, void *);
+    break;
+  case CURLOPT_HSTS:
+    if(!data->hsts) {
+      data->hsts = Curl_hsts_init();
+      if(!data->hsts)
+        return CURLE_OUT_OF_MEMORY;
+    }
+    argptr = va_arg(param, char *);
+    result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr);
+    if(result)
+      return result;
+    if(argptr)
+      (void)Curl_hsts_loadfile(data, data->hsts, argptr);
+    break;
+  case CURLOPT_HSTS_CTRL:
+    arg = va_arg(param, long);
+    if(arg & CURLHSTS_ENABLE) {
+      if(!data->hsts) {
+        data->hsts = Curl_hsts_init();
+        if(!data->hsts)
+          return CURLE_OUT_OF_MEMORY;
+      }
+    }
+    else
+      Curl_hsts_cleanup(&data->hsts);
+    break;
+#endif
+#ifndef CURL_DISABLE_ALTSVC
   case CURLOPT_ALTSVC:
     if(!data->asi) {
       data->asi = Curl_altsvc_init();
diff --git a/lib/setopt.h b/lib/setopt.h
index 5fc4368..affbfd9 100644
--- a/lib/setopt.h
+++ b/lib/setopt.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/setup-os400.h b/lib/setup-os400.h
index b693cb3..8c97371 100644
--- a/lib/setup-os400.h
+++ b/lib/setup-os400.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/setup-vms.h b/lib/setup-vms.h
index 0e39c9f..ba75dc2 100644
--- a/lib/setup-vms.h
+++ b/lib/setup-vms.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/setup-win32.h b/lib/setup-win32.h
index 45b5847..c35dec8 100644
--- a/lib/setup-win32.h
+++ b/lib/setup-win32.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -60,7 +60,6 @@
 
 /*
  * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
- * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
  * undefine USE_WINSOCK.
  */
 
@@ -70,7 +69,7 @@
 #  define USE_WINSOCK 2
 #else
 #  ifdef HAVE_WINSOCK_H
-#    define USE_WINSOCK 1
+#    error "WinSock version 1 is no longer supported, version 2 is required!"
 #  endif
 #endif
 
diff --git a/lib/sha256.c b/lib/sha256.c
index ee5d273..910d7ae 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/share.c b/lib/share.c
index a2d8960..5ce9830 100644
--- a/lib/share.c
+++ b/lib/share.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -92,7 +92,7 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
       if(!share->sslsession) {
         share->max_ssl_sessions = 8;
         share->sslsession = calloc(share->max_ssl_sessions,
-                                   sizeof(struct curl_ssl_session));
+                                   sizeof(struct Curl_ssl_session));
         share->sessionage = 0;
         if(!share->sslsession)
           res = CURLSHE_NOMEM;
diff --git a/lib/share.h b/lib/share.h
index a7dea41..01aa9cd 100644
--- a/lib/share.h
+++ b/lib/share.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -46,7 +46,7 @@ struct Curl_share {
   curl_unlock_function unlockfunc;
   void *clientdata;
   struct conncache conn_cache;
-  struct curl_hash hostcache;
+  struct Curl_hash hostcache;
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
   struct CookieInfo *cookies;
 #endif
@@ -54,7 +54,7 @@ struct Curl_share {
   struct PslCache psl;
 #endif
 
-  struct curl_ssl_session *sslsession;
+  struct Curl_ssl_session *sslsession;
   size_t max_ssl_sessions;
   long sessionage;
 };
diff --git a/lib/sigpipe.h b/lib/sigpipe.h
index 3960a13..430cfc6 100644
--- a/lib/sigpipe.h
+++ b/lib/sigpipe.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/slist.c b/lib/slist.c
index d27fbe1..907c203 100644
--- a/lib/slist.c
+++ b/lib/slist.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/slist.h b/lib/slist.h
index 799b3c0..3114259 100644
--- a/lib/slist.h
+++ b/lib/slist.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/smb.c b/lib/smb.c
index d493adc..dd914a0 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -23,11 +23,9 @@
 
 #include "curl_setup.h"
 
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) &&  \
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) &&  \
   (CURL_SIZEOF_CURL_OFF_T > 4)
 
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
 #define BUILDING_CURL_SMB_C
 
 #ifdef HAVE_PROCESS_H
@@ -88,6 +86,7 @@ const struct Curl_handler Curl_handler_smb = {
   ZERO_NULL,                            /* connection_check */
   PORT_SMB,                             /* defport */
   CURLPROTO_SMB,                        /* protocol */
+  CURLPROTO_SMB,                        /* family */
   PROTOPT_NONE                          /* flags */
 };
 
@@ -113,6 +112,7 @@ const struct Curl_handler Curl_handler_smbs = {
   ZERO_NULL,                            /* connection_check */
   PORT_SMBS,                            /* defport */
   CURLPROTO_SMBS,                       /* protocol */
+  CURLPROTO_SMB,                        /* family */
   PROTOPT_SSL                           /* flags */
 };
 #endif
@@ -204,7 +204,7 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
 static void request_state(struct connectdata *conn,
                           enum smb_req_state newstate)
 {
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
   /* For debug purposes */
   static const char * const names[] = {
@@ -234,7 +234,7 @@ static CURLcode smb_setup_connection(struct connectdata *conn)
   struct smb_request *req;
 
   /* Initialize the request state */
-  conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
+  conn->data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
   if(!req)
     return CURLE_OUT_OF_MEMORY;
 
@@ -342,7 +342,7 @@ static void smb_format_message(struct connectdata *conn, struct smb_header *h,
                                unsigned char cmd, size_t len)
 {
   struct smb_conn *smbc = &conn->proto.smbc;
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
   unsigned int pid;
 
   memset(h, 0, sizeof(*h));
@@ -505,7 +505,7 @@ static CURLcode smb_send_tree_connect(struct connectdata *conn)
 
 static CURLcode smb_send_open(struct connectdata *conn)
 {
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
   struct smb_nt_create msg;
   size_t byte_count;
 
@@ -535,7 +535,7 @@ static CURLcode smb_send_open(struct connectdata *conn)
 
 static CURLcode smb_send_close(struct connectdata *conn)
 {
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
   struct smb_close msg;
 
   memset(&msg, 0, sizeof(msg));
@@ -556,7 +556,7 @@ static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
 
 static CURLcode smb_send_read(struct connectdata *conn)
 {
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
   curl_off_t offset = conn->data->req.offset;
   struct smb_read msg;
 
@@ -575,7 +575,7 @@ static CURLcode smb_send_read(struct connectdata *conn)
 static CURLcode smb_send_write(struct connectdata *conn)
 {
   struct smb_write *msg;
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
   curl_off_t offset = conn->data->req.offset;
   curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
   CURLcode result = Curl_get_upload_buffer(conn->data);
@@ -738,7 +738,7 @@ static void get_posix_time(time_t *out, curl_off_t timestamp)
 
 static CURLcode smb_request_state(struct connectdata *conn, bool *done)
 {
-  struct smb_request *req = conn->data->req.protop;
+  struct smb_request *req = conn->data->req.p.smb;
   struct smb_header *h;
   struct smb_conn *smbc = &conn->proto.smbc;
   enum smb_req_state next_state = SMB_DONE;
@@ -923,7 +923,7 @@ static CURLcode smb_done(struct connectdata *conn, CURLcode status,
                          bool premature)
 {
   (void) premature;
-  Curl_safefree(conn->data->req.protop);
+  Curl_safefree(conn->data->req.p.smb);
   return status;
 }
 
@@ -957,7 +957,7 @@ static CURLcode smb_do(struct connectdata *conn, bool *done)
 static CURLcode smb_parse_url_path(struct connectdata *conn)
 {
   struct Curl_easy *data = conn->data;
-  struct smb_request *req = data->req.protop;
+  struct smb_request *req = data->req.p.smb;
   struct smb_conn *smbc = &conn->proto.smbc;
   char *path;
   char *slash;
@@ -996,6 +996,5 @@ static CURLcode smb_parse_url_path(struct connectdata *conn)
   return CURLE_OK;
 }
 
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE &&
+          CURL_SIZEOF_CURL_OFF_T > 4 */
diff --git a/lib/smb.h b/lib/smb.h
index 136a89c..907cf0c 100644
--- a/lib/smb.h
+++ b/lib/smb.h
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -243,16 +243,13 @@ struct smb_tree_disconnect {
 
 #endif /* BUILDING_CURL_SMB_C */
 
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
     (CURL_SIZEOF_CURL_OFF_T > 4)
 
-#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
-
 extern const struct Curl_handler Curl_handler_smb;
 extern const struct Curl_handler Curl_handler_smbs;
 
-#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
-
-#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE &&
+          CURL_SIZEOF_CURL_OFF_T > 4 */
 
 #endif /* HEADER_CURL_SMB_H */
diff --git a/lib/smtp.c b/lib/smtp.c
index aea41bb..509d802 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -133,6 +133,7 @@ const struct Curl_handler Curl_handler_smtp = {
   ZERO_NULL,                        /* connection_check */
   PORT_SMTP,                        /* defport */
   CURLPROTO_SMTP,                   /* protocol */
+  CURLPROTO_SMTP,                   /* family */
   PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
   PROTOPT_URLOPTIONS
 };
@@ -160,6 +161,7 @@ const struct Curl_handler Curl_handler_smtps = {
   ZERO_NULL,                        /* connection_check */
   PORT_SMTPS,                       /* defport */
   CURLPROTO_SMTPS,                  /* protocol */
+  CURLPROTO_SMTP,                   /* family */
   PROTOPT_CLOSEACTION | PROTOPT_SSL
   | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
 };
@@ -484,7 +486,7 @@ static CURLcode smtp_perform_command(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
 
   if(smtp->rcpt) {
     /* We notify the server we are sending UTF-8 data if a) it supports the
@@ -697,7 +699,7 @@ static CURLcode smtp_perform_mail(struct connectdata *conn)
      any there do, as we need to correctly identify our support for SMTPUTF8
      in the envelope, as per RFC-6531 sect. 3.4 */
   if(conn->proto.smtpc.utf8_supported && !utf8) {
-    struct SMTP *smtp = data->req.protop;
+    struct SMTP *smtp = data->req.p.smtp;
     struct curl_slist *rcpt = smtp->rcpt;
 
     while(rcpt && !utf8) {
@@ -741,7 +743,7 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
   char *address = NULL;
   struct hostname host = { NULL, NULL, NULL, NULL };
 
@@ -989,7 +991,7 @@ static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
   char *line = data->state.buffer;
   size_t len = strlen(line);
 
@@ -1055,7 +1057,7 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
   bool is_smtp_err = FALSE;
   bool is_smtp_blocking_err = FALSE;
 
@@ -1278,7 +1280,7 @@ static CURLcode smtp_init(struct connectdata *conn)
   struct Curl_easy *data = conn->data;
   struct SMTP *smtp;
 
-  smtp = data->req.protop = calloc(sizeof(struct SMTP), 1);
+  smtp = data->req.p.smtp = calloc(sizeof(struct SMTP), 1);
   if(!smtp)
     result = CURLE_OUT_OF_MEMORY;
 
@@ -1322,6 +1324,7 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
   Curl_sasl_init(&smtpc->sasl, &saslsmtp);
 
   /* Initialise the pingpong layer */
+  Curl_pp_setup(pp);
   Curl_pp_init(pp);
 
   /* Parse the URL options */
@@ -1356,7 +1359,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
   struct pingpong *pp = &conn->proto.smtpc.pp;
   char *eob;
   ssize_t len;
@@ -1442,7 +1445,7 @@ static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
   /* This is SMTP and no proxy */
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
 
   DEBUGF(infof(conn->data, "DO phase starts\n"));
 
@@ -1550,7 +1553,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
 /* Call this when the DO phase has completed */
 static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
 {
-  struct SMTP *smtp = conn->data->req.protop;
+  struct SMTP *smtp = conn->data->req.p.smtp;
 
   (void)connected;
 
@@ -1703,7 +1706,7 @@ static CURLcode smtp_parse_custom_request(struct connectdata *conn)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
   const char *custom = data->set.str[STRING_CUSTOMREQUEST];
 
   /* URL decode the custom request */
@@ -1796,7 +1799,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
   ssize_t i;
   ssize_t si;
   struct Curl_easy *data = conn->data;
-  struct SMTP *smtp = data->req.protop;
+  struct SMTP *smtp = data->req.p.smtp;
   char *scratch = data->state.scratch;
   char *newscratch = NULL;
   char *oldscratch = NULL;
diff --git a/lib/smtp.h b/lib/smtp.h
index 164a175..c7c62ee 100644
--- a/lib/smtp.h
+++ b/lib/smtp.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/sockaddr.h b/lib/sockaddr.h
index b037ee0..84c08d9 100644
--- a/lib/sockaddr.h
+++ b/lib/sockaddr.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/socketpair.c b/lib/socketpair.c
index 1ec0d75..2c580ad 100644
--- a/lib/socketpair.c
+++ b/lib/socketpair.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -23,7 +23,7 @@
 #include "curl_setup.h"
 #include "socketpair.h"
 
-#ifndef HAVE_SOCKETPAIR
+#if !defined(HAVE_SOCKETPAIR) && !defined(CURL_DISABLE_SOCKETPAIR)
 #ifdef WIN32
 /*
  * This is a socketpair() implementation for Windows.
diff --git a/lib/socketpair.h b/lib/socketpair.h
index be9fb24..033a235 100644
--- a/lib/socketpair.h
+++ b/lib/socketpair.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/socks.c b/lib/socks.c
index 44783d0..a2d1e62 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -184,12 +184,12 @@ int Curl_SOCKS_getsock(struct connectdata *conn, curl_socket_t *sock,
 *   Set protocol4a=true for  "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
 *   Nonsupport "Identification Protocol (RFC1413)"
 */
-CURLcode Curl_SOCKS4(const char *proxy_user,
-                     const char *hostname,
-                     int remote_port,
-                     int sockindex,
-                     struct connectdata *conn,
-                     bool *done)
+CURLproxycode Curl_SOCKS4(const char *proxy_user,
+                          const char *hostname,
+                          int remote_port,
+                          int sockindex,
+                          struct connectdata *conn,
+                          bool *done)
 {
   const bool protocol4a =
     (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
@@ -237,11 +237,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
         Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
 
       if(rc == CURLRESOLV_ERROR)
-        return CURLE_COULDNT_RESOLVE_PROXY;
+        return CURLPX_RESOLVE_HOST;
       else if(rc == CURLRESOLV_PENDING) {
         sxstate(conn, CONNECT_RESOLVING);
         infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname);
-        return CURLE_OK;
+        return CURLPX_OK;
       }
       sxstate(conn, CONNECT_RESOLVED);
       goto CONNECT_RESOLVED;
@@ -265,8 +265,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
     }
     else {
       result = Curl_resolv_check(data->conn, &dns);
-      if(!dns)
-        return result;
+      if(!dns) {
+        if(result)
+          return CURLPX_RESOLVE_HOST;
+        return CURLPX_OK;
+      }
     }
     /* FALLTHROUGH */
   CONNECT_RESOLVED:
@@ -303,7 +306,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
     if(!hp) {
       failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
             hostname);
-      return CURLE_COULDNT_RESOLVE_HOST;
+      return CURLPX_RESOLVE_HOST;
     }
   }
     /* FALLTHROUGH */
@@ -316,8 +319,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
     if(proxy_user) {
       size_t plen = strlen(proxy_user);
       if(plen >= sizeof(sx->socksreq) - 8) {
-        failf(data, "Too long SOCKS proxy name, can't use!\n");
-        return CURLE_COULDNT_CONNECT;
+        failf(data, "Too long SOCKS proxy user name, can't use!\n");
+        return CURLPX_LONG_USER;
       }
       /* copy the proxy name WITH trailing zero */
       memcpy(socksreq + 8, proxy_user, plen + 1);
@@ -343,7 +346,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
           strcpy((char *)socksreq + packetsize, hostname);
         else {
           failf(data, "SOCKS4: too long host name");
-          return CURLE_COULDNT_CONNECT;
+          return CURLPX_LONG_HOSTNAME;
         }
         packetsize += hostnamelen;
       }
@@ -358,13 +361,13 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
                               sx->outstanding, &written);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Failed to send SOCKS4 connect request.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_SEND_CONNECT;
     }
     if(written != sx->outstanding) {
       /* not done, remain in state */
       sx->outstanding -= written;
       sx->outp += written;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
 
     /* done sending! */
@@ -380,18 +383,18 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "SOCKS4: Failed receiving connect request ack: %s",
             curl_easy_strerror(result));
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_RECV_CONNECT;
     }
     else if(!result && !actualread) {
       /* connection closed */
       failf(data, "connection to proxy closed");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_CLOSED;
     }
     else if(actualread != sx->outstanding) {
       /* remain in reading state */
       sx->outstanding -= actualread;
       sx->outp += actualread;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     sxstate(conn, CONNECT_DONE);
     break;
@@ -422,7 +425,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
   if(socksreq[0] != 0) {
     failf(data,
           "SOCKS4 reply has wrong version, version should be 0.");
-    return CURLE_COULDNT_CONNECT;
+    return CURLPX_BAD_VERSION;
   }
 
   /* Result */
@@ -438,7 +441,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
           (unsigned char)socksreq[6], (unsigned char)socksreq[7],
           (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
           (unsigned char)socksreq[1]);
-    return CURLE_COULDNT_CONNECT;
+    return CURLPX_REQUEST_FAILED;
   case 92:
     failf(data,
           "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
@@ -448,7 +451,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
           (unsigned char)socksreq[6], (unsigned char)socksreq[7],
           (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
           (unsigned char)socksreq[1]);
-    return CURLE_COULDNT_CONNECT;
+    return CURLPX_IDENTD;
   case 93:
     failf(data,
           "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
@@ -458,7 +461,7 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
           (unsigned char)socksreq[6], (unsigned char)socksreq[7],
           (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
           (unsigned char)socksreq[1]);
-    return CURLE_COULDNT_CONNECT;
+    return CURLPX_IDENTD_DIFFER;
   default:
     failf(data,
           "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
@@ -467,24 +470,24 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
           (unsigned char)socksreq[6], (unsigned char)socksreq[7],
           (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
           (unsigned char)socksreq[1]);
-    return CURLE_COULDNT_CONNECT;
+    return CURLPX_UNKNOWN_FAIL;
   }
 
   *done = TRUE;
-  return CURLE_OK; /* Proxy was successful! */
+  return CURLPX_OK; /* Proxy was successful! */
 }
 
 /*
  * This function logs in to a SOCKS5 proxy and sends the specifics to the final
  * destination server.
  */
-CURLcode Curl_SOCKS5(const char *proxy_user,
-                     const char *proxy_password,
-                     const char *hostname,
-                     int remote_port,
-                     int sockindex,
-                     struct connectdata *conn,
-                     bool *done)
+CURLproxycode Curl_SOCKS5(const char *proxy_user,
+                          const char *proxy_password,
+                          const char *hostname,
+                          int remote_port,
+                          int sockindex,
+                          struct connectdata *conn,
+                          bool *done)
 {
   /*
     According to the RFC1928, section "6.  Replies". This is what a SOCK5
@@ -561,13 +564,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
     result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Unable to send initial SOCKS5 request.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_SEND_CONNECT;
     }
     if(written != idx) {
       sxstate(conn, CONNECT_SOCKS_SEND);
       sx->outstanding = idx - written;
       sx->outp = &socksreq[written];
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     sxstate(conn, CONNECT_SOCKS_READ);
     goto CONNECT_SOCKS_READ_INIT;
@@ -576,13 +579,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                               sx->outstanding, &written);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Unable to send initial SOCKS5 request.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_SEND_CONNECT;
     }
     if(written != sx->outstanding) {
       /* not done, remain in state */
       sx->outstanding -= written;
       sx->outp += written;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     /* FALLTHROUGH */
   CONNECT_SOCKS_READ_INIT:
@@ -595,22 +598,22 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                              sx->outstanding, &actualread);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Unable to receive initial SOCKS5 response.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_RECV_CONNECT;
     }
     else if(!result && !actualread) {
       /* connection closed */
       failf(data, "Connection to proxy closed");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_CLOSED;
     }
     else if(actualread != sx->outstanding) {
       /* remain in reading state */
       sx->outstanding -= actualread;
       sx->outp += actualread;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     else if(socksreq[0] != 5) {
       failf(data, "Received invalid version in initial SOCKS5 response.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_BAD_VERSION;
     }
     else if(socksreq[1] == 0) {
       /* DONE! No authentication needed. Send request. */
@@ -628,7 +631,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       result = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
       if(result) {
         failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
-        return CURLE_COULDNT_CONNECT;
+        return CURLPX_GSSAPI;
       }
     }
 #endif
@@ -637,16 +640,16 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       if(!allow_gssapi && (socksreq[1] == 1)) {
         failf(data,
               "SOCKS5 GSSAPI per-message authentication is not supported.");
-        return CURLE_COULDNT_CONNECT;
+        return CURLPX_GSSAPI_PERMSG;
       }
       else if(socksreq[1] == 255) {
         failf(data, "No authentication method was acceptable.");
-        return CURLE_COULDNT_CONNECT;
+        return CURLPX_NO_AUTH;
       }
     }
     failf(data,
           "Undocumented SOCKS5 mode attempted to be used by server.");
-    return CURLE_COULDNT_CONNECT;
+    return CURLPX_UNKNOWN_MODE;
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
   case CONNECT_GSSAPI_INIT:
     /* GSSAPI stuff done non-blocking */
@@ -683,7 +686,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       /* the length must fit in a single byte */
       if(proxy_user_len >= 255) {
         failf(data, "Excessive user name length for proxy auth");
-        return CURLE_BAD_FUNCTION_ARGUMENT;
+        return CURLPX_LONG_USER;
       }
       memcpy(socksreq + len, proxy_user, proxy_user_len);
     }
@@ -693,7 +696,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       /* the length must fit in a single byte */
       if(proxy_password_len > 255) {
         failf(data, "Excessive password length for proxy auth");
-        return CURLE_BAD_FUNCTION_ARGUMENT;
+        return CURLPX_LONG_PASSWD;
       }
       memcpy(socksreq + len, proxy_password, proxy_password_len);
     }
@@ -708,13 +711,13 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                               sx->outstanding, &written);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Failed to send SOCKS5 sub-negotiation request.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_SEND_AUTH;
     }
     if(sx->outstanding != written) {
       /* remain in state */
       sx->outstanding -= written;
       sx->outp += written;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     sx->outp = socksreq;
     sx->outstanding = 2;
@@ -725,24 +728,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                              sx->outstanding, &actualread);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_RECV_AUTH;
     }
     else if(!result && !actualread) {
       /* connection closed */
       failf(data, "connection to proxy closed");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_CLOSED;
     }
     else if(actualread != sx->outstanding) {
       /* remain in state */
       sx->outstanding -= actualread;
       sx->outp += actualread;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     /* ignore the first (VER) byte */
     else if(socksreq[1] != 0) { /* status */
       failf(data, "User was rejected by the SOCKS5 server (%d %d).",
             socksreq[0], socksreq[1]);
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_USER_REJECTED;
     }
 
     /* Everything is good so far, user was authenticated! */
@@ -755,11 +758,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                                       FALSE, &dns);
 
       if(rc == CURLRESOLV_ERROR)
-        return CURLE_COULDNT_RESOLVE_HOST;
+        return CURLPX_RESOLVE_HOST;
 
       if(rc == CURLRESOLV_PENDING) {
         sxstate(conn, CONNECT_RESOLVING);
-        return CURLE_OK;
+        return CURLPX_OK;
       }
       sxstate(conn, CONNECT_RESOLVED);
       goto CONNECT_RESOLVED;
@@ -768,7 +771,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
 
   case CONNECT_RESOLVING:
     /* check if we have the name resolved by now */
-    dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
+    dns = Curl_fetch_addr(conn, hostname, remote_port);
 
     if(dns) {
 #ifdef CURLRES_ASYNCH
@@ -780,8 +783,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
 
     if(!dns) {
       result = Curl_resolv_check(data->conn, &dns);
-      if(!dns)
-        return result;
+      if(!dns) {
+        if(result)
+          return CURLPX_RESOLVE_HOST;
+        return CURLPX_OK;
+      }
     }
     /* FALLTHROUGH */
   CONNECT_RESOLVED:
@@ -793,7 +799,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
     if(!hp) {
       failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
             hostname);
-      return CURLE_COULDNT_RESOLVE_HOST;
+      return CURLPX_RESOLVE_HOST;
     }
 
     Curl_printable_address(hp, dest, sizeof(dest));
@@ -867,7 +873,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
     if(conn->socks5_gssapi_enctype) {
       failf(data, "SOCKS5 GSS-API protection not yet implemented.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_GSSAPI_PROTECTION;
     }
 #endif
     sx->outp = socksreq;
@@ -879,18 +885,18 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                               sx->outstanding, &written);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Failed to send SOCKS5 connect request.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_SEND_REQUEST;
     }
     if(sx->outstanding != written) {
       /* remain in state */
       sx->outstanding -= written;
       sx->outp += written;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
     if(conn->socks5_gssapi_enctype) {
       failf(data, "SOCKS5 GSS-API protection not yet implemented.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_GSSAPI_PROTECTION;
     }
 #endif
     sx->outstanding = 10; /* minimum packet size is 10 */
@@ -902,29 +908,46 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                              sx->outstanding, &actualread);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Failed to receive SOCKS5 connect request ack.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_RECV_REQACK;
     }
     else if(!result && !actualread) {
       /* connection closed */
       failf(data, "connection to proxy closed");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_CLOSED;
     }
     else if(actualread != sx->outstanding) {
       /* remain in state */
       sx->outstanding -= actualread;
       sx->outp += actualread;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
 
     if(socksreq[0] != 5) { /* version */
       failf(data,
             "SOCKS5 reply has wrong version, version should be 5.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_BAD_VERSION;
     }
     else if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+      CURLproxycode rc = CURLPX_REPLY_UNASSIGNED;
+      int code = socksreq[1];
       failf(data, "Can't complete SOCKS5 connection to %s. (%d)",
             hostname, (unsigned char)socksreq[1]);
-      return CURLE_COULDNT_CONNECT;
+      if(code < 9) {
+        /* RFC 1928 section 6 lists: */
+        static const CURLproxycode lookup[] = {
+          CURLPX_OK,
+          CURLPX_REPLY_GENERAL_SERVER_FAILURE,
+          CURLPX_REPLY_NOT_ALLOWED,
+          CURLPX_REPLY_NETWORK_UNREACHABLE,
+          CURLPX_REPLY_HOST_UNREACHABLE,
+          CURLPX_REPLY_CONNECTION_REFUSED,
+          CURLPX_REPLY_TTL_EXPIRED,
+          CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
+          CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
+        };
+        rc = lookup[code];
+      }
+      return rc;
     }
 
     /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
@@ -958,7 +981,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
     }
     else {
       failf(data, "SOCKS5 reply has wrong address type.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_BAD_ADDRESS_TYPE;
     }
 
     /* At this point we already read first 10 bytes */
@@ -984,25 +1007,25 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
                              sx->outstanding, &actualread);
     if(result && (CURLE_AGAIN != result)) {
       failf(data, "Failed to receive SOCKS5 connect request ack.");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_RECV_ADDRESS;
     }
     else if(!result && !actualread) {
       /* connection closed */
       failf(data, "connection to proxy closed");
-      return CURLE_COULDNT_CONNECT;
+      return CURLPX_CLOSED;
     }
     else if(actualread != sx->outstanding) {
       /* remain in state */
       sx->outstanding -= actualread;
       sx->outp += actualread;
-      return CURLE_OK;
+      return CURLPX_OK;
     }
     sxstate(conn, CONNECT_DONE);
   }
   infof(data, "SOCKS5 request granted.\n");
 
   *done = TRUE;
-  return CURLE_OK; /* Proxy was successful! */
+  return CURLPX_OK; /* Proxy was successful! */
 }
 
 #endif /* CURL_DISABLE_PROXY */
diff --git a/lib/socks.h b/lib/socks.h
index 64a7563..1fae58b 100644
--- a/lib/socks.h
+++ b/lib/socks.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -48,24 +48,24 @@ int Curl_SOCKS_getsock(struct connectdata *conn,
  * This function logs in to a SOCKS4(a) proxy and sends the specifics to the
  * final destination server.
  */
-CURLcode Curl_SOCKS4(const char *proxy_name,
-                     const char *hostname,
-                     int remote_port,
-                     int sockindex,
-                     struct connectdata *conn,
-                     bool *done);
+CURLproxycode Curl_SOCKS4(const char *proxy_name,
+                          const char *hostname,
+                          int remote_port,
+                          int sockindex,
+                          struct connectdata *conn,
+                          bool *done);
 
 /*
  * This function logs in to a SOCKS5 proxy and sends the specifics to the
  * final destination server.
  */
-CURLcode Curl_SOCKS5(const char *proxy_name,
-                     const char *proxy_password,
-                     const char *hostname,
-                     int remote_port,
-                     int sockindex,
-                     struct connectdata *conn,
-                     bool *done);
+CURLproxycode Curl_SOCKS5(const char *proxy_name,
+                          const char *proxy_password,
+                          const char *hostname,
+                          int remote_port,
+                          int sockindex,
+                          struct connectdata *conn,
+                          bool *done);
 
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 /*
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 2e36b99..a965796 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -493,7 +493,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
     gss_release_buffer(&gss_status, &gss_recv_token);
 
     if(gss_w_token.length != 1) {
-      failf(data, "Invalid GSS-API encryption response length (%d).",
+      failf(data, "Invalid GSS-API encryption response length (%zu).",
             gss_w_token.length);
       gss_release_buffer(&gss_status, &gss_w_token);
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
@@ -505,7 +505,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   }
   else {
     if(gss_recv_token.length != 1) {
-      failf(data, "Invalid GSS-API encryption response length (%d).",
+      failf(data, "Invalid GSS-API encryption response length (%zu).",
             gss_recv_token.length);
       gss_release_buffer(&gss_status, &gss_recv_token);
       gss_delete_sec_context(&gss_status, &gss_context, NULL);
diff --git a/lib/socks_sspi.c b/lib/socks_sspi.c
index 2f1fd36..b9ac2ad 100644
--- a/lib/socks_sspi.c
+++ b/lib/socks_sspi.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/speedcheck.c b/lib/speedcheck.c
index 3aeea91..2665a44 100644
--- a/lib/speedcheck.c
+++ b/lib/speedcheck.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/speedcheck.h b/lib/speedcheck.h
index 5c2dc9a..1d4c7bf 100644
--- a/lib/speedcheck.h
+++ b/lib/speedcheck.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/splay.c b/lib/splay.c
index 0f5fcd1..98baf5d 100644
--- a/lib/splay.c
+++ b/lib/splay.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1997 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -206,9 +206,9 @@ struct Curl_tree *Curl_splaygetbest(struct curltime i,
  *
  * @unittest: 1309
  */
-int Curl_splayremovebyaddr(struct Curl_tree *t,
-                           struct Curl_tree *removenode,
-                           struct Curl_tree **newroot)
+int Curl_splayremove(struct Curl_tree *t,
+                     struct Curl_tree *removenode,
+                     struct Curl_tree **newroot)
 {
   static const struct curltime KEY_NOTUSED = {
     (time_t)-1, (unsigned int)-1
diff --git a/lib/splay.h b/lib/splay.h
index 9292f34..eb9f65f 100644
--- a/lib/splay.h
+++ b/lib/splay.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1997 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1997 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -40,19 +40,13 @@ struct Curl_tree *Curl_splayinsert(struct curltime key,
                                    struct Curl_tree *t,
                                    struct Curl_tree *newnode);
 
-#if 0
-struct Curl_tree *Curl_splayremove(struct curltime key,
-                                   struct Curl_tree *t,
-                                   struct Curl_tree **removed);
-#endif
-
 struct Curl_tree *Curl_splaygetbest(struct curltime key,
                                     struct Curl_tree *t,
                                     struct Curl_tree **removed);
 
-int Curl_splayremovebyaddr(struct Curl_tree *t,
-                           struct Curl_tree *removenode,
-                           struct Curl_tree **newroot);
+int Curl_splayremove(struct Curl_tree *t,
+                     struct Curl_tree *removenode,
+                     struct Curl_tree **newroot);
 
 #define Curl_splaycomparekeys(i,j) ( ((i.tv_sec)  < (j.tv_sec)) ? -1 : \
                                    ( ((i.tv_sec)  > (j.tv_sec)) ?  1 : \
diff --git a/lib/strcase.c b/lib/strcase.c
index a309e35..955e3c7 100644
--- a/lib/strcase.c
+++ b/lib/strcase.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strcase.h b/lib/strcase.h
index cd4c419..10dc698 100644
--- a/lib/strcase.h
+++ b/lib/strcase.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strdup.c b/lib/strdup.c
index 7732802..9af47ea 100644
--- a/lib/strdup.c
+++ b/lib/strdup.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strdup.h b/lib/strdup.h
index ae3d5d0..0936956 100644
--- a/lib/strdup.h
+++ b/lib/strdup.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strerror.c b/lib/strerror.c
index 015e588..9b2fc26 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -320,6 +320,9 @@ curl_easy_strerror(CURLcode error)
   case CURLE_QUIC_CONNECT_ERROR:
     return "QUIC connection error";
 
+ case CURLE_PROXY:
+    return "proxy handshake error";
+
     /* error codes not used by current libcurl */
   case CURLE_OBSOLETE20:
   case CURLE_OBSOLETE24:
@@ -652,34 +655,27 @@ static const char *
 get_winapi_error(int err, char *buf, size_t buflen)
 {
   char *p;
+  wchar_t wbuf[256];
 
   if(!buflen)
     return NULL;
 
   *buf = '\0';
-
-#ifdef _WIN32_WCE
-  {
-    wchar_t wbuf[256];
-    wbuf[0] = L'\0';
-
-    if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM |
-                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
-                     LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
-      size_t written = wcstombs(buf, wbuf, buflen - 1);
-      if(written != (size_t)-1)
-        buf[written] = '\0';
-      else
-        *buf = '\0';
-    }
-  }
-#else
-  if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM |
-                      FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
-                     LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) {
-    *buf = '\0';
+  *wbuf = L'\0';
+
+  /* We return the local codepage version of the error string because if it is
+     output to the user's terminal it will likely be with functions which
+     expect the local codepage (eg fprintf, failf, infof).
+     FormatMessageW -> wcstombs is used for Windows CE compatibility. */
+  if(FormatMessageW((FORMAT_MESSAGE_FROM_SYSTEM |
+                     FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err,
+                    LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+    size_t written = wcstombs(buf, wbuf, buflen - 1);
+    if(written != (size_t)-1)
+      buf[written] = '\0';
+    else
+      *buf = '\0';
   }
-#endif
 
   /* Truncate multiple lines */
   p = strchr(buf, '\n');
@@ -785,7 +781,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen)
   }
 #else
   {
-    char *msg = strerror(err);
+    const char *msg = strerror(err);
     if(msg)
       strncpy(buf, msg, max);
     else
diff --git a/lib/strerror.h b/lib/strerror.h
index bae8f89..96a7e27 100644
--- a/lib/strerror.h
+++ b/lib/strerror.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtok.c b/lib/strtok.c
index ba6e025..d53e587 100644
--- a/lib/strtok.c
+++ b/lib/strtok.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtok.h b/lib/strtok.h
index e221fa6..831ef0c 100644
--- a/lib/strtok.h
+++ b/lib/strtok.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtoofft.c b/lib/strtoofft.c
index 96e3820..ac87cfc 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/strtoofft.h b/lib/strtoofft.h
index be19cd7..4d22ba3 100644
--- a/lib/strtoofft.h
+++ b/lib/strtoofft.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/system_win32.c b/lib/system_win32.c
index 2e59e03..b377da7 100644
--- a/lib/system_win32.c
+++ b/lib/system_win32.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -55,12 +55,7 @@ CURLcode Curl_win32_init(long flags)
     WSADATA wsaData;
     int res;
 
-#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
-#error IPV6_requires_winsock2
-#endif
-
-    wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
-
+    wVersionRequested = MAKEWORD(2, 2);
     res = WSAStartup(wVersionRequested, &wsaData);
 
     if(res != 0)
@@ -83,9 +78,9 @@ CURLcode Curl_win32_init(long flags)
       return CURLE_FAILED_INIT;
     }
     /* The Windows Sockets DLL is acceptable. Proceed. */
-  #elif defined(USE_LWIPSOCK)
+#elif defined(USE_LWIPSOCK)
     lwip_init();
-  #endif
+#endif
   } /* CURL_GLOBAL_WIN32 */
 
 #ifdef USE_WINDOWS_SSPI
diff --git a/lib/system_win32.h b/lib/system_win32.h
index 2547bda..69e0c81 100644
--- a/lib/system_win32.h
+++ b/lib/system_win32.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/telnet.c b/lib/telnet.c
index c3b58e5..8bf64a9 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -87,12 +87,6 @@
 #define printoption(a,b,c,d)  Curl_nop_stmt
 #endif
 
-#ifdef USE_WINSOCK
-typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void);
-typedef FARPROC WSOCK2_FUNC;
-static CURLcode check_wsock2(struct Curl_easy *data);
-#endif
-
 static
 CURLcode telrcv(struct connectdata *,
                 const unsigned char *inbuf, /* Data received from socket */
@@ -194,50 +188,11 @@ const struct Curl_handler Curl_handler_telnet = {
   ZERO_NULL,                            /* connection_check */
   PORT_TELNET,                          /* defport */
   CURLPROTO_TELNET,                     /* protocol */
+  CURLPROTO_TELNET,                     /* family */
   PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
 
-#ifdef USE_WINSOCK
-static CURLcode
-check_wsock2(struct Curl_easy *data)
-{
-  int err;
-  WORD wVersionRequested;
-  WSADATA wsaData;
-
-  DEBUGASSERT(data);
-
-  /* telnet requires at least WinSock 2.0 so ask for it. */
-  wVersionRequested = MAKEWORD(2, 0);
-
-  err = WSAStartup(wVersionRequested, &wsaData);
-
-  /* We must've called this once already, so this call */
-  /* should always succeed.  But, just in case... */
-  if(err != 0) {
-    failf(data,"WSAStartup failed (%d)",err);
-    return CURLE_FAILED_INIT;
-  }
-
-  /* We have to have a WSACleanup call for every successful */
-  /* WSAStartup call. */
-  WSACleanup();
-
-  /* Check that our version is supported */
-  if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
-      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
-      /* Our version isn't supported */
-    failf(data, "insufficient winsock version to support "
-          "telnet");
-    return CURLE_FAILED_INIT;
-  }
-
-  /* Our version is supported */
-  return CURLE_OK;
-}
-#endif
-
 static
 CURLcode init_telnet(struct connectdata *conn)
 {
@@ -247,7 +202,7 @@ CURLcode init_telnet(struct connectdata *conn)
   if(!tn)
     return CURLE_OUT_OF_MEMORY;
 
-  conn->data->req.protop = tn; /* make us known */
+  conn->data->req.p.telnet = tn; /* make us known */
 
   tn->telrcv_state = CURL_TS_DATA;
 
@@ -292,7 +247,7 @@ CURLcode init_telnet(struct connectdata *conn)
 static void negotiate(struct connectdata *conn)
 {
   int i;
-  struct TELNET *tn = (struct TELNET *) conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *) conn->data->req.p.telnet;
 
   for(i = 0; i < CURL_NTELOPTS; i++) {
     if(i == CURL_TELOPT_ECHO)
@@ -365,7 +320,7 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
 static
 void set_remote_option(struct connectdata *conn, int option, int newstate)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   if(newstate == CURL_YES) {
     switch(tn->him[option]) {
     case CURL_NO:
@@ -439,7 +394,7 @@ void set_remote_option(struct connectdata *conn, int option, int newstate)
 static
 void rec_will(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   switch(tn->him[option]) {
   case CURL_NO:
     if(tn->him_preferred[option] == CURL_YES) {
@@ -487,7 +442,7 @@ void rec_will(struct connectdata *conn, int option)
 static
 void rec_wont(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   switch(tn->him[option]) {
   case CURL_NO:
     /* Already disabled */
@@ -529,7 +484,7 @@ void rec_wont(struct connectdata *conn, int option)
 static void
 set_local_option(struct connectdata *conn, int option, int newstate)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   if(newstate == CURL_YES) {
     switch(tn->us[option]) {
     case CURL_NO:
@@ -603,7 +558,7 @@ set_local_option(struct connectdata *conn, int option, int newstate)
 static
 void rec_do(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   switch(tn->us[option]) {
   case CURL_NO:
     if(tn->us_preferred[option] == CURL_YES) {
@@ -663,7 +618,7 @@ void rec_do(struct connectdata *conn, int option)
 static
 void rec_dont(struct connectdata *conn, int option)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   switch(tn->us[option]) {
   case CURL_NO:
     /* Already disabled */
@@ -822,7 +777,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
   char option_keyword[128] = "";
   char option_arg[256] = "";
   struct Curl_easy *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   CURLcode result = CURLE_OK;
   int binary_option;
 
@@ -929,7 +884,7 @@ static void suboption(struct connectdata *conn)
   char varname[128] = "";
   char varval[128] = "";
   struct Curl_easy *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)data->req.protop;
+  struct TELNET *tn = (struct TELNET *)data->req.p.telnet;
 
   printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn) + 2);
   switch(CURL_SB_GET(tn)) {
@@ -1004,7 +959,7 @@ static void sendsuboption(struct connectdata *conn, int option)
   unsigned char *uc1, *uc2;
 
   struct Curl_easy *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)data->req.protop;
+  struct TELNET *tn = (struct TELNET *)data->req.p.telnet;
 
   switch(option) {
   case CURL_TELOPT_NAWS:
@@ -1062,7 +1017,7 @@ CURLcode telrcv(struct connectdata *conn,
   int in = 0;
   int startwrite = -1;
   struct Curl_easy *data = conn->data;
-  struct TELNET *tn = (struct TELNET *)data->req.protop;
+  struct TELNET *tn = (struct TELNET *)data->req.p.telnet;
 
 #define startskipping()                                       \
   if(startwrite >= 0) {                                       \
@@ -1280,7 +1235,7 @@ static CURLcode send_telnet_data(struct connectdata *conn,
 static CURLcode telnet_done(struct connectdata *conn,
                                  CURLcode status, bool premature)
 {
-  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.p.telnet;
   (void)status; /* unused */
   (void)premature; /* not used */
 
@@ -1290,7 +1245,7 @@ static CURLcode telnet_done(struct connectdata *conn,
   curl_slist_free_all(tn->telnet_vars);
   tn->telnet_vars = NULL;
 
-  Curl_safefree(conn->data->req.protop);
+  Curl_safefree(conn->data->req.p.telnet);
 
   return CURLE_OK;
 }
@@ -1301,11 +1256,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   struct Curl_easy *data = conn->data;
   curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
 #ifdef USE_WINSOCK
-  HMODULE wsock2;
-  WSOCK2_FUNC close_event_func;
-  WSOCK2_EVENT create_event_func;
-  WSOCK2_FUNC event_select_func;
-  WSOCK2_FUNC enum_netevents_func;
   WSAEVENT event_handle;
   WSANETWORKEVENTS events;
   HANDLE stdin_handle;
@@ -1333,82 +1283,28 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   if(result)
     return result;
 
-  tn = (struct TELNET *)data->req.protop;
+  tn = data->req.p.telnet;
 
   result = check_telnet_options(conn);
   if(result)
     return result;
 
 #ifdef USE_WINSOCK
-  /*
-  ** This functionality only works with WinSock >= 2.0.  So,
-  ** make sure we have it.
-  */
-  result = check_wsock2(data);
-  if(result)
-    return result;
-
-  /* OK, so we have WinSock 2.0.  We need to dynamically */
-  /* load ws2_32.dll and get the function pointers we need. */
-  wsock2 = Curl_load_library(TEXT("WS2_32.DLL"));
-  if(wsock2 == NULL) {
-    failf(data, "failed to load WS2_32.DLL (%u)", GetLastError());
-    return CURLE_FAILED_INIT;
-  }
-
-  /* Grab a pointer to WSACreateEvent */
-  create_event_func =
-    CURLX_FUNCTION_CAST(WSOCK2_EVENT,
-                        (GetProcAddress(wsock2, "WSACreateEvent")));
-  if(create_event_func == NULL) {
-    failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
-    FreeLibrary(wsock2);
-    return CURLE_FAILED_INIT;
-  }
-
-  /* And WSACloseEvent */
-  close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
-  if(close_event_func == NULL) {
-    failf(data, "failed to find WSACloseEvent function (%u)", GetLastError());
-    FreeLibrary(wsock2);
-    return CURLE_FAILED_INIT;
-  }
-
-  /* And WSAEventSelect */
-  event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
-  if(event_select_func == NULL) {
-    failf(data, "failed to find WSAEventSelect function (%u)", GetLastError());
-    FreeLibrary(wsock2);
-    return CURLE_FAILED_INIT;
-  }
-
-  /* And WSAEnumNetworkEvents */
-  enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
-  if(enum_netevents_func == NULL) {
-    failf(data, "failed to find WSAEnumNetworkEvents function (%u)",
-          GetLastError());
-    FreeLibrary(wsock2);
-    return CURLE_FAILED_INIT;
-  }
-
   /* We want to wait for both stdin and the socket. Since
   ** the select() function in winsock only works on sockets
   ** we have to use the WaitForMultipleObjects() call.
   */
 
   /* First, create a sockets event object */
-  event_handle = (WSAEVENT)create_event_func();
+  event_handle = WSACreateEvent();
   if(event_handle == WSA_INVALID_EVENT) {
     failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
-    FreeLibrary(wsock2);
     return CURLE_FAILED_INIT;
   }
 
   /* Tell winsock what events we want to listen to */
-  if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
-     SOCKET_ERROR) {
-    close_event_func(event_handle);
-    FreeLibrary(wsock2);
+  if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
+    WSACloseEvent(event_handle);
     return CURLE_OK;
   }
 
@@ -1439,6 +1335,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
     DWORD waitret = WaitForMultipleObjects(obj_count, objs,
                                            FALSE, wait_timeout);
     switch(waitret) {
+
     case WAIT_TIMEOUT:
     {
       for(;;) {
@@ -1508,9 +1405,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
     break;
 
     case WAIT_OBJECT_0:
-
+    {
       events.lNetworkEvents = 0;
-      if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
+      if(WSAEnumNetworkEvents(sockfd, event_handle, &events) == SOCKET_ERROR) {
         err = SOCKERRNO;
         if(err != EINPROGRESS) {
           infof(data, "WSAEnumNetworkEvents failed (%d)", err);
@@ -1554,7 +1451,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
       if(events.lNetworkEvents & FD_CLOSE) {
         keepon = FALSE;
       }
-      break;
+    }
+    break;
 
     }
 
@@ -1569,19 +1467,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
   }
 
   /* We called WSACreateEvent, so call WSACloseEvent */
-  if(!close_event_func(event_handle)) {
+  if(!WSACloseEvent(event_handle)) {
     infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
   }
-
-  /* "Forget" pointers into the library we're about to free */
-  create_event_func = NULL;
-  close_event_func = NULL;
-  event_select_func = NULL;
-  enum_netevents_func = NULL;
-
-  /* We called LoadLibrary, so call FreeLibrary */
-  if(!FreeLibrary(wsock2))
-    infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError());
 #else
   pfd[0].fd = sockfd;
   pfd[0].events = POLLIN;
diff --git a/lib/telnet.h b/lib/telnet.h
index 431427f..1427473 100644
--- a/lib/telnet.h
+++ b/lib/telnet.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/tftp.c b/lib/tftp.c
index 378d956..fba3f5e 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -183,6 +183,7 @@ const struct Curl_handler Curl_handler_tftp = {
   ZERO_NULL,                            /* connection_check */
   PORT_TFTP,                            /* defport */
   CURLPROTO_TFTP,                       /* protocol */
+  CURLPROTO_TFTP,                       /* family */
   PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
 };
 
diff --git a/lib/tftp.h b/lib/tftp.h
index 3334830..4b5bea2 100644
--- a/lib/tftp.h
+++ b/lib/tftp.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/timeval.c b/lib/timeval.c
index e761966..8523dad 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/timeval.h b/lib/timeval.h
index 53e0636..685e729 100644
--- a/lib/timeval.h
+++ b/lib/timeval.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/transfer.c b/lib/transfer.c
index a07c7af..bfd0218 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -78,6 +78,7 @@
 #include "mime.h"
 #include "strcase.h"
 #include "urlapi-int.h"
+#include "hsts.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -167,7 +168,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
   bool sending_http_headers = FALSE;
 
   if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
-    const struct HTTP *http = data->req.protop;
+    const struct HTTP *http = data->req.p.http;
 
     if(http->sending == HTTPSEND_REQUEST)
       /* We're sending the HTTP request headers, not the data.
@@ -426,7 +427,7 @@ CURLcode Curl_readrewind(struct connectdata *conn)
      CURLOPT_HTTPPOST, call app to rewind
   */
   if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
-    struct HTTP *http = data->req.protop;
+    struct HTTP *http = data->req.p.http;
 
     if(http->sendit)
       mimepart = http->sendit;
@@ -1028,7 +1029,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
         /* HTTP pollution, this should be written nicer to become more
            protocol agnostic. */
         size_t fillcount;
-        struct HTTP *http = k->protop;
+        struct HTTP *http = k->p.http;
 
         if((k->exp100 == EXP100_SENDING_REQUEST) &&
            (http->sending == HTTPSEND_BODY)) {
@@ -1152,10 +1153,9 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
 
     win_update_buffer_size(conn->writesockfd);
 
-    if(data->set.verbose)
-      /* show the data before we change the pointer upload_fromhere */
-      Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
-                 (size_t)bytes_written);
+    /* show the data before we change the pointer upload_fromhere */
+    Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
+               (size_t)bytes_written);
 
     k->writebytecount += bytes_written;
     Curl_pgrsSetUploadCounter(data, k->writebytecount);
@@ -1529,6 +1529,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
     }
 #endif
     Curl_http2_init_state(&data->state);
+    Curl_hsts_loadcb(data, data->hsts);
   }
 
   return result;
@@ -1853,7 +1854,7 @@ Curl_setup_transfer(
 {
   struct SingleRequest *k = &data->req;
   struct connectdata *conn = data->conn;
-  struct HTTP *http = data->req.protop;
+  struct HTTP *http = data->req.p.http;
   bool httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
                       (http->sending == HTTPSEND_REQUEST));
   DEBUGASSERT(conn != NULL);
diff --git a/lib/transfer.h b/lib/transfer.h
index 67fd91f..178bb58 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/url.c b/lib/url.c
index 150667a..2b0ba87 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -96,6 +96,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "getinfo.h"
 #include "urlapi-int.h"
 #include "system_win32.h"
+#include "hsts.h"
 
 /* And now for the protocols */
 #include "ftp.h"
@@ -130,7 +131,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
 #include "memdebug.h"
 
 static void conn_free(struct connectdata *conn);
-static unsigned int get_protocol_family(unsigned int protocol);
 
 /* Some parts of the code (e.g. chunked encoding) assume this buffer has at
  * more than just a few bytes to play with. Don't let it become too small or
@@ -140,6 +140,24 @@ static unsigned int get_protocol_family(unsigned int protocol);
 # error READBUFFER_SIZE is too small
 #endif
 
+/*
+* get_protocol_family()
+*
+* This is used to return the protocol family for a given protocol.
+*
+* Parameters:
+*
+* 'h'  [in]  - struct Curl_handler pointer.
+*
+* Returns the family as a single bit protocol identifier.
+*/
+static unsigned int get_protocol_family(const struct Curl_handler *h)
+{
+  DEBUGASSERT(h);
+  DEBUGASSERT(h->family);
+  return h->family;
+}
+
 
 /*
  * Protocol table. Schemes (roughly) in 2019 popularity order:
@@ -215,9 +233,8 @@ static const struct Curl_handler * const protocols[] = {
 #endif
 #endif
 
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
-   (CURL_SIZEOF_CURL_OFF_T > 4) && \
-   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4)
   &Curl_handler_smb,
 #ifdef USE_SSL
   &Curl_handler_smbs,
@@ -228,7 +245,7 @@ static const struct Curl_handler * const protocols[] = {
   &Curl_handler_rtsp,
 #endif
 
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
   &Curl_handler_mqtt,
 #endif
 
@@ -274,6 +291,7 @@ static const struct Curl_handler Curl_handler_dummy = {
   ZERO_NULL,                            /* connection_check */
   0,                                    /* defport */
   0,                                    /* protocol */
+  0,                                    /* family */
   PROTOPT_NONE                          /* flags */
 };
 
@@ -392,11 +410,10 @@ CURLcode Curl_close(struct Curl_easy **datap)
   Curl_dyn_free(&data->state.headerb);
   Curl_safefree(data->state.ulbuf);
   Curl_flush_cookies(data, TRUE);
-#ifdef USE_ALTSVC
   Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
-  Curl_altsvc_cleanup(data->asi);
-  data->asi = NULL;
-#endif
+  Curl_altsvc_cleanup(&data->asi);
+  Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]);
+  Curl_hsts_cleanup(&data->hsts);
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
   Curl_http_auth_cleanup_digest(data);
 #endif
@@ -480,6 +497,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
   set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
   set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
   set->ftp_filemethod = FTPFILE_MULTICWD;
+  set->ftp_skip_ip = TRUE;    /* skip PASV IP by default */
 #endif
   set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
 
@@ -1019,7 +1037,7 @@ static void prune_dead_connections(struct Curl_easy *data)
       Curl_conncache_remove_conn(data, prune.extracted, TRUE);
 
       /* disconnect it */
-      (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
+      (void)Curl_disconnect(data, prune.extracted, TRUE);
     }
     CONNCACHE_LOCK(data);
     data->state.conn_cache->last_cleanup = now;
@@ -1075,7 +1093,7 @@ ConnectionExists(struct Curl_easy *data,
                                       &hostbundle);
   if(bundle) {
     /* Max pipe length is zero (unlimited) for multiplexed connections */
-    struct curl_llist_element *curr;
+    struct Curl_llist_element *curr;
 
     infof(data, "Found bundle for host %s: %p [%s]\n",
           hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ?
@@ -1121,6 +1139,12 @@ ConnectionExists(struct Curl_easy *data,
         /* connect-only or to-be-closed connections will not be reused */
         continue;
 
+      if(extract_if_dead(check, data)) {
+        /* disconnect it */
+        (void)Curl_disconnect(data, check, TRUE);
+        continue;
+      }
+
       if(bundle->multiuse == BUNDLE_MULTIPLEX)
         multiplexed = CONN_INUSE(check);
 
@@ -1171,7 +1195,7 @@ ConnectionExists(struct Curl_easy *data,
       if((needle->handler->flags&PROTOPT_SSL) !=
          (check->handler->flags&PROTOPT_SSL))
         /* don't do mixed SSL and non-SSL connections */
-        if(get_protocol_family(check->handler->protocol) !=
+        if(get_protocol_family(check->handler) !=
            needle->handler->protocol || !check->bits.tls_upgraded)
           /* except protocols that have been upgraded via TLS */
           continue;
@@ -1276,7 +1300,7 @@ ConnectionExists(struct Curl_easy *data,
            is allowed to be upgraded via TLS */
 
         if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
-            (get_protocol_family(check->handler->protocol) ==
+            (get_protocol_family(check->handler) ==
              needle->handler->protocol && check->bits.tls_upgraded)) &&
            (!needle->bits.conn_to_host || strcasecompare(
             needle->conn_to_host.name, check->conn_to_host.name)) &&
@@ -1891,6 +1915,37 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
   if(uc)
     return Curl_uc_to_curlcode(uc);
 
+  uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0);
+  if(uc) {
+    if(!strcasecompare("file", data->state.up.scheme))
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifdef USE_HSTS
+  if(data->hsts && strcasecompare("http", data->state.up.scheme)) {
+    if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) {
+      char *url;
+      Curl_safefree(data->state.up.scheme);
+      uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
+      if(uc)
+        return Curl_uc_to_curlcode(uc);
+      if(data->change.url_alloc)
+        Curl_safefree(data->change.url);
+      /* after update, get the updated version */
+      uc = curl_url_get(uh, CURLUPART_URL, &url, 0);
+      if(uc)
+        return Curl_uc_to_curlcode(uc);
+      uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
+      if(uc)
+        return Curl_uc_to_curlcode(uc);
+      data->change.url = url;
+      data->change.url_alloc = TRUE;
+      infof(data, "Switched from HTTP to HTTPS due to HSTS => %s\n",
+            data->change.url);
+    }
+  }
+#endif
+
   result = findprotocol(data, conn, data->state.up.scheme);
   if(result)
     return result;
@@ -1936,12 +1991,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
   else if(uc != CURLUE_NO_OPTIONS)
     return Curl_uc_to_curlcode(uc);
 
-  uc = curl_url_get(uh, CURLUPART_HOST, &data->state.up.hostname, 0);
-  if(uc) {
-    if(!strcasecompare("file", data->state.up.scheme))
-      return CURLE_OUT_OF_MEMORY;
-  }
-
   uc = curl_url_get(uh, CURLUPART_PATH, &data->state.up.path, 0);
   if(uc)
     return Curl_uc_to_curlcode(uc);
@@ -2060,7 +2109,7 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
 
 void Curl_free_request_state(struct Curl_easy *data)
 {
-  Curl_safefree(data->req.protop);
+  Curl_safefree(data->req.p.http);
   Curl_safefree(data->req.newurl);
 
 #ifndef CURL_DISABLE_DOH
@@ -2377,8 +2426,10 @@ static CURLcode parse_proxy(struct Curl_easy *data,
 static CURLcode parse_proxy_auth(struct Curl_easy *data,
                                  struct connectdata *conn)
 {
-  char *proxyuser = data->set.str[STRING_PROXYUSERNAME];
-  char *proxypasswd = data->set.str[STRING_PROXYPASSWORD];
+  const char *proxyuser = data->set.str[STRING_PROXYUSERNAME] ?
+    data->set.str[STRING_PROXYUSERNAME] : "";
+  const char *proxypasswd = data->set.str[STRING_PROXYPASSWORD] ?
+    data->set.str[STRING_PROXYPASSWORD] : "";
   CURLcode result = CURLE_OK;
 
   if(proxyuser)
@@ -2551,6 +2602,9 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn)
     conn->bits.socksproxy = FALSE;
     conn->bits.proxy_user_passwd = FALSE;
     conn->bits.tunnel_proxy = FALSE;
+    /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need
+       to signal that CURLPROXY_HTTPS is not used for this connection */
+    conn->http_proxy.proxytype = CURLPROXY_HTTP;
   }
 
 out:
@@ -3070,7 +3124,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
     conn_to_host = conn_to_host->next;
   }
 
-#ifdef USE_ALTSVC
+#ifndef CURL_DISABLE_ALTSVC
   if(data->asi && !host && (port == -1) &&
      ((conn->handler->protocol == CURLPROTO_HTTPS) ||
 #ifdef CURLDEBUG
@@ -3611,6 +3665,7 @@ static CURLcode create_conn(struct Curl_easy *data,
   data->set.ssl.primary.pinned_key =
     data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
   data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
+  data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
 
 #ifndef CURL_DISABLE_PROXY
   data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
@@ -3627,18 +3682,15 @@ static CURLcode create_conn(struct Curl_easy *data,
   data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
   data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
   data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
-  data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
   data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
   data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
   data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
   data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
   data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
-  data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
   data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
 #endif
   data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
   data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
-  data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
   data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
   data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
   data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
@@ -3653,7 +3705,6 @@ static CURLcode create_conn(struct Curl_easy *data,
 #endif
 #endif
 
-  data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
   data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG];
   data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG];
 
@@ -3752,8 +3803,7 @@ static CURLcode create_conn(struct Curl_easy *data,
         CONNCACHE_UNLOCK(data);
 
         if(conn_candidate)
-          (void)Curl_disconnect(data, conn_candidate,
-                                /* dead_connection */ FALSE);
+          (void)Curl_disconnect(data, conn_candidate, FALSE);
         else {
           infof(data, "No more connections allowed to host %s: %zu\n",
                 bundlehost, max_host_connections);
@@ -3773,8 +3823,7 @@ static CURLcode create_conn(struct Curl_easy *data,
       /* The cache is full. Let's see if we can kill a connection. */
       conn_candidate = Curl_conncache_extract_oldest(data);
       if(conn_candidate)
-        (void)Curl_disconnect(data, conn_candidate,
-                              /* dead_connection */ FALSE);
+        (void)Curl_disconnect(data, conn_candidate, FALSE);
       else {
         infof(data, "No connections available in cache\n");
         connections_available = FALSE;
@@ -4026,113 +4075,3 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
 
   return CURLE_OK;
 }
-
-/*
-* get_protocol_family()
-*
-* This is used to return the protocol family for a given protocol.
-*
-* Parameters:
-*
-* protocol  [in]  - A single bit protocol identifier such as HTTP or HTTPS.
-*
-* Returns the family as a single bit protocol identifier.
-*/
-
-static unsigned int get_protocol_family(unsigned int protocol)
-{
-  unsigned int family;
-
-  switch(protocol) {
-  case CURLPROTO_HTTP:
-  case CURLPROTO_HTTPS:
-    family = CURLPROTO_HTTP;
-    break;
-
-  case CURLPROTO_FTP:
-  case CURLPROTO_FTPS:
-    family = CURLPROTO_FTP;
-    break;
-
-  case CURLPROTO_SCP:
-    family = CURLPROTO_SCP;
-    break;
-
-  case CURLPROTO_SFTP:
-    family = CURLPROTO_SFTP;
-    break;
-
-  case CURLPROTO_TELNET:
-    family = CURLPROTO_TELNET;
-    break;
-
-  case CURLPROTO_LDAP:
-  case CURLPROTO_LDAPS:
-    family = CURLPROTO_LDAP;
-    break;
-
-  case CURLPROTO_DICT:
-    family = CURLPROTO_DICT;
-    break;
-
-  case CURLPROTO_FILE:
-    family = CURLPROTO_FILE;
-    break;
-
-  case CURLPROTO_TFTP:
-    family = CURLPROTO_TFTP;
-    break;
-
-  case CURLPROTO_IMAP:
-  case CURLPROTO_IMAPS:
-    family = CURLPROTO_IMAP;
-    break;
-
-  case CURLPROTO_POP3:
-  case CURLPROTO_POP3S:
-    family = CURLPROTO_POP3;
-    break;
-
-  case CURLPROTO_SMTP:
-  case CURLPROTO_SMTPS:
-      family = CURLPROTO_SMTP;
-      break;
-
-  case CURLPROTO_RTSP:
-    family = CURLPROTO_RTSP;
-    break;
-
-  case CURLPROTO_RTMP:
-  case CURLPROTO_RTMPS:
-    family = CURLPROTO_RTMP;
-    break;
-
-  case CURLPROTO_RTMPT:
-  case CURLPROTO_RTMPTS:
-    family = CURLPROTO_RTMPT;
-    break;
-
-  case CURLPROTO_RTMPE:
-    family = CURLPROTO_RTMPE;
-    break;
-
-  case CURLPROTO_RTMPTE:
-    family = CURLPROTO_RTMPTE;
-    break;
-
-  case CURLPROTO_GOPHER:
-    family = CURLPROTO_GOPHER;
-    break;
-
-  case CURLPROTO_SMB:
-  case CURLPROTO_SMBS:
-    family = CURLPROTO_SMB;
-    break;
-
-  default:
-      family = 0;
-      break;
-  }
-
-  return family;
-}
diff --git a/lib/url.h b/lib/url.h
index 1941dc6..a9d5bda 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/urlapi-int.h b/lib/urlapi-int.h
index d14d53d..4257233 100644
--- a/lib/urlapi-int.h
+++ b/lib/urlapi-int.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -28,7 +28,7 @@
 bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen);
 
 #ifdef DEBUGBUILD
-CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname);
+CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, bool);
 #endif
 
 #endif /* HEADER_CURL_URLAPI_INT_H */
diff --git a/lib/urlapi.c b/lib/urlapi.c
index acbfb82..ae75963 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -497,7 +497,8 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
   return result;
 }
 
-UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
+UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname,
+                                   bool has_scheme)
 {
   char *portptr = NULL;
   char endbracket;
@@ -542,10 +543,14 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname)
 
     /* Browser behavior adaptation. If there's a colon with no digits after,
        just cut off the name there which makes us ignore the colon and just
-       use the default port. Firefox, Chrome and Safari all do that. */
+       use the default port. Firefox, Chrome and Safari all do that.
+
+       Don't do it if the URL has no scheme, to make something that looks like
+       a scheme not work!
+    */
     if(!portptr[1]) {
       *portptr = '\0';
-      return CURLUE_OK;
+      return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
     }
 
     if(!ISDIGIT(portptr[1]))
@@ -904,7 +909,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags)
     if(result)
       return result;
 
-    result = Curl_parse_port(u, hostname);
+    result = Curl_parse_port(u, hostname, url_has_scheme);
     if(result)
       return result;
 
@@ -1255,8 +1260,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
       return CURLUE_UNKNOWN_PART;
     }
     if(storep && *storep) {
-      free(*storep);
-      *storep = NULL;
+      Curl_safefree(*storep);
     }
     return CURLUE_OK;
   }
@@ -1284,8 +1288,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
     break;
   case CURLUPART_HOST:
     storep = &u->host;
-    free(u->zoneid);
-    u->zoneid = NULL;
+    Curl_safefree(u->zoneid);
     break;
   case CURLUPART_ZONEID:
     storep = &u->zoneid;
@@ -1389,28 +1392,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
     if(urlencode) {
       const unsigned char *i;
       char *o;
-      bool free_part = FALSE;
       char *enc = malloc(nalloc * 3 + 1); /* for worst case! */
       if(!enc)
         return CURLUE_OUT_OF_MEMORY;
-      if(plusencode) {
-        /* space to plus */
-        i = (const unsigned char *)part;
-        for(o = enc; *i; ++o, ++i)
-          *o = (*i == ' ') ? '+' : *i;
-        *o = 0; /* null-terminate */
-        part = strdup(enc);
-        if(!part) {
-          free(enc);
-          return CURLUE_OUT_OF_MEMORY;
-        }
-        free_part = TRUE;
-      }
       for(i = (const unsigned char *)part, o = enc; *i; i++) {
-        if(Curl_isunreserved(*i) ||
-           ((*i == '/') && urlskipslash) ||
-           ((*i == '=') && equalsencode) ||
-           ((*i == '+') && plusencode)) {
+        if((*i == ' ') && plusencode) {
+          *o = '+';
+          o++;
+        }
+        else if(Curl_isunreserved(*i) ||
+                ((*i == '/') && urlskipslash) ||
+                ((*i == '=') && equalsencode)) {
           if((*i == '=') && equalsencode)
             /* only skip the first equals sign */
             equalsencode = FALSE;
@@ -1424,8 +1416,6 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
       }
       *o = 0; /* null-terminate */
       newp = enc;
-      if(free_part)
-        free((char *)part);
     }
     else {
       char *p;
diff --git a/lib/urldata.h b/lib/urldata.h
index 0ae9269..4679c9d 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -76,9 +76,7 @@
 /* length of longest IPv6 address string including the trailing null */
 #define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")
 
-/* Default FTP/IMAP etc response timeout in milliseconds.
-   Symbian OS panics when given a timeout much greater than 1/2 hour.
-*/
+/* Default FTP/IMAP etc response timeout in milliseconds */
 #define RESP_TIMEOUT (120*1000)
 
 /* Max string input length is a precaution against abuse and to detect junk
@@ -207,14 +205,14 @@ struct ssl_backend_data;
 
 /* struct for data related to each SSL connection */
 struct ssl_connect_data {
-  /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm
-     but at least asked to or meaning to use it. See 'state' for the exact
-     current state of the connection. */
   ssl_connection_state state;
   ssl_connect_state connecting_state;
 #if defined(USE_SSL)
   struct ssl_backend_data *backend;
 #endif
+  /* Use ssl encrypted communications TRUE/FALSE. The library is not
+     necessarily using ssl at the moment but at least asked to or means to use
+     it. See 'state' for the exact current state of the connection. */
   BIT(use);
 };
 
@@ -230,6 +228,7 @@ struct ssl_primary_config {
   char *cipher_list13;   /* list of TLS 1.3 cipher suites to use */
   char *pinned_key;
   struct curl_blob *cert_blob;
+  char *curves;          /* list of curves to use */
   BIT(verifypeer);       /* set TRUE if this is desired */
   BIT(verifyhost);       /* set TRUE if CN/SAN must match hostname */
   BIT(verifystatus);     /* set TRUE if certificate status must be checked */
@@ -244,8 +243,6 @@ struct ssl_config_data {
   struct curl_blob *issuercert_blob;
   curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
   void *fsslctxp;        /* parameter for call back */
-  char *cert; /* client certificate file name */
-  struct curl_blob *cert_blob;
   char *cert_type; /* format for certificate (default: PEM)*/
   char *key; /* private key file name */
   struct curl_blob *key_blob;
@@ -271,7 +268,7 @@ struct ssl_general_config {
 };
 
 /* information stored about one single SSL session */
-struct curl_ssl_session {
+struct Curl_ssl_session {
   char *name;       /* host name for which this ID was used */
   char *conn_to_host; /* host name for the connection (may be NULL) */
   const char *scheme; /* protocol scheme used */
@@ -472,6 +469,7 @@ struct ConnectBits {
                          EPRT doesn't work we disable it for the forthcoming
                          requests */
   BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */
+  BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */
 #endif
   BIT(netrc);         /* name+password provided by netrc */
   BIT(bound); /* set true if bind() has already been done on this socket/
@@ -521,7 +519,7 @@ struct Curl_async {
   int port;
   struct Curl_dns_entry *dns;
   int status; /* if done is TRUE, this is the status from the callback */
-  void *os_specific;  /* 'struct thread_data' for Windows */
+  struct thread_data *tdata;
   BIT(done);  /* set TRUE when the lookup is complete */
 };
 
@@ -645,8 +643,23 @@ struct SingleRequest {
      and the 'upload_present' contains the number of bytes available at this
      position */
   char *upload_fromhere;
-  void *protop;       /* Allocated protocol-specific data. Each protocol
-                         handler makes sure this points to data it needs. */
+
+  /* Allocated protocol-specific data. Each protocol handler makes sure this
+     points to data it needs. */
+  union {
+    struct FILEPROTO *file;
+    struct FTP *ftp;
+    struct HTTP *http;
+    struct IMAP *imap;
+    struct ldapreqinfo *ldap;
+    struct MQTT *mqtt;
+    struct POP3 *pop3;
+    struct RTSP *rtsp;
+    struct smb_request *smb;
+    struct SMTP *smtp;
+    struct SSHPROTO *ssh;
+    struct TELNET *telnet;
+  } p;
 #ifndef CURL_DISABLE_DOH
   struct dohdata doh; /* DoH specific data for this request */
 #endif
@@ -740,6 +753,8 @@ struct Curl_handler {
   long defport;           /* Default port. */
   unsigned int protocol;  /* See CURLPROTO_* - this needs to be the single
                              specific protocol bit */
+  unsigned int family;    /* single bit for protocol family; basically the
+                             non-TLS name of the protocol this is */
   unsigned int flags;     /* Extra particular characteristics, see PROTOPT_* */
 };
 
@@ -802,7 +817,11 @@ struct proxy_info {
 /* struct for HTTP CONNECT state data */
 struct http_connect_state {
   struct dynbuf rcvbuf;
-  int keepon;
+  enum keeponval {
+    KEEPON_DONE,
+    KEEPON_CONNECT,
+    KEEPON_IGNORE
+  } keepon;
   curl_off_t cl; /* size of content to read and ignore */
   enum {
     TUNNEL_INIT,    /* init/default/no tunnel state */
@@ -860,7 +879,7 @@ struct connectdata {
      connection is used! */
   struct Curl_easy *data;
   struct connstate cnnct;
-  struct curl_llist_element bundle_node; /* conncache */
+  struct Curl_llist_element bundle_node; /* conncache */
 
   /* chunk is for HTTP chunked encoding, but is in the general connectdata
      struct only because we can do just about any protocol through a HTTP proxy
@@ -1024,7 +1043,7 @@ struct connectdata {
   struct kerberos5data krb5;  /* variables into the structure definition, */
 #endif                        /* however, some of them are ftp specific. */
 
-  struct curl_llist easyq;    /* List of easy handles using this connection */
+  struct Curl_llist easyq;    /* List of easy handles using this connection */
   curl_seek_callback seek_func; /* function that seeks the input */
   void *seek_client;            /* pointer to pass to the seek() above */
 
@@ -1134,6 +1153,7 @@ struct PureInfo {
                                  OpenSSL, GnuTLS, Schannel, NSS and GSKit
                                  builds. Asked for with CURLOPT_CERTINFO
                                  / CURLINFO_CERTINFO */
+  CURLproxycode pxcode;
   BIT(timecond);  /* set to TRUE if the time condition didn't match, which
                      thus made the document NOT get fetched */
 };
@@ -1274,7 +1294,7 @@ typedef enum {
  * One instance for each timeout an easy handle can set.
  */
 struct time_node {
-  struct curl_llist_element list;
+  struct Curl_llist_element list;
   struct curltime time;
   expire_id eid;
 };
@@ -1314,7 +1334,7 @@ struct UrlState {
                        strdup() data.
                     */
   int first_remote_port; /* remote port of the first (not followed) request */
-  struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
+  struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
   long sessionage;                  /* number of the most recent session */
   unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
   struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */
@@ -1338,7 +1358,7 @@ struct UrlState {
 #endif /* USE_OPENSSL */
   struct curltime expiretime; /* set this with Curl_expire() only */
   struct Curl_tree timenode; /* for the splay stuff */
-  struct curl_llist timeoutlist; /* list of pending timeouts */
+  struct Curl_llist timeoutlist; /* list of pending timeouts */
   struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */
 
   /* a place to store the most recently set FTP entrypath */
@@ -1347,8 +1367,7 @@ struct UrlState {
   int httpversion;       /* the lowest HTTP version*10 reported by any server
                             involved in this request */
 
-#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
-    !defined(__SYMBIAN32__)
+#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__)
 /* do FTP line-end conversions on most platforms */
 #define CURL_DO_LINEEND_CONV
   /* for FTP downloads: track CRLF sequences that span blocks */
@@ -1531,39 +1550,31 @@ enum dupstring {
   STRING_RTSP_SESSION_ID, /* Session ID to use */
   STRING_RTSP_STREAM_URI, /* Stream URI for this request */
   STRING_RTSP_TRANSPORT,  /* Transport for this session */
-
   STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
   STRING_SSH_PUBLIC_KEY,  /* path to the public key file for auth */
   STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
   STRING_SSH_KNOWNHOSTS,  /* file name of knownhosts file */
-
   STRING_PROXY_SERVICE_NAME, /* Proxy service name */
   STRING_SERVICE_NAME,    /* Service name */
   STRING_MAIL_FROM,
   STRING_MAIL_AUTH,
-
   STRING_TLSAUTH_USERNAME_ORIG,  /* TLS auth <username> */
   STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
   STRING_TLSAUTH_PASSWORD_ORIG,  /* TLS auth <password> */
   STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
-
   STRING_BEARER,                /* <bearer>, if used */
-
   STRING_UNIX_SOCKET_PATH,      /* path to Unix socket, if used */
-
   STRING_TARGET,                /* CURLOPT_REQUEST_TARGET */
   STRING_DOH,                   /* CURLOPT_DOH_URL */
-
   STRING_ALTSVC,                /* CURLOPT_ALTSVC */
-
+  STRING_HSTS,                  /* CURLOPT_HSTS */
   STRING_SASL_AUTHZID,          /* CURLOPT_SASL_AUTHZID */
-
   STRING_TEMP_URL,              /* temp URL storage for proxy use */
-
   STRING_DNS_SERVERS,
   STRING_DNS_INTERFACE,
   STRING_DNS_LOCAL_IP4,
   STRING_DNS_LOCAL_IP6,
+  STRING_SSL_EC_CURVES,
 
   /* -- end of null-terminated strings -- */
 
@@ -1647,7 +1658,12 @@ struct UserDefined {
   curl_conv_callback convtonetwork;
   /* function to convert from UTF-8 encoding: */
   curl_conv_callback convfromutf8;
-
+#ifdef USE_HSTS
+  curl_hstsread_callback hsts_read;
+  void *hsts_read_userp;
+  curl_hstswrite_callback hsts_write;
+  void *hsts_write_userp;
+#endif
   void *progress_client; /* pointer to pass to the progress callback */
   void *ioctl_client;   /* pointer to pass to the ioctl callback */
   long timeout;         /* in milliseconds, 0 means no timeout */
@@ -1839,7 +1855,7 @@ struct UserDefined {
 };
 
 struct Names {
-  struct curl_hash *hostcache;
+  struct Curl_hash *hostcache;
   enum {
     HCACHE_NONE,    /* not pointing to anything */
     HCACHE_MULTI,   /* points to a shared one in the multi handle */
@@ -1863,8 +1879,8 @@ struct Curl_easy {
   struct Curl_easy *prev;
 
   struct connectdata *conn;
-  struct curl_llist_element connect_queue;
-  struct curl_llist_element conn_queue; /* list per connectdata */
+  struct Curl_llist_element connect_queue;
+  struct Curl_llist_element conn_queue; /* list per connectdata */
 
   CURLMstate mstate;  /* the handle's state */
   CURLcode result;   /* previous result */
@@ -1898,7 +1914,10 @@ struct Curl_easy {
                                   NOTE that the 'cookie' field in the
                                   UserDefined struct defines if the "engine"
                                   is to be used or not. */
-#ifdef USE_ALTSVC
+#ifdef USE_HSTS
+  struct hsts *hsts;
+#endif
+#ifndef CURL_DISABLE_ALTSVC
   struct altsvcinfo *asi;      /* the alt-svc cache */
 #endif
   struct Progress progress;    /* for all the progress meter data */
diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c
index 3a5c943..620dba0 100644
--- a/lib/vauth/cleartext.c
+++ b/lib/vauth/cleartext.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/cram.c b/lib/vauth/cram.c
index 717d7f0..1a37625 100644
--- a/lib/vauth/cram.c
+++ b/lib/vauth/cram.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c
index b9210a8..5fc9285 100644
--- a/lib/vauth/digest.c
+++ b/lib/vauth/digest.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/digest.h b/lib/vauth/digest.h
index cc05fdb..ee373cd 100644
--- a/lib/vauth/digest.h
+++ b/lib/vauth/digest.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c
index 4998306..91d18c9 100644
--- a/lib/vauth/digest_sspi.c
+++ b/lib/vauth/digest_sspi.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/krb5_gssapi.c b/lib/vauth/krb5_gssapi.c
index 95bab0e..0412815 100644
--- a/lib/vauth/krb5_gssapi.c
+++ b/lib/vauth/krb5_gssapi.c
@@ -6,11 +6,11 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
- * Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2015 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/krb5_sspi.c b/lib/vauth/krb5_sspi.c
index 1fb6257..8e56a82 100644
--- a/lib/vauth/krb5_sspi.c
+++ b/lib/vauth/krb5_sspi.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index ecfeacb..a3117f3 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -497,7 +497,6 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
                                              const char *passwdp,
                                              struct ntlmdata *ntlm,
                                              char **outptr, size_t *outlen)
-
 {
   /* NTLM type-3 message structure:
 
diff --git a/lib/vauth/ntlm.h b/lib/vauth/ntlm.h
index 1136b0f..8ec23ad 100644
--- a/lib/vauth/ntlm.h
+++ b/lib/vauth/ntlm.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c
index 84ea51d..28bc3ef 100644
--- a/lib/vauth/ntlm_sspi.c
+++ b/lib/vauth/ntlm_sspi.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/oauth2.c b/lib/vauth/oauth2.c
index b4e9f8e..ca5842a 100644
--- a/lib/vauth/oauth2.c
+++ b/lib/vauth/oauth2.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/spnego_gssapi.c b/lib/vauth/spnego_gssapi.c
index ed7ce02..120925f 100644
--- a/lib/vauth/spnego_gssapi.c
+++ b/lib/vauth/spnego_gssapi.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index 194f250..e7482a4 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/vauth.c b/lib/vauth/vauth.c
index d98e66c..129b8f8 100644
--- a/lib/vauth/vauth.c
+++ b/lib/vauth/vauth.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h
index a1a557d..f25cfc3 100644
--- a/lib/vauth/vauth.h
+++ b/lib/vauth/vauth.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2014 - 2019, Steve Holme, <steve_holme@hotmail.com>.
+ * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/version.c b/lib/version.c
index 4f6dda2..7064c20 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -31,8 +31,8 @@
 #include "curl_printf.h"
 
 #ifdef USE_ARES
-#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
-     (defined(WIN32) || defined(__SYMBIAN32__))
+#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) &&   \
+  defined(WIN32)
 #    define CARES_STATICLIB
 #  endif
 #  include <ares.h>
@@ -56,10 +56,6 @@
 
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
-#ifdef __SYMBIAN32__
-/* zlib pollutes the namespace with this definition */
-#undef WIN32
-#endif
 #endif
 
 #ifdef HAVE_BROTLI
@@ -298,7 +294,7 @@ static const char * const protocols[] = {
   "ldaps",
 #endif
 #endif
-#ifdef CURL_ENABLE_MQTT
+#ifndef CURL_DISABLE_MQTT
   "mqtt",
 #endif
 #ifndef CURL_DISABLE_POP3
@@ -319,9 +315,8 @@ static const char * const protocols[] = {
 #ifdef USE_SSH
   "sftp",
 #endif
-#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
-   (CURL_SIZEOF_CURL_OFF_T > 4) && \
-   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4)
   "smb",
 #  ifdef USE_SSL
   "smbs",
@@ -420,9 +415,12 @@ static curl_version_info_data version_info = {
 #if defined(HAVE_ZSTD)
   | CURL_VERSION_ZSTD
 #endif
-#if defined(USE_ALTSVC)
+#ifndef CURL_DISABLE_ALTSVC
   | CURL_VERSION_ALTSVC
 #endif
+#if defined(USE_HSTS)
+  | CURL_VERSION_HSTS
+#endif
   ,
   NULL, /* ssl_version */
   0,    /* ssl_version_num, this is kept at zero */
@@ -475,11 +473,13 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
 #ifdef USE_SSL
   Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
   version_info.ssl_version = ssl_buffer;
+#ifndef CURL_DISABLE_PROXY
   if(Curl_ssl->supports & SSLSUPP_HTTPS_PROXY)
     version_info.features |= CURL_VERSION_HTTPS_PROXY;
   else
     version_info.features &= ~CURL_VERSION_HTTPS_PROXY;
 #endif
+#endif
 
 #ifdef HAVE_LIBZ
   version_info.libz_version = zlibVersion();
diff --git a/lib/version_win32.c b/lib/version_win32.c
index 6561d36..b8157e9 100644
--- a/lib/version_win32.c
+++ b/lib/version_win32.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/version_win32.h b/lib/version_win32.h
index 94cc626..9b1bd88 100644
--- a/lib/version_win32.h
+++ b/lib/version_win32.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c
index 20ee08d..0f2fea0 100644
--- a/lib/vquic/ngtcp2.c
+++ b/lib/vquic/ngtcp2.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -126,7 +126,7 @@ quic_from_ossl_level(OSSL_ENCRYPTION_LEVEL ossl_level)
   case ssl_encryption_handshake:
     return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
   case ssl_encryption_application:
-    return NGTCP2_CRYPTO_LEVEL_APP;
+    return NGTCP2_CRYPTO_LEVEL_APPLICATION;
   default:
     assert(0);
   }
@@ -143,7 +143,7 @@ quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
   case GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE:
     return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
   case GNUTLS_ENCRYPTION_LEVEL_APPLICATION:
-    return NGTCP2_CRYPTO_LEVEL_APP;
+    return NGTCP2_CRYPTO_LEVEL_APPLICATION;
   default:
     assert(0);
   }
@@ -265,7 +265,7 @@ static int quic_set_encryption_secrets(SSL *ssl,
        qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
     return 0;
 
-  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+  if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
     if(init_ngh3_conn(qs) != CURLE_OK)
       return 0;
   }
@@ -349,14 +349,8 @@ static int quic_init_ssl(struct quicsocket *qs)
   SSL_set_app_data(qs->ssl, qs);
   SSL_set_connect_state(qs->ssl);
 
-  switch(qs->version) {
-#ifdef NGTCP2_PROTO_VER
-  case NGTCP2_PROTO_VER:
-    alpn = (const uint8_t *)NGHTTP3_ALPN_H3;
-    alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1;
-    break;
-#endif
-  }
+  alpn = (const uint8_t *)NGHTTP3_ALPN_H3;
+  alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1;
   if(alpn)
     SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen);
 
@@ -382,7 +376,7 @@ static int secret_func(gnutls_session_t ssl,
        qs->qconn, NULL, NULL, NULL, level, tx_secret, secretlen) != 0)
     return 0;
 
-  if(level == NGTCP2_CRYPTO_LEVEL_APP) {
+  if(level == NGTCP2_CRYPTO_LEVEL_APPLICATION) {
     if(init_ngh3_conn(qs) != CURLE_OK)
       return -1;
   }
@@ -532,15 +526,9 @@ static int quic_init_ssl(struct quicsocket *qs)
     return 1;
   }
 
-  switch(qs->version) {
-#ifdef NGTCP2_PROTO_VER
-  case NGTCP2_PROTO_VER:
-    /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
-    alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1;
-    alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2;
-    break;
-#endif
-  }
+  /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */
+  alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1;
+  alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2;
   if(alpn.data)
     gnutls_alpn_set_protocols(qs->ssl, &alpn, 1, 0);
 
@@ -798,7 +786,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
   infof(data, "Connect socket %d over QUIC to %s:%ld\n",
         sockfd, ipbuf, port);
 
-  qs->version = NGTCP2_PROTO_VER;
+  qs->version = NGTCP2_PROTO_VER_MAX;
 #ifdef USE_OPENSSL
   qs->sslctx = quic_ssl_ctx(data);
   if(!qs->sslctx)
@@ -828,16 +816,13 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
   if(rv == -1)
     return CURLE_QUIC_CONNECT_ERROR;
 
-  ngtcp2_addr_init(&path.local, &qs->local_addr, qs->local_addrlen, NULL);
+  ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr,
+                   qs->local_addrlen, NULL);
   ngtcp2_addr_init(&path.remote, addr, addrlen, NULL);
 
-#ifdef NGTCP2_PROTO_VER
-#define QUICVER NGTCP2_PROTO_VER
-#else
-#error "unsupported ngtcp2 version"
-#endif
-  rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, QUICVER,
-                              &ng_callbacks, &qs->settings, NULL, qs);
+  rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path,
+                              NGTCP2_PROTO_VER_MIN, &ng_callbacks,
+                              &qs->settings, NULL, qs);
   if(rc)
     return CURLE_QUIC_CONNECT_ERROR;
 
@@ -954,6 +939,7 @@ static const struct Curl_handler Curl_handler_http3 = {
   ng_conncheck,                         /* connection_check */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTPS,                      /* protocol */
+  CURLPROTO_HTTP,                       /* family */
   PROTOPT_SSL | PROTOPT_STREAM          /* flags */
 };
 
@@ -962,7 +948,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
                               void *stream_user_data)
 {
   struct Curl_easy *data = stream_user_data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   (void)conn;
   (void)stream_id;
   (void)app_error_code;
@@ -1008,7 +994,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id,
                            void *user_data, void *stream_user_data)
 {
   struct Curl_easy *data = stream_user_data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   CURLcode result = CURLE_OK;
   (void)conn;
 
@@ -1067,7 +1053,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
                              void *user_data, void *stream_user_data)
 {
   struct Curl_easy *data = stream_user_data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   CURLcode result = CURLE_OK;
   (void)conn;
   (void)stream_id;
@@ -1091,7 +1077,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
   nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
   nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
   struct Curl_easy *data = stream_user_data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   CURLcode result = CURLE_OK;
   (void)conn;
   (void)stream_id;
@@ -1166,6 +1152,7 @@ static nghttp3_conn_callbacks ngh3_callbacks = {
   cb_h3_send_stop_sending,
   NULL, /* push_stream */
   NULL, /* end_stream */
+  NULL, /* reset_stream */
 };
 
 static int init_ngh3_conn(struct quicsocket *qs)
@@ -1255,7 +1242,7 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn,
                                 CURLcode *curlcode)
 {
   curl_socket_t sockfd = conn->sock[sockindex];
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
   struct quicsocket *qs = conn->quic;
 
   if(!stream->memlen) {
@@ -1313,7 +1300,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id,
                                    void *stream_user_data)
 {
   struct Curl_easy *data = stream_user_data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   (void)conn;
   (void)stream_id;
   (void)user_data;
@@ -1335,7 +1322,7 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
 {
   struct Curl_easy *data = stream_user_data;
   size_t nread;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   (void)conn;
   (void)stream_id;
   (void)user_data;
@@ -1398,7 +1385,7 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id,
 static CURLcode http_request(struct connectdata *conn, const void *mem,
                              size_t len)
 {
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
   size_t nheader;
   size_t i;
   size_t authority_idx;
@@ -1573,7 +1560,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
 
     if(acc > MAX_ACC) {
       infof(data, "http_request: Warning: The cumulative length of all "
-            "headers exceeds %zu bytes and that could cause the "
+            "headers exceeds %d bytes and that could cause the "
             "stream to be rejected.\n", MAX_ACC);
     }
   }
@@ -1641,7 +1628,7 @@ static ssize_t ngh3_stream_send(struct connectdata *conn,
   ssize_t sent;
   struct quicsocket *qs = conn->quic;
   curl_socket_t sockfd = conn->sock[sockindex];
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
 
   if(!stream->h3req) {
     CURLcode result = http_request(conn, mem, len);
@@ -1718,7 +1705,8 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn,
 
 }
 
-static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
+static CURLcode ng_process_ingress(struct connectdata *conn,
+                                   curl_socket_t sockfd,
                                    struct quicsocket *qs)
 {
   ssize_t recvd;
@@ -1729,10 +1717,11 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
   socklen_t remote_addrlen;
   ngtcp2_path path;
   ngtcp2_tstamp ts = timestamp();
+  ngtcp2_pkt_info pi = { 0 };
 
   for(;;) {
     remote_addrlen = sizeof(remote_addr);
-    while((recvd = recvfrom(sockfd, buf, bufsize, 0,
+    while((recvd = recvfrom(sockfd, (char *)buf, bufsize, 0,
                             (struct sockaddr *)&remote_addr,
                             &remote_addrlen)) == -1 &&
           SOCKERRNO == EINTR)
@@ -1741,16 +1730,16 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
       if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK)
         break;
 
-      failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %d", recvd);
+      failf(conn->data, "ngtcp2: recvfrom() unexpectedly returned %zd", recvd);
       return CURLE_RECV_ERROR;
     }
 
-    ngtcp2_addr_init(&path.local, &qs->local_addr,
+    ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr,
                      qs->local_addrlen, NULL);
     ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr,
                      remote_addrlen, NULL);
 
-    rv = ngtcp2_conn_read_pkt(qs->qconn, &path, buf, recvd, ts);
+    rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts);
     if(rv != 0) {
       /* TODO Send CONNECTION_CLOSE if possible */
       return CURLE_RECV_ERROR;
@@ -1779,7 +1768,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
   nghttp3_vec vec[16];
   ssize_t ndatalen;
 
-  switch(qs->local_addr.sa_family) {
+  switch(qs->local_addr.ss_family) {
   case AF_INET:
     pktlen = NGTCP2_MAX_PKTLEN_IPV4;
     break;
@@ -1815,7 +1804,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
         uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_MORE |
           (fin ? NGTCP2_WRITE_STREAM_FLAG_FIN : 0);
         outlen =
-          ngtcp2_conn_writev_stream(qs->qconn, &ps.path,
+          ngtcp2_conn_writev_stream(qs->qconn, &ps.path, NULL,
                                     out, pktlen, &ndatalen,
                                     flags, stream_id,
                                     (const ngtcp2_vec *)vec, veccnt, ts);
@@ -1860,7 +1849,8 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
       }
     }
     if(outlen < 0) {
-      outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, out, pktlen, ts);
+      outlen = ngtcp2_conn_write_pkt(qs->qconn, &ps.path, NULL,
+                                     out, pktlen, ts);
       if(outlen < 0) {
         failf(conn->data, "ngtcp2_conn_write_pkt returned error: %s\n",
               ngtcp2_strerror((int)outlen));
@@ -1871,7 +1861,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
     }
 
     memcpy(&remote_addr, ps.path.remote.addr, ps.path.remote.addrlen);
-    while((sent = send(sockfd, out, outlen, 0)) == -1 &&
+    while((sent = send(sockfd, (const char *)out, outlen, 0)) == -1 &&
           SOCKERRNO == EINTR)
       ;
 
@@ -1909,7 +1899,7 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn)
 {
   if(conn->handler == &Curl_handler_http3) {
     /* only for HTTP/3 transfers */
-    struct HTTP *stream = conn->data->req.protop;
+    struct HTTP *stream = conn->data->req.p.http;
     struct quicsocket *qs = conn->quic;
     stream->upload_done = TRUE;
     (void)nghttp3_conn_resume_stream(qs->h3conn, stream->stream3_id);
@@ -1926,7 +1916,7 @@ void Curl_quic_done(struct Curl_easy *data, bool premature)
   (void)premature;
   if(data->conn->handler == &Curl_handler_http3) {
     /* only for HTTP/3 transfers */
-    struct HTTP *stream = data->req.protop;
+    struct HTTP *stream = data->req.p.http;
     Curl_dyn_free(&stream->overflow);
   }
 }
@@ -1941,7 +1931,7 @@ bool Curl_quic_data_pending(const struct Curl_easy *data)
      buffer and allocated an overflow buffer. Since it's possible that
      there's no more data coming on the socket, we need to keep reading
      until the overflow buffer is empty. */
-  const struct HTTP *stream = data->req.protop;
+  const struct HTTP *stream = data->req.p.http;
   return Curl_dyn_len(&stream->overflow) > 0;
 }
 
diff --git a/lib/vquic/ngtcp2.h b/lib/vquic/ngtcp2.h
index afdd01b..c6d4d12 100644
--- a/lib/vquic/ngtcp2.h
+++ b/lib/vquic/ngtcp2.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -58,7 +58,7 @@ struct quicsocket {
   struct quic_handshake crypto_data[3];
   /* the last TLS alert description generated by the local endpoint */
   uint8_t tls_alert;
-  struct sockaddr local_addr;
+  struct sockaddr_storage local_addr;
   socklen_t local_addrlen;
 
   nghttp3_conn *h3conn;
diff --git a/lib/vquic/quiche.c b/lib/vquic/quiche.c
index fd9cb8b..d0d150e 100644
--- a/lib/vquic/quiche.c
+++ b/lib/vquic/quiche.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -89,8 +89,17 @@ static int quiche_perform_getsock(const struct connectdata *conn,
   return quiche_getsock((struct connectdata *)conn, socks);
 }
 
-static CURLcode qs_disconnect(struct quicsocket *qs)
+static CURLcode qs_disconnect(struct connectdata *conn,
+                              struct quicsocket *qs)
 {
+  if(qs->conn) {
+    (void)quiche_conn_close(qs->conn, TRUE, 0, NULL, 0);
+    /* flushing the egress is not a failsafe way to deliver all the
+       outstanding packets, but we also don't want to get stuck here... */
+    (void)flush_egress(conn, qs->sockfd, qs);
+    quiche_conn_free(qs->conn);
+    qs->conn = NULL;
+  }
   if(qs->h3config)
     quiche_h3_config_free(qs->h3config);
   if(qs->h3c)
@@ -99,10 +108,6 @@ static CURLcode qs_disconnect(struct quicsocket *qs)
     quiche_config_free(qs->cfg);
     qs->cfg = NULL;
   }
-  if(qs->conn) {
-    quiche_conn_free(qs->conn);
-    qs->conn = NULL;
-  }
   return CURLE_OK;
 }
 
@@ -111,14 +116,14 @@ static CURLcode quiche_disconnect(struct connectdata *conn,
 {
   struct quicsocket *qs = conn->quic;
   (void)dead_connection;
-  return qs_disconnect(qs);
+  return qs_disconnect(conn, qs);
 }
 
 void Curl_quic_disconnect(struct connectdata *conn,
                           int tempindex)
 {
   if(conn->transport == TRNSPRT_QUIC)
-    qs_disconnect(&conn->hequic[tempindex]);
+    qs_disconnect(conn, &conn->hequic[tempindex]);
 }
 
 static unsigned int quiche_conncheck(struct connectdata *conn,
@@ -131,7 +136,7 @@ static unsigned int quiche_conncheck(struct connectdata *conn,
 
 static CURLcode quiche_do(struct connectdata *conn, bool *done)
 {
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
   stream->h3req = FALSE; /* not sent */
   return Curl_http(conn, done);
 }
@@ -154,6 +159,7 @@ static const struct Curl_handler Curl_handler_http3 = {
   quiche_conncheck,                     /* connection_check */
   PORT_HTTP,                            /* defport */
   CURLPROTO_HTTPS,                      /* protocol */
+  CURLPROTO_HTTP,                       /* family */
   PROTOPT_SSL | PROTOPT_STREAM          /* flags */
 };
 
@@ -186,6 +192,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
   (void)addr;
   (void)addrlen;
 
+  qs->sockfd = sockfd;
   qs->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION);
   if(!qs->cfg) {
     failf(data, "can't create quiche config");
@@ -336,7 +343,7 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn, int sockindex,
 
   return result;
   error:
-  qs_disconnect(qs);
+  qs_disconnect(conn, qs);
   return result;
 }
 
@@ -357,7 +364,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
       break;
 
     if(recvd < 0) {
-      failf(conn->data, "quiche: recv() unexpectedly returned %d "
+      failf(conn->data, "quiche: recv() unexpectedly returned %zd "
             "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd);
       return CURLE_RECV_ERROR;
     }
@@ -367,7 +374,7 @@ static CURLcode process_ingress(struct connectdata *conn, int sockfd,
       break;
 
     if(recvd < 0) {
-      failf(conn->data, "quiche_conn_recv() == %d", recvd);
+      failf(conn->data, "quiche_conn_recv() == %zd", recvd);
       return CURLE_RECV_ERROR;
     }
   } while(1);
@@ -383,7 +390,7 @@ static CURLcode flush_egress(struct connectdata *conn, int sockfd,
                              struct quicsocket *qs)
 {
   ssize_t sent;
-  static uint8_t out[1200];
+  uint8_t out[1200];
   int64_t timeout_ns;
 
   do {
@@ -460,7 +467,7 @@ static ssize_t h3_stream_recv(struct connectdata *conn,
   int rc;
   struct h3h1header headers;
   struct Curl_easy *data = conn->data;
-  struct HTTP *stream = data->req.protop;
+  struct HTTP *stream = data->req.p.http;
   headers.dest = buf;
   headers.destlen = buffersize;
   headers.nlen = 0;
@@ -548,7 +555,7 @@ static ssize_t h3_stream_send(struct connectdata *conn,
   ssize_t sent;
   struct quicsocket *qs = conn->quic;
   curl_socket_t sockfd = conn->sock[sockindex];
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
 
   if(!stream->h3req) {
     CURLcode result = http_request(conn, mem, len);
@@ -596,7 +603,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
 {
   /*
    */
-  struct HTTP *stream = conn->data->req.protop;
+  struct HTTP *stream = conn->data->req.p.http;
   size_t nheader;
   size_t i;
   size_t authority_idx;
@@ -761,7 +768,7 @@ static CURLcode http_request(struct connectdata *conn, const void *mem,
 
     if(acc > MAX_ACC) {
       infof(data, "http_request: Warning: The cumulative length of all "
-            "headers exceeds %zu bytes and that could cause the "
+            "headers exceeds %d bytes and that could cause the "
             "stream to be rejected.\n", MAX_ACC);
     }
   }
@@ -824,7 +831,7 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn)
   if(conn->handler == &Curl_handler_http3) {
     /* only for HTTP/3 transfers */
     ssize_t sent;
-    struct HTTP *stream = conn->data->req.protop;
+    struct HTTP *stream = conn->data->req.p.http;
     struct quicsocket *qs = conn->quic;
     fprintf(stderr, "!!! Curl_quic_done_sending\n");
     stream->upload_done = TRUE;
diff --git a/lib/vquic/quiche.h b/lib/vquic/quiche.h
index c8d1837..d311e99 100644
--- a/lib/vquic/quiche.h
+++ b/lib/vquic/quiche.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -41,6 +41,7 @@ struct quicsocket {
   quiche_h3_conn *h3c;
   quiche_h3_config *h3config;
   uint8_t scid[QUICHE_MAX_CONN_ID_LEN];
+  curl_socket_t sockfd;
   uint32_t version;
 };
 
diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c
index aae8e09..7c0cc6d 100644
--- a/lib/vquic/vquic.c
+++ b/lib/vquic/vquic.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vquic/vquic.h b/lib/vquic/vquic.h
index ecff0ed..eb8a893 100644
--- a/lib/vquic/vquic.h
+++ b/lib/vquic/vquic.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index 8988e23..e79d8e8 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -158,6 +158,7 @@ const struct Curl_handler Curl_handler_scp = {
   ZERO_NULL,                    /* connection_check */
   PORT_SSH,                     /* defport */
   CURLPROTO_SCP,                /* protocol */
+  CURLPROTO_SCP,                /* family */
   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY    /* flags */
 };
 
@@ -183,6 +184,7 @@ const struct Curl_handler Curl_handler_sftp = {
   ZERO_NULL,                            /* connection_check */
   PORT_SSH,                             /* defport */
   CURLPROTO_SFTP,                       /* protocol */
+  CURLPROTO_SFTP,                       /* family */
   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
   | PROTOPT_NOURLQUERY                  /* flags */
 };
@@ -662,7 +664,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SSHPROTO *protop = data->req.protop;
+  struct SSHPROTO *protop = data->req.p.ssh;
   struct ssh_conn *sshc = &conn->proto.sshc;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
   int rc = SSH_NO_ERROR, err;
@@ -1430,11 +1432,8 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
           data->req.bytecount += sshc->readdir_len + 1;
 
           /* output debug output if that is requested */
-          if(data->set.verbose) {
-            Curl_debug(data, CURLINFO_DATA_OUT,
-                       (char *)sshc->readdir_filename,
-                       sshc->readdir_len);
-          }
+          Curl_debug(data, CURLINFO_DATA_OUT, (char *)sshc->readdir_filename,
+                     sshc->readdir_len);
         }
         else {
           sshc->readdir_currLen = strlen(sshc->readdir_longentry);
@@ -1546,12 +1545,9 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
                                  sshc->readdir_currLen);
 
       if(!result) {
-
         /* output debug output if that is requested */
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
-                     sshc->readdir_currLen);
-        }
+        Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+                   sshc->readdir_currLen);
         data->req.bytecount += sshc->readdir_currLen;
       }
       Curl_safefree(sshc->readdir_line);
@@ -2129,7 +2125,7 @@ static CURLcode myssh_setup_connection(struct connectdata *conn)
 {
   struct SSHPROTO *ssh;
 
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
   if(!ssh)
     return CURLE_OUT_OF_MEMORY;
 
@@ -2152,7 +2148,7 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done)
   int rc;
 
   /* initialize per-handle data if not already */
-  if(!data->req.protop)
+  if(!data->req.p.ssh)
     myssh_setup_connection(conn);
 
   /* We default to persistent connections. We set this already in this connect
@@ -2353,7 +2349,7 @@ static CURLcode scp_disconnect(struct connectdata *conn,
 static CURLcode myssh_done(struct connectdata *conn, CURLcode status)
 {
   CURLcode result = CURLE_OK;
-  struct SSHPROTO *protop = conn->data->req.protop;
+  struct SSHPROTO *protop = conn->data->req.p.ssh;
 
   if(!status) {
     /* run the state-machine */
@@ -2606,7 +2602,7 @@ static void sftp_quote(struct connectdata *conn)
 {
   const char *cp;
   struct Curl_easy *data = conn->data;
-  struct SSHPROTO *protop = data->req.protop;
+  struct SSHPROTO *protop = data->req.p.ssh;
   struct ssh_conn *sshc = &conn->proto.sshc;
   CURLcode result;
 
@@ -2636,10 +2632,9 @@ static void sftp_quote(struct connectdata *conn)
       sshc->nextstate = SSH_NO_STATE;
       return;
     }
-    if(data->set.verbose) {
-      Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
-      Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
-    }
+    Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
+    Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+
     /* this sends an FTP-like "header" to the header callback so that the
        current directory can be read very similar to how it is read when
        using ordinary FTP. */
@@ -2692,7 +2687,9 @@ static void sftp_quote(struct connectdata *conn)
    */
   if(strncasecompare(cmd, "chgrp ", 6) ||
      strncasecompare(cmd, "chmod ", 6) ||
-     strncasecompare(cmd, "chown ", 6)) {
+     strncasecompare(cmd, "chown ", 6) ||
+     strncasecompare(cmd, "atime ", 6) ||
+     strncasecompare(cmd, "mtime ", 6)) {
     /* attribute change */
 
     /* sshc->quote_path1 contains the mode to set */
@@ -2702,7 +2699,7 @@ static void sftp_quote(struct connectdata *conn)
       if(result == CURLE_OUT_OF_MEMORY)
         failf(data, "Out of memory");
       else
-        failf(data, "Syntax error in chgrp/chmod/chown: "
+        failf(data, "Syntax error in chgrp/chmod/chown/atime/mtime: "
               "Bad second parameter");
       Curl_safefree(sshc->quote_path1);
       state(conn, SSH_SFTP_CLOSE);
@@ -2863,6 +2860,34 @@ static void sftp_quote_stat(struct connectdata *conn)
     }
     sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID;
   }
+  else if(strncasecompare(cmd, "atime", 5)) {
+    time_t date = Curl_getdate_capped(sshc->quote_path1);
+    if(date == -1) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: incorrect access date format");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->atime = (uint32_t)date;
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME;
+  }
+  else if(strncasecompare(cmd, "mtime", 5)) {
+    time_t date = Curl_getdate_capped(sshc->quote_path1);
+    if(date == -1) {
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+      failf(data, "Syntax error: incorrect modification date format");
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_QUOTE_ERROR;
+      return;
+    }
+    sshc->quote_attrs->mtime = (uint32_t)date;
+    sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME;
+  }
 
   /* Now send the completed structure... */
   state(conn, SSH_SFTP_QUOTE_SETSTAT);
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index 4f56bb4..a69bcda 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -150,6 +150,7 @@ const struct Curl_handler Curl_handler_scp = {
   ZERO_NULL,                            /* connection_check */
   PORT_SSH,                             /* defport */
   CURLPROTO_SCP,                        /* protocol */
+  CURLPROTO_SCP,                        /* family */
   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
   | PROTOPT_NOURLQUERY                  /* flags */
 };
@@ -177,6 +178,7 @@ const struct Curl_handler Curl_handler_sftp = {
   ZERO_NULL,                            /* connection_check */
   PORT_SSH,                             /* defport */
   CURLPROTO_SFTP,                       /* protocol */
+  CURLPROTO_SFTP,                       /* family */
   PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
   | PROTOPT_NOURLQUERY                  /* flags */
 };
@@ -442,6 +444,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
   if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
     /* we're asked to verify the host against a file */
     struct ssh_conn *sshc = &conn->proto.sshc;
+    struct libssh2_knownhost *host = NULL;
     int rc;
     int keytype;
     size_t keylen;
@@ -456,7 +459,6 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
        * What host name does OpenSSH store in its file if an IDN name is
        * used?
        */
-      struct libssh2_knownhost *host;
       enum curl_khmatch keymatch;
       curl_sshkeycallback func =
         data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
@@ -568,7 +570,13 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
       /* DEFER means bail out but keep the SSH_HOSTKEY state */
       result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
       break;
+    case CURLKHSTAT_FINE_REPLACE:
+      /* remove old host+key that doesn't match */
+      if(host)
+        libssh2_knownhost_del(sshc->kh, host);
+        /*FALLTHROUGH*/
     case CURLKHSTAT_FINE:
+        /*FALLTHROUGH*/
     case CURLKHSTAT_FINE_ADD_TO_FILE:
       /* proceed */
       if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
@@ -583,7 +591,8 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
         if(addrc)
           infof(data, "Warning adding the known host %s failed!\n",
                 conn->host.name);
-        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE ||
+                rc == CURLKHSTAT_FINE_REPLACE) {
           /* now we write the entire in-memory list of known hosts to the
              known_hosts file */
           int wrc =
@@ -789,7 +798,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
 {
   CURLcode result = CURLE_OK;
   struct Curl_easy *data = conn->data;
-  struct SSHPROTO *sftp_scp = data->req.protop;
+  struct SSHPROTO *sftp_scp = data->req.p.ssh;
   struct ssh_conn *sshc = &conn->proto.sshc;
   curl_socket_t sock = conn->sock[FIRSTSOCKET];
   int rc = LIBSSH2_ERROR_NONE;
@@ -814,6 +823,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
       result = ssh_force_knownhost_key_type(conn);
       if(result) {
         state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = result;
         break;
       }
 
@@ -1255,7 +1265,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
              a time-out or similar */
           result = CURLE_SSH;
         sshc->actualcode = result;
-        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+        DEBUGF(infof(data, "error = %lu makes libcurl = %d\n",
                      sftperr, (int)result));
         state(conn, SSH_STOP);
         break;
@@ -1333,10 +1343,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           sshc->nextstate = SSH_NO_STATE;
           break;
         }
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
-          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
-        }
+        Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
+        Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
+
         /* this sends an FTP-like "header" to the header callback so that the
            current directory can be read very similar to how it is read when
            using ordinary FTP. */
@@ -1390,7 +1399,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
          */
         if(strncasecompare(cmd, "chgrp ", 6) ||
            strncasecompare(cmd, "chmod ", 6) ||
-           strncasecompare(cmd, "chown ", 6) ) {
+           strncasecompare(cmd, "chown ", 6) ||
+           strncasecompare(cmd, "atime ", 6) ||
+           strncasecompare(cmd, "mtime ", 6)) {
           /* attribute change */
 
           /* sshc->quote_path1 contains the mode to set */
@@ -1587,6 +1598,34 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           break;
         }
       }
+      else if(strncasecompare(cmd, "atime", 5)) {
+        time_t date = Curl_getdate_capped(sshc->quote_path1);
+        if(date == -1) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: incorrect access date format");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+        sshc->quote_attrs.atime = (unsigned long)date;
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
+      }
+      else if(strncasecompare(cmd, "mtime", 5)) {
+        time_t date = Curl_getdate_capped(sshc->quote_path1);
+        if(date == -1) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: incorrect modification date format");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+        sshc->quote_attrs.mtime = (unsigned long)date;
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
+      }
 
       /* Now send the completed structure... */
       state(conn, SSH_SFTP_QUOTE_SETSTAT);
@@ -1906,7 +1945,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           sshc->actualcode = CURLE_SSH;
           sftperr = LIBSSH2_FX_OK;
         }
-        failf(data, "Upload failed: %s (%d/%d)",
+        failf(data, "Upload failed: %s (%lu/%d)",
               sftperr != LIBSSH2_FX_OK ?
               sftp_libssh2_strerror(sftperr):"ssh error",
               sftperr, rc);
@@ -2127,11 +2166,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
           data->req.bytecount += readdir_len + 1;
 
           /* output debug output if that is requested */
-          if(data->set.verbose) {
-            Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename,
-                       readdir_len);
-            Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
-          }
+          Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename,
+                     readdir_len);
+          Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1);
         }
         else {
           result = Curl_dyn_add(&sshc->readdir, sshc->readdir_longentry);
@@ -2212,13 +2249,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
                                    Curl_dyn_len(&sshc->readdir));
 
       if(!result) {
-
         /* output debug output if that is requested */
-        if(data->set.verbose) {
-          Curl_debug(data, CURLINFO_DATA_IN,
-                     Curl_dyn_ptr(&sshc->readdir),
-                     Curl_dyn_len(&sshc->readdir));
-        }
+        Curl_debug(data, CURLINFO_DATA_IN,
+                   Curl_dyn_ptr(&sshc->readdir),
+                   Curl_dyn_len(&sshc->readdir));
         data->req.bytecount += Curl_dyn_len(&sshc->readdir);
       }
       if(result) {
@@ -2847,7 +2881,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
 static int ssh_perform_getsock(const struct connectdata *conn,
                                curl_socket_t *sock)
 {
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
   int bitmap = GETSOCK_BLANK;
 
   sock[0] = conn->sock[FIRSTSOCKET];
@@ -2859,11 +2892,6 @@ static int ssh_perform_getsock(const struct connectdata *conn,
     bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
 
   return bitmap;
-#else
-  /* if we don't know the direction we can use the generic *_getsock()
-     function even for the protocol_connect and doing states */
-  return Curl_single_getsock(conn, sock);
-#endif
 }
 
 /* Generic function called by the multi interface to figure out what socket(s)
@@ -2871,20 +2899,11 @@ static int ssh_perform_getsock(const struct connectdata *conn,
 static int ssh_getsock(struct connectdata *conn,
                        curl_socket_t *sock)
 {
-#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
-  (void)conn;
-  (void)sock;
-  /* if we don't know any direction we can just play along as we used to and
-     not provide any sensible info */
-  return GETSOCK_BLANK;
-#else
   /* if we know the direction we can use the generic *_getsock() function even
      for the protocol_connect and doing states */
   return ssh_perform_getsock(conn, sock);
-#endif
 }
 
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
 /*
  * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
  * function is used to figure out in what direction and stores this info so
@@ -2909,10 +2928,6 @@ static void ssh_block2waitfor(struct connectdata *conn, bool block)
        the original set */
     conn->waitfor = sshc->orig_waitfor;
 }
-#else
-  /* no libssh2 directional support so we simply don't know */
-#define ssh_block2waitfor(x,y) Curl_nop_stmt
-#endif
 
 /* called repeatedly until done from multi.c */
 static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
@@ -2961,7 +2976,6 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
       return CURLE_OPERATION_TIMEDOUT;
     }
 
-#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
     if(block) {
       int dir = libssh2_session_block_directions(sshc->ssh_session);
       curl_socket_t sock = conn->sock[FIRSTSOCKET];
@@ -2975,8 +2989,6 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
       (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
                               left>1000?1000:left);
     }
-#endif
-
   }
 
   return result;
@@ -2989,7 +3001,7 @@ static CURLcode ssh_setup_connection(struct connectdata *conn)
 {
   struct SSHPROTO *ssh;
 
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
   if(!ssh)
     return CURLE_OUT_OF_MEMORY;
 
@@ -2999,6 +3011,54 @@ static CURLcode ssh_setup_connection(struct connectdata *conn)
 static Curl_recv scp_recv, sftp_recv;
 static Curl_send scp_send, sftp_send;
 
+#ifndef CURL_DISABLE_PROXY
+static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
+                            size_t length, int flags, void **abstract)
+{
+  struct connectdata *conn = (struct connectdata *)*abstract;
+  ssize_t nread;
+  CURLcode result;
+  Curl_recv *backup = conn->recv[0];
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void)flags;
+
+  /* swap in the TLS reader function for this call only, and then swap back
+     the SSH one again */
+  conn->recv[0] = ssh->tls_recv;
+  result = Curl_read(conn, sock, buffer, length, &nread);
+  conn->recv[0] = backup;
+  if(result == CURLE_AGAIN)
+    return -EAGAIN; /* magic return code for libssh2 */
+  else if(result)
+    return -1; /* generic error */
+  Curl_debug(conn->data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread);
+  return nread;
+}
+
+static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
+                            size_t length, int flags, void **abstract)
+{
+  struct connectdata *conn = (struct connectdata *)*abstract;
+  ssize_t nwrite;
+  CURLcode result;
+  Curl_send *backup = conn->send[0];
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void)flags;
+
+  /* swap in the TLS writer function for this call only, and then swap back
+     the SSH one again */
+  conn->send[0] = ssh->tls_send;
+  result = Curl_write(conn, sock, buffer, length, &nwrite);
+  conn->send[0] = backup;
+  if(result == CURLE_AGAIN)
+    return -EAGAIN; /* magic return code for libssh2 */
+  else if(result)
+    return -1; /* error */
+  Curl_debug(conn->data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite);
+  return nwrite;
+}
+#endif
+
 /*
  * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
  * do protocol-specific actions at connect-time.
@@ -3013,21 +3073,13 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
   struct Curl_easy *data = conn->data;
 
   /* initialize per-handle data if not already */
-  if(!data->req.protop)
+  if(!data->req.p.ssh)
     ssh_setup_connection(conn);
 
   /* We default to persistent connections. We set this already in this connect
      function to make the re-use checks properly be able to check this bit. */
   connkeep(conn, "SSH default");
 
-  if(conn->handler->protocol & CURLPROTO_SCP) {
-    conn->recv[FIRSTSOCKET] = scp_recv;
-    conn->send[FIRSTSOCKET] = scp_send;
-  }
-  else {
-    conn->recv[FIRSTSOCKET] = sftp_recv;
-    conn->send[FIRSTSOCKET] = sftp_send;
-  }
   ssh = &conn->proto.sshc;
 
 #ifdef CURL_LIBSSH2_DEBUG
@@ -3048,6 +3100,61 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
     return CURLE_FAILED_INIT;
   }
 
+#ifndef CURL_DISABLE_PROXY
+  if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
+    /*
+     * This crazy union dance is here to avoid assigning a void pointer a
+     * function pointer as it is invalid C. The problem is of course that
+     * libssh2 has such an API...
+     */
+    union receive {
+      void *recvp;
+      ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **);
+    };
+    union transfer {
+      void *sendp;
+      ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **);
+    };
+    union receive sshrecv;
+    union transfer sshsend;
+
+    sshrecv.recvptr = ssh_tls_recv;
+    sshsend.sendptr = ssh_tls_send;
+
+    infof(data, "Uses HTTPS proxy!\n");
+    /*
+      Setup libssh2 callbacks to make it read/write TLS from the socket.
+
+      ssize_t
+      recvcb(libssh2_socket_t sock, void *buffer, size_t length,
+      int flags, void **abstract);
+
+      ssize_t
+      sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
+      int flags, void **abstract);
+
+    */
+    libssh2_session_callback_set(ssh->ssh_session,
+                                 LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
+    libssh2_session_callback_set(ssh->ssh_session,
+                                 LIBSSH2_CALLBACK_SEND, sshsend.sendp);
+
+    /* Store the underlying TLS recv/send function pointers to be used when
+       reading from the proxy */
+    ssh->tls_recv = conn->recv[FIRSTSOCKET];
+    ssh->tls_send = conn->send[FIRSTSOCKET];
+  }
+
+#endif /* CURL_DISABLE_PROXY */
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+
   if(data->set.ssh_compression) {
 #if LIBSSH2_VERSION_NUM >= 0x010208
     if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
@@ -3192,7 +3299,7 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
 {
   CURLcode result = CURLE_OK;
-  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+  struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
 
   if(!status) {
     /* run the state-machine */
diff --git a/lib/vssh/ssh.h b/lib/vssh/ssh.h
index 9e49993..3773370 100644
--- a/lib/vssh/ssh.h
+++ b/lib/vssh/ssh.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -182,6 +182,12 @@ struct ssh_conn {
   LIBSSH2_SFTP *sftp_session;   /* SFTP handle */
   LIBSSH2_SFTP_HANDLE *sftp_handle;
 
+#ifndef CURL_DISABLE_PROXY
+  /* for HTTPS proxy storage */
+  Curl_recv *tls_recv;
+  Curl_send *tls_send;
+#endif
+
 #ifdef HAVE_LIBSSH2_AGENT_API
   LIBSSH2_AGENT *ssh_agent;     /* proxy to ssh-agent/pageant */
   struct libssh2_agent_publickey *sshagent_identity,
diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c
index dcbbab6..b0dfb20 100644
--- a/lib/vssh/wolfssh.c
+++ b/lib/vssh/wolfssh.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -322,7 +322,7 @@ static CURLcode wssh_setup_connection(struct connectdata *conn)
 {
   struct SSHPROTO *ssh;
 
-  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
   if(!ssh)
     return CURLE_OUT_OF_MEMORY;
 
@@ -356,7 +356,7 @@ static CURLcode wssh_connect(struct connectdata *conn, bool *done)
   int rc;
 
   /* initialize per-handle data if not already */
-  if(!data->req.protop)
+  if(!data->req.p.ssh)
     wssh_setup_connection(conn);
 
   /* We default to persistent connections. We set this already in this connect
@@ -429,7 +429,7 @@ static CURLcode wssh_statemach_act(struct connectdata *conn, bool *block)
   CURLcode result = CURLE_OK;
   struct ssh_conn *sshc = &conn->proto.sshc;
   struct Curl_easy *data = conn->data;
-  struct SSHPROTO *sftp_scp = data->req.protop;
+  struct SSHPROTO *sftp_scp = data->req.p.ssh;
   WS_SFTPNAME *name;
   int rc = 0;
   *block = FALSE; /* we're not blocking by default */
@@ -1027,7 +1027,7 @@ static CURLcode wssh_block_statemach(struct connectdata *conn,
 static CURLcode wssh_done(struct connectdata *conn, CURLcode status)
 {
   CURLcode result = CURLE_OK;
-  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+  struct SSHPROTO *sftp_scp = conn->data->req.p.ssh;
 
   if(!status) {
     /* run the state-machine */
diff --git a/lib/vssh/wolfssh.h b/lib/vssh/wolfssh.h
index a9b9a3b..7b6ac48 100644
--- a/lib/vssh/wolfssh.h
+++ b/lib/vssh/wolfssh.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c
index 44e7406..b0c3dc2 100644
--- a/lib/vtls/bearssl.c
+++ b/lib/vtls/bearssl.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/bearssl.h b/lib/vtls/bearssl.h
index 5f94922..d72b7d0 100644
--- a/lib/vtls/bearssl.h
+++ b/lib/vtls/bearssl.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Michael Forney, <mforney@mforney.org>
+ * Copyright (C) 2019 - 2020, Michael Forney, <mforney@mforney.org>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
index 0538e4a..17584c7 100644
--- a/lib/vtls/gskit.c
+++ b/lib/vtls/gskit.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -705,7 +705,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
   int rc;
   const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
   const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
-  const char * const keyringlabel = SSL_SET_OPTION(cert);
+  const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert);
   const long int ssl_version = SSL_CONN_CONFIG(version);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
   const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
diff --git a/lib/vtls/gskit.h b/lib/vtls/gskit.h
index b06b5e1..202df7e 100644
--- a/lib/vtls/gskit.h
+++ b/lib/vtls/gskit.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 16b0bd6..e848c3f 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -81,7 +81,7 @@ static bool gtls_inited = FALSE;
 struct ssl_backend_data {
   gnutls_session_t session;
   gnutls_certificate_credentials_t cred;
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   gnutls_srp_client_credentials_t srp_client_cred;
 #endif
 };
@@ -304,7 +304,7 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
     return GNUTLS_X509_FMT_PEM;
   if(strcasecompare(type, "DER"))
     return GNUTLS_X509_FMT_DER;
-  return -1;
+  return GNUTLS_X509_FMT_PEM; /* default to PEM */
 }
 
 #define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
@@ -399,15 +399,8 @@ gtls_connect_step1(struct connectdata *conn,
 #endif
   const char *prioritylist;
   const char *err = NULL;
-#ifndef CURL_DISABLE_PROXY
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
-  long * const certverifyresult = SSL_IS_PROXY() ?
-    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
-  const char * const hostname = conn->host.name;
-  long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
+  const char * const hostname = SSL_HOST_NAME();
+  long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
 
   if(connssl->state == ssl_connection_complete)
     /* to make us tolerant against being called more than once for the
@@ -434,7 +427,7 @@ gtls_connect_step1(struct connectdata *conn,
     return CURLE_SSL_CONNECT_ERROR;
   }
 
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
     infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
 
@@ -588,7 +581,7 @@ gtls_connect_step1(struct connectdata *conn,
       return CURLE_SSL_CONNECT_ERROR;
   }
 
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   /* Only add SRP to the cipher list if SRP is requested. Otherwise
    * GnuTLS will disable TLS 1.3 support. */
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
@@ -610,7 +603,7 @@ gtls_connect_step1(struct connectdata *conn,
   else {
 #endif
     rc = gnutls_priority_set_direct(session, prioritylist, &err);
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   }
 #endif
 
@@ -645,7 +638,7 @@ gtls_connect_step1(struct connectdata *conn,
     gnutls_alpn_set_protocols(session, protocols, cur, 0);
   }
 
-  if(SSL_SET_OPTION(cert)) {
+  if(SSL_SET_OPTION(primary.clientcert)) {
     if(SSL_SET_OPTION(key_passwd)) {
       const unsigned int supported_key_encryption_algorithms =
         GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
@@ -654,9 +647,9 @@ gtls_connect_step1(struct connectdata *conn,
         GNUTLS_PKCS_USE_PBES2_AES_256;
       rc = gnutls_certificate_set_x509_key_file2(
            backend->cred,
-           SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(primary.clientcert),
            SSL_SET_OPTION(key) ?
-           SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
            do_file_type(SSL_SET_OPTION(cert_type)),
            SSL_SET_OPTION(key_passwd),
            supported_key_encryption_algorithms);
@@ -670,9 +663,9 @@ gtls_connect_step1(struct connectdata *conn,
     else {
       if(gnutls_certificate_set_x509_key_file(
            backend->cred,
-           SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(primary.clientcert),
            SSL_SET_OPTION(key) ?
-           SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(key) : SSL_SET_OPTION(primary.clientcert),
            do_file_type(SSL_SET_OPTION(cert_type)) ) !=
          GNUTLS_E_SUCCESS) {
         failf(data, "error reading X.509 key or certificate file");
@@ -681,7 +674,7 @@ gtls_connect_step1(struct connectdata *conn,
     }
   }
 
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   /* put the credentials to the current session */
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
@@ -839,15 +832,8 @@ gtls_connect_step3(struct connectdata *conn,
   unsigned int bits;
   gnutls_protocol_t version = gnutls_protocol_get_version(session);
 #endif
-#ifndef CURL_DISABLE_PROXY
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
-  long * const certverifyresult = SSL_IS_PROXY() ?
-    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
-  const char * const hostname = conn->host.name;
-  long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
+  const char * const hostname = SSL_HOST_NAME();
+  long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult);
 
   /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
   ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
@@ -868,7 +854,7 @@ gtls_connect_step3(struct connectdata *conn,
     if(SSL_CONN_CONFIG(verifypeer) ||
        SSL_CONN_CONFIG(verifyhost) ||
        SSL_SET_OPTION(issuercert)) {
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
       if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
          && SSL_SET_OPTION(username) != NULL
          && !SSL_CONN_CONFIG(verifypeer)
@@ -881,7 +867,7 @@ gtls_connect_step3(struct connectdata *conn,
         failf(data, "failed to get server cert");
         *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
         return CURLE_PEER_FAILED_VERIFICATION;
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
       }
 #endif
     }
@@ -1128,22 +1114,15 @@ gtls_connect_step3(struct connectdata *conn,
   }
 #endif
   if(!rc) {
-#ifndef CURL_DISABLE_PROXY
-    const char * const dispname = SSL_IS_PROXY() ?
-      conn->http_proxy.host.dispname : conn->host.dispname;
-#else
-    const char * const dispname = conn->host.dispname;
-#endif
-
     if(SSL_CONN_CONFIG(verifyhost)) {
       failf(data, "SSL: certificate subject name (%s) does not match "
-            "target host name '%s'", certname, dispname);
+            "target host name '%s'", certname, SSL_HOST_DISPNAME());
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_PEER_FAILED_VERIFICATION;
     }
     else
       infof(data, "\t common name: %s (does not match '%s')\n",
-            certname, dispname);
+            certname, SSL_HOST_DISPNAME());
   }
   else
     infof(data, "\t common name: %s (matched)\n", certname);
@@ -1246,13 +1225,18 @@ gtls_connect_step3(struct connectdata *conn,
 
     certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
     showtime(data, "expire date", certclock);
+
+    gnutls_free(certfields.data);
   }
 
   rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
   if(rc)
     infof(data, "Failed to get certificate issuer\n");
-  else
+  else {
     infof(data, "\t issuer: %s\n", certfields.data);
+
+    gnutls_free(certfields.data);
+  }
 #endif
 
   gnutls_x509_crt_deinit(x509_cert);
@@ -1448,7 +1432,7 @@ static void close_one(struct ssl_connect_data *connssl)
     gnutls_certificate_free_credentials(backend->cred);
     backend->cred = NULL;
   }
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   if(backend->srp_client_cred) {
     gnutls_srp_free_client_credentials(backend->srp_client_cred);
     backend->srp_client_cred = NULL;
@@ -1530,7 +1514,7 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
   }
   gnutls_certificate_free_credentials(backend->cred);
 
-#ifdef USE_TLS_SRP
+#ifdef HAVE_GNUTLS_SRP
   if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
      && SSL_SET_OPTION(username) != NULL)
     gnutls_srp_free_client_credentials(backend->srp_client_cred);
diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h
index 780fc10..1a146a3 100644
--- a/lib/vtls/gtls.h
+++ b/lib/vtls/gtls.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/keylog.c b/lib/vtls/keylog.c
index 70d22ec..a45945f 100644
--- a/lib/vtls/keylog.c
+++ b/lib/vtls/keylog.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/keylog.h b/lib/vtls/keylog.h
index c6b99db..63626da 100644
--- a/lib/vtls/keylog.h
+++ b/lib/vtls/keylog.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index 545f824..191315d 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -31,6 +31,9 @@
 
 #ifdef USE_MBEDTLS
 
+/* Define this to enable lots of debugging for mbedTLS */
+/* #define MBEDTLS_DEBUG */
+
 #include <mbedtls/version.h>
 #if MBEDTLS_VERSION_NUMBER >= 0x02040000
 #include <mbedtls/net_sockets.h>
@@ -46,6 +49,12 @@
 #include <mbedtls/ctr_drbg.h>
 #include <mbedtls/sha256.h>
 
+#if MBEDTLS_VERSION_MAJOR >= 2
+#  ifdef MBEDTLS_DEBUG
+#    include <mbedtls/debug.h>
+#  endif
+#endif
+
 #include "urldata.h"
 #include "sendf.h"
 #include "inet_pton.h"
@@ -113,9 +122,6 @@ static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
 
 #endif /* THREADING_SUPPORT */
 
-/* Define this to enable lots of debugging for mbedTLS */
-#undef MBEDTLS_DEBUG
-
 #ifdef MBEDTLS_DEBUG
 static void mbed_debug(void *context, int level, const char *f_name,
                        int line_nb, const char *line)
@@ -244,7 +250,7 @@ mbed_connect_step1(struct connectdata *conn,
   const char * const ssl_cafile = 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(cert);
+  char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
 #ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
diff --git a/lib/vtls/mbedtls.h b/lib/vtls/mbedtls.h
index 0cc64b3..1abd331 100644
--- a/lib/vtls/mbedtls.h
+++ b/lib/vtls/mbedtls.h
@@ -7,12 +7,12 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mbedtls_threadlock.c b/lib/vtls/mbedtls_threadlock.c
index 4d672f1..473f517 100644
--- a/lib/vtls/mbedtls_threadlock.c
+++ b/lib/vtls/mbedtls_threadlock.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mbedtls_threadlock.h b/lib/vtls/mbedtls_threadlock.h
index 96a787d..e40dfc8 100644
--- a/lib/vtls/mbedtls_threadlock.h
+++ b/lib/vtls/mbedtls_threadlock.h
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c
index 7132bdf..309786c 100644
--- a/lib/vtls/mesalink.c
+++ b/lib/vtls/mesalink.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -158,8 +158,8 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
                                                     SSL_CONN_CONFIG(CApath))) {
       if(SSL_CONN_CONFIG(verifypeer)) {
         failf(data,
-              "error setting certificate verify locations:\n"
-              "  CAfile: %s\n  CApath: %s",
+              "error setting certificate verify locations: "
+              " CAfile: %s CApath: %s",
               SSL_CONN_CONFIG(CAfile) ?
               SSL_CONN_CONFIG(CAfile) : "none",
               SSL_CONN_CONFIG(CApath) ?
@@ -173,20 +173,18 @@ mesalink_connect_step1(struct connectdata *conn, int sockindex)
     else {
       infof(data, "successfully set certificate verify locations:\n");
     }
-    infof(data,
-          "  CAfile: %s\n"
-          "  CApath: %s\n",
-          SSL_CONN_CONFIG(CAfile)?
-          SSL_CONN_CONFIG(CAfile): "none",
-          SSL_CONN_CONFIG(CApath)?
-          SSL_CONN_CONFIG(CApath): "none");
+    infof(data, " CAfile: %s\n",
+          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): "none");
+    infof(data, " CApath: %s\n",
+          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): "none");
   }
 
-  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+  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, SSL_SET_OPTION(cert),
-                                     file_type) != 1) {
+    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"
             " phrase?)");
       return CURLE_SSL_CONNECT_ERROR;
diff --git a/lib/vtls/mesalink.h b/lib/vtls/mesalink.h
index 54cb94a..03f520c 100644
--- a/lib/vtls/mesalink.h
+++ b/lib/vtls/mesalink.h
@@ -7,12 +7,12 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2017-2018, Yiming Jing, <jingyiming@baidu.com>
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2017 - 2018, Yiming Jing, <jingyiming@baidu.com>
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 0f0d1ee..59649cc 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -83,7 +83,7 @@ struct ssl_backend_data {
   PRFileDesc *handle;
   char *client_nickname;
   struct Curl_easy *data;
-  struct curl_llist obj_list;
+  struct Curl_llist obj_list;
   PK11GenericObject *obj_clicert;
 };
 
@@ -91,14 +91,14 @@ static PRLock *nss_initlock = NULL;
 static PRLock *nss_crllock = NULL;
 static PRLock *nss_findslot_lock = NULL;
 static PRLock *nss_trustload_lock = NULL;
-static struct curl_llist nss_crl_list;
+static struct Curl_llist nss_crl_list;
 static NSSInitContext *nss_context = NULL;
 static volatile int initialized = 0;
 
 /* type used to wrap pointers as list nodes */
 struct ptr_list_wrap {
   void *ptr;
-  struct curl_llist_element node;
+  struct Curl_llist_element node;
 };
 
 struct cipher_s {
@@ -430,7 +430,7 @@ static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
 }
 
 /* wrap 'ptr' as list node and tail-insert into 'list' */
-static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr)
+static CURLcode insert_wrapped_ptr(struct Curl_llist *list, void *ptr)
 {
   struct ptr_list_wrap *wrap = malloc(sizeof(*wrap));
   if(!wrap)
@@ -1027,12 +1027,7 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
   CERTCertificate *cert;
 
   /* remember the cert verification result */
-#ifndef CURL_DISABLE_PROXY
-  if(SSL_IS_PROXY())
-    data->set.proxy_ssl.certverifyresult = err;
-  else
-#endif
-    data->set.ssl.certverifyresult = err;
+  SSL_SET_OPTION_LVALUE(certverifyresult) = err;
 
   if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
     /* we are asked not to verify the host name */
@@ -1631,9 +1626,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
   if(capath && !capath[0])
     capath = NULL;
 
-  infof(data, "  CAfile: %s\n  CApath: %s\n",
-      cafile ? cafile : "none",
-      capath ? capath : "none");
+  infof(data, " CAfile: %s\n", cafile ? cafile : "none");
+  infof(data, " CApath: %s\n", capath ? capath : "none");
 
   /* load libnssckbi.so if no other trust roots were specified */
   use_trust_module = !cafile && !capath;
@@ -1673,7 +1667,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
       if(!dir)
         return CURLE_SSL_CACERT_BADFILE;
 
-      while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
+      while((entry =
+             PR_ReadDir(dir, (PRDirFlags)(PR_SKIP_BOTH | PR_SKIP_HIDDEN)))) {
         char *fullpath = aprintf("%s/%s", capath, entry->name);
         if(!fullpath) {
           PR_CloseDir(dir);
@@ -1838,12 +1833,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
   CURLcode result;
   bool second_layer = FALSE;
   SSLVersionRange sslver_supported;
-#ifndef CURL_DISABLE_PROXY
-  const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
-#else
-  const char *hostname = conn->host.name;
-#endif
 
   SSLVersionRange sslver = {
     SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
@@ -1948,12 +1937,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     goto error;
 
   /* not checked yet */
-#ifndef CURL_DISABLE_PROXY
-  if(SSL_IS_PROXY())
-    data->set.proxy_ssl.certverifyresult = 0;
-  else
-#endif
-    data->set.ssl.certverifyresult = 0;
+  SSL_SET_OPTION_LVALUE(certverifyresult) = 0;
 
   if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
     goto error;
@@ -1981,14 +1965,15 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     infof(data, "  CRLfile: %s\n", SSL_SET_OPTION(CRLfile));
   }
 
-  if(SSL_SET_OPTION(cert)) {
-    char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
+  if(SSL_SET_OPTION(primary.clientcert)) {
+    char *nickname = dup_nickname(data, SSL_SET_OPTION(primary.clientcert));
     if(nickname) {
       /* we are not going to use libnsspem.so to read the client cert */
       backend->obj_clicert = NULL;
     }
     else {
-      CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
+      CURLcode rv = cert_stuff(conn, sockindex,
+                               SSL_SET_OPTION(primary.clientcert),
                                SSL_SET_OPTION(key));
       if(rv) {
         /* failf() is already done in cert_stuff() */
@@ -2124,11 +2109,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
     goto error;
 
   /* propagate hostname to the TLS layer */
-  if(SSL_SetURL(backend->handle, hostname) != SECSuccess)
+  if(SSL_SetURL(backend->handle, SSL_HOST_NAME()) != SECSuccess)
     goto error;
 
   /* prevent NSS from re-using the session for a different hostname */
-  if(SSL_SetSockPeerID(backend->handle, hostname) != SECSuccess)
+  if(SSL_SetSockPeerID(backend->handle, SSL_HOST_NAME()) != SECSuccess)
     goto error;
 
   return CURLE_OK;
@@ -2147,18 +2132,6 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
   struct Curl_easy *data = conn->data;
   CURLcode result = CURLE_SSL_CONNECT_ERROR;
   PRUint32 timeout;
-#ifndef CURL_DISABLE_PROXY
-  long * const certverifyresult = SSL_IS_PROXY() ?
-    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-  const char * const pinnedpubkey = SSL_IS_PROXY() ?
-              data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
-              data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-#else
-  long * const certverifyresult = &data->set.ssl.certverifyresult;
-  const char * const pinnedpubkey =
-              data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
-#endif
-
 
   /* check timeout situation */
   const timediff_t time_left = Curl_timeleft(data, NULL, TRUE);
@@ -2174,9 +2147,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
     if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
       /* blocking direction is updated by nss_update_connecting_state() */
       return CURLE_AGAIN;
-    else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+    else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN)
       result = CURLE_PEER_FAILED_VERIFICATION;
-    else if(*certverifyresult != 0)
+    else if(SSL_SET_OPTION(certverifyresult) != 0)
       result = CURLE_PEER_FAILED_VERIFICATION;
     goto error;
   }
@@ -2204,7 +2177,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
     }
   }
 
-  result = cmp_peer_pubkey(connssl, pinnedpubkey);
+  result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY());
   if(result)
     /* status already printed */
     goto error;
diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h
index 41e51b0..37b3646 100644
--- a/lib/vtls/nssg.h
+++ b/lib/vtls/nssg.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 1685a4a..e9c535f 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -34,6 +34,13 @@
 /* Wincrypt must be included before anything that could include OpenSSL. */
 #if defined(USE_WIN32_CRYPTO)
 #include <wincrypt.h>
+/* Undefine wincrypt conflicting symbols for BoringSSL. */
+#undef X509_NAME
+#undef X509_EXTENSIONS
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
 #endif
 
 #include "urldata.h"
@@ -193,6 +200,10 @@
      !defined(OPENSSL_IS_BORINGSSL))
 #define HAVE_SSL_CTX_SET_CIPHERSUITES
 #define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH
+/* SET_EC_CURVES available under the same preconditions: see
+ * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
+ */
+#define HAVE_SSL_CTX_SET_EC_CURVES
 #endif
 
 #if defined(LIBRESSL_VERSION_NUMBER)
@@ -214,6 +225,14 @@
   "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
 #endif
 
+#ifdef HAVE_OPENSSL_SRP
+/* the function exists */
+#ifdef USE_TLS_SRP
+/* the functionality is not disabled */
+#define USE_OPENSSL_SRP
+#endif
+#endif
+
 struct ssl_backend_data {
   /* these ones requires specific SSL-types */
   SSL_CTX* ctx;
@@ -1065,9 +1084,6 @@ int cert_stuff(struct connectdata *conn,
 /* returns non-zero on failure */
 static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
 {
-#if 0
-  return X509_NAME_oneline(a, buf, size);
-#else
   BIO *bio_out = BIO_new(BIO_s_mem());
   BUF_MEM *biomem;
   int rc;
@@ -1089,7 +1105,6 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
   BIO_free(bio_out);
 
   return !rc;
-#endif
 }
 
 /**
@@ -1100,6 +1115,21 @@ static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
  */
 static int Curl_ossl_init(void)
 {
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) &&  \
+  !defined(LIBRESSL_VERSION_NUMBER)
+  const uint64_t flags =
+#ifdef OPENSSL_INIT_ENGINE_ALL_BUILTIN
+    /* not present in BoringSSL */
+    OPENSSL_INIT_ENGINE_ALL_BUILTIN |
+#endif
+#ifdef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG
+    OPENSSL_INIT_NO_LOAD_CONFIG |
+#else
+    OPENSSL_INIT_LOAD_CONFIG |
+#endif
+    0;
+  OPENSSL_init_ssl(flags, NULL);
+#else
   OPENSSL_load_builtin_modules();
 
 #ifdef USE_OPENSSL_ENGINE
@@ -1118,10 +1148,6 @@ static int Curl_ossl_init(void)
                          CONF_MFLAGS_IGNORE_MISSING_FILE);
 #endif
 
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
-    !defined(LIBRESSL_VERSION_NUMBER)
-  /* OpenSSL 1.1.0+ takes care of initialization itself */
-#else
   /* Lets get nice error messages */
   SSL_load_error_strings();
 
@@ -1571,16 +1597,8 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
   CURLcode result = CURLE_OK;
   bool dNSName = FALSE; /* if a dNSName field exists in the cert */
   bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
-#ifndef CURL_DISABLE_PROXY
-  const char * const hostname = SSL_IS_PROXY() ?
-    conn->http_proxy.host.name : conn->host.name;
-  const char * const dispname = SSL_IS_PROXY() ?
-    conn->http_proxy.host.dispname : conn->host.dispname;
-#else
-  /* disabled proxy support */
-  const char * const hostname = conn->host.name;
-  const char * const dispname = conn->host.dispname;
-#endif
+  const char * const hostname = SSL_HOST_NAME();
+  const char * const dispname = SSL_HOST_DISPNAME();
 
 #ifdef ENABLE_IPV6
   if(conn->bits.ipv6_ip &&
@@ -1777,6 +1795,11 @@ static CURLcode verifystatus(struct connectdata *conn,
   X509_STORE     *st = NULL;
   STACK_OF(X509) *ch = NULL;
   struct ssl_backend_data *backend = connssl->backend;
+  X509 *cert;
+  OCSP_CERTID *id = NULL;
+  int cert_status, crl_reason;
+  ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+  int ret;
 
   long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
 
@@ -1845,43 +1868,63 @@ static CURLcode verifystatus(struct connectdata *conn,
     goto end;
   }
 
-  for(i = 0; i < OCSP_resp_count(br); i++) {
-    int cert_status, crl_reason;
-    OCSP_SINGLERESP *single = NULL;
-
-    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+  /* Compute the certificate's ID */
+  cert = SSL_get_peer_certificate(backend->handle);
+  if(!cert) {
+    failf(data, "Error getting peer certficate");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
 
-    single = OCSP_resp_get0(br, i);
-    if(!single)
-      continue;
+  for(i = 0; i < sk_X509_num(ch); i++) {
+    X509 *issuer = sk_X509_value(ch, i);
+    if(X509_check_issued(issuer, cert) == X509_V_OK) {
+      id = OCSP_cert_to_id(EVP_sha1(), cert, issuer);
+      break;
+    }
+  }
+  X509_free(cert);
 
-    cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
-                                          &thisupd, &nextupd);
+  if(!id) {
+    failf(data, "Error computing OCSP ID");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
 
-    if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
-      failf(data, "OCSP response has expired");
-      result = CURLE_SSL_INVALIDCERTSTATUS;
-      goto end;
-    }
+  /* Find the single OCSP response corresponding to the certificate ID */
+  ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev,
+                              &thisupd, &nextupd);
+  OCSP_CERTID_free(id);
+  if(ret != 1) {
+    failf(data, "Could not find certificate ID in OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
 
-    infof(data, "SSL certificate status: %s (%d)\n",
-          OCSP_cert_status_str(cert_status), cert_status);
+  /* Validate the corresponding single OCSP response */
+  if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
+    failf(data, "OCSP response has expired");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
 
-    switch(cert_status) {
-      case V_OCSP_CERTSTATUS_GOOD:
-        break;
+  infof(data, "SSL certificate status: %s (%d)\n",
+        OCSP_cert_status_str(cert_status), cert_status);
 
-      case V_OCSP_CERTSTATUS_REVOKED:
-        result = CURLE_SSL_INVALIDCERTSTATUS;
+  switch(cert_status) {
+  case V_OCSP_CERTSTATUS_GOOD:
+    break;
 
-        failf(data, "SSL certificate revocation reason: %s (%d)",
-              OCSP_crl_reason_str(crl_reason), crl_reason);
-        goto end;
+  case V_OCSP_CERTSTATUS_REVOKED:
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    failf(data, "SSL certificate revocation reason: %s (%d)",
+          OCSP_crl_reason_str(crl_reason), crl_reason);
+    goto end;
 
-      case V_OCSP_CERTSTATUS_UNKNOWN:
-        result = CURLE_SSL_INVALIDCERTSTATUS;
-        goto end;
-    }
+  case V_OCSP_CERTSTATUS_UNKNOWN:
+  default:
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
   }
 
 end:
@@ -2459,12 +2502,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
   bool sni;
-#ifndef CURL_DISABLE_PROXY
-  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
-    conn->host.name;
-#else
-  const char * const hostname = conn->host.name;
-#endif
+  const char * const hostname = SSL_HOST_NAME();
 
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
@@ -2472,18 +2510,12 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   struct in_addr addr;
 #endif
 #endif
-#ifndef CURL_DISABLE_PROXY
-  long * const certverifyresult = SSL_IS_PROXY() ?
-    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
-  long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
   const long int ssl_version = SSL_CONN_CONFIG(version);
-#ifdef USE_TLS_SRP
+#ifdef USE_OPENSSL_SRP
   const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
 #endif
-  char * const ssl_cert = SSL_SET_OPTION(cert);
-  const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
+  char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
+  const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
   const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
@@ -2500,7 +2532,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   if(result)
     return result;
 
-  *certverifyresult = !X509_V_OK;
+  SSL_SET_OPTION_LVALUE(certverifyresult) = !X509_V_OK;
 
   /* check to see if we've been told to use an explicit SSL/TLS version */
 
@@ -2524,7 +2556,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
     failf(data, OSSL_PACKAGE " was built without SSLv2 support");
     return CURLE_NOT_BUILT_IN;
 #else
-#ifdef USE_TLS_SRP
+#ifdef USE_OPENSSL_SRP
     if(ssl_authtype == CURL_TLSAUTH_SRP)
       return CURLE_SSL_CONNECT_ERROR;
 #endif
@@ -2537,7 +2569,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
     failf(data, OSSL_PACKAGE " was built without SSLv3 support");
     return CURLE_NOT_BUILT_IN;
 #else
-#ifdef USE_TLS_SRP
+#ifdef USE_OPENSSL_SRP
     if(ssl_authtype == CURL_TLSAUTH_SRP)
       return CURLE_SSL_CONNECT_ERROR;
 #endif
@@ -2735,33 +2767,33 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
     BIO *ssl_cert_bio = NULL;
     BIO *ssl_key_bio = NULL;
-    int result_cert_stuff;
     if(ssl_cert_blob) {
       /* the typecast of blob->len is fine since it is guaranteed to never be
          larger than CURL_MAX_INPUT_LENGTH */
       ssl_cert_bio = BIO_new_mem_buf(ssl_cert_blob->data,
                                      (int)ssl_cert_blob->len);
       if(!ssl_cert_bio)
-        return CURLE_SSL_CERTPROBLEM;
+        result = CURLE_OUT_OF_MEMORY;
     }
-    if(SSL_SET_OPTION(key_blob)) {
+    if(!result && SSL_SET_OPTION(key_blob)) {
       ssl_key_bio = BIO_new_mem_buf(SSL_SET_OPTION(key_blob)->data,
                                     (int)SSL_SET_OPTION(key_blob)->len);
       if(!ssl_key_bio)
-        return CURLE_SSL_CERTPROBLEM;
+        result = CURLE_OUT_OF_MEMORY;
     }
-    result_cert_stuff = cert_stuff(conn, backend->ctx,
+    if(!result &&
+       !cert_stuff(conn, backend->ctx,
                    ssl_cert, ssl_cert_bio, ssl_cert_type,
                    SSL_SET_OPTION(key), ssl_key_bio,
-                   SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd));
+                   SSL_SET_OPTION(key_type), SSL_SET_OPTION(key_passwd)))
+      result = CURLE_SSL_CERTPROBLEM;
     if(ssl_cert_bio)
       BIO_free(ssl_cert_bio);
     if(ssl_key_bio)
       BIO_free(ssl_key_bio);
-    if(!result_cert_stuff) {
+    if(result)
       /* failf() is already done in cert_stuff() */
-      return CURLE_SSL_CERTPROBLEM;
-    }
+      return result;
   }
 
   ciphers = SSL_CONN_CONFIG(cipher_list);
@@ -2793,7 +2825,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   SSL_CTX_set_post_handshake_auth(backend->ctx, 1);
 #endif
 
-#ifdef USE_TLS_SRP
+#ifdef HAVE_SSL_CTX_SET_EC_CURVES
+  {
+    char *curves = SSL_CONN_CONFIG(curves);
+    if(curves) {
+      if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) {
+        failf(data, "failed setting curves list: '%s'", curves);
+        return CURLE_SSL_CIPHER;
+      }
+    }
+  }
+#endif
+
+#ifdef USE_OPENSSL_SRP
   if(ssl_authtype == CURL_TLSAUTH_SRP) {
     char * const ssl_username = SSL_SET_OPTION(username);
 
@@ -2910,7 +2954,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
               /* "If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is
                  good for all uses. If it returns zero, the certificate has no
                  valid uses." */
-              if(GetLastError() != CRYPT_E_NOT_FOUND)
+              if((HRESULT)GetLastError() != CRYPT_E_NOT_FOUND)
                 continue;
             }
             else {
@@ -2970,7 +3014,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   {
     if(ssl_cafile) {
       if(!SSL_CTX_load_verify_file(backend->ctx, ssl_cafile)) {
-        if(verifypeer) {
+        if(verifypeer && !imported_native_ca) {
           /* Fail if we insist on successfully verifying the server. */
           failf(data, "error setting certificate file: %s", ssl_cafile);
           return CURLE_SSL_CACERT_BADFILE;
@@ -2978,11 +3022,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
         /* Continue with a warning if no certificate verif is required. */
         infof(data, "error setting certificate file, continuing anyway\n");
       }
-      infof(data, "  CAfile: %s\n", ssl_cafile);
+      infof(data, " CAfile: %s\n", ssl_cafile);
     }
     if(ssl_capath) {
       if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) {
-        if(verifypeer) {
+        if(verifypeer && !imported_native_ca) {
           /* Fail if we insist on successfully verifying the server. */
           failf(data, "error setting certificate path: %s", ssl_capath);
           return CURLE_SSL_CACERT_BADFILE;
@@ -2990,7 +3034,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
         /* Continue with a warning if no certificate verif is required. */
         infof(data, "error setting certificate path, continuing anyway\n");
       }
-      infof(data, "  CApath: %s\n", ssl_capath);
+      infof(data, " CApath: %s\n", ssl_capath);
     }
   }
 #else
@@ -3000,8 +3044,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
     if(!SSL_CTX_load_verify_locations(backend->ctx, ssl_cafile, ssl_capath)) {
       if(verifypeer && !imported_native_ca) {
         /* Fail if we insist on successfully verifying the server. */
-        failf(data, "error setting certificate verify locations:\n"
-              "  CAfile: %s\n  CApath: %s",
+        failf(data, "error setting certificate verify locations:"
+              "  CAfile: %s CApath: %s",
               ssl_cafile ? ssl_cafile : "none",
               ssl_capath ? ssl_capath : "none");
         return CURLE_SSL_CACERT_BADFILE;
@@ -3015,11 +3059,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
       /* Everything is fine. */
       infof(data, "successfully set certificate verify locations:\n");
     }
-    infof(data,
-          "  CAfile: %s\n"
-          "  CApath: %s\n",
-          ssl_cafile ? ssl_cafile : "none",
-          ssl_capath ? ssl_capath : "none");
+    infof(data, " CAfile: %s\n", ssl_cafile ? ssl_cafile : "none");
+    infof(data, " CApath: %s\n", ssl_capath ? ssl_capath : "none");
   }
 #endif
 
@@ -3201,12 +3242,6 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
   struct Curl_easy *data = conn->data;
   int err;
   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
-#ifndef CURL_DISABLE_PROXY
-  long * const certverifyresult = SSL_IS_PROXY() ?
-    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
-  long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
   struct ssl_backend_data *backend = connssl->backend;
   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
               || ssl_connect_2_reading == connssl->connecting_state
@@ -3265,12 +3300,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
       reason = ERR_GET_REASON(errdetail);
 
       if((lib == ERR_LIB_SSL) &&
-         (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
+         ((reason == SSL_R_CERTIFICATE_VERIFY_FAILED) ||
+          (reason == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED))) {
         result = CURLE_PEER_FAILED_VERIFICATION;
 
         lerr = SSL_get_verify_result(backend->handle);
         if(lerr != X509_V_OK) {
-          *certverifyresult = lerr;
+          SSL_SET_OPTION_LVALUE(certverifyresult) = lerr;
           msnprintf(error_buffer, sizeof(error_buffer),
                     "SSL certificate problem: %s",
                     X509_verify_cert_error_string(lerr));
@@ -3292,12 +3328,10 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
        * the SO_ERROR is also lost.
        */
       if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+        const char * const hostname = SSL_HOST_NAME();
 #ifndef CURL_DISABLE_PROXY
-        const char * const hostname = SSL_IS_PROXY() ?
-          conn->http_proxy.host.name : conn->host.name;
         const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
 #else
-        const char * const hostname = conn->host.name;
         const long int port = conn->remote_port;
 #endif
         char extramsg[80]="";
@@ -3459,7 +3493,6 @@ typedef int numcert_t;
 
 static CURLcode get_cert_chain(struct connectdata *conn,
                                struct ssl_connect_data *connssl)
-
 {
   CURLcode result;
   STACK_OF(X509) *sk;
@@ -3752,12 +3785,6 @@ static CURLcode servercert(struct connectdata *conn,
   char error_buffer[256]="";
   char buffer[2048];
   const char *ptr;
-#ifndef CURL_DISABLE_PROXY
-  long * const certverifyresult = SSL_IS_PROXY() ?
-    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
-#else
-  long * const certverifyresult = &data->set.ssl.certverifyresult;
-#endif
   BIO *mem = BIO_new(BIO_s_mem());
   struct ssl_backend_data *backend = connssl->backend;
 
@@ -3878,9 +3905,9 @@ static CURLcode servercert(struct connectdata *conn,
       X509_free(issuer);
     }
 
-    lerr = *certverifyresult = SSL_get_verify_result(backend->handle);
-
-    if(*certverifyresult != X509_V_OK) {
+    lerr = SSL_get_verify_result(backend->handle);
+    SSL_SET_OPTION_LVALUE(certverifyresult) = lerr;
+    if(lerr != X509_V_OK) {
       if(SSL_CONN_CONFIG(verifypeer)) {
         /* We probably never reach this, because SSL_connect() will fail
            and we return earlier if verifypeer is set? */
@@ -4369,7 +4396,9 @@ static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */
   (void) unused;
 
   mdctx = EVP_MD_CTX_create();
-  EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
+  if(!mdctx)
+    return CURLE_OUT_OF_MEMORY;
+  EVP_DigestInit(mdctx, EVP_md5());
   EVP_DigestUpdate(mdctx, tmp, tmplen);
   EVP_DigestFinal_ex(mdctx, md5sum, &len);
   EVP_MD_CTX_destroy(mdctx);
@@ -4387,7 +4416,9 @@ static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
   (void) unused;
 
   mdctx = EVP_MD_CTX_create();
-  EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL);
+  if(!mdctx)
+    return CURLE_OUT_OF_MEMORY;
+  EVP_DigestInit(mdctx, EVP_sha256());
   EVP_DigestUpdate(mdctx, tmp, tmplen);
   EVP_DigestFinal_ex(mdctx, sha256sum, &len);
   EVP_MD_CTX_destroy(mdctx);
diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h
index 114dc4b..2f6e1b2 100644
--- a/lib/vtls/openssl.h
+++ b/lib/vtls/openssl.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 1c1432d..d7bc389 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -346,6 +346,8 @@ set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers)
 }
 
 #ifdef HAS_CLIENT_CERT_PATH
+
+/* Function allocates memory for store_path only if CURLE_OK is returned */
 static CURLcode
 get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
                   TCHAR **thumbprint)
@@ -388,16 +390,16 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
   if(sep == NULL)
     return CURLE_SSL_CERTPROBLEM;
 
+  *thumbprint = sep + 1;
+  if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN)
+    return CURLE_SSL_CERTPROBLEM;
+
   *sep = TEXT('\0');
   *store_path = _tcsdup(store_path_start);
   *sep = TEXT('\\');
   if(*store_path == NULL)
     return CURLE_OUT_OF_MEMORY;
 
-  *thumbprint = sep + 1;
-  if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN)
-    return CURLE_SSL_CERTPROBLEM;
-
   return CURLE_OK;
 }
 #endif
@@ -418,7 +420,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
   SCHANNEL_CRED schannel_cred;
   PCCERT_CONTEXT client_certs[1] = { NULL };
   SECURITY_STATUS sspi_status = SEC_E_OK;
-  struct curl_schannel_cred *old_cred = NULL;
+  struct Curl_schannel_cred *old_cred = NULL;
   struct in_addr addr;
 #ifdef ENABLE_IPV6
   struct in6_addr addr6;
@@ -588,7 +590,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
 
 #ifdef HAS_CLIENT_CERT_PATH
     /* client certificate */
-    if(data->set.ssl.cert || data->set.ssl.cert_blob) {
+    if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
       DWORD cert_store_name = 0;
       TCHAR *cert_store_path = NULL;
       TCHAR *cert_thumbprint_str = NULL;
@@ -598,27 +600,28 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
       FILE *fInCert = NULL;
       void *certdata = NULL;
       size_t certsize = 0;
-      bool blob = data->set.ssl.cert_blob != NULL;
+      bool blob = data->set.ssl.primary.cert_blob != NULL;
       TCHAR *cert_path = NULL;
       if(blob) {
-        certdata = data->set.ssl.cert_blob->data;
-        certsize = data->set.ssl.cert_blob->len;
+        certdata = data->set.ssl.primary.cert_blob->data;
+        certsize = data->set.ssl.primary.cert_blob->len;
       }
       else {
-        cert_path = curlx_convert_UTF8_to_tchar(data->set.ssl.cert);
+        cert_path = curlx_convert_UTF8_to_tchar(
+          data->set.ssl.primary.clientcert);
         if(!cert_path)
           return CURLE_OUT_OF_MEMORY;
 
         result = get_cert_location(cert_path, &cert_store_name,
           &cert_store_path, &cert_thumbprint_str);
 
-        if(result && (data->set.ssl.cert[0]!='\0'))
-          fInCert = fopen(data->set.ssl.cert, "rb");
+        if(result && (data->set.ssl.primary.clientcert[0]!='\0'))
+          fInCert = fopen(data->set.ssl.primary.clientcert, "rb");
 
         if(result && !fInCert) {
           failf(data, "schannel: Failed to get certificate location"
                 " or file for %s",
-                data->set.ssl.cert);
+                data->set.ssl.primary.clientcert);
           curlx_unicodefree(cert_path);
           return result;
         }
@@ -628,7 +631,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
           (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
         failf(data, "schannel: certificate format compatibility error "
                 " for %s",
-                blob ? "(memory blob)" : data->set.ssl.cert);
+                blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
         curlx_unicodefree(cert_path);
         return CURLE_SSL_CERTPROBLEM;
       }
@@ -643,7 +646,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
         size_t pwd_len = 0;
         int str_w_len = 0;
         const char *cert_showfilename_error = blob ?
-          "(memory blob)" : data->set.ssl.cert;
+          "(memory blob)" : data->set.ssl.primary.clientcert;
         curlx_unicodefree(cert_path);
         if(fInCert) {
           long cert_tell = 0;
@@ -664,7 +667,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
           fclose(fInCert);
           if(!continue_reading) {
             failf(data, "schannel: Failed to read cert file %s",
-                data->set.ssl.cert);
+                data->set.ssl.primary.clientcert);
             free(certdata);
             return CURLE_SSL_CERTPROBLEM;
           }
@@ -771,15 +774,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
       CertCloseStore(cert_store, 0);
     }
 #else
-    if(data->set.ssl.cert) {
+    if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
       failf(data, "schannel: client cert support not built in");
       return CURLE_NOT_BUILT_IN;
     }
 #endif
 
     /* allocate memory for the re-usable credential handle */
-    BACKEND->cred = (struct curl_schannel_cred *)
-      calloc(1, sizeof(struct curl_schannel_cred));
+    BACKEND->cred = (struct Curl_schannel_cred *)
+      calloc(1, sizeof(struct Curl_schannel_cred));
     if(!BACKEND->cred) {
       failf(data, "schannel: unable to allocate memory");
 
@@ -893,8 +896,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
     ISC_REQ_STREAM;
 
   /* allocate memory for the security context handle */
-  BACKEND->ctxt = (struct curl_schannel_ctxt *)
-    calloc(1, sizeof(struct curl_schannel_ctxt));
+  BACKEND->ctxt = (struct Curl_schannel_ctxt *)
+    calloc(1, sizeof(struct Curl_schannel_ctxt));
   if(!BACKEND->ctxt) {
     failf(data, "schannel: unable to allocate memory");
     return CURLE_OUT_OF_MEMORY;
@@ -1178,6 +1181,10 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
         failf(data, "schannel: SNI or certificate check failed: %s",
               Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
         return CURLE_PEER_FAILED_VERIFICATION;
+      case SEC_E_UNTRUSTED_ROOT:
+        failf(data, "schannel: %s",
+              Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
+        return CURLE_PEER_FAILED_VERIFICATION;
         /*
           case SEC_E_INVALID_HANDLE:
           case SEC_E_INVALID_TOKEN:
@@ -1401,7 +1408,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
   /* save the current session data for possible re-use */
   if(SSL_SET_OPTION(primary.sessionid)) {
     bool incache;
-    struct curl_schannel_cred *old_cred = NULL;
+    struct Curl_schannel_cred *old_cred = NULL;
 
     Curl_ssl_sessionid_lock(conn);
     incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
@@ -1417,7 +1424,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
     }
     if(!incache) {
       result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred,
-                                     sizeof(struct curl_schannel_cred),
+                                     sizeof(struct Curl_schannel_cred),
                                      sockindex);
       if(result) {
         Curl_ssl_sessionid_unlock(conn);
@@ -2099,7 +2106,7 @@ static void Curl_schannel_close(struct connectdata *conn, int sockindex)
 static void Curl_schannel_session_free(void *ptr)
 {
   /* this is expected to be called under sessionid lock */
-  struct curl_schannel_cred *cred = ptr;
+  struct Curl_schannel_cred *cred = ptr;
 
   cred->refcount--;
   if(cred->refcount == 0) {
diff --git a/lib/vtls/schannel.h b/lib/vtls/schannel.h
index ee8d7d4..085b3f4 100644
--- a/lib/vtls/schannel.h
+++ b/lib/vtls/schannel.h
@@ -8,11 +8,11 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
- * Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -70,20 +70,20 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex);
 #endif
 #endif
 
-struct curl_schannel_cred {
+struct Curl_schannel_cred {
   CredHandle cred_handle;
   TimeStamp time_stamp;
   int refcount;
 };
 
-struct curl_schannel_ctxt {
+struct Curl_schannel_ctxt {
   CtxtHandle ctxt_handle;
   TimeStamp time_stamp;
 };
 
 struct ssl_backend_data {
-  struct curl_schannel_cred *cred;
-  struct curl_schannel_ctxt *ctxt;
+  struct Curl_schannel_cred *cred;
+  struct Curl_schannel_ctxt *ctxt;
   SecPkgContext_StreamSizes stream_sizes;
   size_t encdata_length, decdata_length;
   size_t encdata_offset, decdata_offset;
diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c
index ab7be39..31b3b2f 100644
--- a/lib/vtls/schannel_verify.c
+++ b/lib/vtls/schannel_verify.c
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c
index 2627aff..8ef60cb 100644
--- a/lib/vtls/sectransp.c
+++ b/lib/vtls/sectransp.c
@@ -10,7 +10,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -1397,11 +1397,16 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
   const struct curl_blob *ssl_cablob = NULL;
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
-  char * const ssl_cert = SSL_SET_OPTION(cert);
-  const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(cert_blob);
+  char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
+  const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
+#ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#else
+  const char * const hostname = conn->host.name;
+  const long int port = conn->remote_port;
+#endif
 #ifdef ENABLE_IPV6
   struct in6_addr addr;
 #else
@@ -1606,8 +1611,11 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
                                                        &kCFTypeArrayCallBacks);
 
 #ifdef USE_NGHTTP2
-      if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
-         (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+      if(data->set.httpversion >= CURL_HTTP_VERSION_2
+#ifndef CURL_DISABLE_PROXY
+         && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
+#endif
+        ) {
         CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID));
         infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
       }
@@ -1962,7 +1970,7 @@ static CURLcode sectransp_connect_step1(struct connectdata *conn,
     else {
       CURLcode result;
       ssl_sessionid =
-        aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
+        aprintf("%s:%d:%d:%s:%ld", ssl_cafile,
                 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
       ssl_sessionid_len = strlen(ssl_sessionid);
 
@@ -2181,7 +2189,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data,
     if(res < 0) {
       free(certbuf);
       CFRelease(array);
-      failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
+      failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
             n, offset);
       return CURLE_SSL_CACERT_BADFILE;
     }
@@ -2379,8 +2387,12 @@ sectransp_connect_step2(struct connectdata *conn, int sockindex)
   OSStatus err;
   SSLCipherSuite cipher;
   SSLProtocol protocol = 0;
+#ifndef CURL_DISABLE_PROXY
   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
     conn->host.name;
+#else
+  const char * const hostname = conn->host.name;
+#endif
 
   DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
               || ssl_connect_2_reading == connssl->connecting_state
diff --git a/lib/vtls/sectransp.h b/lib/vtls/sectransp.h
index 5cec797..0febd66 100644
--- a/lib/vtls/sectransp.h
+++ b/lib/vtls/sectransp.h
@@ -8,11 +8,11 @@
  *                             \___|\___/|_| \_\_____|
  *
  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
- * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 281043a..3bd51fd 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -138,6 +138,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
      Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
      Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
      Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
+     Curl_safe_strcasecompare(data->curves, needle->curves) &&
      Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
     return TRUE;
 
@@ -164,6 +165,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
   CLONE_STRING(cipher_list);
   CLONE_STRING(cipher_list13);
   CLONE_STRING(pinned_key);
+  CLONE_STRING(curves);
 
   return TRUE;
 }
@@ -179,6 +181,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
   Curl_safefree(sslc->cipher_list13);
   Curl_safefree(sslc->pinned_key);
   Curl_safefree(sslc->cert_blob);
+  Curl_safefree(sslc->curves);
 }
 
 #ifdef USE_SSL
@@ -362,7 +365,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
                            size_t *idsize, /* set 0 if unknown */
                            int sockindex)
 {
-  struct curl_ssl_session *check;
+  struct Curl_ssl_session *check;
   struct Curl_easy *data = conn->data;
   size_t i;
   long *general_age;
@@ -429,7 +432,7 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
 /*
  * Kill a single session ID entry in the cache.
  */
-void Curl_ssl_kill_session(struct curl_ssl_session *session)
+void Curl_ssl_kill_session(struct Curl_ssl_session *session)
 {
   if(session->sessionid) {
     /* defensive check */
@@ -456,7 +459,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
   struct Curl_easy *data = conn->data;
 
   for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
-    struct curl_ssl_session *check = &data->state.session[i];
+    struct Curl_ssl_session *check = &data->state.session[i];
 
     if(check->sessionid == ssl_sessionid) {
       Curl_ssl_kill_session(check);
@@ -478,7 +481,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
 {
   size_t i;
   struct Curl_easy *data = conn->data; /* the mother of all structs */
-  struct curl_ssl_session *store = &data->state.session[0];
+  struct Curl_ssl_session *store = &data->state.session[0];
   long oldest_age = data->state.session[0].age; /* zero if unused */
   char *clone_host;
   char *clone_conn_to_host;
@@ -664,13 +667,13 @@ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data)
  */
 CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount)
 {
-  struct curl_ssl_session *session;
+  struct Curl_ssl_session *session;
 
   if(data->state.session)
     /* this is just a precaution to prevent multiple inits */
     return CURLE_OK;
 
-  session = calloc(amount, sizeof(struct curl_ssl_session));
+  session = calloc(amount, sizeof(struct Curl_ssl_session));
   if(!session)
     return CURLE_OUT_OF_MEMORY;
 
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index bcc8444..f4cab99 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -131,12 +131,26 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
                    CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
 #define SSL_SET_OPTION(var)                                             \
   (SSL_IS_PROXY() ? data->set.proxy_ssl.var : data->set.ssl.var)
+#define SSL_SET_OPTION_LVALUE(var)                                      \
+  (*(SSL_IS_PROXY() ? &data->set.proxy_ssl.var : &data->set.ssl.var))
 #define SSL_CONN_CONFIG(var)                                            \
   (SSL_IS_PROXY() ? conn->proxy_ssl_config.var : conn->ssl_config.var)
+#define SSL_HOST_NAME()                                                 \
+  (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name)
+#define SSL_HOST_DISPNAME()                                             \
+  (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname)
+#define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY()                            \
+  ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]                     \
+  : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG])
 #else
 #define SSL_IS_PROXY() FALSE
 #define SSL_SET_OPTION(var) data->set.ssl.var
+#define SSL_SET_OPTION_LVALUE(var) data->set.ssl.var
 #define SSL_CONN_CONFIG(var) conn->ssl_config.var
+#define SSL_HOST_NAME() conn->host.name
+#define SSL_HOST_DISPNAME() conn->host.dispname
+#define SSL_PINNED_PUB_KEY()                                            \
+  data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]
 #endif
 
 bool Curl_ssl_config_matches(struct ssl_primary_config *data,
@@ -221,7 +235,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
  * take sessionid object ownership from sessionid cache
  * (e.g. decrement refcount).
  */
-void Curl_ssl_kill_session(struct curl_ssl_session *session);
+void Curl_ssl_kill_session(struct Curl_ssl_session *session);
 /* delete a session from the cache
  * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
  * This will call engine-specific curlssl_session_free function, which must
diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c
index 7b2a124..44ee2d9 100644
--- a/lib/vtls/wolfssl.c
+++ b/lib/vtls/wolfssl.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -353,8 +353,8 @@ wolfssl_connect_step1(struct connectdata *conn,
                                       SSL_CONN_CONFIG(CApath))) {
       if(SSL_CONN_CONFIG(verifypeer)) {
         /* Fail if we insist on successfully verifying the server. */
-        failf(data, "error setting certificate verify locations:\n"
-              "  CAfile: %s\n  CApath: %s",
+        failf(data, "error setting certificate verify locations:"
+              " CAfile: %s CApath: %s",
               SSL_CONN_CONFIG(CAfile)?
               SSL_CONN_CONFIG(CAfile): "none",
               SSL_CONN_CONFIG(CApath)?
@@ -372,21 +372,19 @@ wolfssl_connect_step1(struct connectdata *conn,
       /* Everything is fine. */
       infof(data, "successfully set certificate verify locations:\n");
     }
-    infof(data,
-          "  CAfile: %s\n"
-          "  CApath: %s\n",
-          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
-          "none",
-          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
-          "none");
+    infof(data, " CAfile: %s\n",
+          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none");
+    infof(data, " CApath: %s\n",
+          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none");
   }
 
   /* Load the client certificate, and private key */
-  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+  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_file(backend->ctx, SSL_SET_OPTION(cert),
-                                     file_type) != 1) {
+    if(SSL_CTX_use_certificate_file(backend->ctx,
+                                    SSL_SET_OPTION(primary.clientcert),
+                                    file_type) != 1) {
       failf(data, "unable to use client certificate (no key or wrong pass"
             " phrase?)");
       return CURLE_SSL_CONNECT_ERROR;
diff --git a/lib/vtls/wolfssl.h b/lib/vtls/wolfssl.h
index 2b9673c..d411e69 100644
--- a/lib/vtls/wolfssl.h
+++ b/lib/vtls/wolfssl.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/warnless.c b/lib/warnless.c
index cfd5e8e..908ee6c 100644
--- a/lib/warnless.c
+++ b/lib/warnless.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/warnless.h b/lib/warnless.h
index ab78f94..ca37378 100644
--- a/lib/warnless.h
+++ b/lib/warnless.h
@@ -11,7 +11,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/wildcard.c b/lib/wildcard.c
index e94d3c5..105bcce 100644
--- a/lib/wildcard.c
+++ b/lib/wildcard.c
@@ -5,11 +5,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/wildcard.h b/lib/wildcard.h
index 306c8c9..081be9e 100644
--- a/lib/wildcard.h
+++ b/lib/wildcard.h
@@ -7,11 +7,11 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2010 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
@@ -39,18 +39,18 @@ typedef enum {
   CURLWC_ERROR, /* error cases */
   CURLWC_DONE   /* if is wildcard->state == CURLWC_DONE wildcard loop
                    will end */
-} curl_wildcard_states;
+} wildcard_states;
 
-typedef void (*curl_wildcard_dtor)(void *ptr);
+typedef void (*wildcard_dtor)(void *ptr);
 
 /* struct keeping information about wildcard download process */
 struct WildcardData {
-  curl_wildcard_states state;
+  wildcard_states state;
   char *path; /* path to the directory, where we trying wildcard-match */
   char *pattern; /* wildcard pattern */
-  struct curl_llist filelist; /* llist with struct Curl_fileinfo */
+  struct Curl_llist filelist; /* llist with struct Curl_fileinfo */
   void *protdata; /* pointer to protocol specific temporary data */
-  curl_wildcard_dtor dtor;
+  wildcard_dtor dtor;
   void *customptr;  /* for CURLOPT_CHUNK_DATA pointer */
 };
 
diff --git a/lib/x509asn1.c b/lib/x509asn1.c
index 52747d5..d7cf9eb 100644
--- a/lib/x509asn1.c
+++ b/lib/x509asn1.c
@@ -9,7 +9,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
diff --git a/lib/x509asn1.h b/lib/x509asn1.h
index 0b7fb88..8497144 100644
--- a/lib/x509asn1.h
+++ b/lib/x509asn1.h
@@ -12,7 +12,7 @@
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.se/docs/copyright.html.
  *
  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  * copies of the Software, and permit persons to whom the Software is
-- 
cgit v0.12