瀏覽代碼

curl 2024-12-11 (75a2079d)

Code extracted from:

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

at commit 75a2079d5c28debb2eaa848ca9430f1fe0d7844c (curl-8_11_1).
Curl Upstream 10 月之前
父節點
當前提交
4cebf01c70
共有 100 個文件被更改,包括 2683 次插入2636 次删除
  1. 19 33
      CMake/CurlSymbolHiding.cmake
  2. 2 19
      CMake/CurlTests.c
  3. 6 7
      CMake/FindBearSSL.cmake
  4. 7 7
      CMake/FindBrotli.cmake
  5. 22 12
      CMake/FindCares.cmake
  6. 58 22
      CMake/FindGSS.cmake
  7. 9 8
      CMake/FindLibgsasl.cmake
  8. 9 8
      CMake/FindLibidn2.cmake
  9. 6 6
      CMake/FindLibpsl.cmake
  10. 9 8
      CMake/FindLibssh.cmake
  11. 6 6
      CMake/FindLibssh2.cmake
  12. 9 8
      CMake/FindLibuv.cmake
  13. 31 35
      CMake/FindMSH3.cmake
  14. 65 67
      CMake/FindMbedTLS.cmake
  15. 6 6
      CMake/FindNGHTTP2.cmake
  16. 6 6
      CMake/FindNGHTTP3.cmake
  17. 15 10
      CMake/FindNGTCP2.cmake
  18. 9 8
      CMake/FindNettle.cmake
  19. 29 35
      CMake/FindQuiche.cmake
  20. 64 34
      CMake/FindRustls.cmake
  21. 8 7
      CMake/FindWolfSSH.cmake
  22. 47 49
      CMake/FindWolfSSL.cmake
  23. 6 8
      CMake/FindZstd.cmake
  24. 13 7
      CMake/Macros.cmake
  25. 9 33
      CMake/OtherTests.cmake
  26. 61 42
      CMake/PickyWarnings.cmake
  27. 4 5
      CMake/Platforms/WindowsCache.cmake
  28. 9 10
      CMake/curl-config.cmake.in
  29. 323 236
      CMakeLists.txt
  30. 25 19
      include/curl/curl.h
  31. 3 3
      include/curl/curlver.h
  32. 7 11
      include/curl/multi.h
  33. 25 21
      lib/CMakeLists.txt
  34. 3 3
      lib/Makefile.inc
  35. 16 18
      lib/altsvc.c
  36. 9 18
      lib/asyn-ares.c
  37. 4 4
      lib/asyn-thread.c
  38. 4 4
      lib/bufq.c
  39. 4 4
      lib/c-hyper.c
  40. 3 3
      lib/cf-h1-proxy.c
  41. 19 18
      lib/cf-h2-proxy.c
  42. 2 2
      lib/cf-haproxy.c
  43. 17 10
      lib/cf-https-connect.c
  44. 214 116
      lib/cf-socket.c
  45. 5 6
      lib/cf-socket.h
  46. 31 28
      lib/cfilters.c
  47. 12 24
      lib/conncache.c
  48. 8 8
      lib/connect.c
  49. 8 8
      lib/content_encoding.c
  50. 450 537
      lib/cookie.c
  51. 21 17
      lib/cookie.h
  52. 46 60
      lib/curl_addrinfo.c
  53. 2 0
      lib/curl_addrinfo.h
  54. 34 20
      lib/curl_config.h.cmake
  55. 3 3
      lib/curl_fnmatch.c
  56. 1 1
      lib/curl_gssapi.c
  57. 14 16
      lib/curl_hmac.h
  58. 7 7
      lib/curl_md5.h
  59. 2 0
      lib/curl_memory.h
  60. 23 11
      lib/curl_ntlm_core.c
  61. 1 1
      lib/curl_rtmp.c
  62. 33 11
      lib/curl_setup.h
  63. 1 1
      lib/curl_sha256.h
  64. 1 1
      lib/curl_sha512_256.c
  65. 3 3
      lib/curl_threads.c
  66. 1 1
      lib/curl_threads.h
  67. 7 7
      lib/curl_trc.c
  68. 11 14
      lib/curl_trc.h
  69. 0 9
      lib/curlx.h
  70. 6 7
      lib/cw-out.c
  71. 21 22
      lib/doh.c
  72. 2 2
      lib/dynhds.c
  73. 36 29
      lib/easy.c
  74. 1 1
      lib/easyif.h
  75. 8 6
      lib/escape.c
  76. 1 1
      lib/file.c
  77. 26 22
      lib/formdata.c
  78. 1 1
      lib/formdata.h
  79. 129 293
      lib/ftp.c
  80. 2 2
      lib/ftplistparser.c
  81. 2 2
      lib/getenv.c
  82. 14 11
      lib/getinfo.c
  83. 1 1
      lib/headers.c
  84. 32 38
      lib/hmac.c
  85. 13 11
      lib/hostip.c
  86. 4 0
      lib/hostip4.c
  87. 23 16
      lib/hsts.c
  88. 84 243
      lib/http.c
  89. 0 3
      lib/http.h
  90. 5 5
      lib/http1.c
  91. 103 49
      lib/http2.c
  92. 5 0
      lib/http2.h
  93. 18 31
      lib/http_aws_sigv4.c
  94. 2 2
      lib/http_chunks.c
  95. 2 2
      lib/http_digest.c
  96. 3 3
      lib/http_negotiate.c
  97. 148 5
      lib/http_proxy.c
  98. 6 0
      lib/http_proxy.h
  99. 13 13
      lib/imap.c
  100. 25 25
      lib/krb5.c

+ 19 - 33
CMake/CurlSymbolHiding.cmake

@@ -21,8 +21,6 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-include(CheckCSourceCompiles)
-
 option(CURL_HIDDEN_SYMBOLS "Hide libcurl internal symbols (=hide all symbols that are not officially external)" ON)
 option(CURL_HIDDEN_SYMBOLS "Hide libcurl internal symbols (=hide all symbols that are not officially external)" ON)
 mark_as_advanced(CURL_HIDDEN_SYMBOLS)
 mark_as_advanced(CURL_HIDDEN_SYMBOLS)
 
 
@@ -33,48 +31,36 @@ if(WIN32 AND (ENABLE_DEBUG OR ENABLE_CURLDEBUG))
   set(CURL_HIDDEN_SYMBOLS OFF)
   set(CURL_HIDDEN_SYMBOLS OFF)
 endif()
 endif()
 
 
-if(CURL_HIDDEN_SYMBOLS)
-  set(_supports_symbol_hiding FALSE)
+set(CURL_HIDES_PRIVATE_SYMBOLS FALSE)
+unset(CURL_EXTERN_SYMBOL)
+unset(CURL_CFLAG_SYMBOLS_HIDE)
 
 
+if(CURL_HIDDEN_SYMBOLS)
   if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
   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")
+    set(CURL_HIDES_PRIVATE_SYMBOLS TRUE)
+    set(CURL_EXTERN_SYMBOL "__attribute__((__visibility__(\"default\")))")
+    set(CURL_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
   elseif(CMAKE_COMPILER_IS_GNUCC)
   elseif(CMAKE_COMPILER_IS_GNUCC)
     if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
     if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
       # Note: This is considered buggy prior to 4.0 but the autotools do not care, so let us ignore that fact
       # Note: This is considered buggy prior to 4.0 but the autotools do not care, so let us ignore that fact
-      set(_supports_symbol_hiding TRUE)
-      set(_symbol_extern "__attribute__ ((__visibility__ (\"default\")))")
-      set(_cflag_symbols_hide "-fvisibility=hidden")
+      set(CURL_HIDES_PRIVATE_SYMBOLS TRUE)
+      set(CURL_EXTERN_SYMBOL "__attribute__((__visibility__(\"default\")))")
+      set(CURL_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
     endif()
     endif()
   elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
   elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
-    set(_supports_symbol_hiding TRUE)
-    set(_symbol_extern "__global")
-    set(_cflag_symbols_hide "-xldscope=hidden")
-  elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
-    # Note: This should probably just check for version 9.1.045 but I am not 100% sure
-    #       so let us do it the same way autotools do.
-    set(_supports_symbol_hiding TRUE)
-    set(_symbol_extern "__attribute__ ((__visibility__ (\"default\")))")
-    set(_cflag_symbols_hide "-fvisibility=hidden")
-    check_c_source_compiles("#include <stdio.h>
-      int main(void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
-    if(NOT _no_bug)
-      set(_supports_symbol_hiding FALSE)
-      set(_symbol_extern "")
-      set(_cflag_symbols_hide "")
-    endif()
+    set(CURL_HIDES_PRIVATE_SYMBOLS TRUE)
+    set(CURL_EXTERN_SYMBOL "__global")
+    set(CURL_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
+  elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)  # Requires 9.1.045
+    set(CURL_HIDES_PRIVATE_SYMBOLS TRUE)
+    set(CURL_EXTERN_SYMBOL "__attribute__((__visibility__(\"default\")))")
+    set(CURL_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
   elseif(MSVC)
   elseif(MSVC)
-    set(_supports_symbol_hiding TRUE)
+    set(CURL_HIDES_PRIVATE_SYMBOLS TRUE)
   endif()
   endif()
-
-  set(CURL_HIDES_PRIVATE_SYMBOLS ${_supports_symbol_hiding})
 else()
 else()
   if(MSVC)
   if(MSVC)
+    # Note: This option is prone to export non-curl extra symbols.
     set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
     set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
   endif()
   endif()
-  set(CURL_HIDES_PRIVATE_SYMBOLS FALSE)
 endif()
 endif()
-
-set(CURL_CFLAG_SYMBOLS_HIDE ${_cflag_symbols_hide})
-set(CURL_EXTERN_SYMBOL ${_symbol_extern})

+ 2 - 19
CMake/CurlTests.c

@@ -50,6 +50,7 @@ int main(void)
   int flags = 0;
   int flags = 0;
   if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
   if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
     return 1;
     return 1;
+  ;
   return 0;
   return 0;
 }
 }
 #endif
 #endif
@@ -159,15 +160,12 @@ int main(void) { return 0; }
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                        && LARGE_OFF_T % 2147483647 == 1)
                        && LARGE_OFF_T % 2147483647 == 1)
                       ? 1 : -1];
                       ? 1 : -1];
-int main(void) { ; return 0; }
+int main(void) { return 0; }
 #endif
 #endif
 
 
 #ifdef HAVE_IOCTLSOCKET
 #ifdef HAVE_IOCTLSOCKET
 /* includes start */
 /* includes start */
 #ifdef _WIN32
 #ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
 #  include <winsock2.h>
 #  include <winsock2.h>
 #endif
 #endif
 int main(void)
 int main(void)
@@ -184,9 +182,6 @@ int main(void)
 #ifdef HAVE_IOCTLSOCKET_CAMEL
 #ifdef HAVE_IOCTLSOCKET_CAMEL
 /* includes start */
 /* includes start */
 #ifdef _WIN32
 #ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
 #  include <winsock2.h>
 #  include <winsock2.h>
 #endif
 #endif
 int main(void)
 int main(void)
@@ -202,9 +197,6 @@ int main(void)
 #ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
 #ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
 /* includes start */
 /* includes start */
 #ifdef _WIN32
 #ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
 #  include <winsock2.h>
 #  include <winsock2.h>
 #endif
 #endif
 int main(void)
 int main(void)
@@ -221,9 +213,6 @@ int main(void)
 #ifdef HAVE_IOCTLSOCKET_FIONBIO
 #ifdef HAVE_IOCTLSOCKET_FIONBIO
 /* includes start */
 /* includes start */
 #ifdef _WIN32
 #ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
 #  include <winsock2.h>
 #  include <winsock2.h>
 #endif
 #endif
 int main(void)
 int main(void)
@@ -296,9 +285,6 @@ int main(void)
 #ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
 #ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
 /* includes start */
 /* includes start */
 #ifdef _WIN32
 #ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
 #  include <winsock2.h>
 #  include <winsock2.h>
 #endif
 #endif
 /* includes start */
 /* includes start */
@@ -409,9 +395,6 @@ int main(void)
 #ifdef HAVE_WIN32_WINNT
 #ifdef HAVE_WIN32_WINNT
 /* includes start */
 /* includes start */
 #ifdef _WIN32
 #ifdef _WIN32
-#  ifndef WIN32_LEAN_AND_MEAN
-#    define WIN32_LEAN_AND_MEAN
-#  endif
 #  ifndef NOGDI
 #  ifndef NOGDI
 #    define NOGDI
 #    define NOGDI
 #  endif
 #  endif

+ 6 - 7
CMake/FindBearSSL.cmake

@@ -21,19 +21,18 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-# Find the bearssl library
+# Find the BearSSL library
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# BEARSSL_INCLUDE_DIR   The bearssl include directory
-# BEARSSL_INCLUDE_DIRS  The bearssl include directory (deprecated)
-# BEARSSL_LIBRARY       Path to bearssl library
+# - `BEARSSL_INCLUDE_DIR`:   The BearSSL include directory.
+# - `BEARSSL_LIBRARY`:       Path to `bearssl` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# BEARSSL_FOUND         System has bearssl
-# BEARSSL_INCLUDE_DIRS  The bearssl include directories
-# BEARSSL_LIBRARIES     The bearssl library names
+# - `BEARSSL_FOUND`:         System has BearSSL.
+# - `BEARSSL_INCLUDE_DIRS`:  The BearSSL include directories.
+# - `BEARSSL_LIBRARIES`:     The BearSSL library names.
 
 
 if(DEFINED BEARSSL_INCLUDE_DIRS AND NOT DEFINED BEARSSL_INCLUDE_DIR)
 if(DEFINED BEARSSL_INCLUDE_DIRS AND NOT DEFINED BEARSSL_INCLUDE_DIR)
   message(WARNING "BEARSSL_INCLUDE_DIRS is deprecated, use BEARSSL_INCLUDE_DIR instead.")
   message(WARNING "BEARSSL_INCLUDE_DIRS is deprecated, use BEARSSL_INCLUDE_DIR instead.")

+ 7 - 7
CMake/FindBrotli.cmake

@@ -25,16 +25,16 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# BROTLI_INCLUDE_DIR   The brotli include directory
-# BROTLICOMMON_LIBRARY Path to brotlicommon library
-# BROTLIDEC_LIBRARY    Path to brotlidec library
+# - `BROTLI_INCLUDE_DIR`:    The brotli include directory.
+# - `BROTLICOMMON_LIBRARY`:  Path to `brotlicommon` library.
+# - `BROTLIDEC_LIBRARY`:     Path to `brotlidec` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# BROTLI_FOUND         System has brotli
-# BROTLI_INCLUDE_DIRS  The brotli include directories
-# BROTLI_LIBRARIES     The brotli library names
-# BROTLI_VERSION       Version of brotli
+# - `BROTLI_FOUND`:          System has brotli.
+# - `BROTLI_INCLUDE_DIRS`:   The brotli include directories.
+# - `BROTLI_LIBRARIES`:      The brotli library names.
+# - `BROTLI_VERSION`:        Version of brotli.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)

+ 22 - 12
CMake/FindCares.cmake

@@ -25,15 +25,15 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# CARES_INCLUDE_DIR   The c-ares include directory
-# CARES_LIBRARY       Path to c-ares library
+# - `CARES_INCLUDE_DIR`:   The c-ares include directory.
+# - `CARES_LIBRARY`:       Path to `cares` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# CARES_FOUND         System has c-ares
-# CARES_INCLUDE_DIRS  The c-ares include directories
-# CARES_LIBRARIES     The c-ares library names
-# CARES_VERSION       Version of c-ares
+# - `CARES_FOUND`:         System has c-ares.
+# - `CARES_INCLUDE_DIRS`:  The c-ares include directories.
+# - `CARES_LIBRARIES`:     The c-ares library names.
+# - `CARES_VERSION`:       Version of c-ares.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
@@ -55,12 +55,22 @@ find_library(CARES_LIBRARY NAMES ${CARES_NAMES} "cares"
 if(PC_CARES_VERSION)
 if(PC_CARES_VERSION)
   set(CARES_VERSION ${PC_CARES_VERSION})
   set(CARES_VERSION ${PC_CARES_VERSION})
 elseif(CARES_INCLUDE_DIR AND EXISTS "${CARES_INCLUDE_DIR}/ares_version.h")
 elseif(CARES_INCLUDE_DIR AND EXISTS "${CARES_INCLUDE_DIR}/ares_version.h")
-  set(_version_regex "#[\t ]*define[\t ]+ARES_VERSION_STR[\t ]+\"([^\"]*)\"")
-  file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str REGEX "${_version_regex}")
-  string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
-  set(CARES_VERSION "${_version_str}")
-  unset(_version_regex)
-  unset(_version_str)
+  set(_version_regex1 "#[\t ]*define[\t ]+ARES_VERSION_MAJOR[\t ]+([0-9]+).*")
+  set(_version_regex2 "#[\t ]*define[\t ]+ARES_VERSION_MINOR[\t ]+([0-9]+).*")
+  set(_version_regex3 "#[\t ]*define[\t ]+ARES_VERSION_PATCH[\t ]+([0-9]+).*")
+  file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str1 REGEX "${_version_regex1}")
+  file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str2 REGEX "${_version_regex2}")
+  file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str3 REGEX "${_version_regex3}")
+  string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
+  string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
+  string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
+  set(CARES_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
+  unset(_version_regex1)
+  unset(_version_regex2)
+  unset(_version_regex3)
+  unset(_version_str1)
+  unset(_version_str2)
+  unset(_version_str3)
 endif()
 endif()
 
 
 include(FindPackageHandleStandardArgs)
 include(FindPackageHandleStandardArgs)

+ 58 - 22
CMake/FindGSS.cmake

@@ -25,20 +25,21 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# GSS_ROOT_DIR      Set this variable to the root installation of GSS
+# - `GSS_ROOT_DIR`:      Set this variable to the root installation of GSS. (also supported as environment)
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# GSS_FOUND         System has the Heimdal library
-# GSS_FLAVOUR       "MIT" or "Heimdal" if anything found
-# GSS_INCLUDE_DIRS  The GSS include directories
-# GSS_LIBRARIES     The GSS library names
-# GSS_LIBRARY_DIRS  The GSS library directories
-# GSS_LDFLAGS       Required linker flags
-# GSS_CFLAGS        Required compiler flags
-# GSS_VERSION       This is set to version advertised by pkg-config or read from manifest.
-#                   In case the library is found but no version info available it is set to "unknown"
+# - `GSS_FOUND`:         System has the Heimdal library.
+# - `GSS_FLAVOUR`:       "GNU", "MIT" or "Heimdal" if anything found.
+# - `GSS_INCLUDE_DIRS`:  The GSS include directories.
+# - `GSS_LIBRARIES`:     The GSS library names.
+# - `GSS_LIBRARY_DIRS`:  The GSS library directories.
+# - `GSS_PC_REQUIRES`:   The GSS pkg-config packages.
+# - `GSS_CFLAGS`:        Required compiler flags.
+# - `GSS_VERSION`:       This is set to version advertised by pkg-config or read from manifest.
+#                        In case the library is found but no version info available it is set to "unknown"
 
 
+set(_gnu_modname "gss")
 set(_mit_modname "mit-krb5-gssapi")
 set(_mit_modname "mit-krb5-gssapi")
 set(_heimdal_modname "heimdal-gssapi")
 set(_heimdal_modname "heimdal-gssapi")
 
 
@@ -55,7 +56,7 @@ set(_gss_root_hints
 if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
 if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
   if(CURL_USE_PKGCONFIG)
   if(CURL_USE_PKGCONFIG)
     find_package(PkgConfig QUIET)
     find_package(PkgConfig QUIET)
-    pkg_search_module(_GSS ${_mit_modname} ${_heimdal_modname})
+    pkg_search_module(_GSS ${_gnu_modname} ${_mit_modname} ${_heimdal_modname})
     list(APPEND _gss_root_hints "${_GSS_PREFIX}")
     list(APPEND _gss_root_hints "${_GSS_PREFIX}")
   endif()
   endif()
   if(WIN32)
   if(WIN32)
@@ -90,7 +91,7 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
       RESULT_VARIABLE _gss_configure_failed
       RESULT_VARIABLE _gss_configure_failed
       OUTPUT_STRIP_TRAILING_WHITESPACE
       OUTPUT_STRIP_TRAILING_WHITESPACE
     )
     )
-    message(STATUS "FindGSS CFLAGS: ${_GSS_CFLAGS}")
+    message(STATUS "FindGSS krb5-config --cflags: ${_GSS_CFLAGS}")
     if(NOT _gss_configure_failed)  # 0 means success
     if(NOT _gss_configure_failed)  # 0 means success
       # Should also work in an odd case when multiple directories are given
       # Should also work in an odd case when multiple directories are given
       string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
       string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
@@ -113,7 +114,7 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
       RESULT_VARIABLE _gss_configure_failed
       RESULT_VARIABLE _gss_configure_failed
       OUTPUT_STRIP_TRAILING_WHITESPACE
       OUTPUT_STRIP_TRAILING_WHITESPACE
     )
     )
-    message(STATUS "FindGSS LDFLAGS: ${_gss_lib_flags}")
+    message(STATUS "FindGSS krb5-config --libs: ${_gss_lib_flags}")
 
 
     if(NOT _gss_configure_failed)  # 0 means success
     if(NOT _gss_configure_failed)  # 0 means success
       # This script gives us libraries and link directories. Blah. We have to deal with it.
       # This script gives us libraries and link directories. Blah. We have to deal with it.
@@ -128,8 +129,6 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
         elseif(_flag MATCHES "^-L.*")
         elseif(_flag MATCHES "^-L.*")
           string(REGEX REPLACE "^-L" "" _val "${_flag}")
           string(REGEX REPLACE "^-L" "" _val "${_flag}")
           list(APPEND _GSS_LIBRARY_DIRS "${_val}")
           list(APPEND _GSS_LIBRARY_DIRS "${_val}")
-        else()
-          list(APPEND _GSS_LDFLAGS "${_flag}")
         endif()
         endif()
       endforeach()
       endforeach()
     endif()
     endif()
@@ -175,6 +174,7 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
     )
     )
 
 
     if(_GSS_INCLUDE_DIRS)  # jay, we have found something
     if(_GSS_INCLUDE_DIRS)  # jay, we have found something
+      cmake_push_check_state()
       set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}")
       set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}")
       check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers)
       check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers)
 
 
@@ -189,8 +189,8 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
         if(_gss_have_roken_h OR _gss_have_heimdal_roken_h)
         if(_gss_have_roken_h OR _gss_have_heimdal_roken_h)
           set(GSS_FLAVOUR "Heimdal")
           set(GSS_FLAVOUR "Heimdal")
         endif()
         endif()
-        list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__")
       endif()
       endif()
+      cmake_pop_check_state()
     else()
     else()
       # I am not convinced if this is the right way but this is what autotools do at the moment
       # I am not convinced if this is the right way but this is what autotools do at the moment
       find_path(_GSS_INCLUDE_DIRS NAMES "gssapi.h"
       find_path(_GSS_INCLUDE_DIRS NAMES "gssapi.h"
@@ -203,6 +203,18 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
 
 
       if(_GSS_INCLUDE_DIRS)
       if(_GSS_INCLUDE_DIRS)
         set(GSS_FLAVOUR "Heimdal")
         set(GSS_FLAVOUR "Heimdal")
+      else()
+        find_path(_GSS_INCLUDE_DIRS NAMES "gss.h"
+          HINTS
+            ${_gss_root_hints}
+          PATH_SUFFIXES
+            "include"
+        )
+
+        if(_GSS_INCLUDE_DIRS)
+          set(GSS_FLAVOUR "GNU")
+          set(GSS_PC_REQUIRES "gss")
+        endif()
       endif()
       endif()
     endif()
     endif()
 
 
@@ -216,14 +228,18 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
       if(WIN32)
       if(WIN32)
         if(CMAKE_SIZEOF_VOID_P EQUAL 8)
         if(CMAKE_SIZEOF_VOID_P EQUAL 8)
           list(APPEND _gss_libdir_suffixes "lib/AMD64")
           list(APPEND _gss_libdir_suffixes "lib/AMD64")
-          if(GSS_FLAVOUR STREQUAL "MIT")
+          if(GSS_FLAVOUR STREQUAL "GNU")
+            set(_gss_libname "gss")
+          elseif(GSS_FLAVOUR STREQUAL "MIT")
             set(_gss_libname "gssapi64")
             set(_gss_libname "gssapi64")
           else()
           else()
             set(_gss_libname "libgssapi")
             set(_gss_libname "libgssapi")
           endif()
           endif()
         else()
         else()
           list(APPEND _gss_libdir_suffixes "lib/i386")
           list(APPEND _gss_libdir_suffixes "lib/i386")
-          if(GSS_FLAVOUR STREQUAL "MIT")
+          if(GSS_FLAVOUR STREQUAL "GNU")
+            set(_gss_libname "gss")
+          elseif(GSS_FLAVOUR STREQUAL "MIT")
             set(_gss_libname "gssapi32")
             set(_gss_libname "gssapi32")
           else()
           else()
             set(_gss_libname "libgssapi")
             set(_gss_libname "libgssapi")
@@ -231,7 +247,9 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
         endif()
         endif()
       else()
       else()
         list(APPEND _gss_libdir_suffixes "lib;lib64")  # those suffixes are not checked for HINTS
         list(APPEND _gss_libdir_suffixes "lib;lib64")  # those suffixes are not checked for HINTS
-        if(GSS_FLAVOUR STREQUAL "MIT")
+        if(GSS_FLAVOUR STREQUAL "GNU")
+          set(_gss_libname "gss")
+        elseif(GSS_FLAVOUR STREQUAL "MIT")
           set(_gss_libname "gssapi_krb5")
           set(_gss_libname "gssapi_krb5")
         else()
         else()
           set(_gss_libname "gssapi")
           set(_gss_libname "gssapi")
@@ -247,13 +265,22 @@ if(NOT _GSS_FOUND)  # Not found by pkg-config. Let us take more traditional appr
     endif()
     endif()
   endif()
   endif()
 else()
 else()
-  if(_GSS_MODULE_NAME STREQUAL _mit_modname OR _GSS_${_mit_modname}_VERSION)  # _GSS_MODULE_NAME set since CMake 3.16
+  # _GSS_MODULE_NAME set since CMake 3.16
+  if(_GSS_MODULE_NAME STREQUAL _gnu_modname OR _GSS_${_gnu_modname}_VERSION)
+    set(GSS_FLAVOUR "GNU")
+    set(GSS_PC_REQUIRES "gss")
+    if(NOT _GSS_VERSION)  # for old CMake versions?
+      set(_GSS_VERSION ${_GSS_${_gnu_modname}_VERSION})
+    endif()
+  elseif(_GSS_MODULE_NAME STREQUAL _mit_modname OR _GSS_${_mit_modname}_VERSION)
     set(GSS_FLAVOUR "MIT")
     set(GSS_FLAVOUR "MIT")
+    set(GSS_PC_REQUIRES "mit-krb5-gssapi")
     if(NOT _GSS_VERSION)  # for old CMake versions?
     if(NOT _GSS_VERSION)  # for old CMake versions?
       set(_GSS_VERSION ${_GSS_${_mit_modname}_VERSION})
       set(_GSS_VERSION ${_GSS_${_mit_modname}_VERSION})
     endif()
     endif()
   else()
   else()
     set(GSS_FLAVOUR "Heimdal")
     set(GSS_FLAVOUR "Heimdal")
+    set(GSS_PC_REQUIRES "heimdal-gssapi")
     if(NOT _GSS_VERSION)  # for old CMake versions?
     if(NOT _GSS_VERSION)  # for old CMake versions?
       set(_GSS_VERSION ${_GSS_${_heimdal_modname}_VERSION})
       set(_GSS_VERSION ${_GSS_${_heimdal_modname}_VERSION})
     endif()
     endif()
@@ -261,10 +288,11 @@ else()
   message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_GSS_INCLUDE_DIRS} (found version \"${_GSS_VERSION}\")")
   message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_GSS_INCLUDE_DIRS} (found version \"${_GSS_VERSION}\")")
 endif()
 endif()
 
 
+string(REPLACE ";" " " _GSS_CFLAGS "${_GSS_CFLAGS}")
+
 set(GSS_INCLUDE_DIRS ${_GSS_INCLUDE_DIRS})
 set(GSS_INCLUDE_DIRS ${_GSS_INCLUDE_DIRS})
 set(GSS_LIBRARIES ${_GSS_LIBRARIES})
 set(GSS_LIBRARIES ${_GSS_LIBRARIES})
 set(GSS_LIBRARY_DIRS ${_GSS_LIBRARY_DIRS})
 set(GSS_LIBRARY_DIRS ${_GSS_LIBRARY_DIRS})
-set(GSS_LDFLAGS ${_GSS_LDFLAGS})
 set(GSS_CFLAGS ${_GSS_CFLAGS})
 set(GSS_CFLAGS ${_GSS_CFLAGS})
 set(GSS_VERSION ${_GSS_VERSION})
 set(GSS_VERSION ${_GSS_VERSION})
 
 
@@ -294,6 +322,15 @@ if(GSS_FLAVOUR)
     else()
     else()
       set(GSS_VERSION "MIT Unknown")
       set(GSS_VERSION "MIT Unknown")
     endif()
     endif()
+  elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "GNU")
+    if(GSS_INCLUDE_DIRS AND EXISTS "${GSS_INCLUDE_DIRS}/gss.h")
+      set(_version_regex "#[\t ]*define[\t ]+GSS_VERSION[\t ]+\"([^\"]*)\"")
+      file(STRINGS "${GSS_INCLUDE_DIRS}/gss.h" _version_str REGEX "${_version_regex}")
+      string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
+      set(GSS_VERSION "${_version_str}")
+      unset(_version_regex)
+      unset(_version_str)
+    endif()
   endif()
   endif()
 endif()
 endif()
 
 
@@ -312,7 +349,6 @@ mark_as_advanced(
   _GSS_CFLAGS
   _GSS_CFLAGS
   _GSS_FOUND
   _GSS_FOUND
   _GSS_INCLUDE_DIRS
   _GSS_INCLUDE_DIRS
-  _GSS_LDFLAGS
   _GSS_LIBRARIES
   _GSS_LIBRARIES
   _GSS_LIBRARY_DIRS
   _GSS_LIBRARY_DIRS
   _GSS_MODULE_NAME
   _GSS_MODULE_NAME

+ 9 - 8
CMake/FindLibgsasl.cmake

@@ -25,17 +25,17 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# LIBGSASL_INCLUDE_DIR   The libgsasl include directory
-# LIBGSASL_LIBRARY       Path to libgsasl library
+# - `LIBGSASL_INCLUDE_DIR`:   The libgsasl include directory.
+# - `LIBGSASL_LIBRARY`:       Path to `libgsasl` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# LIBGSASL_FOUND         System has libgsasl
-# LIBGSASL_INCLUDE_DIRS  The libgsasl include directories
-# LIBGSASL_LIBRARIES     The libgsasl library names
-# LIBGSASL_LIBRARY_DIRS  The libgsasl library directories
-# LIBGSASL_CFLAGS        Required compiler flags
-# LIBGSASL_VERSION       Version of libgsasl
+# - `LIBGSASL_FOUND`:         System has libgsasl.
+# - `LIBGSASL_INCLUDE_DIRS`:  The libgsasl include directories.
+# - `LIBGSASL_LIBRARIES`:     The libgsasl library names.
+# - `LIBGSASL_LIBRARY_DIRS`:  The libgsasl library directories.
+# - `LIBGSASL_CFLAGS`:        Required compiler flags.
+# - `LIBGSASL_VERSION`:       Version of libgsasl.
 
 
 if(CURL_USE_PKGCONFIG AND
 if(CURL_USE_PKGCONFIG AND
    NOT DEFINED LIBGSASL_INCLUDE_DIR AND
    NOT DEFINED LIBGSASL_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
   find_path(LIBGSASL_INCLUDE_DIR NAMES "gsasl.h")
   find_path(LIBGSASL_INCLUDE_DIR NAMES "gsasl.h")
   find_library(LIBGSASL_LIBRARY NAMES "gsasl" "libgsasl")
   find_library(LIBGSASL_LIBRARY NAMES "gsasl" "libgsasl")
 
 
+  unset(LIBGSASL_VERSION CACHE)
   if(LIBGSASL_INCLUDE_DIR AND EXISTS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h")
   if(LIBGSASL_INCLUDE_DIR AND EXISTS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h")
     set(_version_regex "#[\t ]*define[\t ]+GSASL_VERSION[\t ]+\"([^\"]*)\"")
     set(_version_regex "#[\t ]*define[\t ]+GSASL_VERSION[\t ]+\"([^\"]*)\"")
     file(STRINGS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h" _version_str REGEX "${_version_regex}")
     file(STRINGS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h" _version_str REGEX "${_version_regex}")

+ 9 - 8
CMake/FindLibidn2.cmake

@@ -25,17 +25,17 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# LIBIDN2_INCLUDE_DIR   The libidn2 include directory
-# LIBIDN2_LIBRARY       Path to libidn2 library
+# - `LIBIDN2_INCLUDE_DIR`:   The libidn2 include directory.
+# - `LIBIDN2_LIBRARY`:       Path to `libidn2` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# LIBIDN2_FOUND         System has libidn2
-# LIBIDN2_INCLUDE_DIRS  The libidn2 include directories
-# LIBIDN2_LIBRARIES     The libidn2 library names
-# LIBIDN2_LIBRARY_DIRS  The libidn2 library directories
-# LIBIDN2_CFLAGS        Required compiler flags
-# LIBIDN2_VERSION       Version of libidn2
+# - `LIBIDN2_FOUND`:         System has libidn2.
+# - `LIBIDN2_INCLUDE_DIRS`:  The libidn2 include directories.
+# - `LIBIDN2_LIBRARIES`:     The libidn2 library names.
+# - `LIBIDN2_LIBRARY_DIRS`:  The libidn2 library directories.
+# - `LIBIDN2_CFLAGS`:        Required compiler flags.
+# - `LIBIDN2_VERSION`:       Version of libidn2.
 
 
 if(CURL_USE_PKGCONFIG AND
 if(CURL_USE_PKGCONFIG AND
    NOT DEFINED LIBIDN2_INCLUDE_DIR AND
    NOT DEFINED LIBIDN2_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
   find_path(LIBIDN2_INCLUDE_DIR NAMES "idn2.h")
   find_path(LIBIDN2_INCLUDE_DIR NAMES "idn2.h")
   find_library(LIBIDN2_LIBRARY NAMES "idn2" "libidn2")
   find_library(LIBIDN2_LIBRARY NAMES "idn2" "libidn2")
 
 
+  unset(LIBIDN2_VERSION CACHE)
   if(LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/idn2.h")
   if(LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/idn2.h")
     set(_version_regex "#[\t ]*define[\t ]+IDN2_VERSION[\t ]+\"([^\"]*)\"")
     set(_version_regex "#[\t ]*define[\t ]+IDN2_VERSION[\t ]+\"([^\"]*)\"")
     file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" _version_str REGEX "${_version_regex}")
     file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" _version_str REGEX "${_version_regex}")

+ 6 - 6
CMake/FindLibpsl.cmake

@@ -25,15 +25,15 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# LIBPSL_INCLUDE_DIR   The libpsl include directory
-# LIBPSL_LIBRARY       Path to libpsl library
+# - `LIBPSL_INCLUDE_DIR`:   The libpsl include directory.
+# - `LIBPSL_LIBRARY`:       Path to `libpsl` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# LIBPSL_FOUND         System has libpsl
-# LIBPSL_INCLUDE_DIRS  The libpsl include directories
-# LIBPSL_LIBRARIES     The libpsl library names
-# LIBPSL_VERSION       Version of libpsl
+# - `LIBPSL_FOUND`:         System has libpsl.
+# - `LIBPSL_INCLUDE_DIRS`:  The libpsl include directories.
+# - `LIBPSL_LIBRARIES`:     The libpsl library names.
+# - `LIBPSL_VERSION`:       Version of libpsl.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)

+ 9 - 8
CMake/FindLibssh.cmake

@@ -25,17 +25,17 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# LIBSSH_INCLUDE_DIR   The libssh include directory
-# LIBSSH_LIBRARY       Path to libssh library
+# LIBSSH_INCLUDE_DIR   The libssh include directory.
+# LIBSSH_LIBRARY       Path to libssh library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# LIBSSH_FOUND         System has libssh
-# LIBSSH_INCLUDE_DIRS  The libssh include directories
-# LIBSSH_LIBRARIES     The libssh library names
-# LIBSSH_LIBRARY_DIRS  The libssh library directories
-# LIBSSH_CFLAGS        Required compiler flags
-# LIBSSH_VERSION       Version of libssh
+# LIBSSH_FOUND         System has libssh.
+# LIBSSH_INCLUDE_DIRS  The libssh include directories.
+# LIBSSH_LIBRARIES     The libssh library names.
+# LIBSSH_LIBRARY_DIRS  The libssh library directories.
+# LIBSSH_CFLAGS        Required compiler flags.
+# LIBSSH_VERSION       Version of libssh.
 
 
 if(CURL_USE_PKGCONFIG AND
 if(CURL_USE_PKGCONFIG AND
    NOT DEFINED LIBSSH_INCLUDE_DIR AND
    NOT DEFINED LIBSSH_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
   find_path(LIBSSH_INCLUDE_DIR NAMES "libssh/libssh.h")
   find_path(LIBSSH_INCLUDE_DIR NAMES "libssh/libssh.h")
   find_library(LIBSSH_LIBRARY NAMES "ssh" "libssh")
   find_library(LIBSSH_LIBRARY NAMES "ssh" "libssh")
 
 
+  unset(LIBSSH_VERSION CACHE)
   if(LIBSSH_INCLUDE_DIR AND EXISTS "${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h")
   if(LIBSSH_INCLUDE_DIR AND EXISTS "${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h")
     set(_version_regex1 "#[\t ]*define[\t ]+LIBSSH_VERSION_MAJOR[\t ]+([0-9]+).*")
     set(_version_regex1 "#[\t ]*define[\t ]+LIBSSH_VERSION_MAJOR[\t ]+([0-9]+).*")
     set(_version_regex2 "#[\t ]*define[\t ]+LIBSSH_VERSION_MINOR[\t ]+([0-9]+).*")
     set(_version_regex2 "#[\t ]*define[\t ]+LIBSSH_VERSION_MINOR[\t ]+([0-9]+).*")

+ 6 - 6
CMake/FindLibssh2.cmake

@@ -25,15 +25,15 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# LIBSSH2_INCLUDE_DIR   The libssh2 include directory
-# LIBSSH2_LIBRARY       Path to libssh2 library
+# - `LIBSSH2_INCLUDE_DIR`:   The libssh2 include directory.
+# - `LIBSSH2_LIBRARY`:       Path to `libssh2` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# LIBSSH2_FOUND         System has libssh2
-# LIBSSH2_INCLUDE_DIRS  The libssh2 include directories
-# LIBSSH2_LIBRARIES     The libssh2 library names
-# LIBSSH2_VERSION       Version of libssh2
+# - `LIBSSH2_FOUND`:         System has libssh2.
+# - `LIBSSH2_INCLUDE_DIRS`:  The libssh2 include directories.
+# - `LIBSSH2_LIBRARIES`:     The libssh2 library names.
+# - `LIBSSH2_VERSION`:       Version of libssh2.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)

+ 9 - 8
CMake/FindLibuv.cmake

@@ -25,17 +25,17 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# LIBUV_INCLUDE_DIR   The libuv include directory
-# LIBUV_LIBRARY       Path to libuv library
+# - `LIBUV_INCLUDE_DIR`:   The libuv include directory.
+# - `LIBUV_LIBRARY`:       Path to `libuv` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# LIBUV_FOUND         System has libuv
-# LIBUV_INCLUDE_DIRS  The libuv include directories
-# LIBUV_LIBRARIES     The libuv library names
-# LIBUV_LIBRARY_DIRS  The libuv library directories
-# LIBUV_CFLAGS        Required compiler flags
-# LIBUV_VERSION       Version of libuv
+# - `LIBUV_FOUND`:         System has libuv.
+# - `LIBUV_INCLUDE_DIRS`:  The libuv include directories.
+# - `LIBUV_LIBRARIES`:     The libuv library names.
+# - `LIBUV_LIBRARY_DIRS`:  The libuv library directories.
+# - `LIBUV_CFLAGS`:        Required compiler flags.
+# - `LIBUV_VERSION`:       Version of libuv.
 
 
 if(CURL_USE_PKGCONFIG AND
 if(CURL_USE_PKGCONFIG AND
    NOT DEFINED LIBUV_INCLUDE_DIR AND
    NOT DEFINED LIBUV_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
   find_path(LIBUV_INCLUDE_DIR NAMES "uv.h")
   find_path(LIBUV_INCLUDE_DIR NAMES "uv.h")
   find_library(LIBUV_LIBRARY NAMES "uv" "libuv")
   find_library(LIBUV_LIBRARY NAMES "uv" "libuv")
 
 
+  unset(LIBUV_VERSION CACHE)
   if(LIBUV_INCLUDE_DIR AND EXISTS "${LIBUV_INCLUDE_DIR}/uv/version.h")
   if(LIBUV_INCLUDE_DIR AND EXISTS "${LIBUV_INCLUDE_DIR}/uv/version.h")
     set(_version_regex1 "#[\t ]*define[\t ]+UV_VERSION_MAJOR[\t ]+([0-9]+).*")
     set(_version_regex1 "#[\t ]*define[\t ]+UV_VERSION_MAJOR[\t ]+([0-9]+).*")
     set(_version_regex2 "#[\t ]*define[\t ]+UV_VERSION_MINOR[\t ]+([0-9]+).*")
     set(_version_regex2 "#[\t ]*define[\t ]+UV_VERSION_MINOR[\t ]+([0-9]+).*")

+ 31 - 35
CMake/FindMSH3.cmake

@@ -25,49 +25,45 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# MSH3_INCLUDE_DIR   The msh3 include directory
-# MSH3_LIBRARY       Path to msh3 library
+# - `MSH3_INCLUDE_DIR`:   The msh3 include directory.
+# - `MSH3_LIBRARY`:       Path to `msh3` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# MSH3_FOUND         System has msh3
-# MSH3_INCLUDE_DIRS  The msh3 include directories
-# MSH3_LIBRARIES     The msh3 library names
-# MSH3_VERSION       Version of msh3
+# - `MSH3_FOUND`:         System has msh3.
+# - `MSH3_INCLUDE_DIRS`:  The msh3 include directories.
+# - `MSH3_LIBRARIES`:     The msh3 library names.
+# - `MSH3_LIBRARY_DIRS`:  The msh3 library directories.
+# - `MSH3_PC_REQUIRES`:   The msh3 pkg-config packages.
+# - `MSH3_CFLAGS`:        Required compiler flags.
+# - `MSH3_VERSION`:       Version of msh3.
 
 
-if(CURL_USE_PKGCONFIG)
+if(CURL_USE_PKGCONFIG AND
+   NOT DEFINED MSH3_INCLUDE_DIR AND
+   NOT DEFINED MSH3_LIBRARY)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
-  pkg_check_modules(PC_MSH3 "libmsh3")
+  pkg_check_modules(MSH3 "libmsh3")
 endif()
 endif()
 
 
-find_path(MSH3_INCLUDE_DIR NAMES "msh3.h"
-  HINTS
-    ${PC_MSH3_INCLUDEDIR}
-    ${PC_MSH3_INCLUDE_DIRS}
-)
-
-find_library(MSH3_LIBRARY NAMES "msh3"
-  HINTS
-    ${PC_MSH3_LIBDIR}
-    ${PC_MSH3_LIBRARY_DIRS}
-)
+if(MSH3_FOUND)
+  set(MSH3_PC_REQUIRES "libmsh3")
+  string(REPLACE ";" " " MSH3_CFLAGS "${MSH3_CFLAGS}")
+  message(STATUS "Found MSH3 (via pkg-config): ${MSH3_INCLUDE_DIRS} (found version \"${MSH3_VERSION}\")")
+else()
+  find_path(MSH3_INCLUDE_DIR NAMES "msh3.h")
+  find_library(MSH3_LIBRARY NAMES "msh3")
 
 
-if(PC_MSH3_VERSION)
-  set(MSH3_VERSION ${PC_MSH3_VERSION})
-endif()
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(MSH3
+    REQUIRED_VARS
+      MSH3_INCLUDE_DIR
+      MSH3_LIBRARY
+  )
 
 
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(MSH3
-  REQUIRED_VARS
-    MSH3_INCLUDE_DIR
-    MSH3_LIBRARY
-  VERSION_VAR
-    MSH3_VERSION
-)
+  if(MSH3_FOUND)
+    set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
+    set(MSH3_LIBRARIES    ${MSH3_LIBRARY})
+  endif()
 
 
-if(MSH3_FOUND)
-  set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
-  set(MSH3_LIBRARIES    ${MSH3_LIBRARY})
+  mark_as_advanced(MSH3_INCLUDE_DIR MSH3_LIBRARY)
 endif()
 endif()
-
-mark_as_advanced(MSH3_INCLUDE_DIR MSH3_LIBRARY)

+ 65 - 67
CMake/FindMbedTLS.cmake

@@ -21,22 +21,24 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-# Find the mbedtls library
+# Find the mbedTLS library
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# MBEDTLS_INCLUDE_DIR   The mbedtls include directory
-# MBEDTLS_INCLUDE_DIRS  The mbedtls include directory (deprecated)
-# MBEDTLS_LIBRARY       Path to mbedtls library
-# MBEDX509_LIBRARY      Path to mbedx509 library
-# MBEDCRYPTO_LIBRARY    Path to mbedcrypto library
+# - `MBEDTLS_INCLUDE_DIR`:   The mbedTLS include directory.
+# - `MBEDTLS_LIBRARY`:       Path to `mbedtls` library.
+# - `MBEDX509_LIBRARY`:      Path to `mbedx509` library.
+# - `MBEDCRYPTO_LIBRARY`:    Path to `mbedcrypto` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# MBEDTLS_FOUND         System has mbedtls
-# MBEDTLS_INCLUDE_DIRS  The mbedtls include directories
-# MBEDTLS_LIBRARIES     The mbedtls library names
-# MBEDTLS_VERSION       Version of mbedtls
+# - `MBEDTLS_FOUND`:         System has mbedTLS.
+# - `MBEDTLS_INCLUDE_DIRS`:  The mbedTLS include directories.
+# - `MBEDTLS_LIBRARIES`:     The mbedTLS library names.
+# - `MBEDTLS_LIBRARY_DIRS`:  The mbedTLS library directories.
+# - `MBEDTLS_PC_REQUIRES`:   The mbedTLS pkg-config packages.
+# - `MBEDTLS_CFLAGS`:        Required compiler flags.
+# - `MBEDTLS_VERSION`:       Version of mbedTLS.
 
 
 if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
 if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
   message(WARNING "MBEDTLS_INCLUDE_DIRS is deprecated, use MBEDTLS_INCLUDE_DIR instead.")
   message(WARNING "MBEDTLS_INCLUDE_DIRS is deprecated, use MBEDTLS_INCLUDE_DIR instead.")
@@ -44,68 +46,64 @@ if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
   unset(MBEDTLS_INCLUDE_DIRS)
   unset(MBEDTLS_INCLUDE_DIRS)
 endif()
 endif()
 
 
-if(CURL_USE_PKGCONFIG)
+if(CURL_USE_PKGCONFIG AND
+   NOT DEFINED MBEDTLS_INCLUDE_DIR AND
+   NOT DEFINED MBEDTLS_LIBRARY AND
+   NOT DEFINED MBEDX509_LIBRARY AND
+   NOT DEFINED MBEDCRYPTO_LIBRARY)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
-  pkg_check_modules(PC_MBEDTLS "mbedtls")
+  pkg_check_modules(MBEDTLS "mbedtls")
+  pkg_check_modules(MBEDX509 "mbedx509")
+  pkg_check_modules(MBEDCRYPTO "mbedcrypto")
 endif()
 endif()
 
 
-find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h"
-  HINTS
-    ${PC_MBEDTLS_INCLUDEDIR}
-    ${PC_MBEDTLS_INCLUDE_DIRS}
-)
+if(MBEDTLS_FOUND AND MBEDX509_FOUND AND MBEDCRYPTO_FOUND)
+  list(APPEND MBEDTLS_LIBRARIES ${MBEDX509_LIBRARIES} ${MBEDCRYPTO_LIBRARIES})
+  list(REMOVE_DUPLICATES MBEDTLS_LIBRARIES)
+  set(MBEDTLS_PC_REQUIRES "mbedtls")
+  string(REPLACE ";" " " MBEDTLS_CFLAGS "${MBEDTLS_CFLAGS}")
+  message(STATUS "Found MbedTLS (via pkg-config): ${MBEDTLS_INCLUDE_DIRS} (found version \"${MBEDTLS_VERSION}\")")
+else()
+  find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h")
+  find_library(MBEDTLS_LIBRARY NAMES "mbedtls" "libmbedtls")
+  find_library(MBEDX509_LIBRARY NAMES "mbedx509" "libmbedx509")
+  find_library(MBEDCRYPTO_LIBRARY NAMES "mbedcrypto" "libmbedcrypto")
 
 
-find_library(MBEDTLS_LIBRARY NAMES "mbedtls"
-  HINTS
-    ${PC_MBEDTLS_LIBDIR}
-    ${PC_MBEDTLS_LIBRARY_DIRS}
-)
-find_library(MBEDX509_LIBRARY NAMES "mbedx509"
-  HINTS
-    ${PC_MBEDTLS_LIBDIR}
-    ${PC_MBEDTLS_LIBRARY_DIRS}
-)
-find_library(MBEDCRYPTO_LIBRARY NAMES "mbedcrypto"
-  HINTS
-    ${PC_MBEDTLS_LIBDIR}
-    ${PC_MBEDTLS_LIBRARY_DIRS}
-)
-
-if(PC_MBEDTLS_VERSION)
-  set(MBEDTLS_VERSION ${PC_MBEDTLS_VERSION})
-elseif(MBEDTLS_INCLUDE_DIR)
-  if(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")  # 3.x
-    set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
-  elseif(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")  # 2.x
-    set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
-  else()
-    unset(_version_header)
-  endif()
-  if(_version_header)
-    set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"")
-    file(STRINGS "${_version_header}" _version_str REGEX "${_version_regex}")
-    string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
-    set(MBEDTLS_VERSION "${_version_str}")
-    unset(_version_regex)
-    unset(_version_str)
-    unset(_version_header)
+  unset(MBEDTLS_VERSION CACHE)
+  if(MBEDTLS_INCLUDE_DIR)
+    if(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")  # 3.x
+      set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
+    elseif(EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")  # 2.x
+      set(_version_header "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
+    else()
+      unset(_version_header)
+    endif()
+    if(_version_header)
+      set(_version_regex "#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"([0-9.]+)\"")
+      file(STRINGS "${_version_header}" _version_str REGEX "${_version_regex}")
+      string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
+      set(MBEDTLS_VERSION "${_version_str}")
+      unset(_version_regex)
+      unset(_version_str)
+      unset(_version_header)
+    endif()
   endif()
   endif()
-endif()
 
 
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(MbedTLS
-  REQUIRED_VARS
-    MBEDTLS_INCLUDE_DIR
-    MBEDTLS_LIBRARY
-    MBEDX509_LIBRARY
-    MBEDCRYPTO_LIBRARY
-  VERSION_VAR
-    MBEDTLS_VERSION
-)
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(MbedTLS
+    REQUIRED_VARS
+      MBEDTLS_INCLUDE_DIR
+      MBEDTLS_LIBRARY
+      MBEDX509_LIBRARY
+      MBEDCRYPTO_LIBRARY
+    VERSION_VAR
+      MBEDTLS_VERSION
+  )
 
 
-if(MBEDTLS_FOUND)
-  set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR})
-  set(MBEDTLS_LIBRARIES    ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
-endif()
+  if(MBEDTLS_FOUND)
+    set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR})
+    set(MBEDTLS_LIBRARIES    ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
+  endif()
 
 
-mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
+  mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
+endif()

+ 6 - 6
CMake/FindNGHTTP2.cmake

@@ -25,15 +25,15 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# NGHTTP2_INCLUDE_DIR   The nghttp2 include directory
-# NGHTTP2_LIBRARY       Path to nghttp2 library
+# - `NGHTTP2_INCLUDE_DIR`:   The nghttp2 include directory.
+# - `NGHTTP2_LIBRARY`:       Path to `nghttp2` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# NGHTTP2_FOUND         System has nghttp2
-# NGHTTP2_INCLUDE_DIRS  The nghttp2 include directories
-# NGHTTP2_LIBRARIES     The nghttp2 library names
-# NGHTTP2_VERSION       Version of nghttp2
+# - `NGHTTP2_FOUND`:         System has nghttp2.
+# - `NGHTTP2_INCLUDE_DIRS`:  The nghttp2 include directories.
+# - `NGHTTP2_LIBRARIES`:     The nghttp2 library names.
+# - `NGHTTP2_VERSION`:       Version of nghttp2.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)

+ 6 - 6
CMake/FindNGHTTP3.cmake

@@ -25,15 +25,15 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# NGHTTP3_INCLUDE_DIR   The nghttp3 include directory
-# NGHTTP3_LIBRARY       Path to nghttp3 library
+# - `NGHTTP3_INCLUDE_DIR`:   The nghttp3 include directory.
+# - `NGHTTP3_LIBRARY`:       Path to `nghttp3` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# NGHTTP3_FOUND         System has nghttp3
-# NGHTTP3_INCLUDE_DIRS  The nghttp3 include directories
-# NGHTTP3_LIBRARIES     The nghttp3 library names
-# NGHTTP3_VERSION       Version of nghttp3
+# - `NGHTTP3_FOUND`:         System has nghttp3.
+# - `NGHTTP3_INCLUDE_DIRS`:  The nghttp3 include directories.
+# - `NGHTTP3_LIBRARIES`:     The nghttp3 library names.
+# - `NGHTTP3_VERSION`:       Version of nghttp3.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)

+ 15 - 10
CMake/FindNGTCP2.cmake

@@ -26,22 +26,22 @@
 # This module accepts optional COMPONENTS to control the crypto library (these are
 # This module accepts optional COMPONENTS to control the crypto library (these are
 # mutually exclusive):
 # mutually exclusive):
 #
 #
-# quictls:    Use libngtcp2_crypto_quictls   (choose this for LibreSSL)
-# BoringSSL:  Use libngtcp2_crypto_boringssl (choose this for AWS-LC)
-# wolfSSL:    Use libngtcp2_crypto_wolfssl
-# GnuTLS:     Use libngtcp2_crypto_gnutls
+# - quictls:    Use `libngtcp2_crypto_quictls`.   (choose this for LibreSSL)
+# - BoringSSL:  Use `libngtcp2_crypto_boringssl`. (choose this for AWS-LC)
+# - wolfSSL:    Use `libngtcp2_crypto_wolfssl`.
+# - GnuTLS:     Use `libngtcp2_crypto_gnutls`.
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# NGTCP2_INCLUDE_DIR   The ngtcp2 include directory
-# NGTCP2_LIBRARY       Path to ngtcp2 library
+# - `NGTCP2_INCLUDE_DIR`:   The ngtcp2 include directory.
+# - `NGTCP2_LIBRARY`:       Path to `ngtcp2` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# NGTCP2_FOUND         System has ngtcp2
-# NGTCP2_INCLUDE_DIRS  The ngtcp2 include directories
-# NGTCP2_LIBRARIES     The ngtcp2 library names
-# NGTCP2_VERSION       Version of ngtcp2
+# - `NGTCP2_FOUND`:         System has ngtcp2.
+# - `NGTCP2_INCLUDE_DIRS`:  The ngtcp2 include directories.
+# - `NGTCP2_LIBRARIES`:     The ngtcp2 library names.
+# - `NGTCP2_VERSION`:       Version of ngtcp2.
 
 
 if(CURL_USE_PKGCONFIG)
 if(CURL_USE_PKGCONFIG)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
@@ -84,14 +84,19 @@ if(NGTCP2_FIND_COMPONENTS)
 
 
   if(_ngtcp2_crypto_backend)
   if(_ngtcp2_crypto_backend)
     string(TOLOWER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library)
     string(TOLOWER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library)
+
     if(CURL_USE_PKGCONFIG)
     if(CURL_USE_PKGCONFIG)
       pkg_check_modules(PC_${_crypto_library} "lib${_crypto_library}")
       pkg_check_modules(PC_${_crypto_library} "lib${_crypto_library}")
     endif()
     endif()
+
+    get_filename_component(_ngtcp2_library_dir "${NGTCP2_LIBRARY}" DIRECTORY)
     find_library(${_crypto_library}_LIBRARY NAMES ${_crypto_library}
     find_library(${_crypto_library}_LIBRARY NAMES ${_crypto_library}
       HINTS
       HINTS
+        ${_ngtcp2_library_dir}
         ${PC_${_crypto_library}_LIBDIR}
         ${PC_${_crypto_library}_LIBDIR}
         ${PC_${_crypto_library}_LIBRARY_DIRS}
         ${PC_${_crypto_library}_LIBRARY_DIRS}
     )
     )
+
     if(${_crypto_library}_LIBRARY)
     if(${_crypto_library}_LIBRARY)
       set(NGTCP2_${_ngtcp2_crypto_backend}_FOUND TRUE)
       set(NGTCP2_${_ngtcp2_crypto_backend}_FOUND TRUE)
       set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
       set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})

+ 9 - 8
CMake/FindNettle.cmake

@@ -25,17 +25,17 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# NETTLE_INCLUDE_DIR   The nettle include directory
-# NETTLE_LIBRARY       Path to nettle library
+# - `NETTLE_INCLUDE_DIR`:   The nettle include directory.
+# - `NETTLE_LIBRARY`:       Path to `nettle` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# NETTLE_FOUND         System has nettle
-# NETTLE_INCLUDE_DIRS  The nettle include directories
-# NETTLE_LIBRARIES     The nettle library names
-# NETTLE_LIBRARY_DIRS  The nettle library directories
-# NETTLE_CFLAGS        Required compiler flags
-# NETTLE_VERSION       Version of nettle
+# - `NETTLE_FOUND`:         System has nettle.
+# - `NETTLE_INCLUDE_DIRS`:  The nettle include directories.
+# - `NETTLE_LIBRARIES`:     The nettle library names.
+# - `NETTLE_LIBRARY_DIRS`:  The nettle library directories.
+# - `NETTLE_CFLAGS`:        Required compiler flags.
+# - `NETTLE_VERSION`:       Version of nettle.
 
 
 if(CURL_USE_PKGCONFIG AND
 if(CURL_USE_PKGCONFIG AND
    NOT DEFINED NETTLE_INCLUDE_DIR AND
    NOT DEFINED NETTLE_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
   find_path(NETTLE_INCLUDE_DIR NAMES "nettle/sha2.h")
   find_path(NETTLE_INCLUDE_DIR NAMES "nettle/sha2.h")
   find_library(NETTLE_LIBRARY NAMES "nettle")
   find_library(NETTLE_LIBRARY NAMES "nettle")
 
 
+  unset(NETTLE_VERSION CACHE)
   if(NETTLE_INCLUDE_DIR AND EXISTS "${NETTLE_INCLUDE_DIR}/nettle/version.h")
   if(NETTLE_INCLUDE_DIR AND EXISTS "${NETTLE_INCLUDE_DIR}/nettle/version.h")
     set(_version_regex1 "#[\t ]*define[ \t]+NETTLE_VERSION_MAJOR[ \t]+([0-9]+).*")
     set(_version_regex1 "#[\t ]*define[ \t]+NETTLE_VERSION_MAJOR[ \t]+([0-9]+).*")
     set(_version_regex2 "#[\t ]*define[ \t]+NETTLE_VERSION_MINOR[ \t]+([0-9]+).*")
     set(_version_regex2 "#[\t ]*define[ \t]+NETTLE_VERSION_MINOR[ \t]+([0-9]+).*")

+ 29 - 35
CMake/FindQuiche.cmake

@@ -25,49 +25,43 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# QUICHE_INCLUDE_DIR   The quiche include directory
-# QUICHE_LIBRARY       Path to quiche library
+# - `QUICHE_INCLUDE_DIR`:   The quiche include directory.
+# - `QUICHE_LIBRARY`:       Path to `quiche` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# QUICHE_FOUND         System has quiche
-# QUICHE_INCLUDE_DIRS  The quiche include directories
-# QUICHE_LIBRARIES     The quiche library names
-# QUICHE_VERSION       Version of quiche
+# - `QUICHE_FOUND`:         System has quiche.
+# - `QUICHE_INCLUDE_DIRS`:  The quiche include directories.
+# - `QUICHE_LIBRARIES`:     The quiche library names.
+# - `QUICHE_LIBRARY_DIRS`:  The quiche library directories.
+# - `QUICHE_CFLAGS`:        Required compiler flags.
+# - `QUICHE_VERSION`:       Version of quiche.
 
 
-if(CURL_USE_PKGCONFIG)
+if(CURL_USE_PKGCONFIG AND
+   NOT DEFINED QUICHE_INCLUDE_DIR AND
+   NOT DEFINED QUICHE_LIBRARY)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
-  pkg_check_modules(PC_QUICHE "quiche")
+  pkg_check_modules(QUICHE "quiche")
 endif()
 endif()
 
 
-find_path(QUICHE_INCLUDE_DIR NAMES "quiche.h"
-  HINTS
-    ${PC_QUICHE_INCLUDEDIR}
-    ${PC_QUICHE_INCLUDE_DIRS}
-)
-
-find_library(QUICHE_LIBRARY NAMES "quiche"
-  HINTS
-    ${PC_QUICHE_LIBDIR}
-    ${PC_QUICHE_LIBRARY_DIRS}
-)
+if(QUICHE_FOUND)
+  string(REPLACE ";" " " QUICHE_CFLAGS "${QUICHE_CFLAGS}")
+  message(STATUS "Found Quiche (via pkg-config): ${QUICHE_INCLUDE_DIRS} (found version \"${QUICHE_VERSION}\")")
+else()
+  find_path(QUICHE_INCLUDE_DIR NAMES "quiche.h")
+  find_library(QUICHE_LIBRARY NAMES "quiche")
 
 
-if(PC_QUICHE_VERSION)
-  set(QUICHE_VERSION ${PC_QUICHE_VERSION})
-endif()
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(Quiche
+    REQUIRED_VARS
+      QUICHE_INCLUDE_DIR
+      QUICHE_LIBRARY
+  )
 
 
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Quiche
-  REQUIRED_VARS
-    QUICHE_INCLUDE_DIR
-    QUICHE_LIBRARY
-  VERSION_VAR
-    QUICHE_VERSION
-)
+  if(QUICHE_FOUND)
+    set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
+    set(QUICHE_LIBRARIES    ${QUICHE_LIBRARY})
+  endif()
 
 
-if(QUICHE_FOUND)
-  set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
-  set(QUICHE_LIBRARIES    ${QUICHE_LIBRARY})
+  mark_as_advanced(QUICHE_INCLUDE_DIR QUICHE_LIBRARY)
 endif()
 endif()
-
-mark_as_advanced(QUICHE_INCLUDE_DIR QUICHE_LIBRARY)

+ 64 - 34
CMake/FindRustls.cmake

@@ -21,53 +21,83 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-# Find the rustls library
+# Find the Rustls library
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# RUSTLS_INCLUDE_DIR   The rustls include directory
-# RUSTLS_LIBRARY       Path to rustls library
+# - `RUSTLS_INCLUDE_DIR`:   The Rustls include directory.
+# - `RUSTLS_LIBRARY`:       Path to `rustls` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# RUSTLS_FOUND         System has rustls
-# RUSTLS_INCLUDE_DIRS  The rustls include directories
-# RUSTLS_LIBRARIES     The rustls library names
-# RUSTLS_VERSION       Version of rustls
+# - `RUSTLS_FOUND`:         System has Rustls.
+# - `RUSTLS_INCLUDE_DIRS`:  The Rustls include directories.
+# - `RUSTLS_LIBRARIES`:     The Rustls library names.
+# - `RUSTLS_LIBRARY_DIRS`:  The Rustls library directories.
+# - `RUSTLS_PC_REQUIRES`:   The Rustls pkg-config packages.
+# - `RUSTLS_CFLAGS`:        Required compiler flags.
+# - `RUSTLS_VERSION`:       Version of Rustls.
 
 
-if(CURL_USE_PKGCONFIG)
+if(CURL_USE_PKGCONFIG AND
+   NOT DEFINED RUSTLS_INCLUDE_DIR AND
+   NOT DEFINED RUSTLS_LIBRARY)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
-  pkg_check_modules(PC_RUSTLS "rustls")
+  pkg_check_modules(RUSTLS "rustls")
 endif()
 endif()
 
 
-find_path(RUSTLS_INCLUDE_DIR NAMES "rustls.h"
-  HINTS
-    ${PC_RUSTLS_INCLUDEDIR}
-    ${PC_RUSTLS_INCLUDE_DIRS}
-)
+if(RUSTLS_FOUND)
+  set(RUSTLS_PC_REQUIRES "rustls")
+  string(REPLACE ";" " " RUSTLS_CFLAGS "${RUSTLS_CFLAGS}")
+  message(STATUS "Found Rustls (via pkg-config): ${RUSTLS_INCLUDE_DIRS} (found version \"${RUSTLS_VERSION}\")")
+else()
+  find_path(RUSTLS_INCLUDE_DIR NAMES "rustls.h")
+  find_library(RUSTLS_LIBRARY NAMES "rustls")
+
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(Rustls
+    REQUIRED_VARS
+      RUSTLS_INCLUDE_DIR
+      RUSTLS_LIBRARY
+  )
 
 
-find_library(RUSTLS_LIBRARY NAMES "rustls"
-  HINTS
-    ${PC_RUSTLS_LIBDIR}
-    ${PC_RUSTLS_LIBRARY_DIRS}
-)
+  if(RUSTLS_FOUND)
+    set(RUSTLS_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR})
+    set(RUSTLS_LIBRARIES    ${RUSTLS_LIBRARY})
+  endif()
 
 
-if(PC_RUSTLS_VERSION)
-  set(RUSTLS_VERSION ${PC_RUSTLS_VERSION})
+  mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY)
 endif()
 endif()
 
 
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Rustls
-  REQUIRED_VARS
-    RUSTLS_INCLUDE_DIR
-    RUSTLS_LIBRARY
-  VERSION_VAR
-    RUSTLS_VERSION
-)
+if(APPLE)
+  find_library(SECURITY_FRAMEWORK "Security")
+  mark_as_advanced(SECURITY_FRAMEWORK)
+  if(NOT SECURITY_FRAMEWORK)
+    message(FATAL_ERROR "Security framework not found")
+  endif()
+  list(APPEND RUSTLS_LIBRARIES "-framework Security")
 
 
-if(RUSTLS_FOUND)
-  set(RUSTLS_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR})
-  set(RUSTLS_LIBRARIES    ${RUSTLS_LIBRARY})
-endif()
+  find_library(FOUNDATION_FRAMEWORK "Foundation")
+  mark_as_advanced(FOUNDATION_FRAMEWORK)
+  if(NOT FOUNDATION_FRAMEWORK)
+    message(FATAL_ERROR "Foundation framework not found")
+  endif()
+  list(APPEND RUSTLS_LIBRARIES "-framework Foundation")
+elseif(NOT WIN32)
+  find_library(_pthread_library "pthread")
+  if(_pthread_library)
+    list(APPEND RUSTLS_LIBRARIES "pthread")
+  endif()
+  mark_as_advanced(_pthread_library)
+
+  find_library(_dl_library "dl")
+  if(_dl_library)
+    list(APPEND RUSTLS_LIBRARIES "dl")
+  endif()
+  mark_as_advanced(_dl_library)
 
 
-mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY)
+  find_library(_math_library "m")
+  if(_math_library)
+    list(APPEND RUSTLS_LIBRARIES "m")
+  endif()
+  mark_as_advanced(_math_library)
+endif()

+ 8 - 7
CMake/FindWolfSSH.cmake

@@ -21,23 +21,24 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-# Find the wolfssh library
+# Find the wolfSSH library
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# WOLFSSH_INCLUDE_DIR   The wolfssh include directory
-# WOLFSSH_LIBRARY       Path to wolfssh library
+# - `WOLFSSH_INCLUDE_DIR`:   The wolfSSH include directory.
+# - `WOLFSSH_LIBRARY`:       Path to `wolfssh` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# WOLFSSH_FOUND         System has wolfssh
-# WOLFSSH_INCLUDE_DIRS  The wolfssh include directories
-# WOLFSSH_LIBRARIES     The wolfssh library names
-# WOLFSSH_VERSION       Version of wolfssh
+# - `WOLFSSH_FOUND`:         System has wolfSSH.
+# - `WOLFSSH_INCLUDE_DIRS`:  The wolfSSH include directories.
+# - `WOLFSSH_LIBRARIES`:     The wolfSSH library names.
+# - `WOLFSSH_VERSION`:       Version of wolfSSH.
 
 
 find_path(WOLFSSH_INCLUDE_DIR NAMES "wolfssh/ssh.h")
 find_path(WOLFSSH_INCLUDE_DIR NAMES "wolfssh/ssh.h")
 find_library(WOLFSSH_LIBRARY NAMES "wolfssh" "libwolfssh")
 find_library(WOLFSSH_LIBRARY NAMES "wolfssh" "libwolfssh")
 
 
+unset(WOLFSSH_VERSION CACHE)
 if(WOLFSSH_INCLUDE_DIR AND EXISTS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h")
 if(WOLFSSH_INCLUDE_DIR AND EXISTS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h")
   set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSH_VERSION_STRING[\t ]+\"([^\"]*)\"")
   set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSH_VERSION_STRING[\t ]+\"([^\"]*)\"")
   file(STRINGS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h" _version_str REGEX "${_version_regex}")
   file(STRINGS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h" _version_str REGEX "${_version_regex}")

+ 47 - 49
CMake/FindWolfSSL.cmake

@@ -21,21 +21,21 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-# Find the wolfssl library
+# Find the wolfSSL library
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# WOLFSSL_INCLUDE_DIR   The wolfssl include directory
-# WolfSSL_INCLUDE_DIR   The wolfssl include directory (deprecated)
-# WOLFSSL_LIBRARY       Path to wolfssl library
-# WolfSSL_LIBRARY       Path to wolfssl library (deprecated)
+# - `WOLFSSL_INCLUDE_DIR`:   The wolfSSL include directory.
+# - `WOLFSSL_LIBRARY`:       Path to `wolfssl` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# WOLFSSL_FOUND         System has wolfssl
-# WOLFSSL_INCLUDE_DIRS  The wolfssl include directories
-# WOLFSSL_LIBRARIES     The wolfssl library names
-# WOLFSSL_VERSION       Version of wolfssl
+# - `WOLFSSL_FOUND`:         System has wolfSSL.
+# - `WOLFSSL_INCLUDE_DIRS`:  The wolfSSL include directories.
+# - `WOLFSSL_LIBRARIES`:     The wolfSSL library names.
+# - `WOLFSSL_LIBRARY_DIRS`:  The wolfSSL library directories.
+# - `WOLFSSL_CFLAGS`:        Required compiler flags.
+# - `WOLFSSL_VERSION`:       Version of wolfSSL.
 
 
 if(DEFINED WolfSSL_INCLUDE_DIR AND NOT DEFINED WOLFSSL_INCLUDE_DIR)
 if(DEFINED WolfSSL_INCLUDE_DIR AND NOT DEFINED WOLFSSL_INCLUDE_DIR)
   message(WARNING "WolfSSL_INCLUDE_DIR is deprecated, use WOLFSSL_INCLUDE_DIR instead.")
   message(WARNING "WolfSSL_INCLUDE_DIR is deprecated, use WOLFSSL_INCLUDE_DIR instead.")
@@ -46,53 +46,51 @@ if(DEFINED WolfSSL_LIBRARY AND NOT DEFINED WOLFSSL_LIBRARY)
   set(WOLFSSL_LIBRARY "${WolfSSL_LIBRARY}")
   set(WOLFSSL_LIBRARY "${WolfSSL_LIBRARY}")
 endif()
 endif()
 
 
-if(CURL_USE_PKGCONFIG)
+if(CURL_USE_PKGCONFIG AND
+   NOT DEFINED WOLFSSL_INCLUDE_DIR AND
+   NOT DEFINED WOLFSSL_LIBRARY)
   find_package(PkgConfig QUIET)
   find_package(PkgConfig QUIET)
-  pkg_check_modules(PC_WOLFSSL "wolfssl")
+  pkg_check_modules(WOLFSSL "wolfssl")
 endif()
 endif()
 
 
-find_path(WOLFSSL_INCLUDE_DIR NAMES "wolfssl/ssl.h"
-  HINTS
-    ${PC_WOLFSSL_INCLUDEDIR}
-    ${PC_WOLFSSL_INCLUDE_DIRS}
-)
+if(WOLFSSL_FOUND)
+  string(REPLACE ";" " " WOLFSSL_CFLAGS "${WOLFSSL_CFLAGS}")
+  message(STATUS "Found WolfSSL (via pkg-config): ${WOLFSSL_INCLUDE_DIRS} (found version \"${WOLFSSL_VERSION}\")")
+else()
+  find_path(WOLFSSL_INCLUDE_DIR NAMES "wolfssl/ssl.h")
+  find_library(WOLFSSL_LIBRARY NAMES "wolfssl")
 
 
-find_library(WOLFSSL_LIBRARY NAMES "wolfssl"
-  HINTS
-    ${PC_WOLFSSL_LIBDIR}
-    ${PC_WOLFSSL_LIBRARY_DIRS}
-)
+  unset(WOLFSSL_VERSION CACHE)
+  if(WOLFSSL_INCLUDE_DIR AND EXISTS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h")
+    set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSL_VERSION_STRING[\t ]+\"([^\"]*)\"")
+    file(STRINGS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h" _version_str REGEX "${_version_regex}")
+    string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
+    set(WOLFSSL_VERSION "${_version_str}")
+    unset(_version_regex)
+    unset(_version_str)
+  endif()
 
 
-if(PC_WOLFSSL_VERSION)
-  set(WOLFSSL_VERSION ${PC_WOLFSSL_VERSION})
-elseif(WOLFSSL_INCLUDE_DIR AND EXISTS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h")
-  set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSL_VERSION_STRING[\t ]+\"([^\"]*)\"")
-  file(STRINGS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h" _version_str REGEX "${_version_regex}")
-  string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
-  set(WOLFSSL_VERSION "${_version_str}")
-  unset(_version_regex)
-  unset(_version_str)
-endif()
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(WolfSSL
+    REQUIRED_VARS
+      WOLFSSL_INCLUDE_DIR
+      WOLFSSL_LIBRARY
+    VERSION_VAR
+      WOLFSSL_VERSION
+  )
 
 
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(WolfSSL
-  REQUIRED_VARS
-    WOLFSSL_INCLUDE_DIR
-    WOLFSSL_LIBRARY
-  VERSION_VAR
-    WOLFSSL_VERSION
-)
+  if(WOLFSSL_FOUND)
+    set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
+    set(WOLFSSL_LIBRARIES    ${WOLFSSL_LIBRARY})
+  endif()
 
 
-if(WOLFSSL_FOUND)
-  set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
-  set(WOLFSSL_LIBRARIES    ${WOLFSSL_LIBRARY})
+  mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)
+endif()
 
 
-  if(NOT WIN32)
-    find_library(_math_library "m")
-    if(_math_library)
-      list(APPEND WOLFSSL_LIBRARIES "m")  # for log and pow
-    endif()
+if(NOT WIN32)
+  find_library(_math_library "m")
+  if(_math_library)
+    list(APPEND WOLFSSL_LIBRARIES "m")  # for log and pow
   endif()
   endif()
+  mark_as_advanced(_math_library)
 endif()
 endif()
-
-mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)

+ 6 - 8
CMake/FindZstd.cmake

@@ -25,17 +25,15 @@
 #
 #
 # Input variables:
 # Input variables:
 #
 #
-# ZSTD_INCLUDE_DIR   The zstd include directory
-# Zstd_INCLUDE_DIR   The zstd include directory (deprecated)
-# ZSTD_LIBRARY       Path to zstd library
-# Zstd_LIBRARY       Path to zstd library (deprecated)
+# - `ZSTD_INCLUDE_DIR`:   The zstd include directory.
+# - `ZSTD_LIBRARY`:       Path to `zstd` library.
 #
 #
 # Result variables:
 # Result variables:
 #
 #
-# ZSTD_FOUND         System has zstd
-# ZSTD_INCLUDE_DIRS  The zstd include directories
-# ZSTD_LIBRARIES     The zstd library names
-# ZSTD_VERSION       Version of zstd
+# - `ZSTD_FOUND`:         System has zstd.
+# - `ZSTD_INCLUDE_DIRS`:  The zstd include directories.
+# - `ZSTD_LIBRARIES`:     The zstd library names.
+# - `ZSTD_VERSION`:       Version of zstd.
 
 
 if(DEFINED Zstd_INCLUDE_DIR AND NOT DEFINED ZSTD_INCLUDE_DIR)
 if(DEFINED Zstd_INCLUDE_DIR AND NOT DEFINED ZSTD_INCLUDE_DIR)
   message(WARNING "Zstd_INCLUDE_DIR is deprecated, use ZSTD_INCLUDE_DIR instead.")
   message(WARNING "Zstd_INCLUDE_DIR is deprecated, use ZSTD_INCLUDE_DIR instead.")

+ 13 - 7
CMake/Macros.cmake

@@ -30,8 +30,7 @@
 macro(check_include_file_concat _file _variable)
 macro(check_include_file_concat _file _variable)
   check_include_files("${CURL_INCLUDES};${_file}" ${_variable})
   check_include_files("${CURL_INCLUDES};${_file}" ${_variable})
   if(${_variable})
   if(${_variable})
-    set(CURL_INCLUDES ${CURL_INCLUDES} ${_file})
-    set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${_variable}")
+    list(APPEND CURL_INCLUDES ${_file})
   endif()
   endif()
 endmacro()
 endmacro()
 
 
@@ -39,8 +38,7 @@ endmacro()
 # Return result in variable: CURL_TEST_OUTPUT
 # Return result in variable: CURL_TEST_OUTPUT
 macro(curl_internal_test _curl_test)
 macro(curl_internal_test _curl_test)
   if(NOT DEFINED "${_curl_test}")
   if(NOT DEFINED "${_curl_test}")
-    set(_macro_check_function_definitions
-      "-D${_curl_test} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
+    string(REPLACE ";" " " _cmake_required_definitions "${CMAKE_REQUIRED_DEFINITIONS}")
     if(CMAKE_REQUIRED_LIBRARIES)
     if(CMAKE_REQUIRED_LIBRARIES)
       set(_curl_test_add_libraries
       set(_curl_test_add_libraries
         "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
         "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
@@ -48,10 +46,10 @@ macro(curl_internal_test _curl_test)
 
 
     message(STATUS "Performing Test ${_curl_test}")
     message(STATUS "Performing Test ${_curl_test}")
     try_compile(${_curl_test}
     try_compile(${_curl_test}
-      ${CMAKE_BINARY_DIR}
+      ${PROJECT_BINARY_DIR}
       "${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c"
       "${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c"
       CMAKE_FLAGS
       CMAKE_FLAGS
-        "-DCOMPILE_DEFINITIONS:STRING=${_macro_check_function_definitions}"
+        "-DCOMPILE_DEFINITIONS:STRING=-D${_curl_test} ${CURL_TEST_DEFINES} ${_cmake_required_definitions}"
         "${_curl_test_add_libraries}"
         "${_curl_test_add_libraries}"
       OUTPUT_VARIABLE CURL_TEST_OUTPUT)
       OUTPUT_VARIABLE CURL_TEST_OUTPUT)
     if(${_curl_test})
     if(${_curl_test})
@@ -64,7 +62,7 @@ macro(curl_internal_test _curl_test)
   endif()
   endif()
 endmacro()
 endmacro()
 
 
-macro(optional_dependency _dependency)
+macro(curl_dependency_option _dependency)
   set(CURL_${_dependency} "AUTO" CACHE STRING "Build curl with ${_dependency} support (AUTO, ON or OFF)")
   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")
   set_property(CACHE CURL_${_dependency} PROPERTY STRINGS "AUTO" "ON" "OFF")
 
 
@@ -74,3 +72,11 @@ macro(optional_dependency _dependency)
     find_package(${_dependency} REQUIRED)
     find_package(${_dependency} REQUIRED)
   endif()
   endif()
 endmacro()
 endmacro()
+
+# Convert the passed paths to libpath linker options and add them to CMAKE_REQUIRED_LINK_OPTIONS.
+macro(curl_required_libpaths _libpaths_arg)
+  set(_libpaths "${_libpaths_arg}")
+  foreach(_libpath IN LISTS _libpaths)
+    list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_LIBRARY_PATH_FLAG}${_libpath}")
+  endforeach()
+endmacro()

+ 9 - 33
CMake/OtherTests.cmake

@@ -32,20 +32,21 @@ macro(add_header_include _check _header)
   endif()
   endif()
 endmacro()
 endmacro()
 
 
-set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+set(_cmake_try_compile_target_type_save ${CMAKE_TRY_COMPILE_TARGET_TYPE})
+set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
 
 
 if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE)
 if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE)
+  cmake_push_check_state()
   unset(CMAKE_EXTRA_INCLUDE_FILES)
   unset(CMAKE_EXTRA_INCLUDE_FILES)
   if(WIN32)
   if(WIN32)
     set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h")
     set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h")
-    set(CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN")
     set(CMAKE_REQUIRED_LIBRARIES "ws2_32")
     set(CMAKE_REQUIRED_LIBRARIES "ws2_32")
   elseif(HAVE_SYS_SOCKET_H)
   elseif(HAVE_SYS_SOCKET_H)
     set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
     set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
   endif()
   endif()
   check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
   check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
   set(HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE})
   set(HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE})
-  set(CMAKE_EXTRA_INCLUDE_FILES "")
+  cmake_pop_check_state()
 endif()
 endif()
 
 
 if(NOT WIN32)
 if(NOT WIN32)
@@ -74,35 +75,8 @@ check_c_source_compiles("${_source_epilogue}
     return 0;
     return 0;
   }" HAVE_STRUCT_TIMEVAL)
   }" HAVE_STRUCT_TIMEVAL)
 
 
-unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
-
-if(NOT APPLE)
-  set(_source_epilogue "#undef inline")
-  add_header_include(HAVE_SYS_POLL_H "sys/poll.h")
-  add_header_include(HAVE_POLL_H "poll.h")
-  if(NOT CMAKE_CROSSCOMPILING)
-    check_c_source_runs("${_source_epilogue}
-      #include <stdlib.h>
-      int main(void)
-      {
-        if(0 != poll(0, 0, 10)) {
-          return 1; /* fail */
-        }
-        return 0;
-      }" HAVE_POLL_FINE)
-  elseif(UNIX)
-    check_c_source_compiles("${_source_epilogue}
-      #include <stdlib.h>
-      int main(void)
-      {
-        #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
-          (void)poll(0, 0, 0);
-        #else
-          #error force compilation error
-        #endif
-      }" HAVE_POLL_FINE)
-  endif()
-endif()
+set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_cmake_try_compile_target_type_save})
+unset(_cmake_try_compile_target_type_save)
 
 
 # Detect HAVE_GETADDRINFO_THREADSAFE
 # Detect HAVE_GETADDRINFO_THREADSAFE
 
 
@@ -118,7 +92,7 @@ elseif(APPLE OR
        CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
        CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
        CMAKE_SYSTEM_NAME STREQUAL "SunOS")
        CMAKE_SYSTEM_NAME STREQUAL "SunOS")
   set(HAVE_GETADDRINFO_THREADSAFE TRUE)
   set(HAVE_GETADDRINFO_THREADSAFE TRUE)
-elseif(CMAKE_SYSTEM_NAME MATCHES "BSD")
+elseif(BSD OR CMAKE_SYSTEM_NAME MATCHES "BSD")
   set(HAVE_GETADDRINFO_THREADSAFE FALSE)
   set(HAVE_GETADDRINFO_THREADSAFE FALSE)
 endif()
 endif()
 
 
@@ -178,3 +152,5 @@ if(NOT WIN32 AND NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
       return 0;
       return 0;
     }" HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
     }" HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
 endif()
 endif()
+
+unset(_source_epilogue)

+ 61 - 42
CMake/PickyWarnings.cmake

@@ -23,24 +23,27 @@
 ###########################################################################
 ###########################################################################
 include(CheckCCompilerFlag)
 include(CheckCCompilerFlag)
 
 
-unset(WPICKY)
+unset(_picky)
 
 
 if(CURL_WERROR AND
 if(CURL_WERROR AND
    ((CMAKE_COMPILER_IS_GNUCC AND
    ((CMAKE_COMPILER_IS_GNUCC AND
      NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND
      NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND
      NOT CMAKE_VERSION VERSION_LESS 3.23.0) OR  # to avoid check_symbol_exists() conflicting with GCC -pedantic-errors
      NOT CMAKE_VERSION VERSION_LESS 3.23.0) OR  # to avoid check_symbol_exists() conflicting with GCC -pedantic-errors
    CMAKE_C_COMPILER_ID MATCHES "Clang"))
    CMAKE_C_COMPILER_ID MATCHES "Clang"))
-  set(WPICKY "${WPICKY} -pedantic-errors")
+  list(APPEND _picky "-pedantic-errors")
+  if(MSVC)  # clang-cl
+    list(APPEND _picky "-Wno-language-extension-token")  # Override default error to make __int64 size detection pass
+  endif()
 endif()
 endif()
 
 
 if(APPLE AND
 if(APPLE AND
    (CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
    (CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
    (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
    (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
-  set(WPICKY "${WPICKY} -Werror=partial-availability")  # clang 3.6  appleclang 6.3
+  list(APPEND _picky "-Werror=partial-availability")  # clang 3.6  appleclang 6.3
 endif()
 endif()
 
 
 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
 if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
-  set(WPICKY "${WPICKY} -Werror-implicit-function-declaration")  # clang 1.0  gcc 2.95
+  list(APPEND _picky "-Werror-implicit-function-declaration")  # clang 1.0  gcc 2.95
 endif()
 endif()
 
 
 if(PICKY_COMPILER)
 if(PICKY_COMPILER)
@@ -49,29 +52,29 @@ if(PICKY_COMPILER)
     # https://clang.llvm.org/docs/DiagnosticsReference.html
     # https://clang.llvm.org/docs/DiagnosticsReference.html
     # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
     # https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
 
 
-    # WPICKY_ENABLE = Options we want to enable as-is.
-    # WPICKY_DETECT = Options we want to test first and enable if available.
+    # _picky_enable = Options we want to enable as-is.
+    # _picky_detect = Options we want to test first and enable if available.
 
 
     # Prefer the -Wextra alias with clang.
     # Prefer the -Wextra alias with clang.
     if(CMAKE_C_COMPILER_ID MATCHES "Clang")
     if(CMAKE_C_COMPILER_ID MATCHES "Clang")
-      set(WPICKY_ENABLE "-Wextra")
+      set(_picky_enable "-Wextra")
     else()
     else()
-      set(WPICKY_ENABLE "-W")
+      set(_picky_enable "-W")
     endif()
     endif()
 
 
-    list(APPEND WPICKY_ENABLE
+    list(APPEND _picky_enable
       -Wall -pedantic
       -Wall -pedantic
     )
     )
 
 
     # ----------------------------------
     # ----------------------------------
     # Add new options here, if in doubt:
     # Add new options here, if in doubt:
     # ----------------------------------
     # ----------------------------------
-    set(WPICKY_DETECT
+    set(_picky_detect
     )
     )
 
 
     # Assume these options always exist with both clang and gcc.
     # Assume these options always exist with both clang and gcc.
     # Require clang 3.0 / gcc 2.95 or later.
     # Require clang 3.0 / gcc 2.95 or later.
-    list(APPEND WPICKY_ENABLE
+    list(APPEND _picky_enable
       -Wbad-function-cast                  # clang  2.7  gcc  2.95
       -Wbad-function-cast                  # clang  2.7  gcc  2.95
       -Wconversion                         # clang  2.7  gcc  2.95
       -Wconversion                         # clang  2.7  gcc  2.95
       -Winline                             # clang  1.0  gcc  1.0
       -Winline                             # clang  1.0  gcc  1.0
@@ -89,7 +92,7 @@ if(PICKY_COMPILER)
     )
     )
 
 
     # Always enable with clang, version dependent with gcc
     # Always enable with clang, version dependent with gcc
-    set(WPICKY_COMMON_OLD
+    set(_picky_common_old
       -Waddress                            # clang  2.7  gcc  4.3
       -Waddress                            # clang  2.7  gcc  4.3
       -Wattributes                         # clang  2.7  gcc  4.1
       -Wattributes                         # clang  2.7  gcc  4.1
       -Wcast-align                         # clang  1.0  gcc  4.2
       -Wcast-align                         # clang  1.0  gcc  4.2
@@ -118,7 +121,7 @@ if(PICKY_COMPILER)
       -Wvla                                # clang  2.8  gcc  4.3
       -Wvla                                # clang  2.8  gcc  4.3
     )
     )
 
 
-    set(WPICKY_COMMON
+    set(_picky_common
       -Wdouble-promotion                   # clang  3.6  gcc  4.6  appleclang  6.3
       -Wdouble-promotion                   # clang  3.6  gcc  4.6  appleclang  6.3
       -Wenum-conversion                    # clang  3.2  gcc 10.0  appleclang  4.6  g++ 11.0
       -Wenum-conversion                    # clang  3.2  gcc 10.0  appleclang  4.6  g++ 11.0
       -Wpragmas                            # clang  3.5  gcc  4.1  appleclang  6.0
       -Wpragmas                            # clang  3.5  gcc  4.1  appleclang  6.0
@@ -126,51 +129,55 @@ if(PICKY_COMPILER)
     )
     )
 
 
     if(CMAKE_C_COMPILER_ID MATCHES "Clang")
     if(CMAKE_C_COMPILER_ID MATCHES "Clang")
-      list(APPEND WPICKY_ENABLE
-        ${WPICKY_COMMON_OLD}
+      list(APPEND _picky_enable
+        ${_picky_common_old}
         -Wshift-sign-overflow              # clang  2.9
         -Wshift-sign-overflow              # clang  2.9
         -Wshorten-64-to-32                 # clang  1.0
         -Wshorten-64-to-32                 # clang  1.0
-        -Wlanguage-extension-token         # clang  3.0
         -Wformat=2                         # clang  3.0  gcc  4.8
         -Wformat=2                         # clang  3.0  gcc  4.8
       )
       )
+      if(NOT MSVC)
+        list(APPEND _picky_enable
+          -Wlanguage-extension-token         # clang  3.0  # Avoid for clang-cl to allow __int64
+        )
+      endif()
       # Enable based on compiler version
       # Enable based on compiler version
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
-        list(APPEND WPICKY_ENABLE
-          ${WPICKY_COMMON}
-          -Wunreachable-code-break         # clang  3.5            appleclang  6.0
+        list(APPEND _picky_enable
+          ${_picky_common}
+        # -Wunreachable-code-break         # clang  3.5            appleclang  6.0  # Not used: Silent in "unity" builds
           -Wheader-guard                   # clang  3.4            appleclang  5.1
           -Wheader-guard                   # clang  3.4            appleclang  5.1
           -Wsometimes-uninitialized        # clang  3.2            appleclang  4.6
           -Wsometimes-uninitialized        # clang  3.2            appleclang  4.6
         )
         )
       endif()
       endif()
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3))
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3))
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Wcomma                          # clang  3.9            appleclang  8.3
           -Wcomma                          # clang  3.9            appleclang  8.3
           -Wmissing-variable-declarations  # clang  3.2            appleclang  4.6
           -Wmissing-variable-declarations  # clang  3.2            appleclang  4.6
         )
         )
       endif()
       endif()
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3))
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3))
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Wassign-enum                    # clang  7.0            appleclang 10.3
           -Wassign-enum                    # clang  7.0            appleclang 10.3
           -Wextra-semi-stmt                # clang  7.0            appleclang 10.3
           -Wextra-semi-stmt                # clang  7.0            appleclang 10.3
         )
         )
       endif()
       endif()
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) OR
       if((CMAKE_C_COMPILER_ID STREQUAL "Clang"      AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) OR
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.4))
          (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.4))
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Wimplicit-fallthrough           # clang  4.0  gcc  7.0  appleclang 12.4  # We do silencing for clang 10.0 and above only
           -Wimplicit-fallthrough           # clang  4.0  gcc  7.0  appleclang 12.4  # We do silencing for clang 10.0 and above only
         )
         )
       endif()
       endif()
     else()  # gcc
     else()  # gcc
-      list(APPEND WPICKY_DETECT
-        ${WPICKY_COMMON}
+      list(APPEND _picky_detect
+        ${_picky_common}
       )
       )
       # Enable based on compiler version
       # Enable based on compiler version
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3)
-        list(APPEND WPICKY_ENABLE
-          ${WPICKY_COMMON_OLD}
+        list(APPEND _picky_enable
+          ${_picky_common_old}
           -Wclobbered                      #             gcc  4.3
           -Wclobbered                      #             gcc  4.3
           -Wmissing-parameter-type         #             gcc  4.3
           -Wmissing-parameter-type         #             gcc  4.3
           -Wold-style-declaration          #             gcc  4.3
           -Wold-style-declaration          #             gcc  4.3
@@ -179,22 +186,22 @@ if(PICKY_COMPILER)
         )
         )
       endif()
       endif()
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW)
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Wno-pedantic-ms-format          #             gcc  4.5 (MinGW-only)
           -Wno-pedantic-ms-format          #             gcc  4.5 (MinGW-only)
         )
         )
       endif()
       endif()
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8)
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Wformat=2                       # clang  3.0  gcc  4.8
           -Wformat=2                       # clang  3.0  gcc  4.8
         )
         )
       endif()
       endif()
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Warray-bounds=2 -ftree-vrp      # clang  3.0  gcc  5.0 (clang default: -Warray-bounds)
           -Warray-bounds=2 -ftree-vrp      # clang  3.0  gcc  5.0 (clang default: -Warray-bounds)
         )
         )
       endif()
       endif()
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Wduplicated-cond                #             gcc  6.0
           -Wduplicated-cond                #             gcc  6.0
           -Wnull-dereference               # clang  3.0  gcc  6.0 (clang default)
           -Wnull-dereference               # clang  3.0  gcc  6.0 (clang default)
             -fdelete-null-pointer-checks
             -fdelete-null-pointer-checks
@@ -203,17 +210,16 @@ if(PICKY_COMPILER)
         )
         )
       endif()
       endif()
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0)
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Walloc-zero                     #             gcc  7.0
           -Walloc-zero                     #             gcc  7.0
           -Wduplicated-branches            #             gcc  7.0
           -Wduplicated-branches            #             gcc  7.0
-          -Wno-format-overflow             #             gcc  7.0
           -Wformat-truncation=2            #             gcc  7.0
           -Wformat-truncation=2            #             gcc  7.0
           -Wimplicit-fallthrough           # clang  4.0  gcc  7.0
           -Wimplicit-fallthrough           # clang  4.0  gcc  7.0
           -Wrestrict                       #             gcc  7.0
           -Wrestrict                       #             gcc  7.0
         )
         )
       endif()
       endif()
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0)
       if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0)
-        list(APPEND WPICKY_ENABLE
+        list(APPEND _picky_enable
           -Warith-conversion               #             gcc 10.0
           -Warith-conversion               #             gcc 10.0
         )
         )
       endif()
       endif()
@@ -221,26 +227,39 @@ if(PICKY_COMPILER)
 
 
     #
     #
 
 
-    foreach(_ccopt IN LISTS WPICKY_ENABLE)
-      set(WPICKY "${WPICKY} ${_ccopt}")
+    foreach(_ccopt IN LISTS _picky_enable)
+      list(APPEND _picky "${_ccopt}")
     endforeach()
     endforeach()
 
 
-    foreach(_ccopt IN LISTS WPICKY_DETECT)
-      # surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
-      # test result in.
+    foreach(_ccopt IN LISTS _picky_detect)
+      # Use a unique variable name 1. for meaningful log output 2. to have a fresh, undefined variable for each detection
       string(MAKE_C_IDENTIFIER "OPT${_ccopt}" _optvarname)
       string(MAKE_C_IDENTIFIER "OPT${_ccopt}" _optvarname)
       # GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
       # GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
       # so test for the positive form instead
       # so test for the positive form instead
       string(REPLACE "-Wno-" "-W" _ccopt_on "${_ccopt}")
       string(REPLACE "-Wno-" "-W" _ccopt_on "${_ccopt}")
       check_c_compiler_flag(${_ccopt_on} ${_optvarname})
       check_c_compiler_flag(${_ccopt_on} ${_optvarname})
       if(${_optvarname})
       if(${_optvarname})
-        set(WPICKY "${WPICKY} ${_ccopt}")
+        list(APPEND _picky "${_ccopt}")
       endif()
       endif()
     endforeach()
     endforeach()
   endif()
   endif()
 endif()
 endif()
 
 
-if(WPICKY)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WPICKY}")
-  message(STATUS "Picky compiler options:${WPICKY}")
+# clang-cl
+if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC)
+  if(CMAKE_VERSION VERSION_LESS 3.12)
+    set(_picky_tmp "")
+    foreach(_ccopt IN LISTS _picky)
+      list(APPEND _picky_tmp "/clang:${_ccopt}")
+    endforeach()
+    set(_picky ${_picky_tmp})
+  else()
+    list(TRANSFORM _picky PREPEND "/clang:")
+  endif()
+endif()
+
+if(_picky)
+  string(REPLACE ";" " " _picky "${_picky}")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_picky}")
+  message(STATUS "Picky compiler options: ${_picky}")
 endif()
 endif()

+ 4 - 5
CMake/Platforms/WindowsCache.cmake

@@ -88,6 +88,7 @@ set(HAVE_FREEADDRINFO 1)
 set(HAVE_FCHMOD 0)
 set(HAVE_FCHMOD 0)
 set(HAVE_SOCKETPAIR 0)
 set(HAVE_SOCKETPAIR 0)
 set(HAVE_SENDMSG 0)
 set(HAVE_SENDMSG 0)
+set(HAVE_SENDMMSG 0)
 set(HAVE_ALARM 0)
 set(HAVE_ALARM 0)
 set(HAVE_FCNTL 0)
 set(HAVE_FCNTL 0)
 set(HAVE_GETPPID 0)
 set(HAVE_GETPPID 0)
@@ -101,13 +102,12 @@ set(HAVE_IF_NAMETOINDEX 0)
 set(HAVE_GETRLIMIT 0)
 set(HAVE_GETRLIMIT 0)
 set(HAVE_SETRLIMIT 0)
 set(HAVE_SETRLIMIT 0)
 set(HAVE_FSETXATTR 0)
 set(HAVE_FSETXATTR 0)
-set(HAVE_LIBSOCKET 0)
 set(HAVE_SETLOCALE 1)
 set(HAVE_SETLOCALE 1)
 set(HAVE_SETMODE 1)
 set(HAVE_SETMODE 1)
+set(HAVE__SETMODE 1)
 set(HAVE_GETPEERNAME 1)
 set(HAVE_GETPEERNAME 1)
 set(HAVE_GETSOCKNAME 1)
 set(HAVE_GETSOCKNAME 1)
 set(HAVE_GETHOSTNAME 1)
 set(HAVE_GETHOSTNAME 1)
-set(HAVE_LIBZ 0)
 
 
 set(HAVE_RECV 1)
 set(HAVE_RECV 1)
 set(HAVE_SEND 1)
 set(HAVE_SEND 1)
@@ -122,12 +122,13 @@ set(HAVE_IFADDRS_H 0)
 set(HAVE_IO_H 1)
 set(HAVE_IO_H 1)
 set(HAVE_NETDB_H 0)
 set(HAVE_NETDB_H 0)
 set(HAVE_NETINET_IN_H 0)
 set(HAVE_NETINET_IN_H 0)
+set(HAVE_NETINET_IN6_H 0)
 set(HAVE_NETINET_TCP_H 0)
 set(HAVE_NETINET_TCP_H 0)
 set(HAVE_NETINET_UDP_H 0)
 set(HAVE_NETINET_UDP_H 0)
 set(HAVE_NET_IF_H 0)
 set(HAVE_NET_IF_H 0)
 set(HAVE_IOCTL_SIOCGIFADDR 0)
 set(HAVE_IOCTL_SIOCGIFADDR 0)
 set(HAVE_POLL_H 0)
 set(HAVE_POLL_H 0)
-set(HAVE_POLL_FINE 0)
+set(HAVE_POLL 0)
 set(HAVE_PWD_H 0)
 set(HAVE_PWD_H 0)
 set(HAVE_SYS_EVENTFD_H 0)
 set(HAVE_SYS_EVENTFD_H 0)
 set(HAVE_SYS_FILIO_H 0)
 set(HAVE_SYS_FILIO_H 0)
@@ -147,7 +148,6 @@ set(HAVE_TERMIO_H 0)
 set(HAVE_LINUX_TCP_H 0)
 set(HAVE_LINUX_TCP_H 0)
 
 
 set(HAVE_FSEEKO 0)  # mingw-w64 2.0.0 and newer has it
 set(HAVE_FSEEKO 0)  # mingw-w64 2.0.0 and newer has it
-set(HAVE__FSEEKI64 1)
 set(HAVE_SOCKET 1)
 set(HAVE_SOCKET 1)
 set(HAVE_SELECT 1)
 set(HAVE_SELECT 1)
 set(HAVE_STRDUP 1)
 set(HAVE_STRDUP 1)
@@ -166,7 +166,6 @@ set(HAVE_GETHOSTBYNAME_R 0)
 set(HAVE_SIGNAL 1)
 set(HAVE_SIGNAL 1)
 set(HAVE_SIGACTION 0)
 set(HAVE_SIGACTION 0)
 set(HAVE_GLIBC_STRERROR_R 0)
 set(HAVE_GLIBC_STRERROR_R 0)
-set(HAVE_MACH_ABSOLUTE_TIME 0)
 set(HAVE_GETIFADDRS 0)
 set(HAVE_GETIFADDRS 0)
 set(HAVE_FCNTL_O_NONBLOCK 0)
 set(HAVE_FCNTL_O_NONBLOCK 0)
 set(HAVE_IOCTLSOCKET 1)
 set(HAVE_IOCTLSOCKET 1)

+ 9 - 10
CMake/curl-config.cmake.in

@@ -23,20 +23,19 @@
 ###########################################################################
 ###########################################################################
 @PACKAGE_INIT@
 @PACKAGE_INIT@
 
 
-if(NOT DEFINED CURL_USE_PKGCONFIG)
-  if(UNIX OR (MSVC AND VCPKG_TOOLCHAIN))  # Keep in sync with root CMakeLists.txt
-    set(CURL_USE_PKGCONFIG ON)
-  else()
-    set(CURL_USE_PKGCONFIG OFF)
-  endif()
+if(UNIX OR VCPKG_TOOLCHAIN OR (MINGW AND NOT CMAKE_CROSSCOMPILING))  # Keep in sync with root CMakeLists.txt
+  set(_curl_use_pkgconfig_default ON)
+else()
+  set(_curl_use_pkgconfig_default OFF)
 endif()
 endif()
+option(CURL_USE_PKGCONFIG "Enable pkg-config to detect @PROJECT_NAME@ dependencies" ${_curl_use_pkgconfig_default})
 
 
 include(CMakeFindDependencyMacro)
 include(CMakeFindDependencyMacro)
-if(@USE_OPENSSL@)
-  find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@)
+if("@USE_OPENSSL@")
+  find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
 endif()
 endif()
-if(@USE_ZLIB@)
-  find_dependency(ZLIB @ZLIB_VERSION_MAJOR@)
+if("@HAVE_LIBZ@")
+  find_dependency(ZLIB "@ZLIB_VERSION_MAJOR@")
 endif()
 endif()
 
 
 include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
 include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")

File diff suppressed because it is too large
+ 323 - 236
CMakeLists.txt


+ 25 - 19
include/curl/curl.h

@@ -30,14 +30,15 @@
  */
  */
 
 
 #ifdef CURL_NO_OLDIES
 #ifdef CURL_NO_OLDIES
-#define CURL_STRICTER
+#define CURL_STRICTER /* not used since 8.11.0 */
 #endif
 #endif
 
 
 /* Compile-time deprecation macros. */
 /* Compile-time deprecation macros. */
-#if (defined(__GNUC__) &&                                               \
-  ((__GNUC__ > 12) || ((__GNUC__ == 12) && (__GNUC_MINOR__ >= 1 ))) ||  \
-  defined(__IAR_SYSTEMS_ICC__)) &&                                      \
-  !defined(__INTEL_COMPILER) &&                                         \
+#if (defined(__GNUC__) &&                                              \
+  ((__GNUC__ > 12) || ((__GNUC__ == 12) && (__GNUC_MINOR__ >= 1))) ||  \
+  (defined(__clang__) && __clang_major__ >= 3) ||                      \
+  defined(__IAR_SYSTEMS_ICC__)) &&                                     \
+  !defined(__INTEL_COMPILER) &&                                        \
   !defined(CURL_DISABLE_DEPRECATION) && !defined(BUILDING_LIBCURL)
   !defined(CURL_DISABLE_DEPRECATION) && !defined(BUILDING_LIBCURL)
 #define CURL_DEPRECATED(version, message)                       \
 #define CURL_DEPRECATED(version, message)                       \
   __attribute__((deprecated("since " # version ". " message)))
   __attribute__((deprecated("since " # version ". " message)))
@@ -113,13 +114,8 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
-typedef struct Curl_easy CURL;
-typedef struct Curl_share CURLSH;
-#else
 typedef void CURL;
 typedef void CURL;
 typedef void CURLSH;
 typedef void CURLSH;
-#endif
 
 
 /*
 /*
  * libcurl external API function linkage decorations.
  * libcurl external API function linkage decorations.
@@ -253,12 +249,12 @@ typedef int (*curl_xferinfo_callback)(void *clientp,
 #endif
 #endif
 
 
 #ifndef CURL_MAX_WRITE_SIZE
 #ifndef CURL_MAX_WRITE_SIZE
-  /* Tests have proven that 20K is a very bad buffer size for uploads on
-     Windows, while 16K for some odd reason performed a lot better.
-     We do the ifndef check to allow this value to easier be changed at build
-     time for those who feel adventurous. The practical minimum is about
-     400 bytes since libcurl uses a buffer of this size as a scratch area
-     (unrelated to network send operations). */
+  /* Tests have proven that 20K is a bad buffer size for uploads on Windows,
+     while 16K for some odd reason performed a lot better. We do the ifndef
+     check to allow this value to easier be changed at build time for those
+     who feel adventurous. The practical minimum is about 400 bytes since
+     libcurl uses a buffer of this size as a scratch area (unrelated to
+     network send operations). */
 #define CURL_MAX_WRITE_SIZE 16384
 #define CURL_MAX_WRITE_SIZE 16384
 #endif
 #endif
 
 
@@ -555,14 +551,14 @@ typedef enum {
   CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
   CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
   CURLE_OBSOLETE32,              /* 32 - NOT USED */
   CURLE_OBSOLETE32,              /* 32 - NOT USED */
   CURLE_RANGE_ERROR,             /* 33 - RANGE "command" did not work */
   CURLE_RANGE_ERROR,             /* 33 - RANGE "command" did not work */
-  CURLE_HTTP_POST_ERROR,         /* 34 */
+  CURLE_OBSOLETE34,              /* 34 */
   CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
   CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
   CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - could not resume download */
   CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - could not resume download */
   CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
   CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
   CURLE_LDAP_CANNOT_BIND,        /* 38 */
   CURLE_LDAP_CANNOT_BIND,        /* 38 */
   CURLE_LDAP_SEARCH_FAILED,      /* 39 */
   CURLE_LDAP_SEARCH_FAILED,      /* 39 */
   CURLE_OBSOLETE40,              /* 40 - NOT USED */
   CURLE_OBSOLETE40,              /* 40 - NOT USED */
-  CURLE_FUNCTION_NOT_FOUND,      /* 41 - NOT USED starting with 7.53.0 */
+  CURLE_OBSOLETE41,              /* 41 - NOT USED starting with 7.53.0 */
   CURLE_ABORTED_BY_CALLBACK,     /* 42 */
   CURLE_ABORTED_BY_CALLBACK,     /* 42 */
   CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
   CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
   CURLE_OBSOLETE44,              /* 44 - NOT USED */
   CURLE_OBSOLETE44,              /* 44 - NOT USED */
@@ -647,6 +643,12 @@ typedef enum {
 #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
 #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
                           the obsolete stuff removed! */
                           the obsolete stuff removed! */
 
 
+/* removed in 7.53.0 */
+#define CURLE_FUNCTION_NOT_FOUND CURLE_OBSOLETE41
+
+/* removed in 7.56.0 */
+#define CURLE_HTTP_POST_ERROR CURLE_OBSOLETE34
+
 /* Previously obsolete error code reused in 7.38.0 */
 /* Previously obsolete error code reused in 7.38.0 */
 #define CURLE_OBSOLETE16 CURLE_HTTP2
 #define CURLE_OBSOLETE16 CURLE_HTTP2
 
 
@@ -942,6 +944,9 @@ typedef enum {
    a client certificate for authentication. (Schannel) */
    a client certificate for authentication. (Schannel) */
 #define CURLSSLOPT_AUTO_CLIENT_CERT (1<<5)
 #define CURLSSLOPT_AUTO_CLIENT_CERT (1<<5)
 
 
+/* If possible, send data using TLS 1.3 early data */
+#define CURLSSLOPT_EARLYDATA (1<<6)
+
 /* The default connection attempt delay in milliseconds for happy eyeballs.
 /* The default connection attempt delay in milliseconds for happy eyeballs.
    CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
    CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
    this value, keep them in sync. */
    this value, keep them in sync. */
@@ -2953,7 +2958,8 @@ typedef enum {
   CURLINFO_QUEUE_TIME_T     = CURLINFO_OFF_T + 65,
   CURLINFO_QUEUE_TIME_T     = CURLINFO_OFF_T + 65,
   CURLINFO_USED_PROXY       = CURLINFO_LONG + 66,
   CURLINFO_USED_PROXY       = CURLINFO_LONG + 66,
   CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67,
   CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67,
-  CURLINFO_LASTONE          = 67
+  CURLINFO_EARLYDATA_SENT_T = CURLINFO_OFF_T + 68,
+  CURLINFO_LASTONE          = 68
 } CURLINFO;
 } CURLINFO;
 
 
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
 /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as

+ 3 - 3
include/curl/curlver.h

@@ -32,12 +32,12 @@
 
 
 /* This is the version number of the libcurl package from which this header
 /* This is the version number of the libcurl package from which this header
    file origins: */
    file origins: */
-#define LIBCURL_VERSION "8.10.1-DEV"
+#define LIBCURL_VERSION "8.11.1-DEV"
 
 
 /* The numeric version number is also available "in parts" by using these
 /* The numeric version number is also available "in parts" by using these
    defines: */
    defines: */
 #define LIBCURL_VERSION_MAJOR 8
 #define LIBCURL_VERSION_MAJOR 8
-#define LIBCURL_VERSION_MINOR 10
+#define LIBCURL_VERSION_MINOR 11
 #define LIBCURL_VERSION_PATCH 1
 #define LIBCURL_VERSION_PATCH 1
 
 
 /* This is the numeric version of the libcurl version number, meant for easier
 /* This is the numeric version of the libcurl version number, meant for easier
@@ -59,7 +59,7 @@
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
    and needs it to contain the full number.
 */
 */
-#define LIBCURL_VERSION_NUM 0x080a01
+#define LIBCURL_VERSION_NUM 0x080b01
 
 
 /*
 /*
  * This is the date and time when the full source package was created. The
  * This is the date and time when the full source package was created. The

+ 7 - 11
include/curl/multi.h

@@ -54,11 +54,7 @@
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
-typedef struct Curl_multi CURLM;
-#else
 typedef void CURLM;
 typedef void CURLM;
-#endif
 
 
 typedef enum {
 typedef enum {
   CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
   CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
@@ -248,13 +244,13 @@ CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
  *          The data the returned pointer points to will not survive calling
  *          The data the returned pointer points to will not survive calling
  *          curl_multi_cleanup().
  *          curl_multi_cleanup().
  *
  *
- *          The 'CURLMsg' struct is meant to be very simple and only contain
- *          very basic information. If more involved information is wanted,
- *          we will provide the particular "transfer handle" in that struct
- *          and that should/could/would be used in subsequent
- *          curl_easy_getinfo() calls (or similar). The point being that we
- *          must never expose complex structs to applications, as then we will
- *          undoubtably get backwards compatibility problems in the future.
+ *          The 'CURLMsg' struct is meant to be simple and only contain basic
+ *          information. If more involved information is wanted, we will
+ *          provide the particular "transfer handle" in that struct and that
+ *          should/could/would be used in subsequent curl_easy_getinfo() calls
+ *          (or similar). The point being that we must never expose complex
+ *          structs to applications, as then we will undoubtably get backwards
+ *          compatibility problems in the future.
  *
  *
  * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
  * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
  *          of structs. It also writes the number of messages left in the
  *          of structs. It also writes the number of messages left in the

+ 25 - 21
lib/CMakeLists.txt

@@ -21,8 +21,8 @@
 # SPDX-License-Identifier: curl
 # SPDX-License-Identifier: curl
 #
 #
 ###########################################################################
 ###########################################################################
-set(LIB_NAME libcurl)
-set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
+set(LIB_NAME "libcurl")
+set(LIBCURL_OUTPUT_NAME "libcurl" CACHE STRING "Basename of the curl library")
 add_definitions("-DBUILDING_LIBCURL")
 add_definitions("-DBUILDING_LIBCURL")
 
 
 configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
 configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
@@ -39,14 +39,14 @@ list(APPEND HHEADERS "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
 # The rest of the build
 # The rest of the build
 
 
 include_directories(
 include_directories(
-  "${CMAKE_CURRENT_BINARY_DIR}"
-  "${CMAKE_CURRENT_SOURCE_DIR}"
+  "${PROJECT_BINARY_DIR}/lib"  # for "curl_config.h"
+  "${PROJECT_SOURCE_DIR}/lib"  # for "curl_setup.h"
 )
 )
 if(USE_ARES)
 if(USE_ARES)
-  include_directories(${CARES_INCLUDE_DIRS})
+  include_directories(SYSTEM ${CARES_INCLUDE_DIRS})
 endif()
 endif()
 
 
-if(BUILD_TESTING)
+if(CURL_BUILD_TESTING)
   add_library(
   add_library(
     curlu  # special libcurlu library just for unittests
     curlu  # special libcurlu library just for unittests
     STATIC
     STATIC
@@ -112,7 +112,7 @@ if(SHARE_LIB_OBJECT)
 
 
   target_include_directories(${LIB_OBJECT} INTERFACE
   target_include_directories(${LIB_OBJECT} INTERFACE
     "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
     "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
-    "$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>")
+    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
 
 
   set(LIB_SOURCE $<TARGET_OBJECTS:${LIB_OBJECT}>)
   set(LIB_SOURCE $<TARGET_OBJECTS:${LIB_OBJECT}>)
 else()
 else()
@@ -125,7 +125,7 @@ if(BUILD_STATIC_LIBS)
   add_library(${LIB_STATIC} STATIC ${LIB_SOURCE})
   add_library(${LIB_STATIC} STATIC ${LIB_SOURCE})
   add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
   add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
   if(WIN32)
   if(WIN32)
-    set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB")
+    set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB")
   endif()
   endif()
   target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
   target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
   # Remove the "lib" prefix since the library is already named "libcurl".
   # Remove the "lib" prefix since the library is already named "libcurl".
@@ -145,7 +145,7 @@ if(BUILD_STATIC_LIBS)
 
 
   target_include_directories(${LIB_STATIC} INTERFACE
   target_include_directories(${LIB_STATIC} INTERFACE
     "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
     "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
-    "$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>")
+    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
 endif()
 endif()
 
 
 if(BUILD_SHARED_LIBS)
 if(BUILD_SHARED_LIBS)
@@ -156,15 +156,14 @@ if(BUILD_SHARED_LIBS)
     if(CYGWIN)
     if(CYGWIN)
       # For Cygwin always compile dllmain.c as a separate unit since it
       # For Cygwin always compile dllmain.c as a separate unit since it
       # includes windows.h, which should not be included in other units.
       # includes windows.h, which should not be included in other units.
-      set_source_files_properties("dllmain.c" PROPERTIES
-        SKIP_UNITY_BUILD_INCLUSION ON)
+      set_source_files_properties("dllmain.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
     endif()
     endif()
     set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "dllmain.c")
     set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "dllmain.c")
   endif()
   endif()
   if(WIN32)
   if(WIN32)
     set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libcurl.rc")
     set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libcurl.rc")
     if(CURL_HIDES_PRIVATE_SYMBOLS)
     if(CURL_HIDES_PRIVATE_SYMBOLS)
-      set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${CURL_SOURCE_DIR}/lib/libcurl.def")
+      set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${PROJECT_SOURCE_DIR}/lib/libcurl.def")
     endif()
     endif()
   endif()
   endif()
   target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS})
   target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS})
@@ -185,7 +184,7 @@ if(BUILD_SHARED_LIBS)
 
 
   target_include_directories(${LIB_SHARED} INTERFACE
   target_include_directories(${LIB_SHARED} INTERFACE
     "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
     "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
-    "$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>")
+    "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
 
 
   if(CMAKE_DLL_NAME_WITH_SOVERSION OR
   if(CMAKE_DLL_NAME_WITH_SOVERSION OR
     CYGWIN OR
     CYGWIN OR
@@ -238,16 +237,21 @@ if(BUILD_SHARED_LIBS)
         set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "WOLFSSL_")
         set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "WOLFSSL_")
       elseif(CURL_USE_GNUTLS)
       elseif(CURL_USE_GNUTLS)
         set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "GNUTLS_")
         set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "GNUTLS_")
+      elseif(CURL_USE_RUSTLS)
+        set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "RUSTLS_")
       endif()
       endif()
     endif()
     endif()
-    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers" "
-      HIDDEN {};
-      CURL_${CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX}${_cmakesoname}
-      {
-        global: curl_*;
-        local: *;
-      };")
+    # Generate version script for the linker, for versioned symbols.
+    # Consumed variables:
+    #   CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX
+    #   CURL_LIBCURL_VERSIONED_SYMBOLS_SONAME
+    set(CURL_LIBCURL_VERSIONED_SYMBOLS_SONAME ${_cmakesoname})
+    configure_file(
+      "${CMAKE_CURRENT_SOURCE_DIR}/libcurl.vers.in"
+      "${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers" @ONLY)
+    include(CMakePushCheckState)
     include(CheckCSourceCompiles)
     include(CheckCSourceCompiles)
+    cmake_push_check_state()
     set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers")
     set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers")
     check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSIONED_SYMBOLS)
     check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSIONED_SYMBOLS)
     if(HAVE_VERSIONED_SYMBOLS)
     if(HAVE_VERSIONED_SYMBOLS)
@@ -256,7 +260,7 @@ if(BUILD_SHARED_LIBS)
     else()
     else()
       message(WARNING "Versioned symbols requested, but not supported by the toolchain.")
       message(WARNING "Versioned symbols requested, but not supported by the toolchain.")
     endif()
     endif()
-    unset(CMAKE_REQUIRED_LINK_OPTIONS)
+    cmake_pop_check_state()
   endif()
   endif()
 endif()
 endif()
 
 

+ 3 - 3
lib/Makefile.inc

@@ -97,9 +97,11 @@ LIB_VQUIC_HFILES = \
 LIB_VSSH_CFILES =  \
 LIB_VSSH_CFILES =  \
   vssh/libssh.c    \
   vssh/libssh.c    \
   vssh/libssh2.c   \
   vssh/libssh2.c   \
+  vssh/curl_path.c \
   vssh/wolfssh.c
   vssh/wolfssh.c
 
 
-LIB_VSSH_HFILES =  \
+LIB_VSSH_HFILES =    \
+  vssh/curl_path.h   \
   vssh/ssh.h
   vssh/ssh.h
 
 
 LIB_CFILES =         \
 LIB_CFILES =         \
@@ -131,7 +133,6 @@ LIB_CFILES =         \
   curl_memrchr.c     \
   curl_memrchr.c     \
   curl_multibyte.c   \
   curl_multibyte.c   \
   curl_ntlm_core.c   \
   curl_ntlm_core.c   \
-  curl_path.c        \
   curl_range.c       \
   curl_range.c       \
   curl_rtmp.c        \
   curl_rtmp.c        \
   curl_sasl.c        \
   curl_sasl.c        \
@@ -273,7 +274,6 @@ LIB_HFILES =         \
   curl_memrchr.h     \
   curl_memrchr.h     \
   curl_multibyte.h   \
   curl_multibyte.h   \
   curl_ntlm_core.h   \
   curl_ntlm_core.h   \
-  curl_path.h        \
   curl_printf.h      \
   curl_printf.h      \
   curl_range.h       \
   curl_range.h       \
   curl_rtmp.h        \
   curl_rtmp.h        \

+ 16 - 18
lib/altsvc.c

@@ -64,6 +64,8 @@ static enum alpnid alpn2alpnid(char *name)
     return ALPN_h2;
     return ALPN_h2;
   if(strcasecompare(name, H3VERSION))
   if(strcasecompare(name, H3VERSION))
     return ALPN_h3;
     return ALPN_h3;
+  if(strcasecompare(name, "http/1.1"))
+    return ALPN_h1;
   return ALPN_none; /* unknown, probably rubbish input */
   return ALPN_none; /* unknown, probably rubbish input */
 }
 }
 
 
@@ -92,6 +94,7 @@ static void altsvc_free(struct altsvc *as)
 
 
 static struct altsvc *altsvc_createid(const char *srchost,
 static struct altsvc *altsvc_createid(const char *srchost,
                                       const char *dsthost,
                                       const char *dsthost,
+                                      size_t dlen, /* dsthost length */
                                       enum alpnid srcalpnid,
                                       enum alpnid srcalpnid,
                                       enum alpnid dstalpnid,
                                       enum alpnid dstalpnid,
                                       unsigned int srcport,
                                       unsigned int srcport,
@@ -99,11 +102,9 @@ static struct altsvc *altsvc_createid(const char *srchost,
 {
 {
   struct altsvc *as = calloc(1, sizeof(struct altsvc));
   struct altsvc *as = calloc(1, sizeof(struct altsvc));
   size_t hlen;
   size_t hlen;
-  size_t dlen;
   if(!as)
   if(!as)
     return NULL;
     return NULL;
   hlen = strlen(srchost);
   hlen = strlen(srchost);
-  dlen = strlen(dsthost);
   DEBUGASSERT(hlen);
   DEBUGASSERT(hlen);
   DEBUGASSERT(dlen);
   DEBUGASSERT(dlen);
   if(!hlen || !dlen) {
   if(!hlen || !dlen) {
@@ -155,7 +156,8 @@ static struct altsvc *altsvc_create(char *srchost,
   enum alpnid srcalpnid = alpn2alpnid(srcalpn);
   enum alpnid srcalpnid = alpn2alpnid(srcalpn);
   if(!srcalpnid || !dstalpnid)
   if(!srcalpnid || !dstalpnid)
     return NULL;
     return NULL;
-  return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
+  return altsvc_createid(srchost, dsthost, strlen(dsthost),
+                         srcalpnid, dstalpnid,
                          srcport, dstport);
                          srcport, dstport);
 }
 }
 
 
@@ -315,10 +317,8 @@ struct altsvcinfo *Curl_altsvc_init(void)
  */
  */
 CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
 CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
 {
 {
-  CURLcode result;
   DEBUGASSERT(asi);
   DEBUGASSERT(asi);
-  result = altsvc_load(asi, file);
-  return result;
+  return altsvc_load(asi, file);
 }
 }
 
 
 /*
 /*
@@ -490,8 +490,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
                            unsigned short srcport)
                            unsigned short srcport)
 {
 {
   const char *p = value;
   const char *p = value;
-  size_t len;
-  char namebuf[MAX_ALTSVC_HOSTLEN] = "";
   char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
   char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
   struct altsvc *as;
   struct altsvc *as;
   unsigned short dstport = srcport; /* the same by default */
   unsigned short dstport = srcport; /* the same by default */
@@ -521,6 +519,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
       p++;
       p++;
       if(*p == '\"') {
       if(*p == '\"') {
         const char *dsthost = "";
         const char *dsthost = "";
+        size_t dstlen = 0; /* destination hostname length */
         const char *value_ptr;
         const char *value_ptr;
         char option[32];
         char option[32];
         unsigned long num;
         unsigned long num;
@@ -535,32 +534,31 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
           const char *hostp = p;
           const char *hostp = p;
           if(*p == '[') {
           if(*p == '[') {
             /* pass all valid IPv6 letters - does not handle zone id */
             /* pass all valid IPv6 letters - does not handle zone id */
-            len = strspn(++p, "0123456789abcdefABCDEF:.");
-            if(p[len] != ']')
+            dstlen = strspn(++p, "0123456789abcdefABCDEF:.");
+            if(p[dstlen] != ']')
               /* invalid host syntax, bail out */
               /* invalid host syntax, bail out */
               break;
               break;
             /* we store the IPv6 numerical address *with* brackets */
             /* we store the IPv6 numerical address *with* brackets */
-            len += 2;
-            p = &p[len-1];
+            dstlen += 2;
+            p = &p[dstlen-1];
           }
           }
           else {
           else {
             while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
             while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
               p++;
               p++;
-            len = p - hostp;
+            dstlen = p - hostp;
           }
           }
-          if(!len || (len >= MAX_ALTSVC_HOSTLEN)) {
+          if(!dstlen || (dstlen >= MAX_ALTSVC_HOSTLEN)) {
             infof(data, "Excessive alt-svc hostname, ignoring.");
             infof(data, "Excessive alt-svc hostname, ignoring.");
             valid = FALSE;
             valid = FALSE;
           }
           }
           else {
           else {
-            memcpy(namebuf, hostp, len);
-            namebuf[len] = 0;
-            dsthost = namebuf;
+            dsthost = hostp;
           }
           }
         }
         }
         else {
         else {
           /* no destination name, use source host */
           /* no destination name, use source host */
           dsthost = srchost;
           dsthost = srchost;
+          dstlen = strlen(srchost);
         }
         }
         if(*p == ':') {
         if(*p == ':') {
           unsigned long port = 0;
           unsigned long port = 0;
@@ -635,7 +633,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
                this is the first entry of the line. */
                this is the first entry of the line. */
             altsvc_flush(asi, srcalpnid, srchost, srcport);
             altsvc_flush(asi, srcalpnid, srchost, srcport);
 
 
-          as = altsvc_createid(srchost, dsthost,
+          as = altsvc_createid(srchost, dsthost, dstlen,
                                srcalpnid, dstalpnid,
                                srcalpnid, dstalpnid,
                                srcport, dstport);
                                srcport, dstport);
           if(as) {
           if(as) {

+ 9 - 18
lib/asyn-ares.c

@@ -290,23 +290,14 @@ static void destroy_async_data(struct Curl_async *async)
 int Curl_resolver_getsock(struct Curl_easy *data,
 int Curl_resolver_getsock(struct Curl_easy *data,
                           curl_socket_t *socks)
                           curl_socket_t *socks)
 {
 {
-  struct timeval maxtime;
+  struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 };
   struct timeval timebuf;
   struct timeval timebuf;
-  struct timeval *timeout;
-  long milli;
   int max = ares_getsock((ares_channel)data->state.async.resolver,
   int max = ares_getsock((ares_channel)data->state.async.resolver,
                          (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
                          (ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
-
-  maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
-  maxtime.tv_usec = 0;
-
-  timeout = ares_timeout((ares_channel)data->state.async.resolver, &maxtime,
-                         &timebuf);
-  milli = (long)curlx_tvtoms(timeout);
-  if(milli == 0)
-    milli += 10;
+  struct timeval *timeout =
+    ares_timeout((ares_channel)data->state.async.resolver, &maxtime, &timebuf);
+  timediff_t milli = curlx_tvtoms(timeout);
   Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
   Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
-
   return max;
   return max;
 }
 }
 
 
@@ -366,10 +357,10 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
     /* move through the descriptors and ask for processing on them */
     /* move through the descriptors and ask for processing on them */
     for(i = 0; i < num; i++)
     for(i = 0; i < num; i++)
       ares_process_fd((ares_channel)data->state.async.resolver,
       ares_process_fd((ares_channel)data->state.async.resolver,
-                      (pfd[i].revents & (POLLRDNORM|POLLIN))?
-                      pfd[i].fd:ARES_SOCKET_BAD,
-                      (pfd[i].revents & (POLLWRNORM|POLLOUT))?
-                      pfd[i].fd:ARES_SOCKET_BAD);
+                      (pfd[i].revents & (POLLRDNORM|POLLIN)) ?
+                      pfd[i].fd : ARES_SOCKET_BAD,
+                      (pfd[i].revents & (POLLWRNORM|POLLOUT)) ?
+                      pfd[i].fd : ARES_SOCKET_BAD);
   }
   }
   return nfds;
   return nfds;
 }
 }
@@ -801,7 +792,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
       }
       }
 #endif /* CURLRES_IPV6 */
 #endif /* CURLRES_IPV6 */
       hints.ai_family = pf;
       hints.ai_family = pf;
-      hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
+      hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ?
         SOCK_STREAM : SOCK_DGRAM;
         SOCK_STREAM : SOCK_DGRAM;
       /* Since the service is a numerical one, set the hint flags
       /* Since the service is a numerical one, set the hint flags
        * accordingly to save a call to getservbyname in inside C-Ares
        * accordingly to save a call to getservbyname in inside C-Ares

+ 4 - 4
lib/asyn-thread.c

@@ -286,7 +286,7 @@ static CURLcode getaddrinfo_complete(struct Curl_easy *data)
  * and wait on it.
  * and wait on it.
  */
  */
 static
 static
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
 DWORD
 DWORD
 #else
 #else
 unsigned int
 unsigned int
@@ -311,7 +311,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg)
   rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
   rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
 
 
   if(rc) {
   if(rc) {
-    tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
+    tsd->sock_error = SOCKERRNO ? SOCKERRNO : rc;
     if(tsd->sock_error == 0)
     if(tsd->sock_error == 0)
       tsd->sock_error = RESOLVER_ENOMEM;
       tsd->sock_error = RESOLVER_ENOMEM;
   }
   }
@@ -354,7 +354,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg)
  * gethostbyname_thread() resolves a name and then exits.
  * gethostbyname_thread() resolves a name and then exits.
  */
  */
 static
 static
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
 DWORD
 DWORD
 #else
 #else
 unsigned int
 unsigned int
@@ -728,7 +728,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
 
 
   memset(&hints, 0, sizeof(hints));
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = pf;
   hints.ai_family = pf;
-  hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
+  hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ?
     SOCK_STREAM : SOCK_DGRAM;
     SOCK_STREAM : SOCK_DGRAM;
 
 
   reslv->start = Curl_now();
   reslv->start = Curl_now();

+ 4 - 4
lib/bufq.c

@@ -484,17 +484,17 @@ CURLcode Curl_bufq_cwrite(struct bufq *q,
   ssize_t n;
   ssize_t n;
   CURLcode result;
   CURLcode result;
   n = Curl_bufq_write(q, (const unsigned char *)buf, len, &result);
   n = Curl_bufq_write(q, (const unsigned char *)buf, len, &result);
-  *pnwritten = (n < 0)? 0 : (size_t)n;
+  *pnwritten = (n < 0) ? 0 : (size_t)n;
   return result;
   return result;
 }
 }
 
 
 CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len)
 CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len)
 {
 {
   while(len && q->tail) {
   while(len && q->tail) {
-    len -= chunk_unwrite(q->head, len);
+    len -= chunk_unwrite(q->tail, len);
     prune_tail(q);
     prune_tail(q);
   }
   }
-  return len? CURLE_AGAIN : CURLE_OK;
+  return len ? CURLE_AGAIN : CURLE_OK;
 }
 }
 
 
 ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
 ssize_t Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
@@ -526,7 +526,7 @@ CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
   ssize_t n;
   ssize_t n;
   CURLcode result;
   CURLcode result;
   n = Curl_bufq_read(q, (unsigned char *)buf, len, &result);
   n = Curl_bufq_read(q, (unsigned char *)buf, len, &result);
-  *pnread = (n < 0)? 0 : (size_t)n;
+  *pnread = (n < 0) ? 0 : (size_t)n;
   return result;
   return result;
 }
 }
 
 

+ 4 - 4
lib/c-hyper.c

@@ -274,7 +274,7 @@ static CURLcode status_line(struct Curl_easy *data,
   /* We need to set 'httpcodeq' for functions that check the response code in
   /* We need to set 'httpcodeq' for functions that check the response code in
      a single place. */
      a single place. */
   data->req.httpcode = http_status;
   data->req.httpcode = http_status;
-  data->req.httpversion = http_version == HYPER_HTTP_VERSION_1_1? 11 :
+  data->req.httpversion = http_version == HYPER_HTTP_VERSION_1_1 ? 11 :
                           (http_version == HYPER_HTTP_VERSION_2 ? 20 : 10);
                           (http_version == HYPER_HTTP_VERSION_2 ? 20 : 10);
   if(data->state.hconnect)
   if(data->state.hconnect)
     /* CONNECT */
     /* CONNECT */
@@ -481,8 +481,8 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
         goto out;
         goto out;
 
 
       k->deductheadercount =
       k->deductheadercount =
-        (100 <= http_status && 199 >= http_status)?k->headerbytecount:0;
-#ifdef USE_WEBSOCKETS
+        (100 <= http_status && 199 >= http_status) ? k->headerbytecount : 0;
+#ifndef CURL_DISABLE_WEBSOCKETS
       if(k->upgr101 == UPGR101_WS) {
       if(k->upgr101 == UPGR101_WS) {
         if(http_status == 101) {
         if(http_status == 101) {
           /* verify the response */
           /* verify the response */
@@ -1035,7 +1035,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
   }
   }
 
 
   p_accept = Curl_checkheaders(data,
   p_accept = Curl_checkheaders(data,
-                               STRCONST("Accept"))?NULL:"Accept: */*\r\n";
+                               STRCONST("Accept")) ? NULL : "Accept: */*\r\n";
   if(p_accept) {
   if(p_accept) {
     result = Curl_hyper_header(data, headers, p_accept);
     result = Curl_hyper_header(data, headers, p_accept);
     if(result)
     if(result)

+ 3 - 3
lib/cf-h1-proxy.c

@@ -299,7 +299,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
      (checkprefix("Proxy-authenticate:", header) &&
      (checkprefix("Proxy-authenticate:", header) &&
       (407 == k->httpcode))) {
       (407 == k->httpcode))) {
 
 
-    bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+    bool proxy = (k->httpcode == 407);
     char *auth = Curl_copy_header_value(header);
     char *auth = Curl_copy_header_value(header);
     if(!auth)
     if(!auth)
       return CURLE_OUT_OF_MEMORY;
       return CURLE_OUT_OF_MEMORY;
@@ -547,8 +547,8 @@ static CURLcode CONNECT_host(struct Curl_cfilter *cf,
   if(result)
   if(result)
     return result;
     return result;
 
 
-  authority = aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
-                      port);
+  authority = aprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
+                      ipv6_ip ? "]" : "", port);
   if(!authority)
   if(!authority)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 

+ 19 - 18
lib/cf-h2-proxy.c

@@ -98,7 +98,8 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
     return result;
     return result;
 
 
   ts->authority = /* host:port with IPv6 support */
   ts->authority = /* host:port with IPv6 support */
-    aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", port);
+    aprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
+            ipv6_ip ? "]" : "", port);
   if(!ts->authority)
   if(!ts->authority)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
@@ -276,6 +277,8 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf,
 {
 {
   struct cf_h2_proxy_ctx *ctx = cf->ctx;
   struct cf_h2_proxy_ctx *ctx = cf->ctx;
   nghttp2_option *o;
   nghttp2_option *o;
+  nghttp2_mem mem = {NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
+                     Curl_nghttp2_calloc, Curl_nghttp2_realloc};
 
 
   int rc = nghttp2_option_new(&o);
   int rc = nghttp2_option_new(&o);
   if(rc)
   if(rc)
@@ -288,7 +291,7 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf,
      HTTP field value. */
      HTTP field value. */
   nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
   nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
 #endif
 #endif
-  rc = nghttp2_session_client_new2(&ctx->h2, cbs, cf, o);
+  rc = nghttp2_session_client_new3(&ctx->h2, cbs, cf, o, &mem);
   nghttp2_option_del(o);
   nghttp2_option_del(o);
   return rc;
   return rc;
 }
 }
@@ -429,7 +432,7 @@ static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
     return result;
     return result;
   }
   }
   CURL_TRC_CF(data, cf, "[0] nw send buffer flushed");
   CURL_TRC_CF(data, cf, "[0] nw send buffer flushed");
-  return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
+  return Curl_bufq_is_empty(&ctx->outbufq) ? CURLE_OK : CURLE_AGAIN;
 }
 }
 
 
 /*
 /*
@@ -604,29 +607,27 @@ static int proxy_h2_fr_print(const nghttp2_frame *frame,
       return msnprintf(buffer, blen,
       return msnprintf(buffer, blen,
                        "FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
                        "FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
     }
     }
-    case NGHTTP2_PUSH_PROMISE: {
+    case NGHTTP2_PUSH_PROMISE:
       return msnprintf(buffer, blen,
       return msnprintf(buffer, blen,
                        "FRAME[PUSH_PROMISE, len=%d, hend=%d]",
                        "FRAME[PUSH_PROMISE, len=%d, hend=%d]",
                        (int)frame->hd.length,
                        (int)frame->hd.length,
                        !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
                        !!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
-    }
-    case NGHTTP2_PING: {
+    case NGHTTP2_PING:
       return msnprintf(buffer, blen,
       return msnprintf(buffer, blen,
                        "FRAME[PING, len=%d, ack=%d]",
                        "FRAME[PING, len=%d, ack=%d]",
                        (int)frame->hd.length,
                        (int)frame->hd.length,
-                       frame->hd.flags&NGHTTP2_FLAG_ACK);
-    }
+                       frame->hd.flags & NGHTTP2_FLAG_ACK);
     case NGHTTP2_GOAWAY: {
     case NGHTTP2_GOAWAY: {
       char scratch[128];
       char scratch[128];
       size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
       size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
-        size_t len = (frame->goaway.opaque_data_len < s_len)?
-                      frame->goaway.opaque_data_len : s_len-1;
-        if(len)
-          memcpy(scratch, frame->goaway.opaque_data, len);
-        scratch[len] = '\0';
-        return msnprintf(buffer, blen, "FRAME[GOAWAY, error=%d, reason='%s', "
-                         "last_stream=%d]", frame->goaway.error_code,
-                         scratch, frame->goaway.last_stream_id);
+      size_t len = (frame->goaway.opaque_data_len < s_len) ?
+        frame->goaway.opaque_data_len : s_len-1;
+      if(len)
+        memcpy(scratch, frame->goaway.opaque_data, len);
+      scratch[len] = '\0';
+      return msnprintf(buffer, blen, "FRAME[GOAWAY, error=%d, reason='%s', "
+                       "last_stream=%d]", frame->goaway.error_code,
+                       scratch, frame->goaway.last_stream_id);
     }
     }
     case NGHTTP2_WINDOW_UPDATE: {
     case NGHTTP2_WINDOW_UPDATE: {
       return msnprintf(buffer, blen,
       return msnprintf(buffer, blen,
@@ -1220,7 +1221,7 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
      (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED &&
      (ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED &&
       !Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
       !Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
     return TRUE;
     return TRUE;
-  return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
+  return cf->next ? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
 }
 }
 
 
 static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
 static void cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
@@ -1586,7 +1587,7 @@ static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf,
   default:
   default:
     break;
     break;
   }
   }
-  return cf->next?
+  return cf->next ?
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     CURLE_UNKNOWN_OPTION;
     CURLE_UNKNOWN_OPTION;
 }
 }

+ 2 - 2
lib/cf-haproxy.c

@@ -93,7 +93,7 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
     client_ip = ipquad.local_ip;
     client_ip = ipquad.local_ip;
 
 
   result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
   result = Curl_dyn_addf(&ctx->data_out, "PROXY %s %s %s %i %i\r\n",
-                         is_ipv6? "TCP6" : "TCP4",
+                         is_ipv6 ? "TCP6" : "TCP4",
                          client_ip, ipquad.remote_ip,
                          client_ip, ipquad.remote_ip,
                          ipquad.local_port, ipquad.remote_port);
                          ipquad.local_port, ipquad.remote_port);
 
 
@@ -231,7 +231,7 @@ static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf,
 
 
 out:
 out:
   cf_haproxy_ctx_free(ctx);
   cf_haproxy_ctx_free(ctx);
-  *pcf = result? NULL : cf;
+  *pcf = result ? NULL : cf;
   return result;
   return result;
 }
 }
 
 

+ 17 - 10
lib/cf-https-connect.c

@@ -174,6 +174,7 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
 {
 {
   struct cf_hc_ctx *ctx = cf->ctx;
   struct cf_hc_ctx *ctx = cf->ctx;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
+  int reply_ms;
 
 
   DEBUGASSERT(winner->cf);
   DEBUGASSERT(winner->cf);
   if(winner != &ctx->h3_baller)
   if(winner != &ctx->h3_baller)
@@ -181,9 +182,15 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
   if(winner != &ctx->h21_baller)
   if(winner != &ctx->h21_baller)
     cf_hc_baller_reset(&ctx->h21_baller, data);
     cf_hc_baller_reset(&ctx->h21_baller, data);
 
 
-  CURL_TRC_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
-              winner->name, (int)Curl_timediff(Curl_now(), winner->started),
-              cf_hc_baller_reply_ms(winner, data));
+  reply_ms = cf_hc_baller_reply_ms(winner, data);
+  if(reply_ms >= 0)
+    CURL_TRC_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
+                winner->name, (int)Curl_timediff(Curl_now(), winner->started),
+                reply_ms);
+  else
+    CURL_TRC_CF(data, cf, "deferred handshake %s: %dms",
+                winner->name, (int)Curl_timediff(Curl_now(), winner->started));
+
   cf->next = winner->cf;
   cf->next = winner->cf;
   winner->cf = NULL;
   winner->cf = NULL;
 
 
@@ -275,7 +282,7 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
     }
     }
     else if(ctx->h21_baller.enabled)
     else if(ctx->h21_baller.enabled)
       cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
       cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
-                       cf->conn->transport);
+                        cf->conn->transport);
     ctx->state = CF_HC_CONNECT;
     ctx->state = CF_HC_CONNECT;
     FALLTHROUGH();
     FALLTHROUGH();
 
 
@@ -306,8 +313,8 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
        (!ctx->h21_baller.enabled || ctx->h21_baller.result)) {
        (!ctx->h21_baller.enabled || ctx->h21_baller.result)) {
       /* both failed or disabled. we give up */
       /* both failed or disabled. we give up */
       CURL_TRC_CF(data, cf, "connect, all failed");
       CURL_TRC_CF(data, cf, "connect, all failed");
-      result = ctx->result = ctx->h3_baller.enabled?
-                              ctx->h3_baller.result : ctx->h21_baller.result;
+      result = ctx->result = ctx->h3_baller.enabled ?
+        ctx->h3_baller.result : ctx->h21_baller.result;
       ctx->state = CF_HC_FAILURE;
       ctx->state = CF_HC_FAILURE;
       goto out;
       goto out;
     }
     }
@@ -420,13 +427,13 @@ static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
 
 
   memset(&tmax, 0, sizeof(tmax));
   memset(&tmax, 0, sizeof(tmax));
   memset(&t, 0, sizeof(t));
   memset(&t, 0, sizeof(t));
-  cfb = ctx->h21_baller.enabled? ctx->h21_baller.cf : NULL;
+  cfb = ctx->h21_baller.enabled ? ctx->h21_baller.cf : NULL;
   if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
   if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
     if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
     if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
       tmax = t;
       tmax = t;
   }
   }
   memset(&t, 0, sizeof(t));
   memset(&t, 0, sizeof(t));
-  cfb = ctx->h3_baller.enabled? ctx->h3_baller.cf : NULL;
+  cfb = ctx->h3_baller.enabled ? ctx->h3_baller.cf : NULL;
   if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
   if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
     if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
     if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
       tmax = t;
       tmax = t;
@@ -464,7 +471,7 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
       break;
       break;
     }
     }
   }
   }
-  return cf->next?
+  return cf->next ?
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     CURLE_UNKNOWN_OPTION;
     CURLE_UNKNOWN_OPTION;
 }
 }
@@ -553,7 +560,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
   cf_hc_reset(cf, data);
   cf_hc_reset(cf, data);
 
 
 out:
 out:
-  *pcf = result? NULL : cf;
+  *pcf = result ? NULL : cf;
   free(ctx);
   free(ctx);
   return result;
   return result;
 }
 }

+ 214 - 116
lib/cf-socket.c

@@ -177,7 +177,7 @@ static void
 tcpkeepalive(struct Curl_easy *data,
 tcpkeepalive(struct Curl_easy *data,
              curl_socket_t sockfd)
              curl_socket_t sockfd)
 {
 {
-  int optval = data->set.tcp_keepalive?1:0;
+  int optval = data->set.tcp_keepalive ? 1 : 0;
 
 
   /* only set IDLE and INTVL if setting KEEPALIVE is successful */
   /* only set IDLE and INTVL if setting KEEPALIVE is successful */
   if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
   if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
@@ -336,7 +336,7 @@ void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
 
 
   if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
   if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
     dest->addrlen = sizeof(struct Curl_sockaddr_storage);
     dest->addrlen = sizeof(struct Curl_sockaddr_storage);
-  memcpy(&dest->sa_addr, ai->ai_addr, dest->addrlen);
+  memcpy(&dest->curl_sa_addr, ai->ai_addr, dest->addrlen);
 }
 }
 
 
 static CURLcode socket_open(struct Curl_easy *data,
 static CURLcode socket_open(struct Curl_easy *data,
@@ -355,11 +355,11 @@ static CURLcode socket_open(struct Curl_easy *data,
     * might have been changed and this 'new' address will actually be used
     * might have been changed and this 'new' address will actually be used
     * here to connect.
     * here to connect.
     */
     */
-    Curl_set_in_callback(data, true);
+    Curl_set_in_callback(data, TRUE);
     *sockfd = data->set.fopensocket(data->set.opensocket_client,
     *sockfd = data->set.fopensocket(data->set.opensocket_client,
                                     CURLSOCKTYPE_IPCXN,
                                     CURLSOCKTYPE_IPCXN,
                                     (struct curl_sockaddr *)addr);
                                     (struct curl_sockaddr *)addr);
-    Curl_set_in_callback(data, false);
+    Curl_set_in_callback(data, FALSE);
   }
   }
   else {
   else {
     /* opensocket callback not set, so simply create the socket now */
     /* opensocket callback not set, so simply create the socket now */
@@ -372,7 +372,7 @@ static CURLcode socket_open(struct Curl_easy *data,
 
 
 #if defined(USE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
 #if defined(USE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
   if(data->conn->scope_id && (addr->family == AF_INET6)) {
   if(data->conn->scope_id && (addr->family == AF_INET6)) {
-    struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
+    struct sockaddr_in6 * const sa6 = (void *)&addr->curl_sa_addr;
     sa6->sin6_scope_id = data->conn->scope_id;
     sa6->sin6_scope_id = data->conn->scope_id;
   }
   }
 #endif
 #endif
@@ -413,9 +413,9 @@ static int socket_close(struct Curl_easy *data, struct connectdata *conn,
   if(use_callback && conn && conn->fclosesocket) {
   if(use_callback && conn && conn->fclosesocket) {
     int rc;
     int rc;
     Curl_multi_closed(data, sock);
     Curl_multi_closed(data, sock);
-    Curl_set_in_callback(data, true);
+    Curl_set_in_callback(data, TRUE);
     rc = conn->fclosesocket(conn->closesocket_client, sock);
     rc = conn->fclosesocket(conn->closesocket_client, sock);
-    Curl_set_in_callback(data, false);
+    Curl_set_in_callback(data, FALSE);
     return rc;
     return rc;
   }
   }
 
 
@@ -600,36 +600,39 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
   if(!iface && !host && !port)
   if(!iface && !host && !port)
     /* no local kind of binding was requested */
     /* no local kind of binding was requested */
     return CURLE_OK;
     return CURLE_OK;
+  else if(iface && (strlen(iface) >= 255) )
+    return CURLE_BAD_FUNCTION_ARGUMENT;
 
 
   memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
   memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
 
 
-  if(iface && (strlen(iface)<255) ) {
+  if(iface || host) {
     char myhost[256] = "";
     char myhost[256] = "";
     int done = 0; /* -1 for error, 1 for address found */
     int done = 0; /* -1 for error, 1 for address found */
     if2ip_result_t if2ip_result = IF2IP_NOT_FOUND;
     if2ip_result_t if2ip_result = IF2IP_NOT_FOUND;
 
 
-    /* interface */
 #ifdef SO_BINDTODEVICE
 #ifdef SO_BINDTODEVICE
-    /*
-      * This binds the local socket to a particular interface. This will
-      * force even requests to other local interfaces to go out the external
-      * interface. Only bind to the interface when specified as interface,
-      * not just as a hostname or ip address.
-      *
-      * The interface might be a VRF, eg: vrf-blue, which means it cannot be
-      * converted to an IP address and would fail Curl_if2ip. Simply try to
-      * use it straight away.
-      */
-    if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
-                  iface, (curl_socklen_t)strlen(iface) + 1) == 0) {
-      /* This is often "errno 1, error: Operation not permitted" if you are
-        * not running as root or another suitable privileged user. If it
-        * succeeds it means the parameter was a valid interface and not an IP
-        * address. Return immediately.
-        */
-      if(!host_input) {
-        infof(data, "socket successfully bound to interface '%s'", iface);
-        return CURLE_OK;
+    if(iface) {
+      /*
+       * This binds the local socket to a particular interface. This will
+       * force even requests to other local interfaces to go out the external
+       * interface. Only bind to the interface when specified as interface,
+       * not just as a hostname or ip address.
+       *
+       * The interface might be a VRF, eg: vrf-blue, which means it cannot be
+       * converted to an IP address and would fail Curl_if2ip. Simply try to
+       * use it straight away.
+       */
+      if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+                    iface, (curl_socklen_t)strlen(iface) + 1) == 0) {
+        /* This is often "errno 1, error: Operation not permitted" if you are
+         * not running as root or another suitable privileged user. If it
+         * succeeds it means the parameter was a valid interface and not an IP
+         * address. Return immediately.
+         */
+        if(!host_input) {
+          infof(data, "socket successfully bound to interface '%s'", iface);
+          return CURLE_OK;
+        }
       }
       }
     }
     }
 #endif
 #endif
@@ -1088,13 +1091,14 @@ static CURLcode set_remote_ip(struct Curl_cfilter *cf,
   struct cf_socket_ctx *ctx = cf->ctx;
   struct cf_socket_ctx *ctx = cf->ctx;
 
 
   /* store remote address and port used in this connection attempt */
   /* store remote address and port used in this connection attempt */
-  if(!Curl_addr2string(&ctx->addr.sa_addr, (curl_socklen_t)ctx->addr.addrlen,
+  if(!Curl_addr2string(&ctx->addr.curl_sa_addr,
+                       (curl_socklen_t)ctx->addr.addrlen,
                        ctx->ip.remote_ip, &ctx->ip.remote_port)) {
                        ctx->ip.remote_ip, &ctx->ip.remote_port)) {
     char buffer[STRERROR_LEN];
     char buffer[STRERROR_LEN];
 
 
     ctx->error = errno;
     ctx->error = errno;
     /* malformed address or bug in inet_ntop, try next address */
     /* malformed address or bug in inet_ntop, try next address */
-    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+    failf(data, "curl_sa_addr inet_ntop() failed with errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
     return CURLE_FAILED_INIT;
     return CURLE_FAILED_INIT;
   }
   }
@@ -1163,11 +1167,11 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
 
 
   if(data->set.fsockopt) {
   if(data->set.fsockopt) {
     /* activate callback for setting socket options */
     /* activate callback for setting socket options */
-    Curl_set_in_callback(data, true);
+    Curl_set_in_callback(data, TRUE);
     error = data->set.fsockopt(data->set.sockopt_client,
     error = data->set.fsockopt(data->set.sockopt_client,
                                ctx->sock,
                                ctx->sock,
                                CURLSOCKTYPE_IPCXN);
                                CURLSOCKTYPE_IPCXN);
-    Curl_set_in_callback(data, false);
+    Curl_set_in_callback(data, FALSE);
 
 
     if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
     if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
       isconnected = TRUE;
       isconnected = TRUE;
@@ -1185,7 +1189,7 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
 #endif
 #endif
     ) {
     ) {
     result = bindlocal(data, cf->conn, ctx->sock, ctx->addr.family,
     result = bindlocal(data, cf->conn, ctx->sock, ctx->addr.family,
-                       Curl_ipv6_scope(&ctx->addr.sa_addr));
+                       Curl_ipv6_scope(&ctx->addr.curl_sa_addr));
     if(result) {
     if(result) {
       if(result == CURLE_UNSUPPORTED_PROTOCOL) {
       if(result == CURLE_UNSUPPORTED_PROTOCOL) {
         /* The address family is not supported on this interface.
         /* The address family is not supported on this interface.
@@ -1257,7 +1261,7 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data,
       endpoints.sae_srcif = 0;
       endpoints.sae_srcif = 0;
       endpoints.sae_srcaddr = NULL;
       endpoints.sae_srcaddr = NULL;
       endpoints.sae_srcaddrlen = 0;
       endpoints.sae_srcaddrlen = 0;
-      endpoints.sae_dstaddr = &ctx->addr.sa_addr;
+      endpoints.sae_dstaddr = &ctx->addr.curl_sa_addr;
       endpoints.sae_dstaddrlen = ctx->addr.addrlen;
       endpoints.sae_dstaddrlen = ctx->addr.addrlen;
 
 
       rc = connectx(ctx->sock, &endpoints, SAE_ASSOCID_ANY,
       rc = connectx(ctx->sock, &endpoints, SAE_ASSOCID_ANY,
@@ -1265,10 +1269,10 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data,
                     NULL, 0, NULL, NULL);
                     NULL, 0, NULL, NULL);
     }
     }
     else {
     else {
-      rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+      rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
     }
     }
 #  else
 #  else
-    rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+    rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
 #  endif /* HAVE_BUILTIN_AVAILABLE */
 #  endif /* HAVE_BUILTIN_AVAILABLE */
 #elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
 #elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
     if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
     if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
@@ -1276,16 +1280,16 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data,
       infof(data, "Failed to enable TCP Fast Open on fd %" FMT_SOCKET_T,
       infof(data, "Failed to enable TCP Fast Open on fd %" FMT_SOCKET_T,
             ctx->sock);
             ctx->sock);
 
 
-    rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+    rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
 #elif defined(MSG_FASTOPEN) /* old Linux */
 #elif defined(MSG_FASTOPEN) /* old Linux */
     if(cf->conn->given->flags & PROTOPT_SSL)
     if(cf->conn->given->flags & PROTOPT_SSL)
-      rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
+      rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
     else
     else
       rc = 0; /* Do nothing */
       rc = 0; /* Do nothing */
 #endif
 #endif
   }
   }
   else {
   else {
-    rc = connect(ctx->sock, &ctx->addr.sa_addr,
+    rc = connect(ctx->sock, &ctx->addr.curl_sa_addr,
                  (curl_socklen_t)ctx->addr.addrlen);
                  (curl_socklen_t)ctx->addr.addrlen);
   }
   }
   return rc;
   return rc;
@@ -1309,7 +1313,7 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
   if(blocking)
   if(blocking)
     return CURLE_UNSUPPORTED_PROTOCOL;
     return CURLE_UNSUPPORTED_PROTOCOL;
 
 
-  *done = FALSE; /* a very negative world view is best */
+  *done = FALSE; /* a negative world view is best */
   if(ctx->sock == CURL_SOCKET_BAD) {
   if(ctx->sock == CURL_SOCKET_BAD) {
     int error;
     int error;
 
 
@@ -1507,7 +1511,7 @@ static ssize_t cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
   if(cf->conn->bits.tcp_fastopen) {
   if(cf->conn->bits.tcp_fastopen) {
     nwritten = sendto(ctx->sock, buf, len, MSG_FASTOPEN,
     nwritten = sendto(ctx->sock, buf, len, MSG_FASTOPEN,
-                      &cf->conn->remote_addr->sa_addr,
+                      &cf->conn->remote_addr->curl_sa_addr,
                       cf->conn->remote_addr->addrlen);
                       cf->conn->remote_addr->addrlen);
     cf->conn->bits.tcp_fastopen = FALSE;
     cf->conn->bits.tcp_fastopen = FALSE;
   }
   }
@@ -1642,7 +1646,7 @@ static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data)
     cf->conn->primary = ctx->ip;
     cf->conn->primary = ctx->ip;
     cf->conn->remote_addr = &ctx->addr;
     cf->conn->remote_addr = &ctx->addr;
   #ifdef USE_IPV6
   #ifdef USE_IPV6
-    cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6)? TRUE : FALSE;
+    cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6);
   #endif
   #endif
   }
   }
   else {
   else {
@@ -1725,7 +1729,7 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
   case CF_QUERY_CONNECT_REPLY_MS:
   case CF_QUERY_CONNECT_REPLY_MS:
     if(ctx->got_first_byte) {
     if(ctx->got_first_byte) {
       timediff_t ms = Curl_timediff(ctx->first_byte_at, ctx->started_at);
       timediff_t ms = Curl_timediff(ctx->first_byte_at, ctx->started_at);
-      *pres1 = (ms < INT_MAX)? (int)ms : INT_MAX;
+      *pres1 = (ms < INT_MAX) ? (int)ms : INT_MAX;
     }
     }
     else
     else
       *pres1 = -1;
       *pres1 = -1;
@@ -1750,7 +1754,7 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
   }
   }
   case CF_QUERY_IP_INFO:
   case CF_QUERY_IP_INFO:
 #ifdef USE_IPV6
 #ifdef USE_IPV6
-    *pres1 = (ctx->addr.family == AF_INET6)? TRUE : FALSE;
+    *pres1 = (ctx->addr.family == AF_INET6);
 #else
 #else
     *pres1 = FALSE;
     *pres1 = FALSE;
 #endif
 #endif
@@ -1759,7 +1763,7 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
   default:
   default:
     break;
     break;
   }
   }
-  return cf->next?
+  return cf->next ?
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     CURLE_UNKNOWN_OPTION;
     CURLE_UNKNOWN_OPTION;
 }
 }
@@ -1806,7 +1810,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
   result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx);
   result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx);
 
 
 out:
 out:
-  *pcf = (!result)? cf : NULL;
+  *pcf = (!result) ? cf : NULL;
   if(result) {
   if(result) {
     Curl_safefree(cf);
     Curl_safefree(cf);
     Curl_safefree(ctx);
     Curl_safefree(ctx);
@@ -1827,7 +1831,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
   /* QUIC needs a connected socket, nonblocking */
   /* QUIC needs a connected socket, nonblocking */
   DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
   DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
 
 
-  rc = connect(ctx->sock, &ctx->addr.sa_addr,
+  rc = connect(ctx->sock, &ctx->addr.curl_sa_addr,
                (curl_socklen_t)ctx->addr.addrlen);
                (curl_socklen_t)ctx->addr.addrlen);
   if(-1 == rc) {
   if(-1 == rc) {
     return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO);
     return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO);
@@ -1836,7 +1840,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
   set_local_ip(cf, data);
   set_local_ip(cf, data);
   CURL_TRC_CF(data, cf, "%s socket %" FMT_SOCKET_T
   CURL_TRC_CF(data, cf, "%s socket %" FMT_SOCKET_T
               " connected: [%s:%d] -> [%s:%d]",
               " connected: [%s:%d] -> [%s:%d]",
-              (ctx->transport == TRNSPRT_QUIC)? "QUIC" : "UDP",
+              (ctx->transport == TRNSPRT_QUIC) ? "QUIC" : "UDP",
               ctx->sock, ctx->ip.local_ip, ctx->ip.local_port,
               ctx->sock, ctx->ip.local_ip, ctx->ip.local_port,
               ctx->ip.remote_ip, ctx->ip.remote_port);
               ctx->ip.remote_ip, ctx->ip.remote_port);
 
 
@@ -1955,7 +1959,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
   result = Curl_cf_create(&cf, &Curl_cft_udp, ctx);
   result = Curl_cf_create(&cf, &Curl_cft_udp, ctx);
 
 
 out:
 out:
-  *pcf = (!result)? cf : NULL;
+  *pcf = (!result) ? cf : NULL;
   if(result) {
   if(result) {
     Curl_safefree(cf);
     Curl_safefree(cf);
     Curl_safefree(ctx);
     Curl_safefree(ctx);
@@ -2007,7 +2011,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
   result = Curl_cf_create(&cf, &Curl_cft_unix, ctx);
   result = Curl_cf_create(&cf, &Curl_cft_unix, ctx);
 
 
 out:
 out:
-  *pcf = (!result)? cf : NULL;
+  *pcf = (!result) ? cf : NULL;
   if(result) {
   if(result) {
     Curl_safefree(cf);
     Curl_safefree(cf);
     Curl_safefree(ctx);
     Curl_safefree(ctx);
@@ -2016,10 +2020,84 @@ out:
   return result;
   return result;
 }
 }
 
 
+static timediff_t cf_tcp_accept_timeleft(struct Curl_cfilter *cf,
+                                          struct Curl_easy *data)
+{
+  struct cf_socket_ctx *ctx = cf->ctx;
+  timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
+  timediff_t other;
+  struct curltime now;
+
+#ifndef CURL_DISABLE_FTP
+  if(data->set.accepttimeout > 0)
+    timeout_ms = data->set.accepttimeout;
+#endif
+
+  now = Curl_now();
+  /* check if the generic timeout possibly is set shorter */
+  other = Curl_timeleft(data, &now, FALSE);
+  if(other && (other < timeout_ms))
+    /* note that this also works fine for when other happens to be negative
+       due to it already having elapsed */
+    timeout_ms = other;
+  else {
+    /* subtract elapsed time */
+    timeout_ms -= Curl_timediff(now, ctx->started_at);
+    if(!timeout_ms)
+      /* avoid returning 0 as that means no timeout! */
+      timeout_ms = -1;
+  }
+  return timeout_ms;
+}
+
+static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf,
+                                          struct Curl_easy *data)
+{
+  struct cf_socket_ctx *ctx = cf->ctx;
+#ifdef HAVE_GETPEERNAME
+  char buffer[STRERROR_LEN];
+  struct Curl_sockaddr_storage ssrem;
+  curl_socklen_t plen;
+
+  ctx->ip.remote_ip[0] = 0;
+  ctx->ip.remote_port = 0;
+  plen = sizeof(ssrem);
+  memset(&ssrem, 0, plen);
+  if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
+    int error = SOCKERRNO;
+    failf(data, "getpeername() failed with errno %d: %s",
+          error, Curl_strerror(error, buffer, sizeof(buffer)));
+    return;
+  }
+  if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
+                       ctx->ip.remote_ip, &ctx->ip.remote_port)) {
+    failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+    return;
+  }
+#else
+  ctx->ip.remote_ip[0] = 0;
+  ctx->ip.remote_port = 0;
+  (void)data;
+#endif
+}
+
 static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
 static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
                                       struct Curl_easy *data,
                                       struct Curl_easy *data,
                                       bool blocking, bool *done)
                                       bool blocking, bool *done)
 {
 {
+  struct cf_socket_ctx *ctx = cf->ctx;
+#ifdef USE_IPV6
+  struct Curl_sockaddr_storage add;
+#else
+  struct sockaddr_in add;
+#endif
+  curl_socklen_t size = (curl_socklen_t) sizeof(add);
+  curl_socket_t s_accepted = CURL_SOCKET_BAD;
+  timediff_t timeout_ms;
+  int socketstate = 0;
+  bool incoming = FALSE;
+
   /* we start accepted, if we ever close, we cannot go on */
   /* we start accepted, if we ever close, we cannot go on */
   (void)data;
   (void)data;
   (void)blocking;
   (void)blocking;
@@ -2027,7 +2105,79 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
     *done = TRUE;
     *done = TRUE;
     return CURLE_OK;
     return CURLE_OK;
   }
   }
-  return CURLE_FAILED_INIT;
+
+  timeout_ms = cf_tcp_accept_timeleft(cf, data);
+  if(timeout_ms < 0) {
+    /* if a timeout was already reached, bail out */
+    failf(data, "Accept timeout occurred while waiting server connect");
+    return CURLE_FTP_ACCEPT_TIMEOUT;
+  }
+
+  CURL_TRC_CF(data, cf, "Checking for incoming on fd=%" FMT_SOCKET_T
+              " ip=%s:%d", ctx->sock, ctx->ip.local_ip, ctx->ip.local_port);
+  socketstate = Curl_socket_check(ctx->sock, CURL_SOCKET_BAD,
+                                  CURL_SOCKET_BAD, 0);
+  CURL_TRC_CF(data, cf, "socket_check -> %x", socketstate);
+  switch(socketstate) {
+  case -1: /* error */
+    /* let's die here */
+    failf(data, "Error while waiting for server connect");
+    return CURLE_FTP_ACCEPT_FAILED;
+  default:
+    if(socketstate & CURL_CSELECT_IN) {
+      infof(data, "Ready to accept data connection from server");
+      incoming = TRUE;
+    }
+    break;
+  }
+
+  if(!incoming) {
+    CURL_TRC_CF(data, cf, "nothing heard from the server yet");
+    *done = FALSE;
+    return CURLE_OK;
+  }
+
+  if(0 == getsockname(ctx->sock, (struct sockaddr *) &add, &size)) {
+    size = sizeof(add);
+    s_accepted = accept(ctx->sock, (struct sockaddr *) &add, &size);
+  }
+
+  if(CURL_SOCKET_BAD == s_accepted) {
+    failf(data, "Error accept()ing server connect");
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  infof(data, "Connection accepted from server");
+  (void)curlx_nonblock(s_accepted, TRUE); /* enable non-blocking */
+  /* Replace any filter on SECONDARY with one listening on this socket */
+  ctx->listening = FALSE;
+  ctx->accepted = TRUE;
+  socket_close(data, cf->conn, TRUE, ctx->sock);
+  ctx->sock = s_accepted;
+
+  cf->conn->sock[cf->sockindex] = ctx->sock;
+  cf_tcp_set_accepted_remote_ip(cf, data);
+  set_local_ip(cf, data);
+  ctx->active = TRUE;
+  ctx->connected_at = Curl_now();
+  cf->connected = TRUE;
+  CURL_TRC_CF(data, cf, "accepted_set(sock=%" FMT_SOCKET_T
+              ", remote=%s port=%d)",
+              ctx->sock, ctx->ip.remote_ip, ctx->ip.remote_port);
+
+  if(data->set.fsockopt) {
+    int error = 0;
+
+    /* activate callback for setting socket options */
+    Curl_set_in_callback(data, true);
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               ctx->sock, CURLSOCKTYPE_ACCEPT);
+    Curl_set_in_callback(data, false);
+
+    if(error)
+      return CURLE_ABORTED_BY_CALLBACK;
+  }
+  return CURLE_OK;
 }
 }
 
 
 struct Curl_cftype Curl_cft_tcp_accept = {
 struct Curl_cftype Curl_cft_tcp_accept = {
@@ -2075,13 +2225,12 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
     goto out;
     goto out;
   Curl_conn_cf_add(data, conn, sockindex, cf);
   Curl_conn_cf_add(data, conn, sockindex, cf);
 
 
+  ctx->started_at = Curl_now();
   conn->sock[sockindex] = ctx->sock;
   conn->sock[sockindex] = ctx->sock;
   set_local_ip(cf, data);
   set_local_ip(cf, data);
-  ctx->active = TRUE;
-  ctx->connected_at = Curl_now();
-  cf->connected = TRUE;
-  CURL_TRC_CF(data, cf, "Curl_conn_tcp_listen_set(%" FMT_SOCKET_T ")",
-              ctx->sock);
+  CURL_TRC_CF(data, cf, "set filter for listen socket fd=%" FMT_SOCKET_T
+              " ip=%s:%d", ctx->sock,
+              ctx->ip.local_ip, ctx->ip.local_port);
 
 
 out:
 out:
   if(result) {
   if(result) {
@@ -2091,67 +2240,16 @@ out:
   return result;
   return result;
 }
 }
 
 
-static void set_accepted_remote_ip(struct Curl_cfilter *cf,
-                                   struct Curl_easy *data)
+bool Curl_conn_is_tcp_listen(struct Curl_easy *data,
+                             int sockindex)
 {
 {
-  struct cf_socket_ctx *ctx = cf->ctx;
-#ifdef HAVE_GETPEERNAME
-  char buffer[STRERROR_LEN];
-  struct Curl_sockaddr_storage ssrem;
-  curl_socklen_t plen;
-
-  ctx->ip.remote_ip[0] = 0;
-  ctx->ip.remote_port = 0;
-  plen = sizeof(ssrem);
-  memset(&ssrem, 0, plen);
-  if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
-    int error = SOCKERRNO;
-    failf(data, "getpeername() failed with errno %d: %s",
-          error, Curl_strerror(error, buffer, sizeof(buffer)));
-    return;
-  }
-  if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
-                       ctx->ip.remote_ip, &ctx->ip.remote_port)) {
-    failf(data, "ssrem inet_ntop() failed with errno %d: %s",
-          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-    return;
+  struct Curl_cfilter *cf = data->conn->cfilter[sockindex];
+  while(cf) {
+    if(cf->cft == &Curl_cft_tcp_accept)
+      return TRUE;
+    cf = cf->next;
   }
   }
-#else
-  ctx->ip.remote_ip[0] = 0;
-  ctx->ip.remote_port = 0;
-  (void)data;
-#endif
-}
-
-CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
-                                    struct connectdata *conn,
-                                    int sockindex, curl_socket_t *s)
-{
-  struct Curl_cfilter *cf = NULL;
-  struct cf_socket_ctx *ctx = NULL;
-
-  cf = conn->cfilter[sockindex];
-  if(!cf || cf->cft != &Curl_cft_tcp_accept)
-    return CURLE_FAILED_INIT;
-
-  ctx = cf->ctx;
-  DEBUGASSERT(ctx->listening);
-  /* discard the listen socket */
-  socket_close(data, conn, TRUE, ctx->sock);
-  ctx->listening = FALSE;
-  ctx->sock = *s;
-  conn->sock[sockindex] = ctx->sock;
-  set_accepted_remote_ip(cf, data);
-  set_local_ip(cf, data);
-  ctx->active = TRUE;
-  ctx->accepted = TRUE;
-  ctx->connected_at = Curl_now();
-  cf->connected = TRUE;
-  CURL_TRC_CF(data, cf, "accepted_set(sock=%" FMT_SOCKET_T
-              ", remote=%s port=%d)",
-              ctx->sock, ctx->ip.remote_ip, ctx->ip.remote_port);
-
-  return CURLE_OK;
+  return FALSE;
 }
 }
 
 
 /**
 /**

+ 5 - 6
lib/cf-socket.h

@@ -52,7 +52,7 @@ struct Curl_sockaddr_ex {
     struct Curl_sockaddr_storage buff;
     struct Curl_sockaddr_storage buff;
   } _sa_ex_u;
   } _sa_ex_u;
 };
 };
-#define sa_addr _sa_ex_u.addr
+#define curl_sa_addr _sa_ex_u.addr
 
 
 /*
 /*
  * Parse interface option, and return the interface name and the host part.
  * Parse interface option, and return the interface name and the host part.
@@ -147,12 +147,11 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
                                   curl_socket_t *s);
                                   curl_socket_t *s);
 
 
 /**
 /**
- * Replace the listen socket with the accept()ed one.
+ * Return TRUE iff the last filter at `sockindex` was set via
+ * Curl_conn_tcp_listen_set().
  */
  */
-CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
-                                    struct connectdata *conn,
-                                    int sockindex,
-                                    curl_socket_t *s);
+bool Curl_conn_is_tcp_listen(struct Curl_easy *data,
+                             int sockindex);
 
 
 /**
 /**
  * Peek at the socket and remote ip/port the socket filter is using.
  * Peek at the socket and remote ip/port the socket filter is using.

+ 31 - 28
lib/cfilters.c

@@ -96,7 +96,7 @@ void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
 bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
 bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
                               const struct Curl_easy *data)
                               const struct Curl_easy *data)
 {
 {
-  return cf->next?
+  return cf->next ?
     cf->next->cft->has_data_pending(cf->next, data) : FALSE;
     cf->next->cft->has_data_pending(cf->next, data) : FALSE;
 }
 }
 
 
@@ -104,7 +104,7 @@ ssize_t  Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
                           const void *buf, size_t len, bool eos,
                           const void *buf, size_t len, bool eos,
                           CURLcode *err)
                           CURLcode *err)
 {
 {
-  return cf->next?
+  return cf->next ?
     cf->next->cft->do_send(cf->next, data, buf, len, eos, err) :
     cf->next->cft->do_send(cf->next, data, buf, len, eos, err) :
     CURLE_RECV_ERROR;
     CURLE_RECV_ERROR;
 }
 }
@@ -112,7 +112,7 @@ ssize_t  Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
 ssize_t  Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
 ssize_t  Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
                           char *buf, size_t len, CURLcode *err)
                           char *buf, size_t len, CURLcode *err)
 {
 {
-  return cf->next?
+  return cf->next ?
     cf->next->cft->do_recv(cf->next, data, buf, len, err) :
     cf->next->cft->do_recv(cf->next, data, buf, len, err) :
     CURLE_SEND_ERROR;
     CURLE_SEND_ERROR;
 }
 }
@@ -121,7 +121,7 @@ bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
                                struct Curl_easy *data,
                                struct Curl_easy *data,
                                bool *input_pending)
                                bool *input_pending)
 {
 {
-  return cf->next?
+  return cf->next ?
     cf->next->cft->is_alive(cf->next, data, input_pending) :
     cf->next->cft->is_alive(cf->next, data, input_pending) :
     FALSE; /* pessimistic in absence of data */
     FALSE; /* pessimistic in absence of data */
 }
 }
@@ -129,7 +129,7 @@ bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
 CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
 CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
                                      struct Curl_easy *data)
                                      struct Curl_easy *data)
 {
 {
-  return cf->next?
+  return cf->next ?
     cf->next->cft->keep_alive(cf->next, data) :
     cf->next->cft->keep_alive(cf->next, data) :
     CURLE_OK;
     CURLE_OK;
 }
 }
@@ -138,7 +138,7 @@ CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
                            struct Curl_easy *data,
                            struct Curl_easy *data,
                            int query, int *pres1, void *pres2)
                            int query, int *pres1, void *pres2)
 {
 {
-  return cf->next?
+  return cf->next ?
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     CURLE_UNKNOWN_OPTION;
     CURLE_UNKNOWN_OPTION;
 }
 }
@@ -204,13 +204,14 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
   now = Curl_now();
   now = Curl_now();
   if(!Curl_shutdown_started(data, sockindex)) {
   if(!Curl_shutdown_started(data, sockindex)) {
     DEBUGF(infof(data, "shutdown start on%s connection",
     DEBUGF(infof(data, "shutdown start on%s connection",
-           sockindex? " secondary" : ""));
+           sockindex ? " secondary" : ""));
     Curl_shutdown_start(data, sockindex, &now);
     Curl_shutdown_start(data, sockindex, &now);
   }
   }
   else {
   else {
     timeout_ms = Curl_shutdown_timeleft(data->conn, sockindex, &now);
     timeout_ms = Curl_shutdown_timeleft(data->conn, sockindex, &now);
     if(timeout_ms < 0) {
     if(timeout_ms < 0) {
-      failf(data, "SSL shutdown timeout");
+      /* info message, since this might be regarded as acceptable */
+      infof(data, "shutdown timeout");
       return CURLE_OPERATION_TIMEDOUT;
       return CURLE_OPERATION_TIMEDOUT;
     }
     }
   }
   }
@@ -483,12 +484,12 @@ bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf)
 
 
 bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex)
 bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex)
 {
 {
-  return conn? Curl_conn_cf_is_ssl(conn->cfilter[sockindex]) : FALSE;
+  return conn ? Curl_conn_cf_is_ssl(conn->cfilter[sockindex]) : FALSE;
 }
 }
 
 
 bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
 bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
 {
 {
-  struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
+  struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL;
 
 
   for(; cf; cf = cf->next) {
   for(; cf; cf = cf->next) {
     if(cf->cft->flags & CF_TYPE_MULTIPLEX)
     if(cf->cft->flags & CF_TYPE_MULTIPLEX)
@@ -522,10 +523,10 @@ bool Curl_conn_cf_needs_flush(struct Curl_cfilter *cf,
                               struct Curl_easy *data)
                               struct Curl_easy *data)
 {
 {
   CURLcode result;
   CURLcode result;
-  int pending = FALSE;
-  result = cf? cf->cft->query(cf, data, CF_QUERY_NEED_FLUSH,
-                              &pending, NULL) : CURLE_UNKNOWN_OPTION;
-  return (result || pending == FALSE)? FALSE : TRUE;
+  int pending = 0;
+  result = cf ? cf->cft->query(cf, data, CF_QUERY_NEED_FLUSH,
+                               &pending, NULL) : CURLE_UNKNOWN_OPTION;
+  return (result || !pending) ? FALSE : TRUE;
 }
 }
 
 
 bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex)
 bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex)
@@ -672,13 +673,13 @@ curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
 {
 {
   struct Curl_cfilter *cf;
   struct Curl_cfilter *cf;
 
 
-  cf = data->conn? data->conn->cfilter[sockindex] : NULL;
+  cf = data->conn ? data->conn->cfilter[sockindex] : NULL;
   /* if the top filter has not connected, ask it (and its sub-filters)
   /* if the top filter has not connected, ask it (and its sub-filters)
    * for the socket. Otherwise conn->sock[sockindex] should have it.
    * for the socket. Otherwise conn->sock[sockindex] should have it.
    */
    */
   if(cf && !cf->connected)
   if(cf && !cf->connected)
     return Curl_conn_cf_get_socket(cf, data);
     return Curl_conn_cf_get_socket(cf, data);
-  return data->conn? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
+  return data->conn ? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
 }
 }
 
 
 void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
 void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
@@ -807,7 +808,7 @@ CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
                               int sockindex)
                               int sockindex)
 {
 {
   struct Curl_cfilter *cf = conn->cfilter[sockindex];
   struct Curl_cfilter *cf = conn->cfilter[sockindex];
-  return cf? cf->cft->keep_alive(cf, data) : CURLE_OK;
+  return cf ? cf->cft->keep_alive(cf, data) : CURLE_OK;
 }
 }
 
 
 size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
 size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
@@ -818,9 +819,9 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
   int n = 0;
   int n = 0;
 
 
   struct Curl_cfilter *cf = conn->cfilter[sockindex];
   struct Curl_cfilter *cf = conn->cfilter[sockindex];
-  result = cf? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT,
-                              &n, NULL) : CURLE_UNKNOWN_OPTION;
-  return (result || n <= 0)? 1 : (size_t)n;
+  result = cf ? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT,
+                               &n, NULL) : CURLE_UNKNOWN_OPTION;
+  return (result || n <= 0) ? 1 : (size_t)n;
 }
 }
 
 
 int Curl_conn_get_stream_error(struct Curl_easy *data,
 int Curl_conn_get_stream_error(struct Curl_easy *data,
@@ -831,9 +832,9 @@ int Curl_conn_get_stream_error(struct Curl_easy *data,
   int n = 0;
   int n = 0;
 
 
   struct Curl_cfilter *cf = conn->cfilter[sockindex];
   struct Curl_cfilter *cf = conn->cfilter[sockindex];
-  result = cf? cf->cft->query(cf, data, CF_QUERY_STREAM_ERROR,
-                              &n, NULL) : CURLE_UNKNOWN_OPTION;
-  return (result || n < 0)? 0 : n;
+  result = cf ? cf->cft->query(cf, data, CF_QUERY_STREAM_ERROR,
+                               &n, NULL) : CURLE_UNKNOWN_OPTION;
+  return (result || n < 0) ? 0 : n;
 }
 }
 
 
 int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd)
 int Curl_conn_sockindex(struct Curl_easy *data, curl_socket_t sockfd)
@@ -854,7 +855,7 @@ CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
   nread = data->conn->recv[sockindex](data, sockindex, buf, blen, &result);
   nread = data->conn->recv[sockindex](data, sockindex, buf, blen, &result);
   DEBUGASSERT(nread >= 0 || result);
   DEBUGASSERT(nread >= 0 || result);
   DEBUGASSERT(nread < 0 || !result);
   DEBUGASSERT(nread < 0 || !result);
-  *n = (nread >= 0)? (size_t)nread : 0;
+  *n = (nread >= 0) ? (size_t)nread : 0;
   return result;
   return result;
 }
 }
 
 
@@ -889,7 +890,7 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
   nwritten = conn->send[sockindex](data, sockindex, buf, write_len, eos,
   nwritten = conn->send[sockindex](data, sockindex, buf, write_len, eos,
                                    &result);
                                    &result);
   DEBUGASSERT((nwritten >= 0) || result);
   DEBUGASSERT((nwritten >= 0) || result);
-  *pnwritten = (nwritten < 0)? 0 : (size_t)nwritten;
+  *pnwritten = (nwritten < 0) ? 0 : (size_t)nwritten;
   return result;
   return result;
 }
 }
 
 
@@ -899,7 +900,7 @@ void Curl_pollset_reset(struct Curl_easy *data,
   size_t i;
   size_t i;
   (void)data;
   (void)data;
   memset(ps, 0, sizeof(*ps));
   memset(ps, 0, sizeof(*ps));
-  for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
+  for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++)
     ps->sockets[i] = CURL_SOCKET_BAD;
     ps->sockets[i] = CURL_SOCKET_BAD;
 }
 }
 
 
@@ -961,8 +962,10 @@ void Curl_pollset_set(struct Curl_easy *data,
                       bool do_in, bool do_out)
                       bool do_in, bool do_out)
 {
 {
   Curl_pollset_change(data, ps, sock,
   Curl_pollset_change(data, ps, sock,
-                      (do_in?CURL_POLL_IN:0)|(do_out?CURL_POLL_OUT:0),
-                      (!do_in?CURL_POLL_IN:0)|(!do_out?CURL_POLL_OUT:0));
+                      (do_in ? CURL_POLL_IN : 0)|
+                      (do_out ? CURL_POLL_OUT : 0),
+                      (!do_in ? CURL_POLL_IN : 0)|
+                      (!do_out ? CURL_POLL_OUT : 0));
 }
 }
 
 
 static void ps_add(struct Curl_easy *data, struct easy_pollset *ps,
 static void ps_add(struct Curl_easy *data, struct easy_pollset *ps,

+ 12 - 24
lib/conncache.c

@@ -72,7 +72,7 @@
   } while(0)
   } while(0)
 
 
 
 
-/* A list of connections to the same destinationn. */
+/* A list of connections to the same destination. */
 struct cpool_bundle {
 struct cpool_bundle {
   struct Curl_llist conns; /* connections in the bundle */
   struct Curl_llist conns; /* connections in the bundle */
   size_t dest_len; /* total length of destination, including NUL */
   size_t dest_len; /* total length of destination, including NUL */
@@ -163,16 +163,16 @@ int Curl_cpool_init(struct cpool *cpool,
   cpool->idata = curl_easy_init();
   cpool->idata = curl_easy_init();
   if(!cpool->idata)
   if(!cpool->idata)
     return 1; /* bad */
     return 1; /* bad */
-  cpool->idata->state.internal = true;
+  cpool->idata->state.internal = TRUE;
   /* TODO: this is quirky. We need an internal handle for certain
   /* TODO: this is quirky. We need an internal handle for certain
    * operations, but we do not add it to the multi (if there is one).
    * operations, but we do not add it to the multi (if there is one).
    * But we give it the multi so that socket event operations can work.
    * But we give it the multi so that socket event operations can work.
    * Probably better to have an internal handle owned by the multi that
    * Probably better to have an internal handle owned by the multi that
    * can be used for cpool operations. */
    * can be used for cpool operations. */
   cpool->idata->multi = multi;
   cpool->idata->multi = multi;
- #ifdef DEBUGBUILD
+#ifdef DEBUGBUILD
   if(getenv("CURL_DEBUG"))
   if(getenv("CURL_DEBUG"))
-    cpool->idata->set.verbose = true;
+    cpool->idata->set.verbose = TRUE;
 #endif
 #endif
 
 
   cpool->disconnect_cb = disconnect_cb;
   cpool->disconnect_cb = disconnect_cb;
@@ -269,25 +269,10 @@ cpool_add_bundle(struct cpool *cpool, struct connectdata *conn)
 static void cpool_remove_bundle(struct cpool *cpool,
 static void cpool_remove_bundle(struct cpool *cpool,
                                 struct cpool_bundle *bundle)
                                 struct cpool_bundle *bundle)
 {
 {
-  struct Curl_hash_iterator iter;
-  struct Curl_hash_element *he;
-
   if(!cpool)
   if(!cpool)
     return;
     return;
 
 
-  Curl_hash_start_iterate(&cpool->dest2bundle, &iter);
-
-  he = Curl_hash_next_element(&iter);
-  while(he) {
-    if(he->ptr == bundle) {
-      /* The bundle is destroyed by the hash destructor function,
-         free_bundle_hash_entry() */
-      Curl_hash_delete(&cpool->dest2bundle, he->key, he->key_len);
-      return;
-    }
-
-    he = Curl_hash_next_element(&iter);
-  }
+  Curl_hash_delete(&cpool->dest2bundle, bundle->dest, bundle->dest_len);
 }
 }
 
 
 static struct connectdata *
 static struct connectdata *
@@ -329,6 +314,9 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
                    "limit of %zu", oldest_idle->connection_id,
                    "limit of %zu", oldest_idle->connection_id,
                    Curl_llist_count(&bundle->conns), dest_limit));
                    Curl_llist_count(&bundle->conns), dest_limit));
       Curl_cpool_disconnect(data, oldest_idle, FALSE);
       Curl_cpool_disconnect(data, oldest_idle, FALSE);
+
+      /* in case the bundle was destroyed in disconnect, look it up again */
+      bundle = cpool_find_bundle(cpool, conn);
     }
     }
     if(bundle && (Curl_llist_count(&bundle->conns) >= dest_limit)) {
     if(bundle && (Curl_llist_count(&bundle->conns) >= dest_limit)) {
       result = CPOOL_LIMIT_DEST;
       result = CPOOL_LIMIT_DEST;
@@ -409,7 +397,7 @@ static void cpool_remove_conn(struct cpool *cpool,
       cpool->num_conn--;
       cpool->num_conn--;
     }
     }
     else {
     else {
-      /* Not in  a bundle, already in the shutdown list? */
+      /* Not in a bundle, already in the shutdown list? */
       DEBUGASSERT(list == &cpool->shutdowns);
       DEBUGASSERT(list == &cpool->shutdowns);
     }
     }
   }
   }
@@ -491,7 +479,7 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
                               struct connectdata *conn)
                               struct connectdata *conn)
 {
 {
   unsigned int maxconnects = !data->multi->maxconnects ?
   unsigned int maxconnects = !data->multi->maxconnects ?
-    data->multi->num_easy * 4: data->multi->maxconnects;
+    data->multi->num_easy * 4 : data->multi->maxconnects;
   struct connectdata *oldest_idle = NULL;
   struct connectdata *oldest_idle = NULL;
   struct cpool *cpool = cpool_get_instance(data);
   struct cpool *cpool = cpool_get_instance(data);
   bool kept = TRUE;
   bool kept = TRUE;
@@ -820,7 +808,7 @@ void Curl_cpool_disconnect(struct Curl_easy *data,
   if(data->multi) {
   if(data->multi) {
     /* Add it to the multi's cpool for shutdown handling */
     /* Add it to the multi's cpool for shutdown handling */
     infof(data, "%s connection #%" FMT_OFF_T,
     infof(data, "%s connection #%" FMT_OFF_T,
-          aborted? "closing" : "shutting down", conn->connection_id);
+          aborted ? "closing" : "shutting down", conn->connection_id);
     cpool_discard_conn(&data->multi->cpool, data, conn, aborted);
     cpool_discard_conn(&data->multi->cpool, data, conn, aborted);
   }
   }
   else {
   else {
@@ -1180,7 +1168,7 @@ static void cpool_shutdown_all(struct cpool *cpool,
     timespent = Curl_timediff(Curl_now(), started);
     timespent = Curl_timediff(Curl_now(), started);
     if(timespent >= (timediff_t)timeout_ms) {
     if(timespent >= (timediff_t)timeout_ms) {
       DEBUGF(infof(data, "cpool shutdown %s",
       DEBUGF(infof(data, "cpool shutdown %s",
-                   (timeout_ms > 0)? "timeout" : "best effort done"));
+                   (timeout_ms > 0) ? "timeout" : "best effort done"));
       break;
       break;
     }
     }
 
 

+ 8 - 8
lib/connect.c

@@ -139,7 +139,7 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
       return ctimeleft_ms; /* no general timeout, this is it */
       return ctimeleft_ms; /* no general timeout, this is it */
   }
   }
   /* return minimal time left or max amount already expired */
   /* return minimal time left or max amount already expired */
-  return (ctimeleft_ms < timeleft_ms)? ctimeleft_ms : timeleft_ms;
+  return (ctimeleft_ms < timeleft_ms) ? ctimeleft_ms : timeleft_ms;
 }
 }
 
 
 void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
 void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
@@ -172,7 +172,7 @@ timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
   }
   }
   left_ms = conn->shutdown.timeout_ms -
   left_ms = conn->shutdown.timeout_ms -
             Curl_timediff(*nowp, conn->shutdown.start[sockindex]);
             Curl_timediff(*nowp, conn->shutdown.start[sockindex]);
-  return left_ms? left_ms : -1;
+  return left_ms ? left_ms : -1;
 }
 }
 
 
 timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
 timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
@@ -414,9 +414,9 @@ static CURLcode eyeballer_new(struct eyeballer **pballer,
   if(!baller)
   if(!baller)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
-  baller->name = ((ai_family == AF_INET)? "ipv4" : (
+  baller->name = ((ai_family == AF_INET) ? "ipv4" : (
 #ifdef USE_IPV6
 #ifdef USE_IPV6
-                  (ai_family == AF_INET6)? "ipv6" :
+                  (ai_family == AF_INET6) ? "ipv6" :
 #endif
 #endif
                   "ip"));
                   "ip"));
   baller->cf_create = cf_create;
   baller->cf_create = cf_create;
@@ -424,7 +424,7 @@ static CURLcode eyeballer_new(struct eyeballer **pballer,
   baller->ai_family = ai_family;
   baller->ai_family = ai_family;
   baller->primary = primary;
   baller->primary = primary;
   baller->delay_ms = delay_ms;
   baller->delay_ms = delay_ms;
-  baller->timeoutms = addr_next_match(baller->addr, baller->ai_family)?
+  baller->timeoutms = addr_next_match(baller->addr, baller->ai_family) ?
     USETIME(timeout_ms) : timeout_ms;
     USETIME(timeout_ms) : timeout_ms;
   baller->timeout_id = timeout_id;
   baller->timeout_id = timeout_id;
   baller->result = CURLE_COULDNT_CONNECT;
   baller->result = CURLE_COULDNT_CONNECT;
@@ -619,7 +619,7 @@ static CURLcode is_connected(struct Curl_cfilter *cf,
    * If transport is QUIC, we need to shutdown the ongoing 'other'
    * If transport is QUIC, we need to shutdown the ongoing 'other'
    * cot ballers in a QUIC appropriate way. */
    * cot ballers in a QUIC appropriate way. */
 evaluate:
 evaluate:
-  *connected = FALSE; /* a very negative world view is best */
+  *connected = FALSE; /* a negative world view is best */
   now = Curl_now();
   now = Curl_now();
   ongoing = not_started = 0;
   ongoing = not_started = 0;
   for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
   for(i = 0; i < ARRAYSIZE(ctx->baller); i++) {
@@ -1089,7 +1089,7 @@ static CURLcode cf_he_query(struct Curl_cfilter *cf,
     }
     }
   }
   }
 
 
-  return cf->next?
+  return cf->next ?
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     CURLE_UNKNOWN_OPTION;
     CURLE_UNKNOWN_OPTION;
 }
 }
@@ -1417,7 +1417,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
   ctx = NULL;
   ctx = NULL;
 
 
 out:
 out:
-  *pcf = result? NULL : cf;
+  *pcf = result ? NULL : cf;
   free(ctx);
   free(ctx);
   return result;
   return result;
 }
 }

+ 8 - 8
lib/content_encoding.c

@@ -33,13 +33,13 @@
 #endif
 #endif
 
 
 #ifdef HAVE_BROTLI
 #ifdef HAVE_BROTLI
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__)
 /* Ignore -Wvla warnings in brotli headers */
 /* Ignore -Wvla warnings in brotli headers */
 #pragma GCC diagnostic push
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wvla"
 #pragma GCC diagnostic ignored "-Wvla"
 #endif
 #endif
 #include <brotli/decode.h>
 #include <brotli/decode.h>
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic pop
 #pragma GCC diagnostic pop
 #endif
 #endif
 #endif
 #endif
@@ -154,7 +154,7 @@ static CURLcode process_trailer(struct Curl_easy *data,
 {
 {
   z_stream *z = &zp->z;
   z_stream *z = &zp->z;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
-  uInt len = z->avail_in < zp->trailerlen? z->avail_in: zp->trailerlen;
+  uInt len = z->avail_in < zp->trailerlen ? z->avail_in : zp->trailerlen;
 
 
   /* Consume expected trailer bytes. Terminate stream if exhausted.
   /* Consume expected trailer bytes. Terminate stream if exhausted.
      Issue an error if unexpected bytes follow. */
      Issue an error if unexpected bytes follow. */
@@ -654,7 +654,7 @@ static CURLcode brotli_do_init(struct Curl_easy *data,
   (void) data;
   (void) data;
 
 
   bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
   bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
-  return bp->br? CURLE_OK: CURLE_OUT_OF_MEMORY;
+  return bp->br ? CURLE_OK : CURLE_OUT_OF_MEMORY;
 }
 }
 
 
 static CURLcode brotli_do_write(struct Curl_easy *data,
 static CURLcode brotli_do_write(struct Curl_easy *data,
@@ -971,8 +971,8 @@ static const struct Curl_cwtype *find_unencode_writer(const char *name,
 CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
 CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
                                      const char *enclist, int is_transfer)
                                      const char *enclist, int is_transfer)
 {
 {
-  Curl_cwriter_phase phase = is_transfer?
-                             CURL_CW_TRANSFER_DECODE:CURL_CW_CONTENT_DECODE;
+  Curl_cwriter_phase phase = is_transfer ?
+    CURL_CW_TRANSFER_DECODE : CURL_CW_CONTENT_DECODE;
   CURLcode result;
   CURLcode result;
 
 
   do {
   do {
@@ -995,7 +995,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
       struct Curl_cwriter *writer;
       struct Curl_cwriter *writer;
 
 
       CURL_TRC_WRITE(data, "looking for %s decoder: %.*s",
       CURL_TRC_WRITE(data, "looking for %s decoder: %.*s",
-                     is_transfer? "transfer" : "content", (int)namelen, name);
+                     is_transfer ? "transfer" : "content", (int)namelen, name);
       is_chunked = (is_transfer && (namelen == 7) &&
       is_chunked = (is_transfer && (namelen == 7) &&
                     strncasecompare(name, "chunked", 7));
                     strncasecompare(name, "chunked", 7));
       /* if we skip the decoding in this phase, do not look further.
       /* if we skip the decoding in this phase, do not look further.
@@ -1046,7 +1046,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
 
 
       result = Curl_cwriter_create(&writer, data, cwt, phase);
       result = Curl_cwriter_create(&writer, data, cwt, phase);
       CURL_TRC_WRITE(data, "added %s decoder %s -> %d",
       CURL_TRC_WRITE(data, "added %s decoder %s -> %d",
-                     is_transfer? "transfer" : "content", cwt->name, result);
+                     is_transfer ? "transfer" : "content", cwt->name, result);
       if(result)
       if(result)
         return result;
         return result;
 
 

File diff suppressed because it is too large
+ 450 - 537
lib/cookie.c


+ 21 - 17
lib/cookie.h

@@ -27,20 +27,24 @@
 
 
 #include <curl/curl.h>
 #include <curl/curl.h>
 
 
+#include "llist.h"
+
 struct Cookie {
 struct Cookie {
-  struct Cookie *next; /* next in the chain */
-  char *name;        /* <this> = value */
-  char *value;       /* name = <this> */
+  struct Curl_llist_node node; /* for the main cookie list */
+  struct Curl_llist_node getnode; /* for getlist */
+  char *name;         /* <this> = value */
+  char *value;        /* name = <this> */
   char *path;         /* path = <this> which is in Set-Cookie: */
   char *path;         /* path = <this> which is in Set-Cookie: */
   char *spath;        /* sanitized cookie path */
   char *spath;        /* sanitized cookie path */
-  char *domain;      /* domain = <this> */
-  curl_off_t expires;  /* expires = <this> */
-  bool tailmatch;    /* whether we do tail-matching of the domain name */
-  bool secure;       /* whether the 'secure' keyword was used */
-  bool livecookie;   /* updated from a server, not a stored file */
-  bool httponly;     /* true if the httponly directive is present */
-  int creationtime;  /* time when the cookie was written */
-  unsigned char prefix; /* bitmap fields indicating which prefix are set */
+  char *domain;       /* domain = <this> */
+  curl_off_t expires; /* expires = <this> */
+  int creationtime;   /* time when the cookie was written */
+  BIT(tailmatch);     /* tail-match the domain name */
+  BIT(secure);        /* the 'secure' keyword was used */
+  BIT(livecookie);    /* updated from a server, not a stored file */
+  BIT(httponly);      /* the httponly directive is present */
+  BIT(prefix_secure); /* secure prefix is set */
+  BIT(prefix_host);   /* host prefix is set */
 };
 };
 
 
 /*
 /*
@@ -53,8 +57,8 @@ struct Cookie {
 #define COOKIE_HASH_SIZE 63
 #define COOKIE_HASH_SIZE 63
 
 
 struct CookieInfo {
 struct CookieInfo {
-  /* linked list of cookies we know of */
-  struct Cookie *cookies[COOKIE_HASH_SIZE];
+  /* linked lists of cookies we know of */
+  struct Curl_llist cookielist[COOKIE_HASH_SIZE];
   curl_off_t next_expiration; /* the next time at which expiration happens */
   curl_off_t next_expiration; /* the next time at which expiration happens */
   int numcookies;  /* number of cookies in the "jar" */
   int numcookies;  /* number of cookies in the "jar" */
   int lastct;      /* last creation-time used in the jar */
   int lastct;      /* last creation-time used in the jar */
@@ -112,10 +116,10 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
                                const char *domain, const char *path,
                                const char *domain, const char *path,
                                bool secure);
                                bool secure);
 
 
-struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
-                                   struct CookieInfo *c, const char *host,
-                                   const char *path, bool secure);
-void Curl_cookie_freelist(struct Cookie *cookies);
+int Curl_cookie_getlist(struct Curl_easy *data,
+                        struct CookieInfo *c, const char *host,
+                        const char *path, bool secure,
+                        struct Curl_llist *list);
 void Curl_cookie_clearall(struct CookieInfo *cookies);
 void Curl_cookie_clearall(struct CookieInfo *cookies);
 void Curl_cookie_clearsess(struct CookieInfo *cookies);
 void Curl_cookie_clearsess(struct CookieInfo *cookies);
 
 

+ 46 - 60
lib/curl_addrinfo.c

@@ -252,6 +252,7 @@ Curl_getaddrinfo_ex(const char *nodename,
  *     #define h_addr  h_addr_list[0]
  *     #define h_addr  h_addr_list[0]
  */
  */
 
 
+#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
 struct Curl_addrinfo *
 struct Curl_addrinfo *
 Curl_he2ai(const struct hostent *he, int port)
 Curl_he2ai(const struct hostent *he, int port)
 {
 {
@@ -350,19 +351,7 @@ Curl_he2ai(const struct hostent *he, int port)
 
 
   return firstai;
   return firstai;
 }
 }
-
-
-struct namebuff {
-  struct hostent hostentry;
-  union {
-    struct in_addr  ina4;
-#ifdef USE_IPV6
-    struct in6_addr ina6;
 #endif
 #endif
-  } addrentry;
-  char *h_addr_list[2];
-};
-
 
 
 /*
 /*
  * Curl_ip2addr()
  * Curl_ip2addr()
@@ -377,71 +366,68 @@ struct Curl_addrinfo *
 Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
 Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
 {
 {
   struct Curl_addrinfo *ai;
   struct Curl_addrinfo *ai;
-
-#if defined(__VMS) && \
-    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
-#pragma pointer_size save
-#pragma pointer_size short
-#pragma message disable PTRMISMATCH
-#endif
-
-  struct hostent  *h;
-  struct namebuff *buf;
-  char  *addrentry;
-  char  *hoststr;
   size_t addrsize;
   size_t addrsize;
+  size_t namelen;
+  struct sockaddr_in *addr;
+#ifdef USE_IPV6
+  struct sockaddr_in6 *addr6;
+#endif
 
 
   DEBUGASSERT(inaddr && hostname);
   DEBUGASSERT(inaddr && hostname);
 
 
-  buf = malloc(sizeof(struct namebuff));
-  if(!buf)
+  namelen = strlen(hostname) + 1;
+
+  if(af == AF_INET)
+    addrsize = sizeof(struct sockaddr_in);
+#ifdef USE_IPV6
+  else if(af == AF_INET6)
+    addrsize = sizeof(struct sockaddr_in6);
+#endif
+  else
     return NULL;
     return NULL;
 
 
-  hoststr = strdup(hostname);
-  if(!hoststr) {
-    free(buf);
+  /* allocate memory to hold the struct, the address and the name */
+  ai = calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen);
+  if(!ai)
     return NULL;
     return NULL;
-  }
+  /* put the address after the struct */
+  ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
+  /* then put the name after the address */
+  ai->ai_canonname = (char *)ai->ai_addr + addrsize;
+  memcpy(ai->ai_canonname, hostname, namelen);
+  ai->ai_family = af;
+  ai->ai_socktype = SOCK_STREAM;
+  ai->ai_addrlen = (curl_socklen_t)addrsize;
+  /* leave the rest of the struct filled with zero */
 
 
   switch(af) {
   switch(af) {
   case AF_INET:
   case AF_INET:
-    addrsize = sizeof(struct in_addr);
-    addrentry = (void *)&buf->addrentry.ina4;
-    memcpy(addrentry, inaddr, sizeof(struct in_addr));
+    addr = (void *)ai->ai_addr; /* storage area for this info */
+
+    memcpy(&addr->sin_addr, inaddr, sizeof(struct in_addr));
+#ifdef __MINGW32__
+    addr->sin_family = (short)af;
+#else
+    addr->sin_family = (CURL_SA_FAMILY_T)af;
+#endif
+    addr->sin_port = htons((unsigned short)port);
     break;
     break;
+
 #ifdef USE_IPV6
 #ifdef USE_IPV6
   case AF_INET6:
   case AF_INET6:
-    addrsize = sizeof(struct in6_addr);
-    addrentry = (void *)&buf->addrentry.ina6;
-    memcpy(addrentry, inaddr, sizeof(struct in6_addr));
+    addr6 = (void *)ai->ai_addr; /* storage area for this info */
+
+    memcpy(&addr6->sin6_addr, inaddr, sizeof(struct in6_addr));
+#ifdef __MINGW32__
+    addr6->sin6_family = (short)af;
+#else
+    addr6->sin6_family = (CURL_SA_FAMILY_T)af;
+#endif
+    addr6->sin6_port = htons((unsigned short)port);
     break;
     break;
 #endif
 #endif
-  default:
-    free(hoststr);
-    free(buf);
-    return NULL;
   }
   }
 
 
-  h = &buf->hostentry;
-  h->h_name = hoststr;
-  h->h_aliases = NULL;
-  h->h_addrtype = (short)af;
-  h->h_length = (short)addrsize;
-  h->h_addr_list = &buf->h_addr_list[0];
-  h->h_addr_list[0] = addrentry;
-  h->h_addr_list[1] = NULL; /* terminate list of entries */
-
-#if defined(__VMS) && \
-    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
-#pragma pointer_size restore
-#pragma message enable PTRMISMATCH
-#endif
-
-  ai = Curl_he2ai(h, port);
-
-  free(hoststr);
-  free(buf);
-
   return ai;
   return ai;
 }
 }
 
 

+ 2 - 0
lib/curl_addrinfo.h

@@ -71,8 +71,10 @@ Curl_getaddrinfo_ex(const char *nodename,
                     struct Curl_addrinfo **result);
                     struct Curl_addrinfo **result);
 #endif
 #endif
 
 
+#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
 struct Curl_addrinfo *
 struct Curl_addrinfo *
 Curl_he2ai(const struct hostent *he, int port);
 Curl_he2ai(const struct hostent *he, int port);
+#endif
 
 
 struct Curl_addrinfo *
 struct Curl_addrinfo *
 Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
 Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);

+ 34 - 20
lib/curl_config.h.cmake

@@ -21,7 +21,6 @@
  * SPDX-License-Identifier: curl
  * SPDX-License-Identifier: curl
  *
  *
  ***************************************************************************/
  ***************************************************************************/
-/* lib/curl_config.h.in. Generated somehow by cmake.  */
 
 
 /* Location of default ca bundle */
 /* Location of default ca bundle */
 #cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}"
 #cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}"
@@ -56,7 +55,7 @@
 /* disables negotiate authentication */
 /* disables negotiate authentication */
 #cmakedefine CURL_DISABLE_NEGOTIATE_AUTH 1
 #cmakedefine CURL_DISABLE_NEGOTIATE_AUTH 1
 
 
-/* disables AWS-SIG4 */
+/* disables aws-sigv4 */
 #cmakedefine CURL_DISABLE_AWS 1
 #cmakedefine CURL_DISABLE_AWS 1
 
 
 /* disables DICT */
 /* disables DICT */
@@ -131,6 +130,9 @@
 /* disables proxies */
 /* disables proxies */
 #cmakedefine CURL_DISABLE_PROXY 1
 #cmakedefine CURL_DISABLE_PROXY 1
 
 
+/* disables IPFS from the curl tool */
+#cmakedefine CURL_DISABLE_IPFS 1
+
 /* disables RTSP */
 /* disables RTSP */
 #cmakedefine CURL_DISABLE_RTSP 1
 #cmakedefine CURL_DISABLE_RTSP 1
 
 
@@ -146,6 +148,9 @@
 /* disables SMTP */
 /* disables SMTP */
 #cmakedefine CURL_DISABLE_SMTP 1
 #cmakedefine CURL_DISABLE_SMTP 1
 
 
+/* disabled WebSockets */
+#cmakedefine CURL_DISABLE_WEBSOCKETS 1
+
 /* disables use of socketpair for curl_multi_poll */
 /* disables use of socketpair for curl_multi_poll */
 #cmakedefine CURL_DISABLE_SOCKETPAIR 1
 #cmakedefine CURL_DISABLE_SOCKETPAIR 1
 
 
@@ -158,6 +163,12 @@
 /* disables verbose strings */
 /* disables verbose strings */
 #cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
 #cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
 
 
+/* disables unsafe CA bundle search on Windows from the curl tool */
+#cmakedefine CURL_DISABLE_CA_SEARCH 1
+
+/* safe CA bundle search (within the curl tool directory) on Windows */
+#cmakedefine CURL_CA_SEARCH_SAFE 1
+
 /* to make a symbol visible */
 /* to make a symbol visible */
 #cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
 #cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
 /* Ensure using CURL_EXTERN_SYMBOL is possible */
 /* Ensure using CURL_EXTERN_SYMBOL is possible */
@@ -208,6 +219,9 @@
 /* Define to 1 if you have the `closesocket' function. */
 /* Define to 1 if you have the `closesocket' function. */
 #cmakedefine HAVE_CLOSESOCKET 1
 #cmakedefine HAVE_CLOSESOCKET 1
 
 
+/* Define to 1 if you have the `CloseSocket' function. */
+#cmakedefine HAVE_CLOSESOCKET_CAMEL 1
+
 /* Define to 1 if you have the <dirent.h> header file. */
 /* Define to 1 if you have the <dirent.h> header file. */
 #cmakedefine HAVE_DIRENT_H 1
 #cmakedefine HAVE_DIRENT_H 1
 
 
@@ -232,9 +246,6 @@
 /* Define to 1 if you have the fseeko declaration. */
 /* Define to 1 if you have the fseeko declaration. */
 #cmakedefine HAVE_DECL_FSEEKO 1
 #cmakedefine HAVE_DECL_FSEEKO 1
 
 
-/* Define to 1 if you have the _fseeki64 function. */
-#cmakedefine HAVE__FSEEKI64 1
-
 /* Define to 1 if you have the ftruncate function. */
 /* Define to 1 if you have the ftruncate function. */
 #cmakedefine HAVE_FTRUNCATE 1
 #cmakedefine HAVE_FTRUNCATE 1
 
 
@@ -307,9 +318,6 @@
 /* Define to 1 if you have the <gssapi/gssapi.h> header file. */
 /* Define to 1 if you have the <gssapi/gssapi.h> header file. */
 #cmakedefine HAVE_GSSAPI_GSSAPI_H 1
 #cmakedefine HAVE_GSSAPI_GSSAPI_H 1
 
 
-/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
-#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1
-
 /* if you have the GNU gssapi libraries */
 /* if you have the GNU gssapi libraries */
 #cmakedefine HAVE_GSSGNU 1
 #cmakedefine HAVE_GSSGNU 1
 
 
@@ -353,9 +361,6 @@
 /* Define to 1 if you have the lber.h header file. */
 /* Define to 1 if you have the lber.h header file. */
 #cmakedefine HAVE_LBER_H 1
 #cmakedefine HAVE_LBER_H 1
 
 
-/* Define to 1 if you have the ldap.h header file. */
-#cmakedefine HAVE_LDAP_H 1
-
 /* Use LDAPS implementation */
 /* Use LDAPS implementation */
 #cmakedefine HAVE_LDAP_SSL 1
 #cmakedefine HAVE_LDAP_SSL 1
 
 
@@ -401,6 +406,9 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #cmakedefine HAVE_NETINET_IN_H 1
 #cmakedefine HAVE_NETINET_IN_H 1
 
 
+/* Define to 1 if you have the <netinet/in6.h> header file. */
+#cmakedefine HAVE_NETINET_IN6_H 1
+
 /* Define to 1 if you have the <netinet/tcp.h> header file. */
 /* Define to 1 if you have the <netinet/tcp.h> header file. */
 #cmakedefine HAVE_NETINET_TCP_H 1
 #cmakedefine HAVE_NETINET_TCP_H 1
 
 
@@ -422,8 +430,8 @@
 /* Define to 1 if you have the `eventfd' function. */
 /* Define to 1 if you have the `eventfd' function. */
 #cmakedefine HAVE_EVENTFD 1
 #cmakedefine HAVE_EVENTFD 1
 
 
-/* If you have a fine poll */
-#cmakedefine HAVE_POLL_FINE 1
+/* If you have poll */
+#cmakedefine HAVE_POLL 1
 
 
 /* Define to 1 if you have the <poll.h> header file. */
 /* Define to 1 if you have the <poll.h> header file. */
 #cmakedefine HAVE_POLL_H 1
 #cmakedefine HAVE_POLL_H 1
@@ -455,6 +463,9 @@
 /* Define to 1 if you have the sendmsg function. */
 /* Define to 1 if you have the sendmsg function. */
 #cmakedefine HAVE_SENDMSG 1
 #cmakedefine HAVE_SENDMSG 1
 
 
+/* Define to 1 if you have the sendmmsg function. */
+#cmakedefine HAVE_SENDMMSG 1
+
 /* Define to 1 if you have the 'fsetxattr' function. */
 /* Define to 1 if you have the 'fsetxattr' function. */
 #cmakedefine HAVE_FSETXATTR 1
 #cmakedefine HAVE_FSETXATTR 1
 
 
@@ -470,6 +481,9 @@
 /* Define to 1 if you have the `setmode' function. */
 /* Define to 1 if you have the `setmode' function. */
 #cmakedefine HAVE_SETMODE 1
 #cmakedefine HAVE_SETMODE 1
 
 
+/* Define to 1 if you have the `_setmode' function. */
+#cmakedefine HAVE__SETMODE 1
+
 /* Define to 1 if you have the `setrlimit' function. */
 /* Define to 1 if you have the `setrlimit' function. */
 #cmakedefine HAVE_SETRLIMIT 1
 #cmakedefine HAVE_SETRLIMIT 1
 
 
@@ -497,6 +511,9 @@
 /* Define to 1 if you have the `socket' function. */
 /* Define to 1 if you have the `socket' function. */
 #cmakedefine HAVE_SOCKET 1
 #cmakedefine HAVE_SOCKET 1
 
 
+/* Define to 1 if you have the <proto/bsdsocket.h> header file. */
+#cmakedefine HAVE_PROTO_BSDSOCKET_H 1
+
 /* Define to 1 if you have the socketpair function. */
 /* Define to 1 if you have the socketpair function. */
 #cmakedefine HAVE_SOCKETPAIR 1
 #cmakedefine HAVE_SOCKETPAIR 1
 
 
@@ -608,9 +625,6 @@
 /* Define this symbol if your OS supports changing the contents of argv */
 /* Define this symbol if your OS supports changing the contents of argv */
 #cmakedefine HAVE_WRITABLE_ARGV 1
 #cmakedefine HAVE_WRITABLE_ARGV 1
 
 
-/* Define to 1 if you need the lber.h header file even with ldap.h */
-#cmakedefine NEED_LBER_H 1
-
 /* Define to 1 if you need the malloc.h header file even with stdlib.h */
 /* Define to 1 if you need the malloc.h header file even with stdlib.h */
 #cmakedefine NEED_MALLOC_H 1
 #cmakedefine NEED_MALLOC_H 1
 
 
@@ -618,7 +632,7 @@
 #cmakedefine NEED_REENTRANT 1
 #cmakedefine NEED_REENTRANT 1
 
 
 /* cpu-machine-OS */
 /* cpu-machine-OS */
-#cmakedefine OS ${OS}
+#cmakedefine CURL_OS ${CURL_OS}
 
 
 /* Name of package */
 /* Name of package */
 #cmakedefine PACKAGE ${PACKAGE}
 #cmakedefine PACKAGE ${PACKAGE}
@@ -704,6 +718,9 @@ ${SIZEOF_TIME_T_CODE}
 /* if wolfSSL has the wolfSSL_DES_ecb_encrypt function. */
 /* if wolfSSL has the wolfSSL_DES_ecb_encrypt function. */
 #cmakedefine HAVE_WOLFSSL_DES_ECB_ENCRYPT 1
 #cmakedefine HAVE_WOLFSSL_DES_ECB_ENCRYPT 1
 
 
+/* if wolfSSL has the wolfSSL_BIO_new function. */
+#cmakedefine HAVE_WOLFSSL_BIO 1
+
 /* if wolfSSL has the wolfSSL_BIO_set_shutdown function. */
 /* if wolfSSL has the wolfSSL_BIO_set_shutdown function. */
 #cmakedefine HAVE_WOLFSSL_FULL_BIO 1
 #cmakedefine HAVE_WOLFSSL_FULL_BIO 1
 
 
@@ -810,9 +827,6 @@ ${SIZEOF_TIME_T_CODE}
 /* to enable Apple IDN */
 /* to enable Apple IDN */
 #cmakedefine USE_APPLE_IDN 1
 #cmakedefine USE_APPLE_IDN 1
 
 
-/* Define to 1 to enable websocket support. */
-#cmakedefine USE_WEBSOCKETS 1
-
 /* Define to 1 if OpenSSL has the SSL_CTX_set_srp_username function. */
 /* Define to 1 if OpenSSL has the SSL_CTX_set_srp_username function. */
 #cmakedefine HAVE_OPENSSL_SRP 1
 #cmakedefine HAVE_OPENSSL_SRP 1
 
 

+ 3 - 3
lib/curl_fnmatch.c

@@ -161,7 +161,7 @@ static void setcharorrange(unsigned char **pp, unsigned char *charset)
   }
   }
 }
 }
 
 
-/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
+/* returns 1 (TRUE) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
 static int setcharset(unsigned char **p, unsigned char *charset)
 static int setcharset(unsigned char **p, unsigned char *charset)
 {
 {
   setcharset_state state = CURLFNM_SCHS_DEFAULT;
   setcharset_state state = CURLFNM_SCHS_DEFAULT;
@@ -293,7 +293,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
       p++;
       p++;
       break;
       break;
     case '\0':
     case '\0':
-      return *s? CURL_FNMATCH_NOMATCH: CURL_FNMATCH_MATCH;
+      return *s ? CURL_FNMATCH_NOMATCH : CURL_FNMATCH_MATCH;
     case '\\':
     case '\\':
       if(p[1])
       if(p[1])
         p++;
         p++;
@@ -303,7 +303,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
     case '[':
     case '[':
       pp = p + 1; /* Copy in case of syntax error in set. */
       pp = p + 1; /* Copy in case of syntax error in set. */
       if(setcharset(&pp, charset)) {
       if(setcharset(&pp, charset)) {
-        int found = FALSE;
+        bool found = FALSE;
         if(!*s)
         if(!*s)
           return CURL_FNMATCH_NOMATCH;
           return CURL_FNMATCH_NOMATCH;
         if(charset[(unsigned int)*s])
         if(charset[(unsigned int)*s])

+ 1 - 1
lib/curl_gssapi.c

@@ -35,7 +35,7 @@
 #include "memdebug.h"
 #include "memdebug.h"
 
 
 #if defined(__GNUC__)
 #if defined(__GNUC__)
-#define CURL_ALIGN8   __attribute__ ((aligned(8)))
+#define CURL_ALIGN8  __attribute__((aligned(8)))
 #else
 #else
 #define CURL_ALIGN8
 #define CURL_ALIGN8
 #endif
 #endif

+ 14 - 16
lib/curl_hmac.h

@@ -32,30 +32,28 @@
 
 
 #define HMAC_MD5_LENGTH 16
 #define HMAC_MD5_LENGTH 16
 
 
-typedef CURLcode (* HMAC_hinit_func)(void *context);
-typedef void    (* HMAC_hupdate_func)(void *context,
-                                      const unsigned char *data,
-                                      unsigned int len);
-typedef void    (* HMAC_hfinal_func)(unsigned char *result, void *context);
-
+typedef CURLcode (*HMAC_hinit)(void *context);
+typedef void    (*HMAC_hupdate)(void *context,
+                                const unsigned char *data,
+                                unsigned int len);
+typedef void    (*HMAC_hfinal)(unsigned char *result, void *context);
 
 
 /* Per-hash function HMAC parameters. */
 /* Per-hash function HMAC parameters. */
 struct HMAC_params {
 struct HMAC_params {
-  HMAC_hinit_func
-  hmac_hinit;     /* Initialize context procedure. */
-  HMAC_hupdate_func     hmac_hupdate;   /* Update context with data. */
-  HMAC_hfinal_func      hmac_hfinal;    /* Get final result procedure. */
-  unsigned int          hmac_ctxtsize;  /* Context structure size. */
-  unsigned int          hmac_maxkeylen; /* Maximum key length (bytes). */
-  unsigned int          hmac_resultlen; /* Result length (bytes). */
+  HMAC_hinit       hinit;     /* Initialize context procedure. */
+  HMAC_hupdate     hupdate;   /* Update context with data. */
+  HMAC_hfinal      hfinal;    /* Get final result procedure. */
+  unsigned int     ctxtsize;  /* Context structure size. */
+  unsigned int     maxkeylen; /* Maximum key length (bytes). */
+  unsigned int     resultlen; /* Result length (bytes). */
 };
 };
 
 
 
 
 /* HMAC computation context. */
 /* HMAC computation context. */
 struct HMAC_context {
 struct HMAC_context {
-  const struct HMAC_params *hmac_hash; /* Hash function definition. */
-  void *hmac_hashctxt1;         /* Hash function context 1. */
-  void *hmac_hashctxt2;         /* Hash function context 2. */
+  const struct HMAC_params *hash; /* Hash function definition. */
+  void *hashctxt1;         /* Hash function context 1. */
+  void *hashctxt2;         /* Hash function context 2. */
 };
 };
 
 
 
 

+ 7 - 7
lib/curl_md5.h

@@ -31,11 +31,11 @@
 
 
 #define MD5_DIGEST_LEN  16
 #define MD5_DIGEST_LEN  16
 
 
-typedef CURLcode (* Curl_MD5_init_func)(void *context);
-typedef void (* Curl_MD5_update_func)(void *context,
-                                      const unsigned char *data,
-                                      unsigned int len);
-typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
+typedef CURLcode (*Curl_MD5_init_func)(void *context);
+typedef void (*Curl_MD5_update_func)(void *context,
+                                     const unsigned char *data,
+                                     unsigned int len);
+typedef void (*Curl_MD5_final_func)(unsigned char *result, void *context);
 
 
 struct MD5_params {
 struct MD5_params {
   Curl_MD5_init_func     md5_init_func;   /* Initialize context procedure */
   Curl_MD5_init_func     md5_init_func;   /* Initialize context procedure */
@@ -50,8 +50,8 @@ struct MD5_context {
   void                  *md5_hashctx;   /* Hash function context */
   void                  *md5_hashctx;   /* Hash function context */
 };
 };
 
 
-extern const struct MD5_params Curl_DIGEST_MD5[1];
-extern const struct HMAC_params Curl_HMAC_MD5[1];
+extern const struct MD5_params Curl_DIGEST_MD5;
+extern const struct HMAC_params Curl_HMAC_MD5;
 
 
 CURLcode Curl_md5it(unsigned char *output, const unsigned char *input,
 CURLcode Curl_md5it(unsigned char *output, const unsigned char *input,
                     const size_t len);
                     const size_t len);

+ 2 - 0
lib/curl_memory.h

@@ -84,6 +84,7 @@
 #undef socketpair
 #undef socketpair
 #endif
 #endif
 
 
+#ifndef CURL_NO_GETADDRINFO_OVERRIDE
 #ifdef HAVE_GETADDRINFO
 #ifdef HAVE_GETADDRINFO
 #if defined(getaddrinfo) && defined(__osf__)
 #if defined(getaddrinfo) && defined(__osf__)
 #undef ogetaddrinfo
 #undef ogetaddrinfo
@@ -95,6 +96,7 @@
 #ifdef HAVE_FREEADDRINFO
 #ifdef HAVE_FREEADDRINFO
 #undef freeaddrinfo
 #undef freeaddrinfo
 #endif /* HAVE_FREEADDRINFO */
 #endif /* HAVE_FREEADDRINFO */
+#endif /* !CURL_NO_GETADDRINFO_OVERRIDE */
 
 
 /* sclose is probably already defined, redefine it! */
 /* sclose is probably already defined, redefine it! */
 #undef sclose
 #undef sclose

+ 23 - 11
lib/curl_ntlm_core.c

@@ -71,13 +71,6 @@
 #  include <openssl/md5.h>
 #  include <openssl/md5.h>
 #  include <openssl/ssl.h>
 #  include <openssl/ssl.h>
 #  include <openssl/rand.h>
 #  include <openssl/rand.h>
-#else
-#  include <wolfssl/openssl/des.h>
-#  include <wolfssl/openssl/md5.h>
-#  include <wolfssl/openssl/ssl.h>
-#  include <wolfssl/openssl/rand.h>
-#endif
-
 #  if (defined(OPENSSL_VERSION_NUMBER) && \
 #  if (defined(OPENSSL_VERSION_NUMBER) && \
        (OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
        (OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
 #    define DES_key_schedule des_key_schedule
 #    define DES_key_schedule des_key_schedule
@@ -95,6 +88,25 @@
 #    define DESKEYARG(x) *x
 #    define DESKEYARG(x) *x
 #    define DESKEY(x) &x
 #    define DESKEY(x) &x
 #  endif
 #  endif
+#else
+#  include <wolfssl/openssl/des.h>
+#  include <wolfssl/openssl/md5.h>
+#  include <wolfssl/openssl/ssl.h>
+#  include <wolfssl/openssl/rand.h>
+#  if defined(OPENSSL_COEXIST)
+#    define DES_key_schedule WOLFSSL_DES_key_schedule
+#    define DES_cblock WOLFSSL_DES_cblock
+#    define DES_set_odd_parity wolfSSL_DES_set_odd_parity
+#    define DES_set_key wolfSSL_DES_set_key
+#    define DES_set_key_unchecked wolfSSL_DES_set_key_unchecked
+#    define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt
+#    define DESKEY(x) ((WOLFSSL_DES_key_schedule *)(x))
+#    define DESKEYARG(x) *x
+#  else
+#    define DESKEYARG(x) *x
+#    define DESKEY(x) &x
+#  endif
+#endif
 
 
 #elif defined(USE_GNUTLS)
 #elif defined(USE_GNUTLS)
 
 
@@ -483,7 +495,7 @@ static void time2filetime(struct ms_filetime *ft, time_t t)
      134774 days = 11644473600 seconds = 0x2B6109100 */
      134774 days = 11644473600 seconds = 0x2B6109100 */
   r = ft->dwLowDateTime;
   r = ft->dwLowDateTime;
   ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF;
   ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF;
-  ft->dwHighDateTime += ft->dwLowDateTime < r? 0x03: 0x02;
+  ft->dwHighDateTime += ft->dwLowDateTime < r ? 0x03 : 0x02;
 
 
   /* Convert to tenths of microseconds. */
   /* Convert to tenths of microseconds. */
   ft->dwHighDateTime *= 10000000;
   ft->dwHighDateTime *= 10000000;
@@ -528,7 +540,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
   ascii_uppercase_to_unicode_le(identity, user, userlen);
   ascii_uppercase_to_unicode_le(identity, user, userlen);
   ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
   ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
 
 
-  result = Curl_hmacit(Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
+  result = Curl_hmacit(&Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len,
                        ntlmv2hash);
                        ntlmv2hash);
   free(identity);
   free(identity);
 
 
@@ -613,7 +625,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
 
 
   /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
   /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
   memcpy(ptr + 8, &ntlm->nonce[0], 8);
   memcpy(ptr + 8, &ntlm->nonce[0], 8);
-  result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
+  result = Curl_hmacit(&Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8,
                     NTLMv2_BLOB_LEN + 8, hmac_output);
                     NTLMv2_BLOB_LEN + 8, hmac_output);
   if(result) {
   if(result) {
     free(ptr);
     free(ptr);
@@ -656,7 +668,7 @@ CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
   memcpy(&data[0], challenge_server, 8);
   memcpy(&data[0], challenge_server, 8);
   memcpy(&data[8], challenge_client, 8);
   memcpy(&data[8], challenge_client, 8);
 
 
-  result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16,
+  result = Curl_hmacit(&Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16,
                        hmac_output);
                        hmac_output);
   if(result)
   if(result)
     return result;
     return result;

+ 1 - 1
lib/curl_rtmp.c

@@ -255,7 +255,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
     return CURLE_FAILED_INIT;
     return CURLE_FAILED_INIT;
 
 
   /* Clients must send a periodic BytesReceived report to the server */
   /* Clients must send a periodic BytesReceived report to the server */
-  r->m_bSendCounter = true;
+  r->m_bSendCounter = TRUE;
 
 
   *done = TRUE;
   *done = TRUE;
   conn->recv[FIRSTSOCKET] = rtmp_recv;
   conn->recv[FIRSTSOCKET] = rtmp_recv;

+ 33 - 11
lib/curl_setup.h

@@ -33,7 +33,7 @@
 
 
 /* FIXME: Delete this once the warnings have been fixed. */
 /* FIXME: Delete this once the warnings have been fixed. */
 #if !defined(CURL_WARN_SIGN_CONVERSION)
 #if !defined(CURL_WARN_SIGN_CONVERSION)
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic ignored "-Wsign-conversion"
 #pragma GCC diagnostic ignored "-Wsign-conversion"
 #endif
 #endif
 #endif
 #endif
@@ -43,21 +43,24 @@
 #include <_mingw.h>
 #include <_mingw.h>
 #endif
 #endif
 
 
-/* Workaround for Homebrew gcc 12.4.0, 13.3.0, 14.1.0 and newer (as of 14.1.0)
+/* Workaround for Homebrew gcc 12.4.0, 13.3.0, 14.1.0, 14.2.0 (initial build)
    that started advertising the `availability` attribute, which then gets used
    that started advertising the `availability` attribute, which then gets used
-   by Apple SDK, but, in a way incompatible with gcc, resulting in a misc
-   errors inside SDK headers, e.g.:
+   by Apple SDK, but, in a way incompatible with gcc, resulting in misc errors
+   inside SDK headers, e.g.:
      error: attributes should be specified before the declarator in a function
      error: attributes should be specified before the declarator in a function
             definition
             definition
      error: expected ',' or '}' before
      error: expected ',' or '}' before
    Followed by missing declarations.
    Followed by missing declarations.
-   Fix it by overriding the built-in feature-check macro used by the headers
-   to enable the problematic attributes. This makes the feature check fail. */
-#if defined(__APPLE__) &&                \
-  !defined(__clang__) &&                 \
-  defined(__GNUC__) && __GNUC__ >= 12 && \
+   Work it around by overriding the built-in feature-check macro used by the
+   headers to enable the problematic attributes. This makes the feature check
+   fail. Fixed in 14.2.0_1. Disable the workaround if the fix is detected. */
+#if defined(__APPLE__) && !defined(__clang__) && defined(__GNUC__) && \
   defined(__has_attribute)
   defined(__has_attribute)
-#define availability curl_pp_attribute_disabled
+#  if !defined(__has_feature)
+#    define availability curl_pp_attribute_disabled
+#  elif !__has_feature(attribute_availability)
+#    define availability curl_pp_attribute_disabled
+#  endif
 #endif
 #endif
 
 
 #if defined(__APPLE__)
 #if defined(__APPLE__)
@@ -109,7 +112,7 @@
 #  include <winapifamily.h>
 #  include <winapifamily.h>
 #  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) &&  \
 #  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) &&  \
      !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
      !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-#    define CURL_WINDOWS_APP
+#    define CURL_WINDOWS_UWP
 #  endif
 #  endif
 # endif
 # endif
 #endif
 #endif
@@ -208,6 +211,11 @@
 /*  please, do it beyond the point further indicated in this file.  */
 /*  please, do it beyond the point further indicated in this file.  */
 /* ================================================================ */
 /* ================================================================ */
 
 
+/* Give calloc a chance to be dragging in early, so we do not redefine */
+#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
+#  include <pthread.h>
+#endif
+
 /*
 /*
  * Disable other protocols when http is the only one desired.
  * Disable other protocols when http is the only one desired.
  */
  */
@@ -282,6 +290,14 @@
 #  define CURL_DISABLE_HTTP_AUTH 1
 #  define CURL_DISABLE_HTTP_AUTH 1
 #endif
 #endif
 
 
+/*
+ * ECH requires HTTPSRR.
+ */
+
+#if defined(USE_ECH) && !defined(USE_HTTPSRR)
+#  define USE_HTTPSRR
+#endif
+
 /* ================================================================ */
 /* ================================================================ */
 /* No system header file shall be included in this file before this */
 /* No system header file shall be included in this file before this */
 /* point.                                                           */
 /* point.                                                           */
@@ -449,6 +465,12 @@
 #include <curl/stdcheaders.h>
 #include <curl/stdcheaders.h>
 #endif
 #endif
 
 
+#ifdef _WIN32
+#define Curl_getpid() GetCurrentProcessId()
+#else
+#define Curl_getpid() getpid()
+#endif
+
 /*
 /*
  * Large file (>2Gb) support using Win32 functions.
  * Large file (>2Gb) support using Win32 functions.
  */
  */

+ 1 - 1
lib/curl_sha256.h

@@ -31,7 +31,7 @@
 #include <curl/curl.h>
 #include <curl/curl.h>
 #include "curl_hmac.h"
 #include "curl_hmac.h"
 
 
-extern const struct HMAC_params Curl_HMAC_SHA256[1];
+extern const struct HMAC_params Curl_HMAC_SHA256;
 
 
 #ifndef CURL_SHA256_DIGEST_LENGTH
 #ifndef CURL_SHA256_DIGEST_LENGTH
 #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
 #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */

+ 1 - 1
lib/curl_sha512_256.c

@@ -34,7 +34,7 @@
  * * GnuTLS
  * * GnuTLS
  * * wolfSSL
  * * wolfSSL
  * * Schannel SSPI
  * * Schannel SSPI
- * * SecureTransport (Darwin)
+ * * Secure Transport (Darwin)
  * * mbedTLS
  * * mbedTLS
  * * BearSSL
  * * BearSSL
  * * Rustls
  * * Rustls

+ 3 - 3
lib/curl_threads.c

@@ -103,7 +103,7 @@ int Curl_thread_join(curl_thread_t *hnd)
 #elif defined(USE_THREADS_WIN32)
 #elif defined(USE_THREADS_WIN32)
 
 
 curl_thread_t Curl_thread_create(
 curl_thread_t Curl_thread_create(
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
                                  DWORD
                                  DWORD
 #else
 #else
                                  unsigned int
                                  unsigned int
@@ -111,14 +111,14 @@ curl_thread_t Curl_thread_create(
                                  (CURL_STDCALL *func) (void *),
                                  (CURL_STDCALL *func) (void *),
                                  void *arg)
                                  void *arg)
 {
 {
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
   typedef HANDLE curl_win_thread_handle_t;
   typedef HANDLE curl_win_thread_handle_t;
 #else
 #else
   typedef uintptr_t curl_win_thread_handle_t;
   typedef uintptr_t curl_win_thread_handle_t;
 #endif
 #endif
   curl_thread_t t;
   curl_thread_t t;
   curl_win_thread_handle_t thread_handle;
   curl_win_thread_handle_t thread_handle;
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
   thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL);
   thread_handle = CreateThread(NULL, 0, func, arg, 0, NULL);
 #else
 #else
   thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
   thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);

+ 1 - 1
lib/curl_threads.h

@@ -53,7 +53,7 @@
 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
 
 
 curl_thread_t Curl_thread_create(
 curl_thread_t Curl_thread_create(
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
                                  DWORD
                                  DWORD
 #else
 #else
                                  unsigned int
                                  unsigned int

+ 7 - 7
lib/curl_trc.c

@@ -65,7 +65,7 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type,
       "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
       "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
     if(data->set.fdebug) {
     if(data->set.fdebug) {
       bool inCallback = Curl_is_in_callback(data);
       bool inCallback = Curl_is_in_callback(data);
-      Curl_set_in_callback(data, true);
+      Curl_set_in_callback(data, TRUE);
       (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
       (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
       Curl_set_in_callback(data, inCallback);
       Curl_set_in_callback(data, inCallback);
     }
     }
@@ -239,7 +239,7 @@ void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
 }
 }
 #endif /* !CURL_DISABLE_SMTP */
 #endif /* !CURL_DISABLE_SMTP */
 
 
-#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
 struct curl_trc_feat Curl_trc_feat_ws = {
 struct curl_trc_feat Curl_trc_feat_ws = {
   "WS",
   "WS",
   CURL_LOG_LVL_NONE,
   CURL_LOG_LVL_NONE,
@@ -255,7 +255,7 @@ void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
     va_end(ap);
     va_end(ap);
   }
   }
 }
 }
-#endif /* USE_WEBSOCKETS && !CURL_DISABLE_HTTP */
+#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */
 
 
 #define TRC_CT_NONE        (0)
 #define TRC_CT_NONE        (0)
 #define TRC_CT_PROTOCOL    (1<<(0))
 #define TRC_CT_PROTOCOL    (1<<(0))
@@ -279,7 +279,7 @@ static struct trc_feat_def trc_feats[] = {
 #ifndef CURL_DISABLE_SMTP
 #ifndef CURL_DISABLE_SMTP
   { &Curl_trc_feat_smtp,      TRC_CT_PROTOCOL },
   { &Curl_trc_feat_smtp,      TRC_CT_PROTOCOL },
 #endif
 #endif
-#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
   { &Curl_trc_feat_ws,        TRC_CT_PROTOCOL },
   { &Curl_trc_feat_ws,        TRC_CT_PROTOCOL },
 #endif
 #endif
 };
 };
@@ -365,7 +365,7 @@ static CURLcode trc_opt(const char *config)
   if(!tmp)
   if(!tmp)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
-  token = strtok_r(tmp, ", ", &tok_buf);
+  token = Curl_strtok_r(tmp, ", ", &tok_buf);
   while(token) {
   while(token) {
     switch(*token) {
     switch(*token) {
       case '-':
       case '-':
@@ -391,7 +391,7 @@ static CURLcode trc_opt(const char *config)
     else
     else
       trc_apply_level_by_name(token, lvl);
       trc_apply_level_by_name(token, lvl);
 
 
-    token = strtok_r(NULL, ", ", &tok_buf);
+    token = Curl_strtok_r(NULL, ", ", &tok_buf);
   }
   }
   free(tmp);
   free(tmp);
   return CURLE_OK;
   return CURLE_OK;
@@ -399,7 +399,7 @@ static CURLcode trc_opt(const char *config)
 
 
 CURLcode Curl_trc_opt(const char *config)
 CURLcode Curl_trc_opt(const char *config)
 {
 {
-  CURLcode result = config? trc_opt(config) : CURLE_OK;
+  CURLcode result = config ? trc_opt(config) : CURLE_OK;
 #ifdef DEBUGBUILD
 #ifdef DEBUGBUILD
   /* CURL_DEBUG can override anything */
   /* CURL_DEBUG can override anything */
   if(!result) {
   if(!result) {

+ 11 - 14
lib/curl_trc.h

@@ -94,11 +94,11 @@ void Curl_failf(struct Curl_easy *data,
   do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) \
   do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) \
          Curl_trc_smtp(data, __VA_ARGS__); } while(0)
          Curl_trc_smtp(data, __VA_ARGS__); } while(0)
 #endif /* !CURL_DISABLE_SMTP */
 #endif /* !CURL_DISABLE_SMTP */
-#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
-#define CURL_TRC_WS(data, ...) \
+#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+#define CURL_TRC_WS(data, ...)                             \
   do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) \
   do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) \
          Curl_trc_ws(data, __VA_ARGS__); } while(0)
          Curl_trc_ws(data, __VA_ARGS__); } while(0)
-#endif /* USE_WEBSOCKETS && !CURL_DISABLE_HTTP */
+#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */
 
 
 #else /* CURL_HAVE_C99 */
 #else /* CURL_HAVE_C99 */
 
 
@@ -113,7 +113,7 @@ void Curl_failf(struct Curl_easy *data,
 #ifndef CURL_DISABLE_SMTP
 #ifndef CURL_DISABLE_SMTP
 #define CURL_TRC_SMTP  Curl_trc_smtp
 #define CURL_TRC_SMTP  Curl_trc_smtp
 #endif
 #endif
-#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
 #define CURL_TRC_WS    Curl_trc_ws
 #define CURL_TRC_WS    Curl_trc_ws
 #endif
 #endif
 
 
@@ -152,8 +152,6 @@ void Curl_infof(struct Curl_easy *data,
  */
  */
 void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
 void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
                        const char *fmt, ...) CURL_PRINTF(3, 4);
                        const char *fmt, ...) CURL_PRINTF(3, 4);
-void Curl_trc_ft_infof(struct Curl_easy *data, struct curl_trc_feat *ft,
-                       const char *fmt, ...) CURL_PRINTF(3, 4);
 void Curl_trc_write(struct Curl_easy *data,
 void Curl_trc_write(struct Curl_easy *data,
                     const char *fmt, ...) CURL_PRINTF(2, 3);
                     const char *fmt, ...) CURL_PRINTF(2, 3);
 void Curl_trc_read(struct Curl_easy *data,
 void Curl_trc_read(struct Curl_easy *data,
@@ -169,7 +167,7 @@ extern struct curl_trc_feat Curl_trc_feat_smtp;
 void Curl_trc_smtp(struct Curl_easy *data,
 void Curl_trc_smtp(struct Curl_easy *data,
                    const char *fmt, ...) CURL_PRINTF(2, 3);
                    const char *fmt, ...) CURL_PRINTF(2, 3);
 #endif
 #endif
-#if defined(USE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
+#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
 extern struct curl_trc_feat Curl_trc_feat_ws;
 extern struct curl_trc_feat Curl_trc_feat_ws;
 void Curl_trc_ws(struct Curl_easy *data,
 void Curl_trc_ws(struct Curl_easy *data,
                  const char *fmt, ...) CURL_PRINTF(2, 3);
                  const char *fmt, ...) CURL_PRINTF(2, 3);
@@ -197,13 +195,6 @@ static void Curl_trc_cf_infof(struct Curl_easy *data,
 
 
 struct curl_trc_feat;
 struct curl_trc_feat;
 
 
-static void Curl_trc_ft_infof(struct Curl_easy *data,
-                              struct curl_trc_feat *ft,
-                              const char *fmt, ...)
-{
-  (void)data; (void)ft; (void)fmt;
-}
-
 static void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
 static void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
 {
 {
   (void)data; (void)fmt;
   (void)data; (void)fmt;
@@ -226,6 +217,12 @@ static void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
   (void)data; (void)fmt;
   (void)data; (void)fmt;
 }
 }
 #endif
 #endif
+#if !defined(CURL_DISABLE_WEBSOCKETS) || !defined(CURL_DISABLE_HTTP)
+static void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
+{
+  (void)data; (void)fmt;
+}
+#endif
 
 
 #endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
 #endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
 
 

+ 0 - 9
lib/curlx.h

@@ -66,13 +66,4 @@
 #include "version_win32.h"
 #include "version_win32.h"
 /* "version_win32.h" provides curlx_verify_windows_version() */
 /* "version_win32.h" provides curlx_verify_windows_version() */
 
 
-/* Now setup curlx_ * names for the functions that are to become curlx_ and
-   be removed from a future libcurl official API:
-   curlx_getenv
-   curlx_mprintf (and its variations)
-   curlx_strcasecompare
-   curlx_strncasecompare
-
-*/
-
 #endif /* HEADER_CURL_CURLX_H */
 #endif /* HEADER_CURL_CURLX_H */

+ 6 - 7
lib/cw-out.c

@@ -177,8 +177,8 @@ static void cw_get_writefunc(struct Curl_easy *data, cw_out_type otype,
     *pmin_write = 0;
     *pmin_write = 0;
     break;
     break;
   case CW_OUT_HDS:
   case CW_OUT_HDS:
-    *pwcb = data->set.fwrite_header? data->set.fwrite_header :
-             (data->set.writeheader? data->set.fwrite_func : NULL);
+    *pwcb = data->set.fwrite_header ? data->set.fwrite_header :
+             (data->set.writeheader ? data->set.fwrite_func : NULL);
     *pwcb_data = data->set.writeheader;
     *pwcb_data = data->set.writeheader;
     *pmax_write = 0; /* do not chunk-write headers, write them as they are */
     *pmax_write = 0; /* do not chunk-write headers, write them as they are */
     *pmin_write = 0;
     *pmin_write = 0;
@@ -218,12 +218,12 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
   while(blen && !ctx->paused) {
   while(blen && !ctx->paused) {
     if(!flush_all && blen < min_write)
     if(!flush_all && blen < min_write)
       break;
       break;
-    wlen = max_write? CURLMIN(blen, max_write) : blen;
+    wlen = max_write ? CURLMIN(blen, max_write) : blen;
     Curl_set_in_callback(data, TRUE);
     Curl_set_in_callback(data, TRUE);
     nwritten = wcb((char *)buf, 1, wlen, wcb_data);
     nwritten = wcb((char *)buf, 1, wlen, wcb_data);
     Curl_set_in_callback(data, FALSE);
     Curl_set_in_callback(data, FALSE);
     CURL_TRC_WRITE(data, "cw_out, wrote %zu %s bytes -> %zu",
     CURL_TRC_WRITE(data, "cw_out, wrote %zu %s bytes -> %zu",
-                   wlen, (otype == CW_OUT_BODY)? "body" : "header",
+                   wlen, (otype == CW_OUT_BODY) ? "body" : "header",
                    nwritten);
                    nwritten);
     if(CURL_WRITEFUNC_PAUSE == nwritten) {
     if(CURL_WRITEFUNC_PAUSE == nwritten) {
       if(data->conn && data->conn->handler->flags & PROTOPT_NONETWORK) {
       if(data->conn && data->conn->handler->flags & PROTOPT_NONETWORK) {
@@ -402,9 +402,8 @@ static CURLcode cw_out_write(struct Curl_easy *data,
 {
 {
   struct cw_out_ctx *ctx = writer->ctx;
   struct cw_out_ctx *ctx = writer->ctx;
   CURLcode result;
   CURLcode result;
-  bool flush_all;
+  bool flush_all = !!(type & CLIENTWRITE_EOS);
 
 
-  flush_all = (type & CLIENTWRITE_EOS)? TRUE:FALSE;
   if((type & CLIENTWRITE_BODY) ||
   if((type & CLIENTWRITE_BODY) ||
      ((type & CLIENTWRITE_HEADER) && data->set.include_header)) {
      ((type & CLIENTWRITE_HEADER) && data->set.include_header)) {
     result = cw_out_do_write(ctx, data, CW_OUT_BODY, flush_all, buf, blen);
     result = cw_out_do_write(ctx, data, CW_OUT_BODY, flush_all, buf, blen);
@@ -431,7 +430,7 @@ bool Curl_cw_out_is_paused(struct Curl_easy *data)
     return FALSE;
     return FALSE;
 
 
   ctx = (struct cw_out_ctx *)cw_out;
   ctx = (struct cw_out_ctx *)cw_out;
-  CURL_TRC_WRITE(data, "cw-out is%spaused", ctx->paused? "" : " not");
+  CURL_TRC_WRITE(data, "cw-out is%spaused", ctx->paused ? "" : " not");
   return ctx->paused;
   return ctx->paused;
 }
 }
 
 

+ 21 - 22
lib/doh.c

@@ -165,7 +165,7 @@ UNITTEST DOHcode doh_req_encode(const char *host,
   *dnsp++ = 0; /* append zero-length label for root */
   *dnsp++ = 0; /* append zero-length label for root */
 
 
   /* There are assigned TYPE codes beyond 255: use range [1..65535]  */
   /* There are assigned TYPE codes beyond 255: use range [1..65535]  */
-  *dnsp++ = (unsigned char)(255 & (dnstype>>8)); /* upper 8 bit TYPE */
+  *dnsp++ = (unsigned char)(255 & (dnstype >> 8)); /* upper 8 bit TYPE */
   *dnsp++ = (unsigned char)(255 & dnstype);      /* lower 8 bit TYPE */
   *dnsp++ = (unsigned char)(255 & dnstype);      /* lower 8 bit TYPE */
 
 
   *dnsp++ = '\0'; /* upper 8 bit CLASS */
   *dnsp++ = '\0'; /* upper 8 bit CLASS */
@@ -180,7 +180,7 @@ UNITTEST DOHcode doh_req_encode(const char *host,
 }
 }
 
 
 static size_t
 static size_t
-doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp)
+doh_write_cb(char *contents, size_t size, size_t nmemb, void *userp)
 {
 {
   size_t realsize = size * nmemb;
   size_t realsize = size * nmemb;
   struct dynbuf *mem = (struct dynbuf *)userp;
   struct dynbuf *mem = (struct dynbuf *)userp;
@@ -198,10 +198,10 @@ static void doh_print_buf(struct Curl_easy *data,
 {
 {
   unsigned char hexstr[LOCAL_PB_HEXMAX];
   unsigned char hexstr[LOCAL_PB_HEXMAX];
   size_t hlen = LOCAL_PB_HEXMAX;
   size_t hlen = LOCAL_PB_HEXMAX;
-  bool truncated = false;
+  bool truncated = FALSE;
 
 
   if(len > (LOCAL_PB_HEXMAX / 2))
   if(len > (LOCAL_PB_HEXMAX / 2))
-    truncated = true;
+    truncated = TRUE;
   Curl_hexencode(buf, len, hexstr, hlen);
   Curl_hexencode(buf, len, hexstr, hlen);
   if(!truncated)
   if(!truncated)
     infof(data, "%s: len=%d, val=%s", prefix, (int)len, hexstr);
     infof(data, "%s: len=%d, val=%s", prefix, (int)len, hexstr);
@@ -238,14 +238,14 @@ static int doh_done(struct Curl_easy *doh, CURLcode result)
   return 0;
   return 0;
 }
 }
 
 
-#define ERROR_CHECK_SETOPT(x,y) \
-do {                                          \
-  result = curl_easy_setopt(doh, x, y);       \
-  if(result &&                                \
-     result != CURLE_NOT_BUILT_IN &&          \
-     result != CURLE_UNKNOWN_OPTION)          \
-    goto error;                               \
-} while(0)
+#define ERROR_CHECK_SETOPT(x,y)                         \
+  do {                                                  \
+    result = curl_easy_setopt((CURL *)doh, x, y);       \
+    if(result &&                                        \
+       result != CURLE_NOT_BUILT_IN &&                  \
+       result != CURLE_UNKNOWN_OPTION)                  \
+      goto error;                                       \
+  } while(0)
 
 
 static CURLcode doh_run_probe(struct Curl_easy *data,
 static CURLcode doh_run_probe(struct Curl_easy *data,
                               struct doh_probe *p, DNStype dnstype,
                               struct doh_probe *p, DNStype dnstype,
@@ -278,7 +278,7 @@ static CURLcode doh_run_probe(struct Curl_easy *data,
 
 
   /* pass in the struct pointer via a local variable to please coverity and
   /* pass in the struct pointer via a local variable to please coverity and
      the gcc typecheck helpers */
      the gcc typecheck helpers */
-  doh->state.internal = true;
+  doh->state.internal = TRUE;
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   doh->state.feat = &Curl_doh_trc;
   doh->state.feat = &Curl_doh_trc;
 #endif
 #endif
@@ -301,7 +301,7 @@ static CURLcode doh_run_probe(struct Curl_easy *data,
   ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
   ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
 #endif
 #endif
   ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms);
   ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms);
-  ERROR_CHECK_SETOPT(CURLOPT_SHARE, data->share);
+  ERROR_CHECK_SETOPT(CURLOPT_SHARE, (CURLSH *)data->share);
   if(data->set.err && data->set.err != stderr)
   if(data->set.err && data->set.err != stderr)
     ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err);
     ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err);
   if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc))
   if(Curl_trc_ft_is_verbose(data, &Curl_doh_trc))
@@ -847,15 +847,13 @@ static void doh_show(struct Curl_easy *data,
     }
     }
     else if(a->type == DNS_TYPE_AAAA) {
     else if(a->type == DNS_TYPE_AAAA) {
       int j;
       int j;
-      char buffer[128];
-      char *ptr;
-      size_t len;
-      len = msnprintf(buffer, 128, "[DoH] AAAA: ");
-      ptr = &buffer[len];
+      char buffer[128] = "[DoH] AAAA: ";
+      size_t len = strlen(buffer);
+      char *ptr = &buffer[len];
       len = sizeof(buffer) - len;
       len = sizeof(buffer) - len;
       for(j = 0; j < 16; j += 2) {
       for(j = 0; j < 16; j += 2) {
         size_t l;
         size_t l;
-        msnprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j],
+        msnprintf(ptr, len, "%s%02x%02x", j ? ":" : "", d->addr[i].ip.v6[j],
                   d->addr[i].ip.v6[j + 1]);
                   d->addr[i].ip.v6[j + 1]);
         l = strlen(ptr);
         l = strlen(ptr);
         len -= l;
         len -= l;
@@ -1305,7 +1303,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
   if(dohp->probe[DOH_SLOT_IPV4].easy_mid < 0 &&
   if(dohp->probe[DOH_SLOT_IPV4].easy_mid < 0 &&
      dohp->probe[DOH_SLOT_IPV6].easy_mid < 0) {
      dohp->probe[DOH_SLOT_IPV6].easy_mid < 0) {
     failf(data, "Could not DoH-resolve: %s", data->state.async.hostname);
     failf(data, "Could not DoH-resolve: %s", data->state.async.hostname);
-    return CONN_IS_PROXIED(data->conn)?CURLE_COULDNT_RESOLVE_PROXY:
+    return CONN_IS_PROXIED(data->conn) ? CURLE_COULDNT_RESOLVE_PROXY :
       CURLE_COULDNT_RESOLVE_HOST;
       CURLE_COULDNT_RESOLVE_HOST;
   }
   }
   else if(!dohp->pending) {
   else if(!dohp->pending) {
@@ -1415,7 +1413,8 @@ void Curl_doh_close(struct Curl_easy *data)
       doh->probe[slot].easy_mid = -1;
       doh->probe[slot].easy_mid = -1;
       /* should have been called before data is removed from multi handle */
       /* should have been called before data is removed from multi handle */
       DEBUGASSERT(data->multi);
       DEBUGASSERT(data->multi);
-      probe_data = data->multi? Curl_multi_get_handle(data->multi, mid) : NULL;
+      probe_data = data->multi ? Curl_multi_get_handle(data->multi, mid) :
+        NULL;
       if(!probe_data) {
       if(!probe_data) {
         DEBUGF(infof(data, "Curl_doh_close: xfer for mid=%"
         DEBUGF(infof(data, "Curl_doh_close: xfer for mid=%"
                      FMT_OFF_T " not found!",
                      FMT_OFF_T " not found!",

+ 2 - 2
lib/dynhds.c

@@ -141,7 +141,7 @@ void Curl_dynhds_set_opts(struct dynhds *dynhds, int opts)
 struct dynhds_entry *Curl_dynhds_getn(struct dynhds *dynhds, size_t n)
 struct dynhds_entry *Curl_dynhds_getn(struct dynhds *dynhds, size_t n)
 {
 {
   DEBUGASSERT(dynhds);
   DEBUGASSERT(dynhds);
-  return (n < dynhds->hds_len)? dynhds->hds[n] : NULL;
+  return (n < dynhds->hds_len) ? dynhds->hds[n] : NULL;
 }
 }
 
 
 struct dynhds_entry *Curl_dynhds_get(struct dynhds *dynhds, const char *name,
 struct dynhds_entry *Curl_dynhds_get(struct dynhds *dynhds, const char *name,
@@ -272,7 +272,7 @@ CURLcode Curl_dynhds_h1_add_line(struct dynhds *dynhds,
 
 
 CURLcode Curl_dynhds_h1_cadd_line(struct dynhds *dynhds, const char *line)
 CURLcode Curl_dynhds_h1_cadd_line(struct dynhds *dynhds, const char *line)
 {
 {
-  return Curl_dynhds_h1_add_line(dynhds, line, line? strlen(line) : 0);
+  return Curl_dynhds_h1_add_line(dynhds, line, line ? strlen(line) : 0);
 }
 }
 
 
 #ifdef UNITTESTS
 #ifdef UNITTESTS

+ 36 - 29
lib/easy.c

@@ -347,7 +347,7 @@ CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
  * curl_easy_init() is the external interface to alloc, setup and init an
  * curl_easy_init() is the external interface to alloc, setup and init an
  * easy handle that is returned. If anything goes wrong, NULL is returned.
  * easy handle that is returned. If anything goes wrong, NULL is returned.
  */
  */
-struct Curl_easy *curl_easy_init(void)
+CURL *curl_easy_init(void)
 {
 {
   CURLcode result;
   CURLcode result;
   struct Curl_easy *data;
   struct Curl_easy *data;
@@ -398,9 +398,9 @@ struct events {
  * Callback that gets called with a new value when the timeout should be
  * Callback that gets called with a new value when the timeout should be
  * updated.
  * updated.
  */
  */
-static int events_timer(struct Curl_multi *multi,    /* multi handle */
+static int events_timer(CURLM *multi,    /* multi handle */
                         long timeout_ms, /* see above */
                         long timeout_ms, /* see above */
-                        void *userp)    /* private callback pointer */
+                        void *userp)     /* private callback pointer */
 {
 {
   struct events *ev = userp;
   struct events *ev = userp;
   (void)multi;
   (void)multi;
@@ -449,7 +449,7 @@ static short socketcb2poll(int pollmask)
  * Callback that gets called with information about socket activity to
  * Callback that gets called with information about socket activity to
  * monitor.
  * monitor.
  */
  */
-static int events_socket(struct Curl_easy *easy,      /* easy handle */
+static int events_socket(CURL *easy,      /* easy handle */
                          curl_socket_t s, /* socket */
                          curl_socket_t s, /* socket */
                          int what,        /* see above */
                          int what,        /* see above */
                          void *userp,     /* private callback
                          void *userp,     /* private callback
@@ -461,6 +461,7 @@ static int events_socket(struct Curl_easy *easy,      /* easy handle */
   struct socketmonitor *m;
   struct socketmonitor *m;
   struct socketmonitor *prev = NULL;
   struct socketmonitor *prev = NULL;
   bool found = FALSE;
   bool found = FALSE;
+  struct Curl_easy *data = easy;
 
 
 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
 #if defined(CURL_DISABLE_VERBOSE_STRINGS)
   (void) easy;
   (void) easy;
@@ -479,16 +480,16 @@ static int events_socket(struct Curl_easy *easy,      /* easy handle */
         else
         else
           ev->list = nxt;
           ev->list = nxt;
         free(m);
         free(m);
-        infof(easy, "socket cb: socket %" FMT_SOCKET_T " REMOVED", s);
+        infof(data, "socket cb: socket %" FMT_SOCKET_T " REMOVED", s);
       }
       }
       else {
       else {
         /* The socket 's' is already being monitored, update the activity
         /* The socket 's' is already being monitored, update the activity
            mask. Convert from libcurl bitmask to the poll one. */
            mask. Convert from libcurl bitmask to the poll one. */
         m->socket.events = socketcb2poll(what);
         m->socket.events = socketcb2poll(what);
-        infof(easy, "socket cb: socket %" FMT_SOCKET_T
+        infof(data, "socket cb: socket %" FMT_SOCKET_T
               " UPDATED as %s%s", s,
               " UPDATED as %s%s", s,
-              (what&CURL_POLL_IN)?"IN":"",
-              (what&CURL_POLL_OUT)?"OUT":"");
+              (what&CURL_POLL_IN) ? "IN" : "",
+              (what&CURL_POLL_OUT) ? "OUT" : "");
       }
       }
       break;
       break;
     }
     }
@@ -499,7 +500,7 @@ static int events_socket(struct Curl_easy *easy,      /* easy handle */
   if(!found) {
   if(!found) {
     if(what == CURL_POLL_REMOVE) {
     if(what == CURL_POLL_REMOVE) {
       /* should not happen if our logic is correct, but is no drama. */
       /* should not happen if our logic is correct, but is no drama. */
-      DEBUGF(infof(easy, "socket cb: asked to REMOVE socket %"
+      DEBUGF(infof(data, "socket cb: asked to REMOVE socket %"
                    FMT_SOCKET_T "but not present!", s));
                    FMT_SOCKET_T "but not present!", s));
       DEBUGASSERT(0);
       DEBUGASSERT(0);
     }
     }
@@ -511,9 +512,9 @@ static int events_socket(struct Curl_easy *easy,      /* easy handle */
         m->socket.events = socketcb2poll(what);
         m->socket.events = socketcb2poll(what);
         m->socket.revents = 0;
         m->socket.revents = 0;
         ev->list = m;
         ev->list = m;
-        infof(easy, "socket cb: socket %" FMT_SOCKET_T " ADDED as %s%s", s,
-              (what&CURL_POLL_IN)?"IN":"",
-              (what&CURL_POLL_OUT)?"OUT":"");
+        infof(data, "socket cb: socket %" FMT_SOCKET_T " ADDED as %s%s", s,
+              (what&CURL_POLL_IN) ? "IN" : "",
+              (what&CURL_POLL_OUT) ? "OUT" : "");
       }
       }
       else
       else
         return CURLE_OUT_OF_MEMORY;
         return CURLE_OUT_OF_MEMORY;
@@ -617,7 +618,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
       DEBUGASSERT(data);
       DEBUGASSERT(data);
 
 
       /* loop over the monitored sockets to see which ones had activity */
       /* loop over the monitored sockets to see which ones had activity */
-      for(i = 0; i< numfds; i++) {
+      for(i = 0; i < numfds; i++) {
         if(fds[i].revents) {
         if(fds[i].revents) {
           /* socket activity, tell libcurl */
           /* socket activity, tell libcurl */
           int act = poll2cselect(fds[i].revents); /* convert */
           int act = poll2cselect(fds[i].revents); /* convert */
@@ -809,7 +810,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
  * curl_easy_perform() is the external interface that performs a blocking
  * curl_easy_perform() is the external interface that performs a blocking
  * transfer as previously setup.
  * transfer as previously setup.
  */
  */
-CURLcode curl_easy_perform(struct Curl_easy *data)
+CURLcode curl_easy_perform(CURL *data)
 {
 {
   return easy_perform(data, FALSE);
   return easy_perform(data, FALSE);
 }
 }
@@ -830,8 +831,9 @@ CURLcode curl_easy_perform_ev(struct Curl_easy *data)
  * curl_easy_cleanup() is the external interface to cleaning/freeing the given
  * curl_easy_cleanup() is the external interface to cleaning/freeing the given
  * easy handle.
  * easy handle.
  */
  */
-void curl_easy_cleanup(struct Curl_easy *data)
+void curl_easy_cleanup(CURL *ptr)
 {
 {
+  struct Curl_easy *data = ptr;
   if(GOOD_EASY_HANDLE(data)) {
   if(GOOD_EASY_HANDLE(data)) {
     SIGPIPE_VARIABLE(pipe_st);
     SIGPIPE_VARIABLE(pipe_st);
     sigpipe_ignore(data, &pipe_st);
     sigpipe_ignore(data, &pipe_st);
@@ -845,7 +847,7 @@ void curl_easy_cleanup(struct Curl_easy *data)
  * information from a performed transfer and similar.
  * information from a performed transfer and similar.
  */
  */
 #undef curl_easy_getinfo
 #undef curl_easy_getinfo
-CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
+CURLcode curl_easy_getinfo(CURL *data, CURLINFO info, ...)
 {
 {
   va_list arg;
   va_list arg;
   void *paramp;
   void *paramp;
@@ -877,7 +879,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
   memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *));
   memset(dst->set.blobs, 0, BLOB_LAST * sizeof(struct curl_blob *));
 
 
   /* duplicate all strings */
   /* duplicate all strings */
-  for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
+  for(i = (enum dupstring)0; i < STRING_LASTZEROTERMINATED; i++) {
     result = Curl_setstropt(&dst->set.str[i], src->set.str[i]);
     result = Curl_setstropt(&dst->set.str[i], src->set.str[i]);
     if(result)
     if(result)
       return result;
       return result;
@@ -919,8 +921,9 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
  * given input easy handle. The returned handle will be a new working handle
  * given input easy handle. The returned handle will be a new working handle
  * with all options set exactly as the input source handle.
  * with all options set exactly as the input source handle.
  */
  */
-struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
+CURL *curl_easy_duphandle(CURL *d)
 {
 {
+  struct Curl_easy *data = d;
   struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
   struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
   if(!outcurl)
   if(!outcurl)
     goto fail;
     goto fail;
@@ -937,6 +940,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
     goto fail;
     goto fail;
 
 
   Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
   Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
+  Curl_netrc_init(&outcurl->state.netrc);
 
 
   /* the connection pool is setup on demand */
   /* the connection pool is setup on demand */
   outcurl->state.lastconnect_id = -1;
   outcurl->state.lastconnect_id = -1;
@@ -1066,8 +1070,9 @@ fail:
  * curl_easy_reset() is an external interface that allows an app to re-
  * curl_easy_reset() is an external interface that allows an app to re-
  * initialize a session handle to the default values.
  * initialize a session handle to the default values.
  */
  */
-void curl_easy_reset(struct Curl_easy *data)
+void curl_easy_reset(CURL *d)
 {
 {
+  struct Curl_easy *data = d;
   Curl_req_hard_reset(&data->req, data);
   Curl_req_hard_reset(&data->req, data);
 
 
   /* zero out UserDefined data: */
   /* zero out UserDefined data: */
@@ -1107,7 +1112,7 @@ void curl_easy_reset(struct Curl_easy *data)
  * NOTE: This is one of few API functions that are allowed to be called from
  * NOTE: This is one of few API functions that are allowed to be called from
  * within a callback.
  * within a callback.
  */
  */
-CURLcode curl_easy_pause(struct Curl_easy *data, int action)
+CURLcode curl_easy_pause(CURL *d, int action)
 {
 {
   struct SingleRequest *k;
   struct SingleRequest *k;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
@@ -1115,6 +1120,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
   int newstate;
   int newstate;
   bool recursive = FALSE;
   bool recursive = FALSE;
   bool keep_changed, unpause_read, not_all_paused;
   bool keep_changed, unpause_read, not_all_paused;
+  struct Curl_easy *data = d;
 
 
   if(!GOOD_EASY_HANDLE(data) || !data->conn)
   if(!GOOD_EASY_HANDLE(data) || !data->conn)
     /* crazy input, do not continue */
     /* crazy input, do not continue */
@@ -1127,8 +1133,8 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
 
 
   /* first switch off both pause bits then set the new pause bits */
   /* first switch off both pause bits then set the new pause bits */
   newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) |
   newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) |
-    ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
-    ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
+    ((action & CURLPAUSE_RECV) ? KEEP_RECV_PAUSE : 0) |
+    ((action & CURLPAUSE_SEND) ? KEEP_SEND_PAUSE : 0);
 
 
   keep_changed = ((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) != oldstate);
   keep_changed = ((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) != oldstate);
   not_all_paused = (newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
   not_all_paused = (newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
@@ -1218,12 +1224,12 @@ static CURLcode easy_connection(struct Curl_easy *data,
  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
  * Returns CURLE_OK on success, error code on error.
  * Returns CURLE_OK on success, error code on error.
  */
  */
-CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
-                        size_t *n)
+CURLcode curl_easy_recv(CURL *d, void *buffer, size_t buflen, size_t *n)
 {
 {
   CURLcode result;
   CURLcode result;
   ssize_t n1;
   ssize_t n1;
   struct connectdata *c;
   struct connectdata *c;
+  struct Curl_easy *data = d;
 
 
   if(Curl_is_in_callback(data))
   if(Curl_is_in_callback(data))
     return CURLE_RECURSIVE_API_CALL;
     return CURLE_RECURSIVE_API_CALL;
@@ -1247,7 +1253,7 @@ CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
-#ifdef USE_WEBSOCKETS
+#ifndef CURL_DISABLE_WEBSOCKETS
 CURLcode Curl_connect_only_attach(struct Curl_easy *data)
 CURLcode Curl_connect_only_attach(struct Curl_easy *data)
 {
 {
   CURLcode result;
   CURLcode result;
@@ -1264,7 +1270,7 @@ CURLcode Curl_connect_only_attach(struct Curl_easy *data)
 
 
   return CURLE_OK;
   return CURLE_OK;
 }
 }
-#endif /* USE_WEBSOCKETS */
+#endif /* !CURL_DISABLE_WEBSOCKETS */
 
 
 /*
 /*
  * Sends data over the connected socket.
  * Sends data over the connected socket.
@@ -1301,11 +1307,11 @@ CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer,
  * Sends data over the connected socket. Use after successful
  * Sends data over the connected socket. Use after successful
  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
  * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
  */
  */
-CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
-                        size_t buflen, size_t *n)
+CURLcode curl_easy_send(CURL *d, const void *buffer, size_t buflen, size_t *n)
 {
 {
   size_t written = 0;
   size_t written = 0;
   CURLcode result;
   CURLcode result;
+  struct Curl_easy *data = d;
   if(Curl_is_in_callback(data))
   if(Curl_is_in_callback(data))
     return CURLE_RECURSIVE_API_CALL;
     return CURLE_RECURSIVE_API_CALL;
 
 
@@ -1317,8 +1323,9 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
 /*
 /*
  * Performs connection upkeep for the given session handle.
  * Performs connection upkeep for the given session handle.
  */
  */
-CURLcode curl_easy_upkeep(struct Curl_easy *data)
+CURLcode curl_easy_upkeep(CURL *d)
 {
 {
+  struct Curl_easy *data = d;
   /* Verify that we got an easy handle we can work with. */
   /* Verify that we got an easy handle we can work with. */
   if(!GOOD_EASY_HANDLE(data))
   if(!GOOD_EASY_HANDLE(data))
     return CURLE_BAD_FUNCTION_ARGUMENT;
     return CURLE_BAD_FUNCTION_ARGUMENT;

+ 1 - 1
lib/easyif.h

@@ -30,7 +30,7 @@
 CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer,
 CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer,
                        size_t buflen, size_t *n);
                        size_t buflen, size_t *n);
 
 
-#ifdef USE_WEBSOCKETS
+#ifndef CURL_DISABLE_WEBSOCKETS
 CURLcode Curl_connect_only_attach(struct Curl_easy *data);
 CURLcode Curl_connect_only_attach(struct Curl_easy *data);
 #endif
 #endif
 
 

+ 8 - 6
lib/escape.c

@@ -29,6 +29,8 @@
 
 
 #include <curl/curl.h>
 #include <curl/curl.h>
 
 
+struct Curl_easy;
+
 #include "urldata.h"
 #include "urldata.h"
 #include "warnless.h"
 #include "warnless.h"
 #include "escape.h"
 #include "escape.h"
@@ -53,7 +55,7 @@ char *curl_unescape(const char *string, int length)
 /* Escapes for URL the given unescaped string of given length.
 /* Escapes for URL the given unescaped string of given length.
  * 'data' is ignored since 7.82.0.
  * 'data' is ignored since 7.82.0.
  */
  */
-char *curl_easy_escape(struct Curl_easy *data, const char *string,
+char *curl_easy_escape(CURL *data, const char *string,
                        int inlength)
                        int inlength)
 {
 {
   size_t length;
   size_t length;
@@ -63,7 +65,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
   if(!string || (inlength < 0))
   if(!string || (inlength < 0))
     return NULL;
     return NULL;
 
 
-  length = (inlength?(size_t)inlength:strlen(string));
+  length = (inlength ? (size_t)inlength : strlen(string));
   if(!length)
   if(!length)
     return strdup("");
     return strdup("");
 
 
@@ -82,7 +84,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
       /* encode it */
       /* encode it */
       const char hex[] = "0123456789ABCDEF";
       const char hex[] = "0123456789ABCDEF";
       char out[3]={'%'};
       char out[3]={'%'};
-      out[1] = hex[in>>4];
+      out[1] = hex[in >> 4];
       out[2] = hex[in & 0xf];
       out[2] = hex[in & 0xf];
       if(Curl_dyn_addn(&d, out, 3))
       if(Curl_dyn_addn(&d, out, 3))
         return NULL;
         return NULL;
@@ -128,7 +130,7 @@ CURLcode Curl_urldecode(const char *string, size_t length,
   DEBUGASSERT(string);
   DEBUGASSERT(string);
   DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */
   DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */
 
 
-  alloc = (length?length:strlen(string));
+  alloc = (length ? length : strlen(string));
   ns = malloc(alloc + 1);
   ns = malloc(alloc + 1);
 
 
   if(!ns)
   if(!ns)
@@ -176,7 +178,7 @@ CURLcode Curl_urldecode(const char *string, size_t length,
  * If olen == NULL, no output length is stored.
  * If olen == NULL, no output length is stored.
  * 'data' is ignored since 7.82.0.
  * 'data' is ignored since 7.82.0.
  */
  */
-char *curl_easy_unescape(struct Curl_easy *data, const char *string,
+char *curl_easy_unescape(CURL *data, const char *string,
                          int length, int *olen)
                          int length, int *olen)
 {
 {
   char *str = NULL;
   char *str = NULL;
@@ -223,7 +225,7 @@ void Curl_hexencode(const unsigned char *src, size_t len, /* input length */
     while(len-- && (olen >= 3)) {
     while(len-- && (olen >= 3)) {
       /* clang-tidy warns on this line without this comment: */
       /* clang-tidy warns on this line without this comment: */
       /* NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult) */
       /* NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult) */
-      *out++ = (unsigned char)hex[(*src & 0xF0)>>4];
+      *out++ = (unsigned char)hex[(*src & 0xF0) >> 4];
       *out++ = (unsigned char)hex[*src & 0x0F];
       *out++ = (unsigned char)hex[*src & 0x0F];
       ++src;
       ++src;
       olen -= 2;
       olen -= 2;

+ 1 - 1
lib/file.c

@@ -489,7 +489,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
     headerlen =
     headerlen =
       msnprintf(header, sizeof(header),
       msnprintf(header, sizeof(header),
                 "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
                 "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
-                Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+                Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6],
                 tm->tm_mday,
                 tm->tm_mday,
                 Curl_month[tm->tm_mon],
                 Curl_month[tm->tm_mon],
                 tm->tm_year + 1900,
                 tm->tm_year + 1900,

+ 26 - 22
lib/formdata.c

@@ -26,6 +26,8 @@
 
 
 #include <curl/curl.h>
 #include <curl/curl.h>
 
 
+struct Curl_easy;
+
 #include "formdata.h"
 #include "formdata.h"
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API)
 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API)
 
 
@@ -282,8 +284,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       if(current_form->name)
       if(current_form->name)
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else {
       else {
-        char *name = array_state?
-          array_value:va_arg(params, char *);
+        char *name = array_state ?
+          array_value : va_arg(params, char *);
         if(name)
         if(name)
           current_form->name = name; /* store for the moment */
           current_form->name = name; /* store for the moment */
         else
         else
@@ -295,7 +297,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else
       else
         current_form->namelength =
         current_form->namelength =
-          array_state?(size_t)array_value:(size_t)va_arg(params, long);
+          array_state ? (size_t)array_value : (size_t)va_arg(params, long);
       break;
       break;
 
 
       /*
       /*
@@ -309,7 +311,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else {
       else {
         char *value =
         char *value =
-          array_state?array_value:va_arg(params, char *);
+          array_state ? array_value : va_arg(params, char *);
         if(value)
         if(value)
           current_form->value = value; /* store for the moment */
           current_form->value = value; /* store for the moment */
         else
         else
@@ -318,13 +320,14 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       break;
       break;
     case CURLFORM_CONTENTSLENGTH:
     case CURLFORM_CONTENTSLENGTH:
       current_form->contentslength =
       current_form->contentslength =
-        array_state?(size_t)array_value:(size_t)va_arg(params, long);
+        array_state ? (size_t)array_value : (size_t)va_arg(params, long);
       break;
       break;
 
 
     case CURLFORM_CONTENTLEN:
     case CURLFORM_CONTENTLEN:
       current_form->flags |= CURL_HTTPPOST_LARGE;
       current_form->flags |= CURL_HTTPPOST_LARGE;
       current_form->contentslength =
       current_form->contentslength =
-        array_state?(curl_off_t)(size_t)array_value:va_arg(params, curl_off_t);
+        array_state ? (curl_off_t)(size_t)array_value :
+        va_arg(params, curl_off_t);
       break;
       break;
 
 
       /* Get contents from a given filename */
       /* Get contents from a given filename */
@@ -332,8 +335,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
       if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else {
       else {
-        const char *filename = array_state?
-          array_value:va_arg(params, char *);
+        const char *filename = array_state ?
+          array_value : va_arg(params, char *);
         if(filename) {
         if(filename) {
           current_form->value = strdup(filename);
           current_form->value = strdup(filename);
           if(!current_form->value)
           if(!current_form->value)
@@ -351,7 +354,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       /* We upload a file */
       /* We upload a file */
     case CURLFORM_FILE:
     case CURLFORM_FILE:
       {
       {
-        const char *filename = array_state?array_value:
+        const char *filename = array_state ? array_value :
           va_arg(params, char *);
           va_arg(params, char *);
 
 
         if(current_form->value) {
         if(current_form->value) {
@@ -401,7 +404,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else {
       else {
         char *buffer =
         char *buffer =
-          array_state?array_value:va_arg(params, char *);
+          array_state ? array_value : va_arg(params, char *);
         if(buffer) {
         if(buffer) {
           current_form->buffer = buffer; /* store for the moment */
           current_form->buffer = buffer; /* store for the moment */
           current_form->value = buffer; /* make it non-NULL to be accepted
           current_form->value = buffer; /* make it non-NULL to be accepted
@@ -417,7 +420,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else
       else
         current_form->bufferlength =
         current_form->bufferlength =
-          array_state?(size_t)array_value:(size_t)va_arg(params, long);
+          array_state ? (size_t)array_value : (size_t)va_arg(params, long);
       break;
       break;
 
 
     case CURLFORM_STREAM:
     case CURLFORM_STREAM:
@@ -426,7 +429,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
         return_value = CURL_FORMADD_OPTION_TWICE;
         return_value = CURL_FORMADD_OPTION_TWICE;
       else {
       else {
         char *userp =
         char *userp =
-          array_state?array_value:va_arg(params, char *);
+          array_state ? array_value : va_arg(params, char *);
         if(userp) {
         if(userp) {
           current_form->userp = userp;
           current_form->userp = userp;
           current_form->value = userp; /* this is not strictly true but we
           current_form->value = userp; /* this is not strictly true but we
@@ -442,7 +445,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
     case CURLFORM_CONTENTTYPE:
     case CURLFORM_CONTENTTYPE:
       {
       {
         const char *contenttype =
         const char *contenttype =
-          array_state?array_value:va_arg(params, char *);
+          array_state ? array_value : va_arg(params, char *);
         if(current_form->contenttype) {
         if(current_form->contenttype) {
           if(current_form->flags & HTTPPOST_FILENAME) {
           if(current_form->flags & HTTPPOST_FILENAME) {
             if(contenttype) {
             if(contenttype) {
@@ -485,8 +488,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       {
       {
         /* this "cast increases required alignment of target type" but
         /* this "cast increases required alignment of target type" but
            we consider it OK anyway */
            we consider it OK anyway */
-        struct curl_slist *list = array_state?
-          (struct curl_slist *)(void *)array_value:
+        struct curl_slist *list = array_state ?
+          (struct curl_slist *)(void *)array_value :
           va_arg(params, struct curl_slist *);
           va_arg(params, struct curl_slist *);
 
 
         if(current_form->contentheader)
         if(current_form->contentheader)
@@ -499,7 +502,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
     case CURLFORM_FILENAME:
     case CURLFORM_FILENAME:
     case CURLFORM_BUFFER:
     case CURLFORM_BUFFER:
       {
       {
-        const char *filename = array_state?array_value:
+        const char *filename = array_state ? array_value :
           va_arg(params, char *);
           va_arg(params, char *);
         if(current_form->showfilename)
         if(current_form->showfilename)
           return_value = CURL_FORMADD_OPTION_TWICE;
           return_value = CURL_FORMADD_OPTION_TWICE;
@@ -569,7 +572,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
       if(((form->flags & HTTPPOST_FILENAME) ||
       if(((form->flags & HTTPPOST_FILENAME) ||
           (form->flags & HTTPPOST_BUFFER)) &&
           (form->flags & HTTPPOST_BUFFER)) &&
          !form->contenttype) {
          !form->contenttype) {
-        char *f = (form->flags & HTTPPOST_BUFFER)?
+        char *f = (form->flags & HTTPPOST_BUFFER) ?
           form->showfilename : form->value;
           form->showfilename : form->value;
         char const *type;
         char const *type;
         type = Curl_mime_contenttype(f);
         type = Curl_mime_contenttype(f);
@@ -603,8 +606,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
            app passed in a bad combo, so we better check for that first. */
            app passed in a bad combo, so we better check for that first. */
         if(form->name) {
         if(form->name) {
           /* copy name (without strdup; possibly not null-terminated) */
           /* copy name (without strdup; possibly not null-terminated) */
-          form->name = Curl_memdup0(form->name, form->namelength?
-                                    form->namelength:
+          form->name = Curl_memdup0(form->name, form->namelength ?
+                                    form->namelength :
                                     strlen(form->name));
                                     strlen(form->name));
         }
         }
         if(!form->name) {
         if(!form->name) {
@@ -790,7 +793,7 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
 /* wrap call to fseeko so it matches the calling convention of callback */
 /* wrap call to fseeko so it matches the calling convention of callback */
 static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
 static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
 {
 {
-#if defined(HAVE__FSEEKI64)
+#if defined(_WIN32) && defined(USE_WIN32_LARGE_FILES)
   return _fseeki64(stream, (__int64)offset, whence);
   return _fseeki64(stream, (__int64)offset, whence);
 #elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
 #elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
   return fseeko(stream, (off_t)offset, whence);
   return fseeko(stream, (off_t)offset, whence);
@@ -811,7 +814,7 @@ static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
  * a NULL pointer in the 'data' argument.
  * a NULL pointer in the 'data' argument.
  */
  */
 
 
-CURLcode Curl_getformdata(struct Curl_easy *data,
+CURLcode Curl_getformdata(CURL *data,
                           curl_mimepart *finalform,
                           curl_mimepart *finalform,
                           struct curl_httppost *post,
                           struct curl_httppost *post,
                           curl_read_callback fread_func)
                           curl_read_callback fread_func)
@@ -896,7 +899,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
         }
         }
         else if(post->flags & HTTPPOST_BUFFER)
         else if(post->flags & HTTPPOST_BUFFER)
           result = curl_mime_data(part, post->buffer,
           result = curl_mime_data(part, post->buffer,
-                                  post->bufferlength? post->bufferlength: -1);
+                                  post->bufferlength ?
+                                  post->bufferlength : -1);
         else if(post->flags & HTTPPOST_CALLBACK) {
         else if(post->flags & HTTPPOST_CALLBACK) {
           /* the contents should be read with the callback and the size is set
           /* the contents should be read with the callback and the size is set
              with the contentslength */
              with the contentslength */

+ 1 - 1
lib/formdata.h

@@ -49,7 +49,7 @@ struct FormInfo {
   bool showfilename_alloc;
   bool showfilename_alloc;
 };
 };
 
 
-CURLcode Curl_getformdata(struct Curl_easy *data,
+CURLcode Curl_getformdata(CURL *data,
                           curl_mimepart *,
                           curl_mimepart *,
                           struct curl_httppost *post,
                           struct curl_httppost *post,
                           curl_read_callback fread_func);
                           curl_read_callback fread_func);

+ 129 - 293
lib/ftp.c

@@ -302,10 +302,10 @@ static void close_secondarysocket(struct Curl_easy *data)
  * requests on files respond with headers passed to the client/stdout that
  * requests on files respond with headers passed to the client/stdout that
  * looked like HTTP ones.
  * looked like HTTP ones.
  *
  *
- * This approach is not very elegant, it causes confusion and is error-prone.
- * It is subject for removal at the next (or at least a future) soname bump.
- * Until then you can test the effects of the removal by undefining the
- * following define named CURL_FTP_HTTPSTYLE_HEAD.
+ * This approach is not elegant, it causes confusion and is error-prone. It is
+ * subject for removal at the next (or at least a future) soname bump. Until
+ * then you can test the effects of the removal by undefining the following
+ * define named CURL_FTP_HTTPSTYLE_HEAD.
  */
  */
 #define CURL_FTP_HTTPSTYLE_HEAD 1
 #define CURL_FTP_HTTPSTYLE_HEAD 1
 
 
@@ -419,138 +419,19 @@ static const struct Curl_cwtype ftp_cw_lc = {
 #endif /* CURL_PREFER_LF_LINEENDS */
 #endif /* CURL_PREFER_LF_LINEENDS */
 /***********************************************************************
 /***********************************************************************
  *
  *
- * AcceptServerConnect()
- *
- * After connection request is received from the server this function is
- * called to accept the connection and close the listening socket
- *
- */
-static CURLcode AcceptServerConnect(struct Curl_easy *data)
-{
-  struct connectdata *conn = data->conn;
-  curl_socket_t sock = conn->sock[SECONDARYSOCKET];
-  curl_socket_t s = CURL_SOCKET_BAD;
-#ifdef USE_IPV6
-  struct Curl_sockaddr_storage add;
-#else
-  struct sockaddr_in add;
-#endif
-  curl_socklen_t size = (curl_socklen_t) sizeof(add);
-  CURLcode result;
-
-  if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
-    size = sizeof(add);
-
-    s = accept(sock, (struct sockaddr *) &add, &size);
-  }
-
-  if(CURL_SOCKET_BAD == s) {
-    failf(data, "Error accept()ing server connect");
-    return CURLE_FTP_PORT_FAILED;
-  }
-  infof(data, "Connection accepted from server");
-  /* when this happens within the DO state it is important that we mark us as
-     not needing DO_MORE anymore */
-  conn->bits.do_more = FALSE;
-
-  (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
-  /* Replace any filter on SECONDARY with one listening on this socket */
-  result = Curl_conn_tcp_accepted_set(data, conn, SECONDARYSOCKET, &s);
-  if(result) {
-    sclose(s);
-    return result;
-  }
-
-  if(data->set.fsockopt) {
-    int error = 0;
-
-    /* activate callback for setting socket options */
-    Curl_set_in_callback(data, true);
-    error = data->set.fsockopt(data->set.sockopt_client,
-                               s,
-                               CURLSOCKTYPE_ACCEPT);
-    Curl_set_in_callback(data, false);
-
-    if(error) {
-      close_secondarysocket(data);
-      return CURLE_ABORTED_BY_CALLBACK;
-    }
-  }
-
-  return CURLE_OK;
-
-}
-
-/*
- * ftp_timeleft_accept() returns the amount of milliseconds left allowed for
- * waiting server to connect. If the value is negative, the timeout time has
- * already elapsed.
- *
- * The start time is stored in progress.t_acceptdata - as set with
- * Curl_pgrsTime(..., TIMER_STARTACCEPT);
- *
- */
-static timediff_t ftp_timeleft_accept(struct Curl_easy *data)
-{
-  timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
-  timediff_t other;
-  struct curltime now;
-
-  if(data->set.accepttimeout > 0)
-    timeout_ms = data->set.accepttimeout;
-
-  now = Curl_now();
-
-  /* check if the generic timeout possibly is set shorter */
-  other = Curl_timeleft(data, &now, FALSE);
-  if(other && (other < timeout_ms))
-    /* note that this also works fine for when other happens to be negative
-       due to it already having elapsed */
-    timeout_ms = other;
-  else {
-    /* subtract elapsed time */
-    timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata);
-    if(!timeout_ms)
-      /* avoid returning 0 as that means no timeout! */
-      return -1;
-  }
-
-  return timeout_ms;
-}
-
-
-/***********************************************************************
- *
- * ReceivedServerConnect()
- *
- * After allowing server to connect to us from data port, this function
- * checks both data connection for connection establishment and ctrl
- * connection for a negative response regarding a failure in connecting
+ * ftp_check_ctrl_on_data_wait()
  *
  *
  */
  */
-static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
+static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data)
 {
 {
   struct connectdata *conn = data->conn;
   struct connectdata *conn = data->conn;
   curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
   curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
-  curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct pingpong *pp = &ftpc->pp;
   struct pingpong *pp = &ftpc->pp;
-  int socketstate = 0;
-  timediff_t timeout_ms;
   ssize_t nread;
   ssize_t nread;
   int ftpcode;
   int ftpcode;
   bool response = FALSE;
   bool response = FALSE;
 
 
-  *received = FALSE;
-
-  timeout_ms = ftp_timeleft_accept(data);
-  infof(data, "Checking for server connect");
-  if(timeout_ms < 0) {
-    /* if a timeout was already reached, bail out */
-    failf(data, "Accept timeout occurred while waiting server connect");
-    return CURLE_FTP_ACCEPT_TIMEOUT;
-  }
-
   /* First check whether there is a cached response from server */
   /* First check whether there is a cached response from server */
   if(Curl_dyn_len(&pp->recvbuf) && (*Curl_dyn_ptr(&pp->recvbuf) > '3')) {
   if(Curl_dyn_len(&pp->recvbuf) && (*Curl_dyn_ptr(&pp->recvbuf) > '3')) {
     /* Data connection could not be established, let's return */
     /* Data connection could not be established, let's return */
@@ -562,26 +443,22 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
   if(pp->overflow)
   if(pp->overflow)
     /* there is pending control data still in the buffer to read */
     /* there is pending control data still in the buffer to read */
     response = TRUE;
     response = TRUE;
-  else
-    socketstate = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
-
-  /* see if the connection request is already here */
-  switch(socketstate) {
-  case -1: /* error */
-    /* let's die here */
-    failf(data, "Error while waiting for server connect");
-    return CURLE_FTP_ACCEPT_FAILED;
-  case 0:  /* Server connect is not received yet */
-    break; /* loop */
-  default:
-    if(socketstate & CURL_CSELECT_IN2) {
-      infof(data, "Ready to accept data connection from server");
-      *received = TRUE;
+  else {
+    int socketstate = Curl_socket_check(ctrl_sock, CURL_SOCKET_BAD,
+                                        CURL_SOCKET_BAD, 0);
+    /* see if the connection request is already here */
+    switch(socketstate) {
+    case -1: /* error */
+      /* let's die here */
+      failf(data, "Error while waiting for server connect");
+      return CURLE_FTP_ACCEPT_FAILED;
+    default:
+      if(socketstate & CURL_CSELECT_IN)
+        response = TRUE;
+      break;
     }
     }
-    else if(socketstate & CURL_CSELECT_IN)
-      response = TRUE;
-    break;
   }
   }
+
   if(response) {
   if(response) {
     infof(data, "Ctrl conn has data while waiting for data conn");
     infof(data, "Ctrl conn has data while waiting for data conn");
     if(pp->overflow > 3) {
     if(pp->overflow > 3) {
@@ -600,7 +477,6 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
              noticed. Leave the 226 in there and use this as a trigger to read
              noticed. Leave the 226 in there and use this as a trigger to read
              the data socket. */
              the data socket. */
           infof(data, "Got 226 before data activity");
           infof(data, "Got 226 before data activity");
-          *received = TRUE;
           return CURLE_OK;
           return CURLE_OK;
         }
         }
       }
       }
@@ -619,7 +495,6 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
-
 /***********************************************************************
 /***********************************************************************
  *
  *
  * InitiateTransfer()
  * InitiateTransfer()
@@ -635,12 +510,6 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
   bool connected;
   bool connected;
 
 
   CURL_TRC_FTP(data, "InitiateTransfer()");
   CURL_TRC_FTP(data, "InitiateTransfer()");
-  if(conn->bits.ftp_use_data_ssl && data->set.ftp_use_port &&
-     !Curl_conn_is_ssl(conn, SECONDARYSOCKET)) {
-    result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET);
-    if(result)
-      return result;
-  }
   result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &connected);
   result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &connected);
   if(result || !connected)
   if(result || !connected)
     return result;
     return result;
@@ -653,12 +522,14 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
     /* set the SO_SNDBUF for the secondary socket for those who need it */
     /* set the SO_SNDBUF for the secondary socket for those who need it */
     Curl_sndbuf_init(conn->sock[SECONDARYSOCKET]);
     Curl_sndbuf_init(conn->sock[SECONDARYSOCKET]);
 
 
-    Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE);
+    /* FTP upload, shutdown DATA, ignore shutdown errors, as we rely
+     * on the server response on the CONTROL connection. */
+    Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE, TRUE);
   }
   }
   else {
   else {
-    /* FTP download: */
+    /* FTP download, shutdown, do not ignore errors */
     Curl_xfer_setup2(data, CURL_XFER_RECV,
     Curl_xfer_setup2(data, CURL_XFER_RECV,
-                     conn->proto.ftpc.retr_size_saved, TRUE);
+                     conn->proto.ftpc.retr_size_saved, TRUE, FALSE);
   }
   }
 
 
   conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
   conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
@@ -667,60 +538,6 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
-/***********************************************************************
- *
- * AllowServerConnect()
- *
- * When we have issue the PORT command, we have told the server to connect to
- * us. This function checks whether data connection is established if so it is
- * accepted.
- *
- */
-static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected)
-{
-  timediff_t timeout_ms;
-  CURLcode result = CURLE_OK;
-
-  *connected = FALSE;
-  infof(data, "Preparing for accepting server on data port");
-
-  /* Save the time we start accepting server connect */
-  Curl_pgrsTime(data, TIMER_STARTACCEPT);
-
-  timeout_ms = ftp_timeleft_accept(data);
-  if(timeout_ms < 0) {
-    /* if a timeout was already reached, bail out */
-    failf(data, "Accept timeout occurred while waiting server connect");
-    result = CURLE_FTP_ACCEPT_TIMEOUT;
-    goto out;
-  }
-
-  /* see if the connection request is already here */
-  result = ReceivedServerConnect(data, connected);
-  if(result)
-    goto out;
-
-  if(*connected) {
-    result = AcceptServerConnect(data);
-    if(result)
-      goto out;
-
-    result = InitiateTransfer(data);
-    if(result)
-      goto out;
-  }
-  else {
-    /* Add timeout to multi handle and break out of the loop */
-    Curl_expire(data, data->set.accepttimeout ?
-                data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT,
-                EXPIRE_FTP_ACCEPT);
-  }
-
-out:
-  CURL_TRC_FTP(data, "AllowServerConnect() -> %d", result);
-  return result;
-}
-
 static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn,
 static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn,
                           char *line, size_t len, int *code)
                           char *line, size_t len, int *code)
 {
 {
@@ -864,8 +681,8 @@ CURLcode Curl_GetFTPResponse(struct Curl_easy *data,
        */
        */
     }
     }
     else if(!Curl_conn_data_pending(data, FIRSTSOCKET)) {
     else if(!Curl_conn_data_pending(data, FIRSTSOCKET)) {
-      curl_socket_t wsock = Curl_pp_needs_flush(data, pp)?
-                            sockfd : CURL_SOCKET_BAD;
+      curl_socket_t wsock = Curl_pp_needs_flush(data, pp) ?
+        sockfd : CURL_SOCKET_BAD;
       int ev = Curl_socket_check(sockfd, CURL_SOCKET_BAD, wsock, interval_ms);
       int ev = Curl_socket_check(sockfd, CURL_SOCKET_BAD, wsock, interval_ms);
       if(ev < 0) {
       if(ev < 0) {
         failf(data, "FTP response aborted due to select/poll error: %d",
         failf(data, "FTP response aborted due to select/poll error: %d",
@@ -914,7 +731,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
 {
 {
   CURLcode result = Curl_pp_sendf(data,
   CURLcode result = Curl_pp_sendf(data,
                                   &conn->proto.ftpc.pp, "USER %s",
                                   &conn->proto.ftpc.pp, "USER %s",
-                                  conn->user?conn->user:"");
+                                  conn->user ? conn->user : "");
   if(!result) {
   if(!result) {
     struct ftp_conn *ftpc = &conn->proto.ftpc;
     struct ftp_conn *ftpc = &conn->proto.ftpc;
     ftpc->ftp_trying_alternative = FALSE;
     ftpc->ftp_trying_alternative = FALSE;
@@ -1138,7 +955,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
       /* attempt to get the address of the given interface name */
       /* attempt to get the address of the given interface name */
       switch(Curl_if2ip(conn->remote_addr->family,
       switch(Curl_if2ip(conn->remote_addr->family,
 #ifdef USE_IPV6
 #ifdef USE_IPV6
-                        Curl_ipv6_scope(&conn->remote_addr->sa_addr),
+                        Curl_ipv6_scope(&conn->remote_addr->curl_sa_addr),
                         conn->scope_id,
                         conn->scope_id,
 #endif
 #endif
                         ipstr, hbuf, sizeof(hbuf))) {
                         ipstr, hbuf, sizeof(hbuf))) {
@@ -1304,12 +1121,6 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
     conn->bits.ftp_use_eprt = TRUE;
     conn->bits.ftp_use_eprt = TRUE;
 #endif
 #endif
 
 
-  /* Replace any filter on SECONDARY with one listening on this socket */
-  result = Curl_conn_tcp_listen_set(data, conn, SECONDARYSOCKET, &portsock);
-  if(result)
-    goto out;
-  portsock = CURL_SOCKET_BAD; /* now held in filter */
-
   for(; fcmd != DONE; fcmd++) {
   for(; fcmd != DONE; fcmd++) {
 
 
     if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
     if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
@@ -1343,7 +1154,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
        */
        */
 
 
       result = Curl_pp_sendf(data, &ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
       result = Curl_pp_sendf(data, &ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
-                             sa->sa_family == AF_INET?1:2,
+                             sa->sa_family == AF_INET ? 1 : 2,
                              myhost, port);
                              myhost, port);
       if(result) {
       if(result) {
         failf(data, "Failure sending EPRT command: %s",
         failf(data, "Failure sending EPRT command: %s",
@@ -1368,7 +1179,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
         source++;
         source++;
       }
       }
       *dest = 0;
       *dest = 0;
-      msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
+      msnprintf(dest, 20, ",%d,%d", (int)(port >> 8), (int)(port & 0xff));
 
 
       result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target);
       result = Curl_pp_sendf(data, &ftpc->pp, "%s %s", mode[fcmd], target);
       if(result) {
       if(result) {
@@ -1382,9 +1193,13 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
 
 
   /* store which command was sent */
   /* store which command was sent */
   ftpc->count1 = fcmd;
   ftpc->count1 = fcmd;
-
   ftp_state(data, FTP_PORT);
   ftp_state(data, FTP_PORT);
 
 
+  /* Replace any filter on SECONDARY with one listening on this socket */
+  result = Curl_conn_tcp_listen_set(data, conn, SECONDARYSOCKET, &portsock);
+  if(!result)
+    portsock = CURL_SOCKET_BAD; /* now held in filter */
+
 out:
 out:
   /* If we looked up a dns_entry, now is the time to safely release it */
   /* If we looked up a dns_entry, now is the time to safely release it */
   if(dns_entry)
   if(dns_entry)
@@ -1392,6 +1207,18 @@ out:
   if(result) {
   if(result) {
     ftp_state(data, FTP_STOP);
     ftp_state(data, FTP_STOP);
   }
   }
+  else {
+    /* successfully setup the list socket filter. Do we need more? */
+    if(conn->bits.ftp_use_data_ssl && data->set.ftp_use_port &&
+       !Curl_conn_is_ssl(conn, SECONDARYSOCKET)) {
+      result = Curl_ssl_cfilter_add(data, conn, SECONDARYSOCKET);
+    }
+    data->conn->bits.do_more = FALSE;
+    Curl_pgrsTime(data, TIMER_STARTACCEPT);
+    Curl_expire(data, data->set.accepttimeout ?
+                data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT,
+                EXPIRE_FTP_ACCEPT);
+  }
   if(portsock != CURL_SOCKET_BAD)
   if(portsock != CURL_SOCKET_BAD)
     Curl_socket_close(data, conn, portsock);
     Curl_socket_close(data, conn, portsock);
   return result;
   return result;
@@ -1426,7 +1253,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
     conn->bits.ftp_use_epsv = TRUE;
     conn->bits.ftp_use_epsv = TRUE;
 #endif
 #endif
 
 
-  modeoff = conn->bits.ftp_use_epsv?0:1;
+  modeoff = conn->bits.ftp_use_epsv ? 0 : 1;
 
 
   result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
   result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
   if(!result) {
   if(!result) {
@@ -1469,9 +1296,9 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
       struct ftp_conn *ftpc = &conn->proto.ftpc;
       struct ftp_conn *ftpc = &conn->proto.ftpc;
       if(!conn->proto.ftpc.file)
       if(!conn->proto.ftpc.file)
         result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s",
         result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s",
-                               data->set.str[STRING_CUSTOMREQUEST]?
-                               data->set.str[STRING_CUSTOMREQUEST]:
-                               (data->state.list_only?"NLST":"LIST"));
+                               data->set.str[STRING_CUSTOMREQUEST] ?
+                               data->set.str[STRING_CUSTOMREQUEST] :
+                               (data->state.list_only ? "NLST" : "LIST"));
       else if(data->state.upload)
       else if(data->state.upload)
         result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
         result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
                                conn->proto.ftpc.file);
                                conn->proto.ftpc.file);
@@ -1576,11 +1403,11 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
   }
   }
 
 
   cmd = aprintf("%s%s%s",
   cmd = aprintf("%s%s%s",
-                data->set.str[STRING_CUSTOMREQUEST]?
-                data->set.str[STRING_CUSTOMREQUEST]:
-                (data->state.list_only?"NLST":"LIST"),
-                lstArg? " ": "",
-                lstArg? lstArg: "");
+                data->set.str[STRING_CUSTOMREQUEST] ?
+                data->set.str[STRING_CUSTOMREQUEST] :
+                (data->state.list_only ? "NLST" : "LIST"),
+                lstArg ? " " : "",
+                lstArg ? lstArg : "");
   free(lstArg);
   free(lstArg);
 
 
   if(!cmd)
   if(!cmd)
@@ -1702,10 +1529,10 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
 
 
     /* Let's read off the proper amount of bytes from the input. */
     /* Let's read off the proper amount of bytes from the input. */
     if(data->set.seek_func) {
     if(data->set.seek_func) {
-      Curl_set_in_callback(data, true);
+      Curl_set_in_callback(data, TRUE);
       seekerr = data->set.seek_func(data->set.seek_client,
       seekerr = data->set.seek_func(data->set.seek_client,
                                     data->state.resume_from, SEEK_SET);
                                     data->state.resume_from, SEEK_SET);
-      Curl_set_in_callback(data, false);
+      Curl_set_in_callback(data, FALSE);
     }
     }
 
 
     if(seekerr != CURL_SEEKFUNC_OK) {
     if(seekerr != CURL_SEEKFUNC_OK) {
@@ -1736,7 +1563,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
       } while(passed < data->state.resume_from);
       } while(passed < data->state.resume_from);
     }
     }
     /* now, decrease the size of the read */
     /* now, decrease the size of the read */
-    if(data->state.infilesize>0) {
+    if(data->state.infilesize > 0) {
       data->state.infilesize -= data->state.resume_from;
       data->state.infilesize -= data->state.resume_from;
 
 
       if(data->state.infilesize <= 0) {
       if(data->state.infilesize <= 0) {
@@ -1756,7 +1583,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
     /* we have passed, proceed as normal */
     /* we have passed, proceed as normal */
   } /* resume_from */
   } /* resume_from */
 
 
-  result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s",
+  result = Curl_pp_sendf(data, &ftpc->pp, append ? "APPE %s" : "STOR %s",
                          ftpc->file);
                          ftpc->file);
   if(!result)
   if(!result)
     ftp_state(data, FTP_STOR);
     ftp_state(data, FTP_STOR);
@@ -1804,7 +1631,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
     int i = 0;
     int i = 0;
 
 
     /* Skip count1 items in the linked list */
     /* Skip count1 items in the linked list */
-    while((i< ftpc->count1) && item) {
+    while((i < ftpc->count1) && item) {
       item = item->next;
       item = item->next;
       i++;
       i++;
     }
     }
@@ -2038,7 +1865,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
     if(!ftpc->newhost)
     if(!ftpc->newhost)
       return CURLE_OUT_OF_MEMORY;
       return CURLE_OUT_OF_MEMORY;
 
 
-    ftpc->newport = (unsigned short)(((ip[4]<<8) + ip[5]) & 0xffff);
+    ftpc->newport = (unsigned short)(((ip[4] << 8) + ip[5]) & 0xffff);
   }
   }
   else if(ftpc->count1 == 0) {
   else if(ftpc->count1 == 0) {
     /* EPSV failed, move on to PASV */
     /* EPSV failed, move on to PASV */
@@ -2101,7 +1928,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
   }
   }
 
 
   result = Curl_conn_setup(data, conn, SECONDARYSOCKET, addr,
   result = Curl_conn_setup(data, conn, SECONDARYSOCKET, addr,
-                           conn->bits.ftp_use_data_ssl?
+                           conn->bits.ftp_use_data_ssl ?
                            CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
                            CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
 
 
   if(result) {
   if(result) {
@@ -2215,10 +2042,10 @@ static CURLcode client_write_header(struct Curl_easy *data,
    * headers from CONNECT should not automatically be part of the
    * headers from CONNECT should not automatically be part of the
    * output. */
    * output. */
   CURLcode result;
   CURLcode result;
-  int save = data->set.include_header;
+  bool save = data->set.include_header;
   data->set.include_header = TRUE;
   data->set.include_header = TRUE;
   result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, blen);
   result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, blen);
-  data->set.include_header = save? TRUE:FALSE;
+  data->set.include_header = save;
   return result;
   return result;
 }
 }
 
 
@@ -2267,15 +2094,16 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
           return result;
           return result;
 
 
         /* format: "Tue, 15 Nov 1994 12:45:26" */
         /* format: "Tue, 15 Nov 1994 12:45:26" */
-        headerbuflen = msnprintf(headerbuf, sizeof(headerbuf),
-                  "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
-                  Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
-                  tm->tm_mday,
-                  Curl_month[tm->tm_mon],
-                  tm->tm_year + 1900,
-                  tm->tm_hour,
-                  tm->tm_min,
-                  tm->tm_sec);
+        headerbuflen =
+          msnprintf(headerbuf, sizeof(headerbuf),
+                    "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+                    Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6],
+                    tm->tm_mday,
+                    Curl_month[tm->tm_mon],
+                    tm->tm_year + 1900,
+                    tm->tm_hour,
+                    tm->tm_min,
+                    tm->tm_sec);
         result = client_write_header(data, headerbuf, headerbuflen);
         result = client_write_header(data, headerbuf, headerbuflen);
         if(result)
         if(result)
           return result;
           return result;
@@ -2387,7 +2215,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
     else {
     else {
       /* We got a file size report, so we check that there actually is a
       /* We got a file size report, so we check that there actually is a
          part of the file left to get, or else we go home.  */
          part of the file left to get, or else we go home.  */
-      if(data->state.resume_from< 0) {
+      if(data->state.resume_from < 0) {
         /* We are supposed to download the last abs(from) bytes */
         /* We are supposed to download the last abs(from) bytes */
         if(filesize < -data->state.resume_from) {
         if(filesize < -data->state.resume_from) {
           failf(data, "Offset (%" FMT_OFF_T
           failf(data, "Offset (%" FMT_OFF_T
@@ -2562,21 +2390,21 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
 
 
   /* PORT means we are now awaiting the server to connect to us. */
   /* PORT means we are now awaiting the server to connect to us. */
   if(data->set.ftp_use_port) {
   if(data->set.ftp_use_port) {
+    struct ftp_conn *ftpc = &conn->proto.ftpc;
     bool connected;
     bool connected;
 
 
     ftp_state(data, FTP_STOP); /* no longer in STOR state */
     ftp_state(data, FTP_STOP); /* no longer in STOR state */
 
 
-    result = AllowServerConnect(data, &connected);
+    result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
     if(result)
     if(result)
       return result;
       return result;
 
 
     if(!connected) {
     if(!connected) {
-      struct ftp_conn *ftpc = &conn->proto.ftpc;
       infof(data, "Data conn was not available immediately");
       infof(data, "Data conn was not available immediately");
       ftpc->wait_data_conn = TRUE;
       ftpc->wait_data_conn = TRUE;
+      return ftp_check_ctrl_on_data_wait(data);
     }
     }
-
-    return CURLE_OK;
+    ftpc->wait_data_conn = FALSE;
   }
   }
   return InitiateTransfer(data);
   return InitiateTransfer(data);
 }
 }
@@ -2626,10 +2454,10 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
        !data->set.ignorecl &&
        !data->set.ignorecl &&
        (ftp->downloadsize < 1)) {
        (ftp->downloadsize < 1)) {
       /*
       /*
-       * It seems directory listings either do not show the size or very
-       * often uses size 0 anyway. ASCII transfers may very well turn out
-       * that the transferred amount of data is not the same as this line
-       * tells, why using this number in those cases only confuses us.
+       * It seems directory listings either do not show the size or often uses
+       * size 0 anyway. ASCII transfers may cause that the transferred amount
+       * of data is not the same as this line tells, why using this number in
+       * those cases only confuses us.
        *
        *
        * Example D above makes this parsing a little tricky */
        * Example D above makes this parsing a little tricky */
       char *bytes;
       char *bytes;
@@ -2676,21 +2504,22 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
     conn->proto.ftpc.retr_size_saved = size;
     conn->proto.ftpc.retr_size_saved = size;
 
 
     if(data->set.ftp_use_port) {
     if(data->set.ftp_use_port) {
+      struct ftp_conn *ftpc = &conn->proto.ftpc;
       bool connected;
       bool connected;
 
 
-      result = AllowServerConnect(data, &connected);
+      result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
       if(result)
       if(result)
         return result;
         return result;
 
 
       if(!connected) {
       if(!connected) {
-        struct ftp_conn *ftpc = &conn->proto.ftpc;
         infof(data, "Data conn was not available immediately");
         infof(data, "Data conn was not available immediately");
         ftp_state(data, FTP_STOP);
         ftp_state(data, FTP_STOP);
         ftpc->wait_data_conn = TRUE;
         ftpc->wait_data_conn = TRUE;
+        return ftp_check_ctrl_on_data_wait(data);
       }
       }
+      ftpc->wait_data_conn = FALSE;
     }
     }
-    else
-      return InitiateTransfer(data);
+    return InitiateTransfer(data);
   }
   }
   else {
   else {
     if((instate == FTP_LIST) && (ftpcode == 450)) {
     if((instate == FTP_LIST) && (ftpcode == 450)) {
@@ -2700,8 +2529,8 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
     }
     }
     else {
     else {
       failf(data, "RETR response: %03d", ftpcode);
       failf(data, "RETR response: %03d", ftpcode);
-      return instate == FTP_RETR && ftpcode == 550?
-        CURLE_REMOTE_FILE_NOT_FOUND:
+      return instate == FTP_RETR && ftpcode == 550 ?
+        CURLE_REMOTE_FILE_NOT_FOUND :
         CURLE_FTP_COULDNT_RETR_FILE;
         CURLE_FTP_COULDNT_RETR_FILE;
     }
     }
   }
   }
@@ -2753,7 +2582,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
     /* 331 Password required for ...
     /* 331 Password required for ...
        (the server requires to send the user's password too) */
        (the server requires to send the user's password too) */
     result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
     result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
-                           conn->passwd?conn->passwd:"");
+                           conn->passwd ? conn->passwd : "");
     if(!result)
     if(!result)
       ftp_state(data, FTP_PASS);
       ftp_state(data, FTP_PASS);
   }
   }
@@ -2964,7 +2793,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
       if(ftpcode/100 == 2)
       if(ftpcode/100 == 2)
         /* We have enabled SSL for the data connection! */
         /* We have enabled SSL for the data connection! */
         conn->bits.ftp_use_data_ssl =
         conn->bits.ftp_use_data_ssl =
-          (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
+          (data->set.use_ssl != CURLUSESSL_CONTROL);
       /* FTP servers typically responds with 500 if they decide to reject
       /* FTP servers typically responds with 500 if they decide to reject
          our 'P' request */
          our 'P' request */
       else if(data->set.use_ssl > CURLUSESSL_CONTROL)
       else if(data->set.use_ssl > CURLUSESSL_CONTROL)
@@ -3281,7 +3110,7 @@ static CURLcode ftp_multi_statemach(struct Curl_easy *data,
   /* Check for the state outside of the Curl_socket_check() return code checks
   /* Check for the state outside of the Curl_socket_check() return code checks
      since at times we are in fact already in this state when this function
      since at times we are in fact already in this state when this function
      gets called. */
      gets called. */
-  *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
+  *done = (ftpc->state == FTP_STOP);
 
 
   return result;
   return result;
 }
 }
@@ -3403,9 +3232,9 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
 
 
   if(data->state.wildcardmatch) {
   if(data->state.wildcardmatch) {
     if(data->set.chunk_end && ftpc->file) {
     if(data->set.chunk_end && ftpc->file) {
-      Curl_set_in_callback(data, true);
+      Curl_set_in_callback(data, TRUE);
       data->set.chunk_end(data->set.wildcardptr);
       data->set.chunk_end(data->set.wildcardptr);
-      Curl_set_in_callback(data, false);
+      Curl_set_in_callback(data, FALSE);
     }
     }
     ftpc->known_filesize = -1;
     ftpc->known_filesize = -1;
   }
   }
@@ -3432,7 +3261,8 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
         if(data->set.ftp_filemethod == FTPFILE_NOCWD)
         if(data->set.ftp_filemethod == FTPFILE_NOCWD)
           pathLen = 0; /* relative path => working directory is FTP home */
           pathLen = 0; /* relative path => working directory is FTP home */
         else
         else
-          pathLen -= ftpc->file?strlen(ftpc->file):0; /* file is url-decoded */
+          /* file is url-decoded */
+          pathLen -= ftpc->file ? strlen(ftpc->file) : 0;
 
 
         rawPath[pathLen] = '\0';
         rawPath[pathLen] = '\0';
         ftpc->prevpath = rawPath;
         ftpc->prevpath = rawPath;
@@ -3550,7 +3380,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
     }
     }
     else if(!ftpc->dont_check &&
     else if(!ftpc->dont_check &&
             !data->req.bytecount &&
             !data->req.bytecount &&
-            (data->req.size>0)) {
+            (data->req.size > 0)) {
       failf(data, "No data was received");
       failf(data, "No data was received");
       result = CURLE_FTP_COULDNT_RETR_FILE;
       result = CURLE_FTP_COULDNT_RETR_FILE;
     }
     }
@@ -3634,7 +3464,7 @@ CURLcode ftp_sendquote(struct Curl_easy *data,
 static int ftp_need_type(struct connectdata *conn,
 static int ftp_need_type(struct connectdata *conn,
                          bool ascii_wanted)
                          bool ascii_wanted)
 {
 {
-  return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
+  return conn->proto.ftpc.transfertype != (ascii_wanted ? 'A' : 'I');
 }
 }
 
 
 /***********************************************************************
 /***********************************************************************
@@ -3651,7 +3481,7 @@ static CURLcode ftp_nb_type(struct Curl_easy *data,
 {
 {
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   struct ftp_conn *ftpc = &conn->proto.ftpc;
   CURLcode result;
   CURLcode result;
-  char want = (char)(ascii?'A':'I');
+  char want = (char)(ascii ? 'A' : 'I');
 
 
   if(ftpc->transfertype == want) {
   if(ftpc->transfertype == want) {
     ftp_state(data, newstate);
     ftp_state(data, newstate);
@@ -3714,20 +3544,25 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
    * complete */
    * complete */
   struct FTP *ftp = NULL;
   struct FTP *ftp = NULL;
 
 
-  /* if the second connection is not done yet, wait for it to have
-   * connected to the remote host. When using proxy tunneling, this
-   * means the tunnel needs to have been establish. However, we
-   * can not expect the remote host to talk to us in any way yet.
-   * So, when using ftps: the SSL handshake will not start until we
-   * tell the remote server that we are there. */
+  /* if the second connection has been set up, try to connect it fully
+   * to the remote host. This may not complete at this time, for several
+   * reasons:
+   * - we do EPTR and the server will not connect to our listen socket
+   *   until we send more FTP commands
+   * - an SSL filter is in place and the server will not start the TLS
+   *   handshake until we send more FTP commands
+   */
   if(conn->cfilter[SECONDARYSOCKET]) {
   if(conn->cfilter[SECONDARYSOCKET]) {
+    bool is_eptr = Curl_conn_is_tcp_listen(data, SECONDARYSOCKET);
     result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
     result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
-    if(result || !Curl_conn_is_ip_connected(data, SECONDARYSOCKET)) {
-      if(result && (ftpc->count1 == 0)) {
+    if(result || (!connected && !is_eptr &&
+                  !Curl_conn_is_ip_connected(data, SECONDARYSOCKET))) {
+      if(result && !is_eptr && (ftpc->count1 == 0)) {
         *completep = -1; /* go back to DOING please */
         *completep = -1; /* go back to DOING please */
         /* this is a EPSV connect failing, try PASV instead */
         /* this is a EPSV connect failing, try PASV instead */
         return ftp_epsv_disable(data, conn);
         return ftp_epsv_disable(data, conn);
       }
       }
+      *completep = (int)complete;
       return result;
       return result;
     }
     }
   }
   }
@@ -3760,16 +3595,14 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
     if(ftpc->wait_data_conn) {
     if(ftpc->wait_data_conn) {
       bool serv_conned;
       bool serv_conned;
 
 
-      result = ReceivedServerConnect(data, &serv_conned);
+      result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &serv_conned);
       if(result)
       if(result)
         return result; /* Failed to accept data connection */
         return result; /* Failed to accept data connection */
 
 
       if(serv_conned) {
       if(serv_conned) {
         /* It looks data connection is established */
         /* It looks data connection is established */
-        result = AcceptServerConnect(data);
         ftpc->wait_data_conn = FALSE;
         ftpc->wait_data_conn = FALSE;
-        if(!result)
-          result = InitiateTransfer(data);
+        result = InitiateTransfer(data);
 
 
         if(result)
         if(result)
           return result;
           return result;
@@ -3777,6 +3610,11 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
         *completep = 1; /* this state is now complete when the server has
         *completep = 1; /* this state is now complete when the server has
                            connected back to us */
                            connected back to us */
       }
       }
+      else {
+        result = ftp_check_ctrl_on_data_wait(data);
+        if(result)
+          return result;
+      }
     }
     }
     else if(data->state.upload) {
     else if(data->state.upload) {
       result = ftp_nb_type(data, conn, data->state.prefer_ascii,
       result = ftp_nb_type(data, conn, data->state.prefer_ascii,
@@ -3912,8 +3750,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
     last_slash++;
     last_slash++;
     if(last_slash[0] == '\0') {
     if(last_slash[0] == '\0') {
       wildcard->state = CURLWC_CLEAN;
       wildcard->state = CURLWC_CLEAN;
-      result = ftp_parse_url_path(data);
-      return result;
+      return ftp_parse_url_path(data);
     }
     }
     wildcard->pattern = strdup(last_slash);
     wildcard->pattern = strdup(last_slash);
     if(!wildcard->pattern)
     if(!wildcard->pattern)
@@ -3929,8 +3766,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
     }
     }
     else { /* only list */
     else { /* only list */
       wildcard->state = CURLWC_CLEAN;
       wildcard->state = CURLWC_CLEAN;
-      result = ftp_parse_url_path(data);
-      return result;
+      return ftp_parse_url_path(data);
     }
     }
   }
   }
 
 
@@ -4050,11 +3886,11 @@ static CURLcode wc_statemach(struct Curl_easy *data)
       infof(data, "Wildcard - START of \"%s\"", finfo->filename);
       infof(data, "Wildcard - START of \"%s\"", finfo->filename);
       if(data->set.chunk_bgn) {
       if(data->set.chunk_bgn) {
         long userresponse;
         long userresponse;
-        Curl_set_in_callback(data, true);
+        Curl_set_in_callback(data, TRUE);
         userresponse = data->set.chunk_bgn(
         userresponse = data->set.chunk_bgn(
           finfo, data->set.wildcardptr,
           finfo, data->set.wildcardptr,
           (int)Curl_llist_count(&wildcard->filelist));
           (int)Curl_llist_count(&wildcard->filelist));
-        Curl_set_in_callback(data, false);
+        Curl_set_in_callback(data, FALSE);
         switch(userresponse) {
         switch(userresponse) {
         case CURL_CHUNK_BGN_FUNC_SKIP:
         case CURL_CHUNK_BGN_FUNC_SKIP:
           infof(data, "Wildcard - \"%s\" skipped by user",
           infof(data, "Wildcard - \"%s\" skipped by user",
@@ -4093,9 +3929,9 @@ static CURLcode wc_statemach(struct Curl_easy *data)
 
 
     case CURLWC_SKIP: {
     case CURLWC_SKIP: {
       if(data->set.chunk_end) {
       if(data->set.chunk_end) {
-        Curl_set_in_callback(data, true);
+        Curl_set_in_callback(data, TRUE);
         data->set.chunk_end(data->set.wildcardptr);
         data->set.chunk_end(data->set.wildcardptr);
-        Curl_set_in_callback(data, false);
+        Curl_set_in_callback(data, FALSE);
       }
       }
       Curl_node_remove(Curl_llist_head(&wildcard->filelist));
       Curl_node_remove(Curl_llist_head(&wildcard->filelist));
       wildcard->state = (Curl_llist_count(&wildcard->filelist) == 0) ?
       wildcard->state = (Curl_llist_count(&wildcard->filelist) == 0) ?
@@ -4406,7 +4242,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
       if(data->set.ftp_filemethod == FTPFILE_NOCWD)
       if(data->set.ftp_filemethod == FTPFILE_NOCWD)
         n = 0; /* CWD to entry for relative paths */
         n = 0; /* CWD to entry for relative paths */
       else
       else
-        n -= ftpc->file?strlen(ftpc->file):0;
+        n -= ftpc->file ? strlen(ftpc->file) : 0;
 
 
       if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
       if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
         infof(data, "Request has same path as previous transfer");
         infof(data, "Request has same path as previous transfer");

+ 2 - 2
lib/ftplistparser.c

@@ -334,7 +334,7 @@ static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
     compare = Curl_fnmatch;
     compare = Curl_fnmatch;
 
 
   /* filter pattern-corresponding filenames */
   /* filter pattern-corresponding filenames */
-  Curl_set_in_callback(data, true);
+  Curl_set_in_callback(data, TRUE);
   if(compare(data->set.fnmatch_data, wc->pattern,
   if(compare(data->set.fnmatch_data, wc->pattern,
              finfo->filename) == 0) {
              finfo->filename) == 0) {
     /* discard symlink which is containing multiple " -> " */
     /* discard symlink which is containing multiple " -> " */
@@ -346,7 +346,7 @@ static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
   else {
   else {
     add = FALSE;
     add = FALSE;
   }
   }
-  Curl_set_in_callback(data, false);
+  Curl_set_in_callback(data, FALSE);
 
 
   if(add) {
   if(add) {
     Curl_llist_append(llist, finfo, &infop->list);
     Curl_llist_append(llist, finfo, &infop->list);

+ 2 - 2
lib/getenv.c

@@ -31,7 +31,7 @@
 
 
 static char *GetEnv(const char *variable)
 static char *GetEnv(const char *variable)
 {
 {
-#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP) || \
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP) || \
   defined(__ORBIS__) || defined(__PROSPERO__) /* PlayStation 4 and 5 */
   defined(__ORBIS__) || defined(__PROSPERO__) /* PlayStation 4 and 5 */
   (void)variable;
   (void)variable;
   return NULL;
   return NULL;
@@ -70,7 +70,7 @@ static char *GetEnv(const char *variable)
   }
   }
 #else
 #else
   char *env = getenv(variable);
   char *env = getenv(variable);
-  return (env && env[0])?strdup(env):NULL;
+  return (env && env[0]) ? strdup(env) : NULL;
 #endif
 #endif
 }
 }
 
 

+ 14 - 11
lib/getinfo.c

@@ -57,7 +57,7 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
   pro->t_starttransfer = 0;
   pro->t_starttransfer = 0;
   pro->timespent = 0;
   pro->timespent = 0;
   pro->t_redirect = 0;
   pro->t_redirect = 0;
-  pro->is_t_startransfer_set = false;
+  pro->is_t_startransfer_set = FALSE;
 
 
   info->httpcode = 0;
   info->httpcode = 0;
   info->httpproxycode = 0;
   info->httpproxycode = 0;
@@ -96,7 +96,7 @@ static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
 {
 {
   switch(info) {
   switch(info) {
   case CURLINFO_EFFECTIVE_URL:
   case CURLINFO_EFFECTIVE_URL:
-    *param_charp = data->state.url?data->state.url:(char *)"";
+    *param_charp = data->state.url ? data->state.url : (char *)"";
     break;
     break;
   case CURLINFO_EFFECTIVE_METHOD: {
   case CURLINFO_EFFECTIVE_METHOD: {
     const char *m = data->set.str[STRING_CUSTOMREQUEST];
     const char *m = data->set.str[STRING_CUSTOMREQUEST];
@@ -405,12 +405,12 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
     *param_offt = data->progress.ul.speed;
     *param_offt = data->progress.ul.speed;
     break;
     break;
   case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T:
   case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T:
-    *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
-      data->progress.dl.total_size:-1;
+    *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN) ?
+      data->progress.dl.total_size : -1;
     break;
     break;
   case CURLINFO_CONTENT_LENGTH_UPLOAD_T:
   case CURLINFO_CONTENT_LENGTH_UPLOAD_T:
-    *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
-      data->progress.ul.total_size:-1;
+    *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN) ?
+      data->progress.ul.total_size : -1;
     break;
     break;
    case CURLINFO_TOTAL_TIME_T:
    case CURLINFO_TOTAL_TIME_T:
     *param_offt = data->progress.timespent;
     *param_offt = data->progress.timespent;
@@ -446,9 +446,12 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
     *param_offt = data->id;
     *param_offt = data->id;
     break;
     break;
   case CURLINFO_CONN_ID:
   case CURLINFO_CONN_ID:
-    *param_offt = data->conn?
+    *param_offt = data->conn ?
       data->conn->connection_id : data->state.recent_conn_id;
       data->conn->connection_id : data->state.recent_conn_id;
     break;
     break;
+  case CURLINFO_EARLYDATA_SENT_T:
+    *param_offt = data->progress.earlydata_sent;
+    break;
   default:
   default:
     return CURLE_UNKNOWN_OPTION;
     return CURLE_UNKNOWN_OPTION;
   }
   }
@@ -512,12 +515,12 @@ static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
     *param_doublep = (double)data->progress.ul.speed;
     *param_doublep = (double)data->progress.ul.speed;
     break;
     break;
   case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
   case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
-    *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
-      (double)data->progress.dl.total_size:-1;
+    *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN) ?
+      (double)data->progress.dl.total_size : -1;
     break;
     break;
   case CURLINFO_CONTENT_LENGTH_UPLOAD:
   case CURLINFO_CONTENT_LENGTH_UPLOAD:
-    *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
-      (double)data->progress.ul.total_size:-1;
+    *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN) ?
+      (double)data->progress.ul.total_size : -1;
     break;
     break;
   case CURLINFO_REDIRECT_TIME:
   case CURLINFO_REDIRECT_TIME:
     *param_doublep = DOUBLE_SECS(data->progress.t_redirect);
     *param_doublep = DOUBLE_SECS(data->progress.t_redirect);

+ 1 - 1
lib/headers.c

@@ -54,7 +54,7 @@ static void copy_header_external(struct Curl_header_store *hs,
      impossible for applications to do == comparisons, as that would otherwise
      impossible for applications to do == comparisons, as that would otherwise
      be very tempting and then lead to the reserved bits not being reserved
      be very tempting and then lead to the reserved bits not being reserved
      anymore. */
      anymore. */
-  h->origin = (unsigned int)(hs->type | (1<<27));
+  h->origin = (unsigned int)(hs->type | (1 << 27));
   h->anchor = e;
   h->anchor = e;
 }
 }
 
 

+ 32 - 38
lib/hmac.c

@@ -49,8 +49,6 @@
 static const unsigned char hmac_ipad = 0x36;
 static const unsigned char hmac_ipad = 0x36;
 static const unsigned char hmac_opad = 0x5C;
 static const unsigned char hmac_opad = 0x5C;
 
 
-
-
 struct HMAC_context *
 struct HMAC_context *
 Curl_HMAC_init(const struct HMAC_params *hashparams,
 Curl_HMAC_init(const struct HMAC_params *hashparams,
                const unsigned char *key,
                const unsigned char *key,
@@ -62,42 +60,40 @@ Curl_HMAC_init(const struct HMAC_params *hashparams,
   unsigned char b;
   unsigned char b;
 
 
   /* Create HMAC context. */
   /* Create HMAC context. */
-  i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize +
-    hashparams->hmac_resultlen;
+  i = sizeof(*ctxt) + 2 * hashparams->ctxtsize + hashparams->resultlen;
   ctxt = malloc(i);
   ctxt = malloc(i);
 
 
   if(!ctxt)
   if(!ctxt)
     return ctxt;
     return ctxt;
 
 
-  ctxt->hmac_hash = hashparams;
-  ctxt->hmac_hashctxt1 = (void *) (ctxt + 1);
-  ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 +
-      hashparams->hmac_ctxtsize);
+  ctxt->hash = hashparams;
+  ctxt->hashctxt1 = (void *) (ctxt + 1);
+  ctxt->hashctxt2 = (void *) ((char *) ctxt->hashctxt1 + hashparams->ctxtsize);
 
 
   /* If the key is too long, replace it by its hash digest. */
   /* If the key is too long, replace it by its hash digest. */
-  if(keylen > hashparams->hmac_maxkeylen) {
-    (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
-    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen);
-    hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize;
-    (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1);
+  if(keylen > hashparams->maxkeylen) {
+    hashparams->hinit(ctxt->hashctxt1);
+    hashparams->hupdate(ctxt->hashctxt1, key, keylen);
+    hkey = (unsigned char *) ctxt->hashctxt2 + hashparams->ctxtsize;
+    hashparams->hfinal(hkey, ctxt->hashctxt1);
     key = hkey;
     key = hkey;
-    keylen = hashparams->hmac_resultlen;
+    keylen = hashparams->resultlen;
   }
   }
 
 
   /* Prime the two hash contexts with the modified key. */
   /* Prime the two hash contexts with the modified key. */
-  (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
-  (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
+  hashparams->hinit(ctxt->hashctxt1);
+  hashparams->hinit(ctxt->hashctxt2);
 
 
   for(i = 0; i < keylen; i++) {
   for(i = 0; i < keylen; i++) {
     b = (unsigned char)(*key ^ hmac_ipad);
     b = (unsigned char)(*key ^ hmac_ipad);
-    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
+    hashparams->hupdate(ctxt->hashctxt1, &b, 1);
     b = (unsigned char)(*key++ ^ hmac_opad);
     b = (unsigned char)(*key++ ^ hmac_opad);
-    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
+    hashparams->hupdate(ctxt->hashctxt2, &b, 1);
   }
   }
 
 
-  for(; i < hashparams->hmac_maxkeylen; i++) {
-    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1);
-    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1);
+  for(; i < hashparams->maxkeylen; i++) {
+    hashparams->hupdate(ctxt->hashctxt1, &hmac_ipad, 1);
+    hashparams->hupdate(ctxt->hashctxt2, &hmac_opad, 1);
   }
   }
 
 
   /* Done, return pointer to HMAC context. */
   /* Done, return pointer to HMAC context. */
@@ -105,31 +101,29 @@ Curl_HMAC_init(const struct HMAC_params *hashparams,
 }
 }
 
 
 int Curl_HMAC_update(struct HMAC_context *ctxt,
 int Curl_HMAC_update(struct HMAC_context *ctxt,
-                     const unsigned char *data,
+                     const unsigned char *ptr,
                      unsigned int len)
                      unsigned int len)
 {
 {
   /* Update first hash calculation. */
   /* Update first hash calculation. */
-  (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len);
+  ctxt->hash->hupdate(ctxt->hashctxt1, ptr, len);
   return 0;
   return 0;
 }
 }
 
 
 
 
-int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *result)
+int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *output)
 {
 {
-  const struct HMAC_params *hashparams = ctxt->hmac_hash;
+  const struct HMAC_params *hashparams = ctxt->hash;
 
 
-  /* Do not get result if called with a null parameter: only release
+  /* Do not get output if called with a null parameter: only release
      storage. */
      storage. */
 
 
-  if(!result)
-    result = (unsigned char *) ctxt->hmac_hashctxt2 +
-     ctxt->hmac_hash->hmac_ctxtsize;
+  if(!output)
+    output = (unsigned char *) ctxt->hashctxt2 + ctxt->hash->ctxtsize;
 
 
-  (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1);
-  (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2,
-   result, hashparams->hmac_resultlen);
-  (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2);
-  free((char *) ctxt);
+  hashparams->hfinal(output, ctxt->hashctxt1);
+  hashparams->hupdate(ctxt->hashctxt2, output, hashparams->resultlen);
+  hashparams->hfinal(output, ctxt->hashctxt2);
+  free(ctxt);
   return 0;
   return 0;
 }
 }
 
 
@@ -144,15 +138,15 @@ int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *result)
  * hashparams [in]     - The hash function (Curl_HMAC_MD5).
  * hashparams [in]     - The hash function (Curl_HMAC_MD5).
  * key        [in]     - The key to use.
  * key        [in]     - The key to use.
  * keylen     [in]     - The length of the key.
  * keylen     [in]     - The length of the key.
- * data       [in]     - The data to encrypt.
- * datalen    [in]     - The length of the data.
+ * buf        [in]     - The data to encrypt.
+ * buflen     [in]     - The length of the data.
  * output     [in/out] - The output buffer.
  * output     [in/out] - The output buffer.
  *
  *
  * Returns CURLE_OK on success.
  * Returns CURLE_OK on success.
  */
  */
 CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
 CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
                      const unsigned char *key, const size_t keylen,
                      const unsigned char *key, const size_t keylen,
-                     const unsigned char *data, const size_t datalen,
+                     const unsigned char *buf, const size_t buflen,
                      unsigned char *output)
                      unsigned char *output)
 {
 {
   struct HMAC_context *ctxt =
   struct HMAC_context *ctxt =
@@ -162,7 +156,7 @@ CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
   /* Update the digest with the given challenge */
   /* Update the digest with the given challenge */
-  Curl_HMAC_update(ctxt, data, curlx_uztoui(datalen));
+  Curl_HMAC_update(ctxt, buf, curlx_uztoui(buflen));
 
 
   /* Finalise the digest */
   /* Finalise the digest */
   Curl_HMAC_final(ctxt, output);
   Curl_HMAC_final(ctxt, output);

+ 13 - 11
lib/hostip.c

@@ -313,7 +313,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
   /* See if the returned entry matches the required resolve mode */
   /* See if the returned entry matches the required resolve mode */
   if(dns && data->conn->ip_version != CURL_IPRESOLVE_WHATEVER) {
   if(dns && data->conn->ip_version != CURL_IPRESOLVE_WHATEVER) {
     int pf = PF_INET;
     int pf = PF_INET;
-    bool found = false;
+    bool found = FALSE;
     struct Curl_addrinfo *addr = dns->addr;
     struct Curl_addrinfo *addr = dns->addr;
 
 
 #ifdef PF_INET6
 #ifdef PF_INET6
@@ -323,7 +323,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
 
 
     while(addr) {
     while(addr) {
       if(addr->ai_family == pf) {
       if(addr->ai_family == pf) {
-        found = true;
+        found = TRUE;
         break;
         break;
       }
       }
       addr = addr->ai_next;
       addr = addr->ai_next;
@@ -630,7 +630,7 @@ bool Curl_ipv6works(struct Curl_easy *data)
       ipv6_works = 1;
       ipv6_works = 1;
       sclose(s);
       sclose(s);
     }
     }
-    return (ipv6_works>0)?TRUE:FALSE;
+    return (ipv6_works > 0);
   }
   }
 }
 }
 #endif /* USE_IPV6 */
 #endif /* USE_IPV6 */
@@ -739,7 +739,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
     /* notify the resolver start callback */
     /* notify the resolver start callback */
     if(data->set.resolver_start) {
     if(data->set.resolver_start) {
       int st;
       int st;
-      Curl_set_in_callback(data, true);
+      Curl_set_in_callback(data, TRUE);
       st = data->set.resolver_start(
       st = data->set.resolver_start(
 #ifdef USE_CURL_ASYNC
 #ifdef USE_CURL_ASYNC
         data->state.async.resolver,
         data->state.async.resolver,
@@ -748,7 +748,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
 #endif
 #endif
         NULL,
         NULL,
         data->set.resolver_start_client);
         data->set.resolver_start_client);
-      Curl_set_in_callback(data, false);
+      Curl_set_in_callback(data, FALSE);
       if(st)
       if(st)
         return CURLRESOLV_ERROR;
         return CURLRESOLV_ERROR;
     }
     }
@@ -798,7 +798,9 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
         return CURLRESOLV_ERROR;
         return CURLRESOLV_ERROR;
 
 
       if(strcasecompare(hostname, "localhost") ||
       if(strcasecompare(hostname, "localhost") ||
-         tailmatch(hostname, ".localhost"))
+         strcasecompare(hostname, "localhost.") ||
+         tailmatch(hostname, ".localhost") ||
+         tailmatch(hostname, ".localhost."))
         addr = get_localhost(port, hostname);
         addr = get_localhost(port, hostname);
 #ifndef CURL_DISABLE_DOH
 #ifndef CURL_DISABLE_DOH
       else if(allowDOH && data->set.doh && !ipnum)
       else if(allowDOH && data->set.doh && !ipnum)
@@ -1068,7 +1070,7 @@ void Curl_resolv_unlink(struct Curl_easy *data, struct Curl_dns_entry **pdns)
 static void hostcache_unlink_entry(void *entry)
 static void hostcache_unlink_entry(void *entry)
 {
 {
   struct Curl_dns_entry *dns = (struct Curl_dns_entry *) entry;
   struct Curl_dns_entry *dns = (struct Curl_dns_entry *) entry;
-  DEBUGASSERT(dns && (dns->refcount>0));
+  DEBUGASSERT(dns && (dns->refcount > 0));
 
 
   dns->refcount--;
   dns->refcount--;
   if(dns->refcount == 0) {
   if(dns->refcount == 0) {
@@ -1129,7 +1131,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
   char *host_end;
   char *host_end;
 
 
   /* Default is no wildcard found */
   /* Default is no wildcard found */
-  data->state.wildcard_resolve = false;
+  data->state.wildcard_resolve = FALSE;
 
 
   for(hostp = data->state.resolve; hostp; hostp = hostp->next) {
   for(hostp = data->state.resolve; hostp; hostp = hostp->next) {
     char entry_id[MAX_HOSTCACHE_LEN];
     char entry_id[MAX_HOSTCACHE_LEN];
@@ -1179,7 +1181,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
       char *end_ptr;
       char *end_ptr;
       bool permanent = TRUE;
       bool permanent = TRUE;
       unsigned long tmp_port;
       unsigned long tmp_port;
-      bool error = true;
+      bool error = TRUE;
       char *host_begin = hostp->data;
       char *host_begin = hostp->data;
       size_t hlen = 0;
       size_t hlen = 0;
 
 
@@ -1256,7 +1258,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
       if(!head)
       if(!head)
         goto err;
         goto err;
 
 
-      error = false;
+      error = FALSE;
 err:
 err:
       if(error) {
       if(error) {
         failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'",
         failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'",
@@ -1316,7 +1318,7 @@ err:
       /* Wildcard hostname */
       /* Wildcard hostname */
       if((hlen == 1) && (host_begin[0] == '*')) {
       if((hlen == 1) && (host_begin[0] == '*')) {
         infof(data, "RESOLVE *:%d using wildcard", port);
         infof(data, "RESOLVE *:%d using wildcard", port);
-        data->state.wildcard_resolve = true;
+        data->state.wildcard_resolve = TRUE;
       }
       }
     }
     }
   }
   }

+ 4 - 0
lib/hostip4.c

@@ -126,8 +126,10 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
   int res;
   int res;
 #endif
 #endif
   struct Curl_addrinfo *ai = NULL;
   struct Curl_addrinfo *ai = NULL;
+#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
   struct hostent *h = NULL;
   struct hostent *h = NULL;
   struct hostent *buf = NULL;
   struct hostent *buf = NULL;
+#endif
 
 
 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)
 #if defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)
   struct addrinfo hints;
   struct addrinfo hints;
@@ -288,12 +290,14 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
 #endif /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) ||
 #endif /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) ||
            HAVE_GETHOSTBYNAME_R */
            HAVE_GETHOSTBYNAME_R */
 
 
+#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
   if(h) {
   if(h) {
     ai = Curl_he2ai(h, port);
     ai = Curl_he2ai(h, port);
 
 
     if(buf) /* used a *_r() function */
     if(buf) /* used a *_r() function */
       free(buf);
       free(buf);
   }
   }
+#endif
 
 
   return ai;
   return ai;
 }
 }

+ 23 - 16
lib/hsts.c

@@ -159,7 +159,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
   do {
   do {
     while(*p && ISBLANK(*p))
     while(*p && ISBLANK(*p))
       p++;
       p++;
-    if(strncasecompare("max-age=", p, 8)) {
+    if(strncasecompare("max-age", p, 7)) {
       bool quoted = FALSE;
       bool quoted = FALSE;
       CURLofft offt;
       CURLofft offt;
       char *endp;
       char *endp;
@@ -167,9 +167,14 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
       if(gotma)
       if(gotma)
         return CURLE_BAD_FUNCTION_ARGUMENT;
         return CURLE_BAD_FUNCTION_ARGUMENT;
 
 
-      p += 8;
+      p += 7;
       while(*p && ISBLANK(*p))
       while(*p && ISBLANK(*p))
         p++;
         p++;
+      if(*p++ != '=')
+        return CURLE_BAD_FUNCTION_ARGUMENT;
+      while(*p && ISBLANK(*p))
+        p++;
+
       if(*p == '\"') {
       if(*p == '\"') {
         p++;
         p++;
         quoted = TRUE;
         quoted = TRUE;
@@ -249,24 +254,23 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
 struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
 struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
                            bool subdomain)
                            bool subdomain)
 {
 {
+  struct stsentry *bestsub = NULL;
   if(h) {
   if(h) {
-    char buffer[MAX_HSTS_HOSTLEN + 1];
     time_t now = time(NULL);
     time_t now = time(NULL);
     size_t hlen = strlen(hostname);
     size_t hlen = strlen(hostname);
     struct Curl_llist_node *e;
     struct Curl_llist_node *e;
     struct Curl_llist_node *n;
     struct Curl_llist_node *n;
+    size_t blen = 0;
 
 
     if((hlen > MAX_HSTS_HOSTLEN) || !hlen)
     if((hlen > MAX_HSTS_HOSTLEN) || !hlen)
       return NULL;
       return NULL;
-    memcpy(buffer, hostname, hlen);
     if(hostname[hlen-1] == '.')
     if(hostname[hlen-1] == '.')
       /* remove the trailing dot */
       /* remove the trailing dot */
       --hlen;
       --hlen;
-    buffer[hlen] = 0;
-    hostname = buffer;
 
 
     for(e = Curl_llist_head(&h->list); e; e = n) {
     for(e = Curl_llist_head(&h->list); e; e = n) {
       struct stsentry *sts = Curl_node_elem(e);
       struct stsentry *sts = Curl_node_elem(e);
+      size_t ntail;
       n = Curl_node_next(e);
       n = Curl_node_next(e);
       if(sts->expires <= now) {
       if(sts->expires <= now) {
         /* remove expired entries */
         /* remove expired entries */
@@ -274,20 +278,23 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
         hsts_free(sts);
         hsts_free(sts);
         continue;
         continue;
       }
       }
-      if(subdomain && sts->includeSubDomains) {
-        size_t ntail = strlen(sts->host);
-        if(ntail < hlen) {
-          size_t offs = hlen - ntail;
-          if((hostname[offs-1] == '.') &&
-             strncasecompare(&hostname[offs], sts->host, ntail))
-            return sts;
+      ntail = strlen(sts->host);
+      if((subdomain && sts->includeSubDomains) && (ntail < hlen)) {
+        size_t offs = hlen - ntail;
+        if((hostname[offs-1] == '.') &&
+           strncasecompare(&hostname[offs], sts->host, ntail) &&
+           (ntail > blen)) {
+          /* save the tail match with the longest tail */
+          bestsub = sts;
+          blen = ntail;
         }
         }
       }
       }
-      if(strcasecompare(hostname, sts->host))
+      /* avoid strcasecompare because the host name is not null terminated */
+      if((hlen == ntail) && strncasecompare(hostname, sts->host, hlen))
         return sts;
         return sts;
     }
     }
   }
   }
-  return NULL; /* no match */
+  return bestsub;
 }
 }
 
 
 /*
 /*
@@ -439,7 +446,7 @@ static CURLcode hsts_add(struct hsts *h, char *line)
     e = Curl_hsts(h, p, subdomain);
     e = Curl_hsts(h, p, subdomain);
     if(!e)
     if(!e)
       result = hsts_create(h, p, subdomain, expires);
       result = hsts_create(h, p, subdomain, expires);
-    else {
+    else if(strcasecompare(p, e->host)) {
       /* the same hostname, use the largest expire time */
       /* the same hostname, use the largest expire time */
       if(expires > e->expires)
       if(expires > e->expires)
         e->expires = expires;
         e->expires = expires;

+ 84 - 243
lib/http.c

@@ -407,7 +407,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
 {
 {
   curl_off_t bytessent = data->req.writebytecount;
   curl_off_t bytessent = data->req.writebytecount;
   curl_off_t expectsend = Curl_creader_total_length(data);
   curl_off_t expectsend = Curl_creader_total_length(data);
-  curl_off_t upload_remain = (expectsend >= 0)? (expectsend - bytessent) : -1;
+  curl_off_t upload_remain = (expectsend >= 0) ? (expectsend - bytessent) : -1;
   bool little_upload_remains = (upload_remain >= 0 && upload_remain < 2000);
   bool little_upload_remains = (upload_remain >= 0 && upload_remain < 2000);
   bool needs_rewind = Curl_creader_needs_rewind(data);
   bool needs_rewind = Curl_creader_needs_rewind(data);
   /* By default, we would like to abort the transfer when little or unknown
   /* By default, we would like to abort the transfer when little or unknown
@@ -463,14 +463,14 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
   if(abort_upload) {
   if(abort_upload) {
     if(upload_remain >= 0)
     if(upload_remain >= 0)
       infof(data, "%s%sclose instead of sending %" FMT_OFF_T " more bytes",
       infof(data, "%s%sclose instead of sending %" FMT_OFF_T " more bytes",
-            ongoing_auth? ongoing_auth : "",
-            ongoing_auth? " send, " : "",
+            ongoing_auth ? ongoing_auth : "",
+            ongoing_auth ? " send, " : "",
             upload_remain);
             upload_remain);
     else
     else
       infof(data, "%s%sclose instead of sending unknown amount "
       infof(data, "%s%sclose instead of sending unknown amount "
             "of more bytes",
             "of more bytes",
-            ongoing_auth? ongoing_auth : "",
-            ongoing_auth? " send, " : "");
+            ongoing_auth ? ongoing_auth : "",
+            ongoing_auth ? " send, " : "");
     /* We decided to abort the ongoing transfer */
     /* We decided to abort the ongoing transfer */
     streamclose(conn, "Mid-auth HTTP and much data left to send");
     streamclose(conn, "Mid-auth HTTP and much data left to send");
     /* FIXME: questionable manipulation here, can we do this differently? */
     /* FIXME: questionable manipulation here, can we do this differently? */
@@ -502,7 +502,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
     return CURLE_OK;
     return CURLE_OK;
 
 
   if(data->state.authproblem)
   if(data->state.authproblem)
-    return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
+    return data->set.http_fail_on_error ? CURLE_HTTP_RETURNED_ERROR : CURLE_OK;
 
 
   if((data->state.aptr.user || data->set.str[STRING_BEARER]) &&
   if((data->state.aptr.user || data->set.str[STRING_BEARER]) &&
      ((data->req.httpcode == 401) ||
      ((data->req.httpcode == 401) ||
@@ -677,7 +677,7 @@ output_auth_headers(struct Curl_easy *data,
           auth, data->state.aptr.user ?
           auth, data->state.aptr.user ?
           data->state.aptr.user : "");
           data->state.aptr.user : "");
 #endif
 #endif
-    authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
+    authstatus->multipass = !authstatus->done;
   }
   }
   else
   else
     authstatus->multipass = FALSE;
     authstatus->multipass = FALSE;
@@ -1229,163 +1229,6 @@ static const char *get_http_string(const struct Curl_easy *data,
 }
 }
 #endif
 #endif
 
 
-enum proxy_use {
-  HEADER_SERVER,  /* direct to server */
-  HEADER_PROXY,   /* regular request to proxy */
-  HEADER_CONNECT  /* sending CONNECT to a proxy */
-};
-
-static bool hd_name_eq(const char *n1, size_t n1len,
-                       const char *n2, size_t n2len)
-{
-  if(n1len == n2len) {
-    return strncasecompare(n1, n2, n1len);
-  }
-  return FALSE;
-}
-
-CURLcode Curl_dynhds_add_custom(struct Curl_easy *data,
-                                bool is_connect,
-                                struct dynhds *hds)
-{
-  struct connectdata *conn = data->conn;
-  char *ptr;
-  struct curl_slist *h[2];
-  struct curl_slist *headers;
-  int numlists = 1; /* by default */
-  int i;
-
-#ifndef CURL_DISABLE_PROXY
-  enum proxy_use proxy;
-
-  if(is_connect)
-    proxy = HEADER_CONNECT;
-  else
-    proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
-      HEADER_PROXY:HEADER_SERVER;
-
-  switch(proxy) {
-  case HEADER_SERVER:
-    h[0] = data->set.headers;
-    break;
-  case HEADER_PROXY:
-    h[0] = data->set.headers;
-    if(data->set.sep_headers) {
-      h[1] = data->set.proxyheaders;
-      numlists++;
-    }
-    break;
-  case HEADER_CONNECT:
-    if(data->set.sep_headers)
-      h[0] = data->set.proxyheaders;
-    else
-      h[0] = data->set.headers;
-    break;
-  }
-#else
-  (void)is_connect;
-  h[0] = data->set.headers;
-#endif
-
-  /* loop through one or two lists */
-  for(i = 0; i < numlists; i++) {
-    for(headers = h[i]; headers; headers = headers->next) {
-      const char *name, *value;
-      size_t namelen, valuelen;
-
-      /* There are 2 quirks in place for custom headers:
-       * 1. setting only 'name:' to suppress a header from being sent
-       * 2. setting only 'name;' to send an empty (illegal) header
-       */
-      ptr = strchr(headers->data, ':');
-      if(ptr) {
-        name = headers->data;
-        namelen = ptr - headers->data;
-        ptr++; /* pass the colon */
-        while(*ptr && ISSPACE(*ptr))
-          ptr++;
-        if(*ptr) {
-          value = ptr;
-          valuelen = strlen(value);
-        }
-        else {
-          /* quirk #1, suppress this header */
-          continue;
-        }
-      }
-      else {
-        ptr = strchr(headers->data, ';');
-
-        if(!ptr) {
-          /* neither : nor ; in provided header value. We seem
-           * to ignore this silently */
-          continue;
-        }
-
-        name = headers->data;
-        namelen = ptr - headers->data;
-        ptr++; /* pass the semicolon */
-        while(*ptr && ISSPACE(*ptr))
-          ptr++;
-        if(!*ptr) {
-          /* quirk #2, send an empty header */
-          value = "";
-          valuelen = 0;
-        }
-        else {
-          /* this may be used for something else in the future,
-           * ignore this for now */
-          continue;
-        }
-      }
-
-      DEBUGASSERT(name && value);
-      if(data->state.aptr.host &&
-         /* a Host: header was sent already, do not pass on any custom Host:
-            header as that will produce *two* in the same request! */
-         hd_name_eq(name, namelen, STRCONST("Host:")))
-        ;
-      else if(data->state.httpreq == HTTPREQ_POST_FORM &&
-              /* this header (extended by formdata.c) is sent later */
-              hd_name_eq(name, namelen, STRCONST("Content-Type:")))
-        ;
-      else if(data->state.httpreq == HTTPREQ_POST_MIME &&
-              /* this header is sent later */
-              hd_name_eq(name, namelen, STRCONST("Content-Type:")))
-        ;
-      else if(data->req.authneg &&
-              /* while doing auth neg, do not allow the custom length since
-                 we will force length zero then */
-              hd_name_eq(name, namelen, STRCONST("Content-Length:")))
-        ;
-      else if(data->state.aptr.te &&
-              /* when asking for Transfer-Encoding, do not pass on a custom
-                 Connection: */
-              hd_name_eq(name, namelen, STRCONST("Connection:")))
-        ;
-      else if((conn->httpversion >= 20) &&
-              hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:")))
-        /* HTTP/2 does not support chunked requests */
-        ;
-      else if((hd_name_eq(name, namelen, STRCONST("Authorization:")) ||
-               hd_name_eq(name, namelen, STRCONST("Cookie:"))) &&
-              /* be careful of sending this potentially sensitive header to
-                 other hosts */
-              !Curl_auth_allowed_to_host(data))
-        ;
-      else {
-        CURLcode result;
-
-        result = Curl_dynhds_add(hds, name, namelen, value, valuelen);
-        if(result)
-          return result;
-      }
-    }
-  }
-
-  return CURLE_OK;
-}
-
 CURLcode Curl_add_custom_headers(struct Curl_easy *data,
 CURLcode Curl_add_custom_headers(struct Curl_easy *data,
                                  bool is_connect,
                                  bool is_connect,
 #ifndef USE_HYPER
 #ifndef USE_HYPER
@@ -1403,13 +1246,13 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
   int i;
   int i;
 
 
 #ifndef CURL_DISABLE_PROXY
 #ifndef CURL_DISABLE_PROXY
-  enum proxy_use proxy;
+  enum Curl_proxy_use proxy;
 
 
   if(is_connect)
   if(is_connect)
     proxy = HEADER_CONNECT;
     proxy = HEADER_CONNECT;
   else
   else
-    proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
-      HEADER_PROXY:HEADER_SERVER;
+    proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy ?
+      HEADER_PROXY : HEADER_SERVER;
 
 
   switch(proxy) {
   switch(proxy) {
   case HEADER_SERVER:
   case HEADER_SERVER:
@@ -1602,7 +1445,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
   msnprintf(datestr, sizeof(datestr),
   msnprintf(datestr, sizeof(datestr),
             "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
             "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
             condp,
             condp,
-            Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+            Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6],
             tm->tm_mday,
             tm->tm_mday,
             Curl_month[tm->tm_mon],
             Curl_month[tm->tm_mon],
             tm->tm_year + 1900,
             tm->tm_year + 1900,
@@ -1755,11 +1598,12 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
         (conn->remote_port == PORT_HTTP)) )
         (conn->remote_port == PORT_HTTP)) )
       /* if(HTTPS on port 443) OR (HTTP on port 80) then do not include
       /* if(HTTPS on port 443) OR (HTTP on port 80) then do not include
          the port number in the host string */
          the port number in the host string */
-      aptr->host = aprintf("Host: %s%s%s\r\n", conn->bits.ipv6_ip?"[":"",
-                           host, conn->bits.ipv6_ip?"]":"");
+      aptr->host = aprintf("Host: %s%s%s\r\n", conn->bits.ipv6_ip ? "[" : "",
+                           host, conn->bits.ipv6_ip ? "]" : "");
     else
     else
-      aptr->host = aprintf("Host: %s%s%s:%d\r\n", conn->bits.ipv6_ip?"[":"",
-                           host, conn->bits.ipv6_ip?"]":"",
+      aptr->host = aprintf("Host: %s%s%s:%d\r\n",
+                           conn->bits.ipv6_ip ? "[" : "",
+                           host, conn->bits.ipv6_ip ? "]" : "",
                            conn->remote_port);
                            conn->remote_port);
 
 
     if(!aptr->host)
     if(!aptr->host)
@@ -1836,8 +1680,8 @@ CURLcode Curl_http_target(struct Curl_easy *data,
     curl_url_cleanup(h);
     curl_url_cleanup(h);
 
 
     /* target or URL */
     /* target or URL */
-    result = Curl_dyn_add(r, data->set.str[STRING_TARGET]?
-      data->set.str[STRING_TARGET]:url);
+    result = Curl_dyn_add(r, data->set.str[STRING_TARGET] ?
+      data->set.str[STRING_TARGET] : url);
     free(url);
     free(url);
     if(result)
     if(result)
       return (result);
       return (result);
@@ -1973,11 +1817,8 @@ static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq)
 
 
   switch(httpreq) {
   switch(httpreq) {
   case HTTPREQ_PUT: /* Let's PUT the data to the server! */
   case HTTPREQ_PUT: /* Let's PUT the data to the server! */
-    if(!postsize)
-      result = Curl_creader_set_null(data);
-    else
-      result = Curl_creader_set_fread(data, postsize);
-    return result;
+    return postsize ? Curl_creader_set_fread(data, postsize) :
+      Curl_creader_set_null(data);
 
 
 #if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API)
 #if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API)
   case HTTPREQ_POST_FORM:
   case HTTPREQ_POST_FORM:
@@ -2010,7 +1851,7 @@ static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq)
         chunked = Curl_compareheader(ptr, STRCONST("Transfer-Encoding:"),
         chunked = Curl_compareheader(ptr, STRCONST("Transfer-Encoding:"),
                                      STRCONST("chunked"));
                                      STRCONST("chunked"));
       }
       }
-      result = Curl_creader_set_fread(data, chunked? -1 : postsize);
+      result = Curl_creader_set_fread(data, chunked ? -1 : postsize);
     }
     }
     return result;
     return result;
 
 
@@ -2250,8 +2091,9 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
     addcookies = data->set.str[STRING_COOKIE];
     addcookies = data->set.str[STRING_COOKIE];
 
 
   if(data->cookies || addcookies) {
   if(data->cookies || addcookies) {
-    struct Cookie *co = NULL; /* no cookies from start */
+    struct Curl_llist list;
     int count = 0;
     int count = 0;
+    int rc = 1;
 
 
     if(data->cookies && data->state.cookie_engine) {
     if(data->cookies && data->state.cookie_engine) {
       const char *host = data->state.aptr.cookiehost ?
       const char *host = data->state.aptr.cookiehost ?
@@ -2260,17 +2102,19 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
         conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
         conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
         strcasecompare("localhost", host) ||
         strcasecompare("localhost", host) ||
         !strcmp(host, "127.0.0.1") ||
         !strcmp(host, "127.0.0.1") ||
-        !strcmp(host, "::1") ? TRUE : FALSE;
+        !strcmp(host, "::1");
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
-      co = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path,
-                               secure_context);
+      rc = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path,
+                               secure_context, &list);
       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
     }
     }
-    if(co) {
-      struct Cookie *store = co;
+    if(!rc) {
+      struct Curl_llist_node *n;
       size_t clen = 8; /* hold the size of the generated Cookie: header */
       size_t clen = 8; /* hold the size of the generated Cookie: header */
-      /* now loop through all cookies that matched */
-      while(co) {
+
+      /* loop through all cookies that matched */
+      for(n = Curl_llist_head(&list); n; n = Curl_node_next(n)) {
+        struct Cookie *co = Curl_node_elem(n);
         if(co->value) {
         if(co->value) {
           size_t add;
           size_t add;
           if(!count) {
           if(!count) {
@@ -2285,22 +2129,21 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
             linecap = TRUE;
             linecap = TRUE;
             break;
             break;
           }
           }
-          result = Curl_dyn_addf(r, "%s%s=%s", count?"; ":"",
+          result = Curl_dyn_addf(r, "%s%s=%s", count ? "; " : "",
                                  co->name, co->value);
                                  co->name, co->value);
           if(result)
           if(result)
             break;
             break;
           clen += add + (count ? 2 : 0);
           clen += add + (count ? 2 : 0);
           count++;
           count++;
         }
         }
-        co = co->next; /* next cookie please */
       }
       }
-      Curl_cookie_freelist(store);
+      Curl_llist_destroy(&list, NULL);
     }
     }
     if(addcookies && !result && !linecap) {
     if(addcookies && !result && !linecap) {
       if(!count)
       if(!count)
         result = Curl_dyn_addn(r, STRCONST("Cookie: "));
         result = Curl_dyn_addn(r, STRCONST("Cookie: "));
       if(!result) {
       if(!result) {
-        result = Curl_dyn_addf(r, "%s%s", count?"; ":"", addcookies);
+        result = Curl_dyn_addf(r, "%s%s", count ? "; " : "", addcookies);
         count++;
         count++;
       }
       }
     }
     }
@@ -2350,7 +2193,7 @@ CURLcode Curl_http_range(struct Curl_easy *data,
         /* TODO: not sure if we want to send this header during authentication
         /* TODO: not sure if we want to send this header during authentication
          * negotiation, but test1084 checks for it. In which case we have a
          * negotiation, but test1084 checks for it. In which case we have a
          * "null" client reader installed that gives an unexpected length. */
          * "null" client reader installed that gives an unexpected length. */
-        curl_off_t total_len = data->req.authneg?
+        curl_off_t total_len = data->req.authneg ?
                                data->state.infilesize :
                                data->state.infilesize :
                                (data->state.resume_from + req_clen);
                                (data->state.resume_from + req_clen);
         data->state.aptr.rangeline =
         data->state.aptr.rangeline =
@@ -2582,7 +2425,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
     goto fail;
     goto fail;
 
 
   p_accept = Curl_checkheaders(data,
   p_accept = Curl_checkheaders(data,
-                               STRCONST("Accept"))?NULL:"Accept: */*\r\n";
+                               STRCONST("Accept")) ? NULL : "Accept: */*\r\n";
 
 
   result = Curl_http_range(data, httpreq);
   result = Curl_http_range(data, httpreq);
   if(result)
   if(result)
@@ -2634,35 +2477,34 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
                   "%s",/* Alt-Used */
                   "%s",/* Alt-Used */
 
 
                   httpstring,
                   httpstring,
-                  (data->state.aptr.host?data->state.aptr.host:""),
+                  (data->state.aptr.host ? data->state.aptr.host : ""),
 #ifndef CURL_DISABLE_PROXY
 #ifndef CURL_DISABLE_PROXY
-                  data->state.aptr.proxyuserpwd?
-                  data->state.aptr.proxyuserpwd:"",
+                  data->state.aptr.proxyuserpwd ?
+                  data->state.aptr.proxyuserpwd : "",
 #else
 #else
                   "",
                   "",
 #endif
 #endif
-                  data->state.aptr.userpwd?data->state.aptr.userpwd:"",
-                  (data->state.use_range && data->state.aptr.rangeline)?
-                  data->state.aptr.rangeline:"",
+                  data->state.aptr.userpwd ? data->state.aptr.userpwd : "",
+                  (data->state.use_range && data->state.aptr.rangeline) ?
+                  data->state.aptr.rangeline : "",
                   (data->set.str[STRING_USERAGENT] &&
                   (data->set.str[STRING_USERAGENT] &&
                    *data->set.str[STRING_USERAGENT] &&
                    *data->set.str[STRING_USERAGENT] &&
-                   data->state.aptr.uagent)?
-                  data->state.aptr.uagent:"",
-                  p_accept?p_accept:"",
-                  data->state.aptr.te?data->state.aptr.te:"",
+                   data->state.aptr.uagent) ?
+                  data->state.aptr.uagent : "",
+                  p_accept ? p_accept : "",
+                  data->state.aptr.te ? data->state.aptr.te : "",
                   (data->set.str[STRING_ENCODING] &&
                   (data->set.str[STRING_ENCODING] &&
                    *data->set.str[STRING_ENCODING] &&
                    *data->set.str[STRING_ENCODING] &&
-                   data->state.aptr.accept_encoding)?
-                  data->state.aptr.accept_encoding:"",
-                  (data->state.referer && data->state.aptr.ref)?
-                  data->state.aptr.ref:"" /* Referer: <data> */,
+                   data->state.aptr.accept_encoding) ?
+                  data->state.aptr.accept_encoding : "",
+                  (data->state.referer && data->state.aptr.ref) ?
+                  data->state.aptr.ref : "" /* Referer: <data> */,
 #ifndef CURL_DISABLE_PROXY
 #ifndef CURL_DISABLE_PROXY
                   (conn->bits.httpproxy &&
                   (conn->bits.httpproxy &&
                    !conn->bits.tunnel_proxy &&
                    !conn->bits.tunnel_proxy &&
                    !Curl_checkheaders(data, STRCONST("Proxy-Connection")) &&
                    !Curl_checkheaders(data, STRCONST("Proxy-Connection")) &&
-                   !Curl_checkProxyheaders(data,
-                                           conn,
-                                           STRCONST("Proxy-Connection")))?
+                   !Curl_checkProxyheaders(data, conn,
+                                           STRCONST("Proxy-Connection"))) ?
                   "Proxy-Connection: Keep-Alive\r\n":"",
                   "Proxy-Connection: Keep-Alive\r\n":"",
 #else
 #else
                   "",
                   "",
@@ -2697,7 +2539,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
   }
   }
 
 
   result = Curl_http_cookies(data, conn, &req);
   result = Curl_http_cookies(data, conn, &req);
-#ifdef USE_WEBSOCKETS
+#ifndef CURL_DISABLE_WEBSOCKETS
   if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
   if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
     result = Curl_ws_request(data, &req);
     result = Curl_ws_request(data, &req);
 #endif
 #endif
@@ -2754,7 +2596,7 @@ checkhttpprefix(struct Curl_easy *data,
 {
 {
   struct curl_slist *head = data->set.http200aliases;
   struct curl_slist *head = data->set.http200aliases;
   statusline rc = STATUS_BAD;
   statusline rc = STATUS_BAD;
-  statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
+  statusline onmatch = len >= 5 ? STATUS_DONE : STATUS_UNKNOWN;
 
 
   while(head) {
   while(head) {
     if(checkprefixmax(head->data, s, len)) {
     if(checkprefixmax(head->data, s, len)) {
@@ -2776,7 +2618,7 @@ checkrtspprefix(struct Curl_easy *data,
                 const char *s, size_t len)
                 const char *s, size_t len)
 {
 {
   statusline result = STATUS_BAD;
   statusline result = STATUS_BAD;
-  statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
+  statusline onmatch = len >= 5 ? STATUS_DONE : STATUS_UNKNOWN;
   (void)data; /* unused */
   (void)data; /* unused */
   if(checkprefixmax("RTSP/", s, len))
   if(checkprefixmax("RTSP/", s, len))
     result = onmatch;
     result = onmatch;
@@ -2837,10 +2679,10 @@ CURLcode Curl_http_header(struct Curl_easy *data,
 #else
 #else
           0
           0
 #endif
 #endif
-        ))? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL;
+        )) ? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL;
     if(v) {
     if(v) {
       /* the ALPN of the current request */
       /* the ALPN of the current request */
-      enum alpnid id = (conn->httpversion == 30)? ALPN_h3 :
+      enum alpnid id = (conn->httpversion == 30) ? ALPN_h3 :
                          (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
                          (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
       return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name,
       return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name,
                                curlx_uitous((unsigned int)conn->remote_port));
                                curlx_uitous((unsigned int)conn->remote_port));
@@ -2850,8 +2692,8 @@ CURLcode Curl_http_header(struct Curl_easy *data,
   case 'c':
   case 'c':
   case 'C':
   case 'C':
     /* Check for Content-Length: header lines to get size */
     /* Check for Content-Length: header lines to get size */
-    v = (!k->http_bodyless && !data->set.ignorecl)?
-        HD_VAL(hd, hdlen, "Content-Length:") : NULL;
+    v = (!k->http_bodyless && !data->set.ignorecl) ?
+      HD_VAL(hd, hdlen, "Content-Length:") : NULL;
     if(v) {
     if(v) {
       curl_off_t contentlength;
       curl_off_t contentlength;
       CURLofft offt = curlx_strtoofft(v, NULL, 10, &contentlength);
       CURLofft offt = curlx_strtoofft(v, NULL, 10, &contentlength);
@@ -2876,8 +2718,8 @@ CURLcode Curl_http_header(struct Curl_easy *data,
       }
       }
       return CURLE_OK;
       return CURLE_OK;
     }
     }
-    v = (!k->http_bodyless && data->set.str[STRING_ENCODING])?
-        HD_VAL(hd, hdlen, "Content-Encoding:") : NULL;
+    v = (!k->http_bodyless && data->set.str[STRING_ENCODING]) ?
+      HD_VAL(hd, hdlen, "Content-Encoding:") : NULL;
     if(v) {
     if(v) {
       /*
       /*
        * Process Content-Encoding. Look for the values: identity,
        * Process Content-Encoding. Look for the values: identity,
@@ -2925,7 +2767,7 @@ CURLcode Curl_http_header(struct Curl_easy *data,
       infof(data, "HTTP/1.0 connection set to keep alive");
       infof(data, "HTTP/1.0 connection set to keep alive");
       return CURLE_OK;
       return CURLE_OK;
     }
     }
-    v = !k->http_bodyless? HD_VAL(hd, hdlen, "Content-Range:") : NULL;
+    v = !k->http_bodyless ? HD_VAL(hd, hdlen, "Content-Range:") : NULL;
     if(v) {
     if(v) {
       /* Content-Range: bytes [num]-
       /* Content-Range: bytes [num]-
          Content-Range: bytes: [num]-
          Content-Range: bytes: [num]-
@@ -2959,7 +2801,7 @@ CURLcode Curl_http_header(struct Curl_easy *data,
   case 'l':
   case 'l':
   case 'L':
   case 'L':
     v = (!k->http_bodyless &&
     v = (!k->http_bodyless &&
-         (data->set.timecondition || data->set.get_filetime))?
+         (data->set.timecondition || data->set.get_filetime)) ?
         HD_VAL(hd, hdlen, "Last-Modified:") : NULL;
         HD_VAL(hd, hdlen, "Last-Modified:") : NULL;
     if(v) {
     if(v) {
       k->timeofdoc = Curl_getdate_capped(v);
       k->timeofdoc = Curl_getdate_capped(v);
@@ -3042,8 +2884,7 @@ CURLcode Curl_http_header(struct Curl_easy *data,
         char *persistentauth = Curl_copy_header_value(hd);
         char *persistentauth = Curl_copy_header_value(hd);
         if(!persistentauth)
         if(!persistentauth)
           return CURLE_OUT_OF_MEMORY;
           return CURLE_OUT_OF_MEMORY;
-        negdata->noauthpersist = checkprefix("false", persistentauth)?
-          TRUE:FALSE;
+        negdata->noauthpersist = !!checkprefix("false", persistentauth);
         negdata->havenoauthpersist = TRUE;
         negdata->havenoauthpersist = TRUE;
         infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
         infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
               negdata->noauthpersist, persistentauth);
               negdata->noauthpersist, persistentauth);
@@ -3073,18 +2914,18 @@ CURLcode Curl_http_header(struct Curl_easy *data,
   case 's':
   case 's':
   case 'S':
   case 'S':
 #if !defined(CURL_DISABLE_COOKIES)
 #if !defined(CURL_DISABLE_COOKIES)
-    v = (data->cookies && data->state.cookie_engine)?
+    v = (data->cookies && data->state.cookie_engine) ?
         HD_VAL(hd, hdlen, "Set-Cookie:") : NULL;
         HD_VAL(hd, hdlen, "Set-Cookie:") : NULL;
     if(v) {
     if(v) {
       /* If there is a custom-set Host: name, use it here, or else use
       /* If there is a custom-set Host: name, use it here, or else use
        * real peer hostname. */
        * real peer hostname. */
-      const char *host = data->state.aptr.cookiehost?
-        data->state.aptr.cookiehost:conn->host.name;
+      const char *host = data->state.aptr.cookiehost ?
+        data->state.aptr.cookiehost : conn->host.name;
       const bool secure_context =
       const bool secure_context =
         conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
         conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
         strcasecompare("localhost", host) ||
         strcasecompare("localhost", host) ||
         !strcmp(host, "127.0.0.1") ||
         !strcmp(host, "127.0.0.1") ||
-        !strcmp(host, "::1") ? TRUE : FALSE;
+        !strcmp(host, "::1");
 
 
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
                       CURL_LOCK_ACCESS_SINGLE);
                       CURL_LOCK_ACCESS_SINGLE);
@@ -3105,7 +2946,7 @@ CURLcode Curl_http_header(struct Curl_easy *data,
            0
            0
 #endif
 #endif
             )
             )
-        )? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL;
+        ) ? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL;
     if(v) {
     if(v) {
       CURLcode check =
       CURLcode check =
         Curl_hsts_parse(data->hsts, conn->host.name, v);
         Curl_hsts_parse(data->hsts, conn->host.name, v);
@@ -3133,8 +2974,8 @@ CURLcode Curl_http_header(struct Curl_easy *data,
      */
      */
     v = (!k->http_bodyless &&
     v = (!k->http_bodyless &&
          (data->state.httpreq != HTTPREQ_HEAD) &&
          (data->state.httpreq != HTTPREQ_HEAD) &&
-         (k->httpcode != 304))?
-        HD_VAL(hd, hdlen, "Transfer-Encoding:") : NULL;
+         (k->httpcode != 304)) ?
+      HD_VAL(hd, hdlen, "Transfer-Encoding:") : NULL;
     if(v) {
     if(v) {
       /* One or more encodings. We check for chunked and/or a compression
       /* One or more encodings. We check for chunked and/or a compression
          algorithm. */
          algorithm. */
@@ -3372,8 +3213,8 @@ static CURLcode http_write_header(struct Curl_easy *data,
     return result;
     return result;
 
 
   data->req.deductheadercount = (100 <= data->req.httpcode &&
   data->req.deductheadercount = (100 <= data->req.httpcode &&
-                                 199 >= data->req.httpcode)?
-                                data->req.headerbytecount:0;
+                                 199 >= data->req.httpcode) ?
+    data->req.headerbytecount : 0;
   return result;
   return result;
 }
 }
 
 
@@ -3449,7 +3290,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
           goto out;
           goto out;
         *pconsumed += blen;
         *pconsumed += blen;
       }
       }
-#ifdef USE_WEBSOCKETS
+#ifndef CURL_DISABLE_WEBSOCKETS
       else if(k->upgr101 == UPGR101_WS) {
       else if(k->upgr101 == UPGR101_WS) {
         /* verify the response. Any passed `buf` bytes are already in
         /* verify the response. Any passed `buf` bytes are already in
          * WebSockets format and taken in by the protocol handler. */
          * WebSockets format and taken in by the protocol handler. */
@@ -3534,7 +3375,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
   }
   }
 #endif
 #endif
 
 
-#ifdef USE_WEBSOCKETS
+#ifndef CURL_DISABLE_WEBSOCKETS
   /* All >=200 HTTP status codes are errors when wanting WebSockets */
   /* All >=200 HTTP status codes are errors when wanting WebSockets */
   if(data->req.upgr101 == UPGR101_WS) {
   if(data->req.upgr101 == UPGR101_WS) {
     failf(data, "Refused WebSockets upgrade: %d", k->httpcode);
     failf(data, "Refused WebSockets upgrade: %d", k->httpcode);
@@ -4052,7 +3893,7 @@ CURLcode Curl_http_decode_status(int *pstatus, const char *s, size_t len)
   }
   }
   result = CURLE_OK;
   result = CURLE_OK;
 out:
 out:
-  *pstatus = result? -1 : status;
+  *pstatus = result ? -1 : status;
   return result;
   return result;
 }
 }
 
 
@@ -4095,7 +3936,7 @@ CURLcode Curl_http_req_make(struct httpreq **preq,
 out:
 out:
   if(result && req)
   if(result && req)
     Curl_http_req_free(req);
     Curl_http_req_free(req);
-  *preq = result? NULL : req;
+  *preq = result ? NULL : req;
   return result;
   return result;
 }
 }
 
 
@@ -4253,7 +4094,7 @@ CURLcode Curl_http_req_make2(struct httpreq **preq,
 out:
 out:
   if(result && req)
   if(result && req)
     Curl_http_req_free(req);
     Curl_http_req_free(req);
-  *preq = result? NULL : req;
+  *preq = result ? NULL : req;
   return result;
   return result;
 }
 }
 
 
@@ -4319,8 +4160,8 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers,
       infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme);
       infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme);
     }
     }
     else {
     else {
-      scheme = (data->conn && data->conn->handler->flags & PROTOPT_SSL)?
-                "https" : "http";
+      scheme = (data->conn && data->conn->handler->flags & PROTOPT_SSL) ?
+        "https" : "http";
     }
     }
   }
   }
 
 
@@ -4384,7 +4225,7 @@ CURLcode Curl_http_resp_make(struct http_resp **presp,
 out:
 out:
   if(result && resp)
   if(result && resp)
     Curl_http_resp_free(resp);
     Curl_http_resp_free(resp);
-  *presp = result? NULL : resp;
+  *presp = result ? NULL : resp;
   return result;
   return result;
 }
 }
 
 
@@ -4479,7 +4320,7 @@ static void cr_exp100_done(struct Curl_easy *data,
                            struct Curl_creader *reader, int premature)
                            struct Curl_creader *reader, int premature)
 {
 {
   struct cr_exp100_ctx *ctx = reader->ctx;
   struct cr_exp100_ctx *ctx = reader->ctx;
-  ctx->state = premature? EXP100_FAILED : EXP100_SEND_DATA;
+  ctx->state = premature ? EXP100_FAILED : EXP100_SEND_DATA;
   data->req.keepon &= ~KEEP_SEND_TIMED;
   data->req.keepon &= ~KEEP_SEND_TIMED;
   Curl_expire_done(data, EXPIRE_100_TIMEOUT);
   Curl_expire_done(data, EXPIRE_100_TIMEOUT);
 }
 }
@@ -4545,7 +4386,7 @@ static void http_exp100_send_anyway(struct Curl_easy *data)
 bool Curl_http_exp100_is_selected(struct Curl_easy *data)
 bool Curl_http_exp100_is_selected(struct Curl_easy *data)
 {
 {
   struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100);
   struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100);
-  return r? TRUE : FALSE;
+  return !!r;
 }
 }
 
 
 #endif /* CURL_DISABLE_HTTP */
 #endif /* CURL_DISABLE_HTTP */

+ 0 - 3
lib/http.h

@@ -89,9 +89,6 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
                                  void *headers
                                  void *headers
 #endif
 #endif
   );
   );
-CURLcode Curl_dynhds_add_custom(struct Curl_easy *data,
-                                bool is_connect,
-                                struct dynhds *hds);
 
 
 void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
 void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
                       const char **method, Curl_HttpReq *);
                       const char **method, Curl_HttpReq *);

+ 5 - 5
lib/http1.c

@@ -128,7 +128,7 @@ static ssize_t next_line(struct h1_req_parser *parser,
   else if(*err == CURLE_AGAIN) {
   else if(*err == CURLE_AGAIN) {
     /* no line end in `buf`, add it to our scratch */
     /* no line end in `buf`, add it to our scratch */
     *err = Curl_dyn_addn(&parser->scratch, (const unsigned char *)buf, buflen);
     *err = Curl_dyn_addn(&parser->scratch, (const unsigned char *)buf, buflen);
-    nread = (*err)? -1 : (ssize_t)buflen;
+    nread = (*err) ? -1 : (ssize_t)buflen;
   }
   }
   return nread;
   return nread;
 }
 }
@@ -325,10 +325,10 @@ CURLcode Curl_h1_req_write_head(struct httpreq *req, int http_minor,
 
 
   result = Curl_dyn_addf(dbuf, "%s %s%s%s%s HTTP/1.%d\r\n",
   result = Curl_dyn_addf(dbuf, "%s %s%s%s%s HTTP/1.%d\r\n",
                          req->method,
                          req->method,
-                         req->scheme? req->scheme : "",
-                         req->scheme? "://" : "",
-                         req->authority? req->authority : "",
-                         req->path? req->path : "",
+                         req->scheme ? req->scheme : "",
+                         req->scheme ? "://" : "",
+                         req->authority ? req->authority : "",
+                         req->path ? req->path : "",
                          http_minor);
                          http_minor);
   if(result)
   if(result)
     goto out;
     goto out;

+ 103 - 49
lib/http2.c

@@ -254,7 +254,7 @@ static struct h2_stream_ctx *h2_stream_ctx_create(struct cf_h2_ctx *ctx)
 static void free_push_headers(struct h2_stream_ctx *stream)
 static void free_push_headers(struct h2_stream_ctx *stream)
 {
 {
   size_t i;
   size_t i;
-  for(i = 0; i<stream->push_headers_used; i++)
+  for(i = 0; i < stream->push_headers_used; i++)
     free(stream->push_headers[i]);
     free(stream->push_headers[i]);
   Curl_safefree(stream->push_headers);
   Curl_safefree(stream->push_headers);
   stream->push_headers_used = 0;
   stream->push_headers_used = 0;
@@ -299,7 +299,7 @@ static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf,
   int32_t dwsize;
   int32_t dwsize;
   int rv;
   int rv;
 
 
-  dwsize = paused? 0 : cf_h2_get_desired_local_win(cf, data);
+  dwsize = paused ? 0 : cf_h2_get_desired_local_win(cf, data);
   if(dwsize != stream->local_window_size) {
   if(dwsize != stream->local_window_size) {
     int32_t wsize = nghttp2_session_get_stream_effective_local_window_size(
     int32_t wsize = nghttp2_session_get_stream_effective_local_window_size(
                       ctx->h2, stream->id);
                       ctx->h2, stream->id);
@@ -433,6 +433,8 @@ static int h2_client_new(struct Curl_cfilter *cf,
 {
 {
   struct cf_h2_ctx *ctx = cf->ctx;
   struct cf_h2_ctx *ctx = cf->ctx;
   nghttp2_option *o;
   nghttp2_option *o;
+  nghttp2_mem mem = {NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
+                     Curl_nghttp2_calloc, Curl_nghttp2_realloc};
 
 
   int rc = nghttp2_option_new(&o);
   int rc = nghttp2_option_new(&o);
   if(rc)
   if(rc)
@@ -445,7 +447,7 @@ static int h2_client_new(struct Curl_cfilter *cf,
      HTTP field value. */
      HTTP field value. */
   nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
   nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
 #endif
 #endif
-  rc = nghttp2_session_client_new2(&ctx->h2, cbs, cf, o);
+  rc = nghttp2_session_client_new3(&ctx->h2, cbs, cf, o, &mem);
   nghttp2_option_del(o);
   nghttp2_option_del(o);
   return rc;
   return rc;
 }
 }
@@ -498,9 +500,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
                      const uint8_t *value, size_t valuelen,
                      const uint8_t *value, size_t valuelen,
                      uint8_t flags,
                      uint8_t flags,
                      void *userp);
                      void *userp);
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
 static int error_callback(nghttp2_session *session, const char *msg,
 static int error_callback(nghttp2_session *session, const char *msg,
                           size_t len, void *userp);
                           size_t len, void *userp);
-
+#endif
 static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
 static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
                                struct Curl_easy *data)
                                struct Curl_easy *data)
 {
 {
@@ -530,7 +533,9 @@ static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
   nghttp2_session_callbacks_set_on_begin_headers_callback(
   nghttp2_session_callbacks_set_on_begin_headers_callback(
     cbs, on_begin_headers);
     cbs, on_begin_headers);
   nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
   nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
   nghttp2_session_callbacks_set_error_callback(cbs, error_callback);
   nghttp2_session_callbacks_set_error_callback(cbs, error_callback);
+#endif
 
 
   /* The nghttp2 session is not yet setup, do it */
   /* The nghttp2 session is not yet setup, do it */
   rc = h2_client_new(cf, cbs);
   rc = h2_client_new(cf, cbs);
@@ -606,7 +611,7 @@ static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
   /* all set, traffic will be send on connect */
   /* all set, traffic will be send on connect */
   result = CURLE_OK;
   result = CURLE_OK;
   CURL_TRC_CF(data, cf, "[0] created h2 session%s",
   CURL_TRC_CF(data, cf, "[0] created h2 session%s",
-              ctx->via_h1_upgrade? " (via h1 upgrade)" : "");
+              ctx->via_h1_upgrade ? " (via h1 upgrade)" : "");
 
 
 out:
 out:
   if(cbs)
   if(cbs)
@@ -764,7 +769,7 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
     }
     }
     return result;
     return result;
   }
   }
-  return Curl_bufq_is_empty(&ctx->outbufq)? CURLE_OK: CURLE_AGAIN;
+  return Curl_bufq_is_empty(&ctx->outbufq) ? CURLE_OK : CURLE_AGAIN;
 }
 }
 
 
 /*
 /*
@@ -786,8 +791,11 @@ static ssize_t send_callback(nghttp2_session *h2,
   (void)flags;
   (void)flags;
   DEBUGASSERT(data);
   DEBUGASSERT(data);
 
 
-  nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
-                                  nw_out_writer, cf, &result);
+  if(!cf->connected)
+    nwritten = Curl_bufq_write(&ctx->outbufq, buf, blen, &result);
+  else
+    nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
+                                    nw_out_writer, cf, &result);
   if(nwritten < 0) {
   if(nwritten < 0) {
     if(result == CURLE_AGAIN) {
     if(result == CURLE_AGAIN) {
       ctx->nw_out_blocked = 1;
       ctx->nw_out_blocked = 1;
@@ -852,7 +860,7 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
     return NULL;
     return NULL;
 
 
   len = strlen(header);
   len = strlen(header);
-  for(i = 0; i<stream->push_headers_used; i++) {
+  for(i = 0; i < stream->push_headers_used; i++) {
     if(!strncmp(header, stream->push_headers[i], len)) {
     if(!strncmp(header, stream->push_headers[i], len)) {
       /* sub-match, make sure that it is followed by a colon */
       /* sub-match, make sure that it is followed by a colon */
       if(stream->push_headers[i][len] != ':')
       if(stream->push_headers[i][len] != ':')
@@ -990,11 +998,11 @@ static int push_promise(struct Curl_cfilter *cf,
     }
     }
     DEBUGASSERT(stream);
     DEBUGASSERT(stream);
 
 
-    Curl_set_in_callback(data, true);
+    Curl_set_in_callback(data, TRUE);
     rv = data->multi->push_cb(data, newhandle,
     rv = data->multi->push_cb(data, newhandle,
                               stream->push_headers_used, &heads,
                               stream->push_headers_used, &heads,
                               data->multi->push_userp);
                               data->multi->push_userp);
-    Curl_set_in_callback(data, false);
+    Curl_set_in_callback(data, FALSE);
 
 
     /* free the headers again */
     /* free the headers again */
     free_push_headers(stream);
     free_push_headers(stream);
@@ -1113,9 +1121,6 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
         return CURLE_RECV_ERROR;
         return CURLE_RECV_ERROR;
       }
       }
     }
     }
-    if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
-      drain_stream(cf, data, stream);
-    }
     break;
     break;
   case NGHTTP2_HEADERS:
   case NGHTTP2_HEADERS:
     if(stream->bodystarted) {
     if(stream->bodystarted) {
@@ -1131,10 +1136,10 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
       return CURLE_RECV_ERROR;
       return CURLE_RECV_ERROR;
 
 
     /* Only final status code signals the end of header */
     /* Only final status code signals the end of header */
-    if(stream->status_code / 100 != 1) {
+    if(stream->status_code / 100 != 1)
       stream->bodystarted = TRUE;
       stream->bodystarted = TRUE;
+    else
       stream->status_code = -1;
       stream->status_code = -1;
-    }
 
 
     h2_xfer_write_resp_hd(cf, data, stream, STRCONST("\r\n"), stream->closed);
     h2_xfer_write_resp_hd(cf, data, stream, STRCONST("\r\n"), stream->closed);
 
 
@@ -1181,6 +1186,22 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
   default:
   default:
     break;
     break;
   }
   }
+
+  if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
+    if(!stream->closed && !stream->body_eos &&
+       ((stream->status_code >= 400) || (stream->status_code < 200))) {
+      /* The server did not give us a positive response and we are not
+       * done uploading the request body. We need to stop doing that and
+       * also inform the server that we aborted our side. */
+      CURL_TRC_CF(data, cf, "[%d] EOS frame with unfinished upload and "
+                  "HTTP status %d, abort upload by RST",
+                  stream_id, stream->status_code);
+      nghttp2_submit_rst_stream(ctx->h2, NGHTTP2_FLAG_NONE,
+                                stream->id, NGHTTP2_STREAM_CLOSED);
+      stream->closed = TRUE;
+    }
+    drain_stream(cf, data, stream);
+  }
   return CURLE_OK;
   return CURLE_OK;
 }
 }
 
 
@@ -1235,14 +1256,14 @@ static int fr_print(const nghttp2_frame *frame, char *buffer, size_t blen)
     case NGHTTP2_GOAWAY: {
     case NGHTTP2_GOAWAY: {
       char scratch[128];
       char scratch[128];
       size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
       size_t s_len = sizeof(scratch)/sizeof(scratch[0]);
-        size_t len = (frame->goaway.opaque_data_len < s_len)?
-                      frame->goaway.opaque_data_len : s_len-1;
-        if(len)
-          memcpy(scratch, frame->goaway.opaque_data, len);
-        scratch[len] = '\0';
-        return msnprintf(buffer, blen, "FRAME[GOAWAY, error=%d, reason='%s', "
-                         "last_stream=%d]", frame->goaway.error_code,
-                         scratch, frame->goaway.last_stream_id);
+      size_t len = (frame->goaway.opaque_data_len < s_len) ?
+        frame->goaway.opaque_data_len : s_len-1;
+      if(len)
+        memcpy(scratch, frame->goaway.opaque_data, len);
+      scratch[len] = '\0';
+      return msnprintf(buffer, blen, "FRAME[GOAWAY, error=%d, reason='%s', "
+                       "last_stream=%d]", frame->goaway.error_code,
+                       scratch, frame->goaway.last_stream_id);
     }
     }
     case NGHTTP2_WINDOW_UPDATE: {
     case NGHTTP2_WINDOW_UPDATE: {
       return msnprintf(buffer, blen,
       return msnprintf(buffer, blen,
@@ -1350,7 +1371,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
     return 0;
     return 0;
   }
   }
 
 
-  return on_stream_frame(cf, data_s, frame)? NGHTTP2_ERR_CALLBACK_FAILURE : 0;
+  return on_stream_frame(cf, data_s, frame) ? NGHTTP2_ERR_CALLBACK_FAILURE : 0;
 }
 }
 
 
 static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
 static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
@@ -1402,8 +1423,8 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
 
 
   DEBUGASSERT(call_data);
   DEBUGASSERT(call_data);
   /* stream id 0 is the connection, do not look there for streams. */
   /* stream id 0 is the connection, do not look there for streams. */
-  data_s = stream_id?
-             nghttp2_session_get_stream_user_data(session, stream_id) : NULL;
+  data_s = stream_id ?
+    nghttp2_session_get_stream_user_data(session, stream_id) : NULL;
   if(!data_s) {
   if(!data_s) {
     CURL_TRC_CF(call_data, cf,
     CURL_TRC_CF(call_data, cf,
                 "[%d] on_stream_close, no easy set on stream", stream_id);
                 "[%d] on_stream_close, no easy set on stream", stream_id);
@@ -1683,7 +1704,7 @@ static ssize_t req_body_read_callback(nghttp2_session *session,
     *data_flags = NGHTTP2_DATA_FLAG_EOF;
     *data_flags = NGHTTP2_DATA_FLAG_EOF;
     return nread;
     return nread;
   }
   }
-  return (nread == 0)? NGHTTP2_ERR_DEFERRED : nread;
+  return (nread == 0) ? NGHTTP2_ERR_DEFERRED : nread;
 }
 }
 
 
 #if !defined(CURL_DISABLE_VERBOSE_STRINGS)
 #if !defined(CURL_DISABLE_VERBOSE_STRINGS)
@@ -1773,7 +1794,7 @@ static ssize_t http2_handle_stream_close(struct Curl_cfilter *cf,
   }
   }
   else if(stream->reset) {
   else if(stream->reset) {
     failf(data, "HTTP/2 stream %u was reset", stream->id);
     failf(data, "HTTP/2 stream %u was reset", stream->id);
-    *err = data->req.bytecount? CURLE_PARTIAL_FILE : CURLE_HTTP2;
+    *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2;
     return -1;
     return -1;
   }
   }
 
 
@@ -1826,14 +1847,14 @@ out:
 static int sweight_wanted(const struct Curl_easy *data)
 static int sweight_wanted(const struct Curl_easy *data)
 {
 {
   /* 0 weight is not set by user and we take the nghttp2 default one */
   /* 0 weight is not set by user and we take the nghttp2 default one */
-  return data->set.priority.weight?
+  return data->set.priority.weight ?
     data->set.priority.weight : NGHTTP2_DEFAULT_WEIGHT;
     data->set.priority.weight : NGHTTP2_DEFAULT_WEIGHT;
 }
 }
 
 
 static int sweight_in_effect(const struct Curl_easy *data)
 static int sweight_in_effect(const struct Curl_easy *data)
 {
 {
   /* 0 weight is not set by user and we take the nghttp2 default one */
   /* 0 weight is not set by user and we take the nghttp2 default one */
-  return data->state.priority.weight?
+  return data->state.priority.weight ?
     data->state.priority.weight : NGHTTP2_DEFAULT_WEIGHT;
     data->state.priority.weight : NGHTTP2_DEFAULT_WEIGHT;
 }
 }
 
 
@@ -1849,7 +1870,7 @@ static void h2_pri_spec(struct cf_h2_ctx *ctx,
 {
 {
   struct Curl_data_priority *prio = &data->set.priority;
   struct Curl_data_priority *prio = &data->set.priority;
   struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent);
   struct h2_stream_ctx *depstream = H2_STREAM_CTX(ctx, prio->parent);
-  int32_t depstream_id = depstream? depstream->id:0;
+  int32_t depstream_id = depstream ? depstream->id : 0;
   nghttp2_priority_spec_init(pri_spec, depstream_id,
   nghttp2_priority_spec_init(pri_spec, depstream_id,
                              sweight_wanted(data),
                              sweight_wanted(data),
                              data->set.priority.exclusive);
                              data->set.priority.exclusive);
@@ -1895,6 +1916,11 @@ out:
                 nghttp2_strerror(rv), rv);
                 nghttp2_strerror(rv), rv);
     return CURLE_SEND_ERROR;
     return CURLE_SEND_ERROR;
   }
   }
+  /* Defer flushing during the connect phase so that the SETTINGS and
+   * other initial frames are sent together with the first request.
+   * Unless we are 'connect_only' where the request will never come. */
+  if(!cf->connected && !cf->conn->connect_only)
+    return CURLE_OK;
   return nw_out_flush(cf, data);
   return nw_out_flush(cf, data);
 }
 }
 
 
@@ -1920,7 +1946,7 @@ static ssize_t stream_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
           (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) ||
           (ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) ||
           (ctx->rcvd_goaway && ctx->remote_max_sid < stream->id)) {
           (ctx->rcvd_goaway && ctx->remote_max_sid < stream->id)) {
     CURL_TRC_CF(data, cf, "[%d] returning ERR", stream->id);
     CURL_TRC_CF(data, cf, "[%d] returning ERR", stream->id);
-    *err = data->req.bytecount? CURLE_PARTIAL_FILE : CURLE_HTTP2;
+    *err = data->req.bytecount ? CURLE_PARTIAL_FILE : CURLE_HTTP2;
     nread = -1;
     nread = -1;
   }
   }
 
 
@@ -1978,8 +2004,8 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
     }
     }
     else {
     else {
       CURL_TRC_CF(data, cf, "[0] ingress: read %zd bytes", nread);
       CURL_TRC_CF(data, cf, "[0] ingress: read %zd bytes", nread);
-      data_max_bytes = (data_max_bytes > (size_t)nread)?
-                        (data_max_bytes - (size_t)nread) : 0;
+      data_max_bytes = (data_max_bytes > (size_t)nread) ?
+        (data_max_bytes - (size_t)nread) : 0;
     }
     }
 
 
     if(h2_process_pending_input(cf, data, &result))
     if(h2_process_pending_input(cf, data, &result))
@@ -2244,7 +2270,7 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream,
 
 
 out:
 out:
   CURL_TRC_CF(data, cf, "[%d] submit -> %zd, %d",
   CURL_TRC_CF(data, cf, "[%d] submit -> %zd, %d",
-              stream? stream->id : -1, nwritten, *err);
+              stream ? stream->id : -1, nwritten, *err);
   Curl_safefree(nva);
   Curl_safefree(nva);
   *pstream = stream;
   *pstream = stream;
   Curl_dynhds_free(&h2_headers);
   Curl_dynhds_free(&h2_headers);
@@ -2436,6 +2462,7 @@ static CURLcode cf_h2_connect(struct Curl_cfilter *cf,
   struct cf_h2_ctx *ctx = cf->ctx;
   struct cf_h2_ctx *ctx = cf->ctx;
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct cf_call_data save;
   struct cf_call_data save;
+  bool first_time = FALSE;
 
 
   if(cf->connected) {
   if(cf->connected) {
     *done = TRUE;
     *done = TRUE;
@@ -2457,11 +2484,14 @@ static CURLcode cf_h2_connect(struct Curl_cfilter *cf,
     result = cf_h2_ctx_open(cf, data);
     result = cf_h2_ctx_open(cf, data);
     if(result)
     if(result)
       goto out;
       goto out;
+    first_time = TRUE;
   }
   }
 
 
-  result = h2_progress_ingress(cf, data, H2_CHUNK_SIZE);
-  if(result)
-    goto out;
+  if(!first_time) {
+    result = h2_progress_ingress(cf, data, H2_CHUNK_SIZE);
+    if(result)
+      goto out;
+  }
 
 
   /* Send out our SETTINGS and ACKs and such. If that blocks, we
   /* Send out our SETTINGS and ACKs and such. If that blocks, we
    * have it buffered and  can count this filter as being connected */
    * have it buffered and  can count this filter as being connected */
@@ -2584,7 +2614,7 @@ static CURLcode http2_data_pause(struct Curl_cfilter *cf,
       Curl_expire(data, 0, EXPIRE_RUN_NOW);
       Curl_expire(data, 0, EXPIRE_RUN_NOW);
     }
     }
     CURL_TRC_CF(data, cf, "[%d] stream now %spaused", stream->id,
     CURL_TRC_CF(data, cf, "[%d] stream now %spaused", stream->id,
-                pause? "" : "un");
+                pause ? "" : "un");
   }
   }
   return CURLE_OK;
   return CURLE_OK;
 }
 }
@@ -2630,7 +2660,7 @@ static bool cf_h2_data_pending(struct Curl_cfilter *cf,
   if(ctx && (!Curl_bufq_is_empty(&ctx->inbufq)
   if(ctx && (!Curl_bufq_is_empty(&ctx->inbufq)
             || (stream && !Curl_bufq_is_empty(&stream->sendbuf))))
             || (stream && !Curl_bufq_is_empty(&stream->sendbuf))))
     return TRUE;
     return TRUE;
-  return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
+  return cf->next ? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
 }
 }
 
 
 static bool cf_h2_is_alive(struct Curl_cfilter *cf,
 static bool cf_h2_is_alive(struct Curl_cfilter *cf,
@@ -2681,12 +2711,12 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf,
     else {
     else {
       effective_max = ctx->max_concurrent_streams;
       effective_max = ctx->max_concurrent_streams;
     }
     }
-    *pres1 = (effective_max > INT_MAX)? INT_MAX : (int)effective_max;
+    *pres1 = (effective_max > INT_MAX) ? INT_MAX : (int)effective_max;
     CF_DATA_RESTORE(cf, save);
     CF_DATA_RESTORE(cf, save);
     return CURLE_OK;
     return CURLE_OK;
   case CF_QUERY_STREAM_ERROR: {
   case CF_QUERY_STREAM_ERROR: {
     struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data);
     struct h2_stream_ctx *stream = H2_STREAM_CTX(ctx, data);
-    *pres1 = stream? (int)stream->error : 0;
+    *pres1 = stream ? (int)stream->error : 0;
     return CURLE_OK;
     return CURLE_OK;
   }
   }
   case CF_QUERY_NEED_FLUSH: {
   case CF_QUERY_NEED_FLUSH: {
@@ -2701,7 +2731,7 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf,
   default:
   default:
     break;
     break;
   }
   }
-  return cf->next?
+  return cf->next ?
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     cf->next->cft->query(cf->next, data, query, pres1, pres2) :
     CURLE_UNKNOWN_OPTION;
     CURLE_UNKNOWN_OPTION;
 }
 }
@@ -2751,7 +2781,7 @@ static CURLcode http2_cfilter_add(struct Curl_cfilter **pcf,
 out:
 out:
   if(result)
   if(result)
     cf_h2_ctx_free(ctx);
     cf_h2_ctx_free(ctx);
-  *pcf = result? NULL : cf;
+  *pcf = result ? NULL : cf;
   return result;
   return result;
 }
 }
 
 
@@ -2782,8 +2812,8 @@ out:
   return result;
   return result;
 }
 }
 
 
-static bool Curl_cf_is_http2(struct Curl_cfilter *cf,
-                             const struct Curl_easy *data)
+static bool cf_is_http2(struct Curl_cfilter *cf,
+                        const struct Curl_easy *data)
 {
 {
   (void)data;
   (void)data;
   for(; cf; cf = cf->next) {
   for(; cf; cf = cf->next) {
@@ -2799,7 +2829,7 @@ bool Curl_conn_is_http2(const struct Curl_easy *data,
                         const struct connectdata *conn,
                         const struct connectdata *conn,
                         int sockindex)
                         int sockindex)
 {
 {
-  return conn? Curl_cf_is_http2(conn->cfilter[sockindex], data) : FALSE;
+  return conn ? cf_is_http2(conn->cfilter[sockindex], data) : FALSE;
 }
 }
 
 
 bool Curl_http2_may_switch(struct Curl_easy *data,
 bool Curl_http2_may_switch(struct Curl_easy *data,
@@ -2851,7 +2881,7 @@ CURLcode Curl_http2_switch_at(struct Curl_cfilter *cf, struct Curl_easy *data)
   struct Curl_cfilter *cf_h2;
   struct Curl_cfilter *cf_h2;
   CURLcode result;
   CURLcode result;
 
 
-  DEBUGASSERT(!Curl_cf_is_http2(cf, data));
+  DEBUGASSERT(!cf_is_http2(cf, data));
 
 
   result = http2_cfilter_insert_after(cf, data, FALSE);
   result = http2_cfilter_insert_after(cf, data, FALSE);
   if(result)
   if(result)
@@ -2932,6 +2962,30 @@ bool Curl_h2_http_1_1_error(struct Curl_easy *data)
   return FALSE;
   return FALSE;
 }
 }
 
 
+void *Curl_nghttp2_malloc(size_t size, void *user_data)
+{
+  (void)user_data;
+  return Curl_cmalloc(size);
+}
+
+void Curl_nghttp2_free(void *ptr, void *user_data)
+{
+  (void)user_data;
+  Curl_cfree(ptr);
+}
+
+void *Curl_nghttp2_calloc(size_t nmemb, size_t size, void *user_data)
+{
+  (void)user_data;
+  return Curl_ccalloc(nmemb, size);
+}
+
+void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data)
+{
+  (void)user_data;
+  return Curl_crealloc(ptr, size);
+}
+
 #else /* !USE_NGHTTP2 */
 #else /* !USE_NGHTTP2 */
 
 
 /* Satisfy external references even if http2 is not compiled in. */
 /* Satisfy external references even if http2 is not compiled in. */

+ 5 - 0
lib/http2.h

@@ -60,6 +60,11 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data,
                             struct connectdata *conn, int sockindex,
                             struct connectdata *conn, int sockindex,
                             const char *ptr, size_t nread);
                             const char *ptr, size_t nread);
 
 
+void *Curl_nghttp2_malloc(size_t size, void *user_data);
+void Curl_nghttp2_free(void *ptr, void *user_data);
+void *Curl_nghttp2_calloc(size_t nmemb, size_t size, void *user_data);
+void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data);
+
 extern struct Curl_cftype Curl_cft_nghttp2;
 extern struct Curl_cftype Curl_cft_nghttp2;
 
 
 #else /* USE_NGHTTP2 */
 #else /* USE_NGHTTP2 */

+ 18 - 31
lib/http_aws_sigv4.c

@@ -47,7 +47,7 @@
 
 
 #define HMAC_SHA256(k, kl, d, dl, o)           \
 #define HMAC_SHA256(k, kl, d, dl, o)           \
   do {                                         \
   do {                                         \
-    result = Curl_hmacit(Curl_HMAC_SHA256,     \
+    result = Curl_hmacit(&Curl_HMAC_SHA256,    \
                          (unsigned char *)k,   \
                          (unsigned char *)k,   \
                          kl,                   \
                          kl,                   \
                          (unsigned char *)d,   \
                          (unsigned char *)d,   \
@@ -122,10 +122,6 @@ static void trim_headers(struct curl_slist *head)
 
 
 #define DATE_HDR_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Date"))
 #define DATE_HDR_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Date"))
 
 
-#define MAX_HOST_LEN 255
-/* FQDN + host: */
-#define FULL_HOST_LEN (MAX_HOST_LEN + sizeof("host:"))
-
 /* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */
 /* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */
 #define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1)
 #define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1)
 
 
@@ -176,7 +172,7 @@ static CURLcode make_headers(struct Curl_easy *data,
   struct curl_slist *tmp_head = NULL;
   struct curl_slist *tmp_head = NULL;
   CURLcode ret = CURLE_OUT_OF_MEMORY;
   CURLcode ret = CURLE_OUT_OF_MEMORY;
   struct curl_slist *l;
   struct curl_slist *l;
-  int again = 1;
+  bool again = TRUE;
 
 
   /* provider1 mid */
   /* provider1 mid */
   Curl_strntolower(provider1, provider1, strlen(provider1));
   Curl_strntolower(provider1, provider1, strlen(provider1));
@@ -190,31 +186,22 @@ static CURLcode make_headers(struct Curl_easy *data,
             "x-%s-date:%s", provider1, timestamp);
             "x-%s-date:%s", provider1, timestamp);
 
 
   if(!Curl_checkheaders(data, STRCONST("Host"))) {
   if(!Curl_checkheaders(data, STRCONST("Host"))) {
-    char full_host[FULL_HOST_LEN + 1];
+    char *fullhost;
 
 
     if(data->state.aptr.host) {
     if(data->state.aptr.host) {
-      size_t pos;
-
-      if(strlen(data->state.aptr.host) > FULL_HOST_LEN) {
-        ret = CURLE_URL_MALFORMAT;
-        goto fail;
-      }
-      strcpy(full_host, data->state.aptr.host);
       /* remove /r/n as the separator for canonical request must be '\n' */
       /* remove /r/n as the separator for canonical request must be '\n' */
-      pos = strcspn(full_host, "\n\r");
-      full_host[pos] = 0;
-    }
-    else {
-      if(strlen(hostname) > MAX_HOST_LEN) {
-        ret = CURLE_URL_MALFORMAT;
-        goto fail;
-      }
-      msnprintf(full_host, FULL_HOST_LEN, "host:%s", hostname);
+      size_t pos = strcspn(data->state.aptr.host, "\n\r");
+      fullhost = Curl_memdup0(data->state.aptr.host, pos);
     }
     }
+    else
+      fullhost = aprintf("host:%s", hostname);
 
 
-    head = curl_slist_append(NULL, full_host);
-    if(!head)
+    if(fullhost)
+      head = Curl_slist_append_nodup(NULL, fullhost);
+    if(!head) {
+      free(fullhost);
       goto fail;
       goto fail;
+    }
   }
   }
 
 
 
 
@@ -300,7 +287,7 @@ static CURLcode make_headers(struct Curl_easy *data,
 
 
   /* alpha-sort by header name in a case sensitive manner */
   /* alpha-sort by header name in a case sensitive manner */
   do {
   do {
-    again = 0;
+    again = FALSE;
     for(l = head; l; l = l->next) {
     for(l = head; l; l = l->next) {
       struct curl_slist *next = l->next;
       struct curl_slist *next = l->next;
 
 
@@ -309,7 +296,7 @@ static CURLcode make_headers(struct Curl_easy *data,
 
 
         l->data = next->data;
         l->data = next->data;
         next->data = tmp;
         next->data = tmp;
-        again = 1;
+        again = TRUE;
       }
       }
     }
     }
   } while(again);
   } while(again);
@@ -507,12 +494,12 @@ static CURLcode canon_string(const char *q, size_t len,
           /* allowed as-is */
           /* allowed as-is */
           if(*q == '=') {
           if(*q == '=') {
             result = Curl_dyn_addn(dq, q, 1);
             result = Curl_dyn_addn(dq, q, 1);
-            *found_equals = true;
+            *found_equals = TRUE;
             break;
             break;
           }
           }
         }
         }
         /* URL encode */
         /* URL encode */
-        out[1] = hex[((unsigned char)*q)>>4];
+        out[1] = hex[((unsigned char)*q) >> 4];
         out[2] = hex[*q & 0xf];
         out[2] = hex[*q & 0xf];
         result = Curl_dyn_addn(dq, out, 3);
         result = Curl_dyn_addn(dq, out, 3);
         break;
         break;
@@ -562,7 +549,7 @@ static CURLcode canon_query(struct Curl_easy *data,
   ap = &array[0];
   ap = &array[0];
   for(i = 0; !result && (i < entry); i++, ap++) {
   for(i = 0; !result && (i < entry); i++, ap++) {
     const char *q = ap->p;
     const char *q = ap->p;
-    bool found_equals = false;
+    bool found_equals = FALSE;
     if(!ap->len)
     if(!ap->len)
       continue;
       continue;
     result = canon_string(q, ap->len, dq, &found_equals);
     result = canon_string(q, ap->len, dq, &found_equals);
@@ -589,7 +576,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
   char provider1[MAX_SIGV4_LEN + 1]="";
   char provider1[MAX_SIGV4_LEN + 1]="";
   char region[MAX_SIGV4_LEN + 1]="";
   char region[MAX_SIGV4_LEN + 1]="";
   char service[MAX_SIGV4_LEN + 1]="";
   char service[MAX_SIGV4_LEN + 1]="";
-  bool sign_as_s3 = false;
+  bool sign_as_s3 = FALSE;
   const char *hostname = conn->host.name;
   const char *hostname = conn->host.name;
   time_t clock;
   time_t clock;
   struct tm tm;
   struct tm tm;

+ 2 - 2
lib/http_chunks.c

@@ -516,9 +516,9 @@ static CURLcode add_last_chunk(struct Curl_easy *data,
   if(result)
   if(result)
     goto out;
     goto out;
 
 
-  Curl_set_in_callback(data, true);
+  Curl_set_in_callback(data, TRUE);
   rc = data->set.trailer_callback(&trailers, data->set.trailer_data);
   rc = data->set.trailer_callback(&trailers, data->set.trailer_data);
-  Curl_set_in_callback(data, false);
+  Curl_set_in_callback(data, FALSE);
 
 
   if(rc != CURL_TRAILERFUNC_OK) {
   if(rc != CURL_TRAILERFUNC_OK) {
     failf(data, "operation aborted by trailing headers callback");
     failf(data, "operation aborted by trailing headers callback");

+ 2 - 2
lib/http_digest.c

@@ -121,9 +121,9 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
     passwdp = "";
     passwdp = "";
 
 
 #if defined(USE_WINDOWS_SSPI)
 #if defined(USE_WINDOWS_SSPI)
-  have_chlg = digest->input_token ? TRUE : FALSE;
+  have_chlg = !!digest->input_token;
 #else
 #else
-  have_chlg = digest->nonce ? TRUE : FALSE;
+  have_chlg = !!digest->nonce;
 #endif
 #endif
 
 
   if(!have_chlg) {
   if(!have_chlg) {

+ 3 - 3
lib/http_negotiate.c

@@ -108,9 +108,9 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
   neg_ctx->sslContext = conn->sslContext;
   neg_ctx->sslContext = conn->sslContext;
 #endif
 #endif
   /* Check if the connection is using SSL and get the channel binding data */
   /* Check if the connection is using SSL and get the channel binding data */
-#ifdef HAVE_GSSAPI
+#if defined(USE_SSL) && defined(HAVE_GSSAPI)
   if(conn->handler->flags & PROTOPT_SSL) {
   if(conn->handler->flags & PROTOPT_SSL) {
-    Curl_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE);
+    Curl_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE + 1);
     result = Curl_ssl_get_channel_binding(
     result = Curl_ssl_get_channel_binding(
       data, FIRSTSOCKET, &neg_ctx->channel_binding_data);
       data, FIRSTSOCKET, &neg_ctx->channel_binding_data);
     if(result) {
     if(result) {
@@ -124,7 +124,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
   result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
   result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
                                            host, header, neg_ctx);
                                            host, header, neg_ctx);
 
 
-#ifdef HAVE_GSSAPI
+#if defined(USE_SSL) && defined(HAVE_GSSAPI)
   Curl_dyn_free(&neg_ctx->channel_binding_data);
   Curl_dyn_free(&neg_ctx->channel_binding_data);
 #endif
 #endif
 
 

+ 148 - 5
lib/http_proxy.c

@@ -45,12 +45,155 @@
 #include "vtls/vtls.h"
 #include "vtls/vtls.h"
 #include "transfer.h"
 #include "transfer.h"
 #include "multiif.h"
 #include "multiif.h"
+#include "vauth/vauth.h"
 
 
 /* The last 3 #include files should be in this order */
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
 #include "curl_printf.h"
 #include "curl_memory.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 #include "memdebug.h"
 
 
+static bool hd_name_eq(const char *n1, size_t n1len,
+                       const char *n2, size_t n2len)
+{
+  return (n1len == n2len) ? strncasecompare(n1, n2, n1len) : FALSE;
+}
+
+static CURLcode dynhds_add_custom(struct Curl_easy *data,
+                                  bool is_connect,
+                                  struct dynhds *hds)
+{
+  struct connectdata *conn = data->conn;
+  char *ptr;
+  struct curl_slist *h[2];
+  struct curl_slist *headers;
+  int numlists = 1; /* by default */
+  int i;
+
+  enum Curl_proxy_use proxy;
+
+  if(is_connect)
+    proxy = HEADER_CONNECT;
+  else
+    proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy ?
+      HEADER_PROXY : HEADER_SERVER;
+
+  switch(proxy) {
+  case HEADER_SERVER:
+    h[0] = data->set.headers;
+    break;
+  case HEADER_PROXY:
+    h[0] = data->set.headers;
+    if(data->set.sep_headers) {
+      h[1] = data->set.proxyheaders;
+      numlists++;
+    }
+    break;
+  case HEADER_CONNECT:
+    if(data->set.sep_headers)
+      h[0] = data->set.proxyheaders;
+    else
+      h[0] = data->set.headers;
+    break;
+  }
+
+  /* loop through one or two lists */
+  for(i = 0; i < numlists; i++) {
+    for(headers = h[i]; headers; headers = headers->next) {
+      const char *name, *value;
+      size_t namelen, valuelen;
+
+      /* There are 2 quirks in place for custom headers:
+       * 1. setting only 'name:' to suppress a header from being sent
+       * 2. setting only 'name;' to send an empty (illegal) header
+       */
+      ptr = strchr(headers->data, ':');
+      if(ptr) {
+        name = headers->data;
+        namelen = ptr - headers->data;
+        ptr++; /* pass the colon */
+        while(*ptr && ISSPACE(*ptr))
+          ptr++;
+        if(*ptr) {
+          value = ptr;
+          valuelen = strlen(value);
+        }
+        else {
+          /* quirk #1, suppress this header */
+          continue;
+        }
+      }
+      else {
+        ptr = strchr(headers->data, ';');
+
+        if(!ptr) {
+          /* neither : nor ; in provided header value. We seem
+           * to ignore this silently */
+          continue;
+        }
+
+        name = headers->data;
+        namelen = ptr - headers->data;
+        ptr++; /* pass the semicolon */
+        while(*ptr && ISSPACE(*ptr))
+          ptr++;
+        if(!*ptr) {
+          /* quirk #2, send an empty header */
+          value = "";
+          valuelen = 0;
+        }
+        else {
+          /* this may be used for something else in the future,
+           * ignore this for now */
+          continue;
+        }
+      }
+
+      DEBUGASSERT(name && value);
+      if(data->state.aptr.host &&
+         /* a Host: header was sent already, do not pass on any custom Host:
+            header as that will produce *two* in the same request! */
+         hd_name_eq(name, namelen, STRCONST("Host:")))
+        ;
+      else if(data->state.httpreq == HTTPREQ_POST_FORM &&
+              /* this header (extended by formdata.c) is sent later */
+              hd_name_eq(name, namelen, STRCONST("Content-Type:")))
+        ;
+      else if(data->state.httpreq == HTTPREQ_POST_MIME &&
+              /* this header is sent later */
+              hd_name_eq(name, namelen, STRCONST("Content-Type:")))
+        ;
+      else if(data->req.authneg &&
+              /* while doing auth neg, do not allow the custom length since
+                 we will force length zero then */
+              hd_name_eq(name, namelen, STRCONST("Content-Length:")))
+        ;
+      else if(data->state.aptr.te &&
+              /* when asking for Transfer-Encoding, do not pass on a custom
+                 Connection: */
+              hd_name_eq(name, namelen, STRCONST("Connection:")))
+        ;
+      else if((conn->httpversion >= 20) &&
+              hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:")))
+        /* HTTP/2 does not support chunked requests */
+        ;
+      else if((hd_name_eq(name, namelen, STRCONST("Authorization:")) ||
+               hd_name_eq(name, namelen, STRCONST("Cookie:"))) &&
+              /* be careful of sending this potentially sensitive header to
+                 other hosts */
+              !Curl_auth_allowed_to_host(data))
+        ;
+      else {
+        CURLcode result;
+
+        result = Curl_dynhds_add(hds, name, namelen, value, valuelen);
+        if(result)
+          return result;
+      }
+    }
+  }
+
+  return CURLE_OK;
+}
 
 
 CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
 CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
                                          const char **phostname,
                                          const char **phostname,
@@ -97,8 +240,8 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
   if(result)
   if(result)
     goto out;
     goto out;
 
 
-  authority = aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname,
-                      ipv6_ip?"]":"", port);
+  authority = aprintf("%s%s%s:%d", ipv6_ip ? "[" : "", hostname,
+                      ipv6_ip ?"]" : "", port);
   if(!authority) {
   if(!authority) {
     result = CURLE_OUT_OF_MEMORY;
     result = CURLE_OUT_OF_MEMORY;
     goto out;
     goto out;
@@ -146,7 +289,7 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
       goto out;
       goto out;
   }
   }
 
 
-  result = Curl_dynhds_add_custom(data, TRUE, &req->headers);
+  result = dynhds_add_custom(data, TRUE, &req->headers);
 
 
 out:
 out:
   if(result && req) {
   if(result && req) {
@@ -185,7 +328,7 @@ connect_sub:
   *done = FALSE;
   *done = FALSE;
   if(!ctx->cf_protocol) {
   if(!ctx->cf_protocol) {
     struct Curl_cfilter *cf_protocol = NULL;
     struct Curl_cfilter *cf_protocol = NULL;
-    int alpn = Curl_conn_cf_is_ssl(cf->next)?
+    int alpn = Curl_conn_cf_is_ssl(cf->next) ?
       cf->conn->proxy_alpn : CURL_HTTP_VERSION_1_1;
       cf->conn->proxy_alpn : CURL_HTTP_VERSION_1_1;
 
 
     /* First time call after the subchain connected */
     /* First time call after the subchain connected */
@@ -195,7 +338,7 @@ connect_sub:
     case CURL_HTTP_VERSION_1_1:
     case CURL_HTTP_VERSION_1_1:
       CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.1");
       CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.1");
       infof(data, "CONNECT tunnel: HTTP/1.%d negotiated",
       infof(data, "CONNECT tunnel: HTTP/1.%d negotiated",
-            (alpn == CURL_HTTP_VERSION_1_0)? 0 : 1);
+            (alpn == CURL_HTTP_VERSION_1_0) ? 0 : 1);
       result = Curl_cf_h1_proxy_insert_after(cf, data);
       result = Curl_cf_h1_proxy_insert_after(cf, data);
       if(result)
       if(result)
         goto out;
         goto out;

+ 6 - 0
lib/http_proxy.h

@@ -30,6 +30,12 @@
 
 
 #include "urldata.h"
 #include "urldata.h"
 
 
+enum Curl_proxy_use {
+  HEADER_SERVER,  /* direct to server */
+  HEADER_PROXY,   /* regular request to proxy */
+  HEADER_CONNECT  /* sending CONNECT to a proxy */
+};
+
 CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
 CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
                                          const char **phostname,
                                          const char **phostname,
                                          int *pport, bool *pipv6_ip);
                                          int *pport, bool *pipv6_ip);

+ 13 - 13
lib/imap.c

@@ -520,8 +520,8 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
   }
   }
 
 
   /* Make sure the username and password are in the correct atom format */
   /* Make sure the username and password are in the correct atom format */
-  user = imap_atom(conn->user, false);
-  passwd = imap_atom(conn->passwd, false);
+  user = imap_atom(conn->user, FALSE);
+  passwd = imap_atom(conn->passwd, FALSE);
 
 
   /* Send the LOGIN command */
   /* Send the LOGIN command */
   result = imap_sendf(data, "LOGIN %s %s", user ? user : "",
   result = imap_sendf(data, "LOGIN %s %s", user ? user : "",
@@ -655,7 +655,7 @@ static CURLcode imap_perform_list(struct Curl_easy *data)
                         imap->custom_params ? imap->custom_params : "");
                         imap->custom_params ? imap->custom_params : "");
   else {
   else {
     /* Make sure the mailbox is in the correct atom format if necessary */
     /* Make sure the mailbox is in the correct atom format if necessary */
-    char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, true)
+    char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, TRUE)
                                   : strdup("");
                                   : strdup("");
     if(!mailbox)
     if(!mailbox)
       return CURLE_OUT_OF_MEMORY;
       return CURLE_OUT_OF_MEMORY;
@@ -697,7 +697,7 @@ static CURLcode imap_perform_select(struct Curl_easy *data)
   }
   }
 
 
   /* Make sure the mailbox is in the correct atom format */
   /* Make sure the mailbox is in the correct atom format */
-  mailbox = imap_atom(imap->mailbox, false);
+  mailbox = imap_atom(imap->mailbox, FALSE);
   if(!mailbox)
   if(!mailbox)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
@@ -809,7 +809,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data)
   }
   }
 
 
   /* Make sure the mailbox is in the correct atom format */
   /* Make sure the mailbox is in the correct atom format */
-  mailbox = imap_atom(imap->mailbox, false);
+  mailbox = imap_atom(imap->mailbox, FALSE);
   if(!mailbox)
   if(!mailbox)
     return CURLE_OUT_OF_MEMORY;
     return CURLE_OUT_OF_MEMORY;
 
 
@@ -1399,7 +1399,7 @@ static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done)
   }
   }
 
 
   result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE);
   result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE);
-  *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
+  *done = (imapc->state == IMAP_STOP);
 
 
   return result;
   return result;
 }
 }
@@ -1859,7 +1859,7 @@ static bool imap_is_bchar(char ch)
   /* Performing the alnum check with this macro is faster because of ASCII
   /* Performing the alnum check with this macro is faster because of ASCII
      arithmetic */
      arithmetic */
   if(ISALNUM(ch))
   if(ISALNUM(ch))
-    return true;
+    return TRUE;
 
 
   switch(ch) {
   switch(ch) {
     /* bchar */
     /* bchar */
@@ -1873,10 +1873,10 @@ static bool imap_is_bchar(char ch)
     case '+': case ',':
     case '+': case ',':
     /* bchar -> achar -> uchar -> pct-encoded */
     /* bchar -> achar -> uchar -> pct-encoded */
     case '%': /* HEXDIG chars are already included above */
     case '%': /* HEXDIG chars are already included above */
-      return true;
+      return TRUE;
 
 
     default:
     default:
-      return false;
+      return FALSE;
   }
   }
 }
 }
 
 
@@ -1891,7 +1891,7 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
   CURLcode result = CURLE_OK;
   CURLcode result = CURLE_OK;
   struct imap_conn *imapc = &conn->proto.imapc;
   struct imap_conn *imapc = &conn->proto.imapc;
   const char *ptr = conn->options;
   const char *ptr = conn->options;
-  bool prefer_login = false;
+  bool prefer_login = FALSE;
 
 
   while(!result && ptr && *ptr) {
   while(!result && ptr && *ptr) {
     const char *key = ptr;
     const char *key = ptr;
@@ -1907,16 +1907,16 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
 
 
     if(strncasecompare(key, "AUTH=+LOGIN", 11)) {
     if(strncasecompare(key, "AUTH=+LOGIN", 11)) {
       /* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */
       /* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */
-      prefer_login = true;
+      prefer_login = TRUE;
       imapc->sasl.prefmech = SASL_AUTH_NONE;
       imapc->sasl.prefmech = SASL_AUTH_NONE;
     }
     }
     else if(strncasecompare(key, "AUTH=", 5)) {
     else if(strncasecompare(key, "AUTH=", 5)) {
-      prefer_login = false;
+      prefer_login = FALSE;
       result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
       result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
                                                value, ptr - value);
                                                value, ptr - value);
     }
     }
     else {
     else {
-      prefer_login = false;
+      prefer_login = FALSE;
       result = CURLE_URL_MALFORMAT;
       result = CURLE_URL_MALFORMAT;
     }
     }
 
 

+ 25 - 25
lib/krb5.c

@@ -202,14 +202,15 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
                         data->set.str[STRING_SERVICE_NAME] :
                         data->set.str[STRING_SERVICE_NAME] :
                         "ftp";
                         "ftp";
   const char *srv_host = "host";
   const char *srv_host = "host";
-  gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp;
+  gss_buffer_desc input_buffer, output_buffer, *gssresp;
+  gss_buffer_desc _gssresp = GSS_C_EMPTY_BUFFER;
   OM_uint32 maj, min;
   OM_uint32 maj, min;
   gss_name_t gssname;
   gss_name_t gssname;
   gss_ctx_id_t *context = app_data;
   gss_ctx_id_t *context = app_data;
   struct gss_channel_bindings_struct chan;
   struct gss_channel_bindings_struct chan;
   size_t base64_sz = 0;
   size_t base64_sz = 0;
   struct sockaddr_in *remote_addr =
   struct sockaddr_in *remote_addr =
-    (struct sockaddr_in *)(void *)&conn->remote_addr->sa_addr;
+    (struct sockaddr_in *)(void *)&conn->remote_addr->curl_sa_addr;
   char *stringp;
   char *stringp;
 
 
   if(getsockname(conn->sock[FIRSTSOCKET],
   if(getsockname(conn->sock[FIRSTSOCKET],
@@ -363,7 +364,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
       free(_gssresp.value);
       free(_gssresp.value);
 
 
     if(ret == AUTH_OK || service == srv_host)
     if(ret == AUTH_OK || service == srv_host)
-      return ret;
+      break;
 
 
     service = srv_host;
     service = srv_host;
   }
   }
@@ -372,13 +373,13 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
 
 
 static void krb5_end(void *app_data)
 static void krb5_end(void *app_data)
 {
 {
-    OM_uint32 min;
-    gss_ctx_id_t *context = app_data;
-    if(*context != GSS_C_NO_CONTEXT) {
-      OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
-      (void)maj;
-      DEBUGASSERT(maj == GSS_S_COMPLETE);
-    }
+  OM_uint32 min;
+  gss_ctx_id_t *context = app_data;
+  if(*context != GSS_C_NO_CONTEXT) {
+    OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+    (void)maj;
+    DEBUGASSERT(maj == GSS_S_COMPLETE);
+  }
 }
 }
 
 
 static const struct Curl_sec_client_mech Curl_krb5_client_mech = {
 static const struct Curl_sec_client_mech Curl_krb5_client_mech = {
@@ -612,10 +613,10 @@ static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
   return total_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. */
+/* Send |length| bytes from |from| to the |sockindex| socket taking care of
+   encoding and negotiating with the server. |from| can be NULL. */
 static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
 static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
-                        curl_socket_t fd, const char *from, int length)
+                        int sockindex, const char *from, int length)
 {
 {
   int bytes, htonl_bytes; /* 32-bit integers for htonl */
   int bytes, htonl_bytes; /* 32-bit integers for htonl */
   char *buffer = NULL;
   char *buffer = NULL;
@@ -623,7 +624,7 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
   size_t cmd_size = 0;
   size_t cmd_size = 0;
   CURLcode error;
   CURLcode error;
   enum protection_level prot_level = conn->data_prot;
   enum protection_level prot_level = conn->data_prot;
-  bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
+  bool iscmd = (prot_level == PROT_CMD);
 
 
   DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
   DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
 
 
@@ -649,27 +650,27 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
       static const char *enc = "ENC ";
       static const char *enc = "ENC ";
       static const char *mic = "MIC ";
       static const char *mic = "MIC ";
       if(prot_level == PROT_PRIVATE)
       if(prot_level == PROT_PRIVATE)
-        socket_write(data, fd, enc, 4);
+        socket_write(data, sockindex, enc, 4);
       else
       else
-        socket_write(data, fd, mic, 4);
+        socket_write(data, sockindex, mic, 4);
 
 
-      socket_write(data, fd, cmd_buffer, cmd_size);
-      socket_write(data, fd, "\r\n", 2);
-      infof(data, "Send: %s%s", prot_level == PROT_PRIVATE?enc:mic,
+      socket_write(data, sockindex, cmd_buffer, cmd_size);
+      socket_write(data, sockindex, "\r\n", 2);
+      infof(data, "Send: %s%s", prot_level == PROT_PRIVATE ? enc : mic,
             cmd_buffer);
             cmd_buffer);
       free(cmd_buffer);
       free(cmd_buffer);
     }
     }
   }
   }
   else {
   else {
     htonl_bytes = (int)htonl((OM_uint32)bytes);
     htonl_bytes = (int)htonl((OM_uint32)bytes);
-    socket_write(data, fd, &htonl_bytes, sizeof(htonl_bytes));
-    socket_write(data, fd, buffer, curlx_sitouz(bytes));
+    socket_write(data, sockindex, &htonl_bytes, sizeof(htonl_bytes));
+    socket_write(data, sockindex, buffer, curlx_sitouz(bytes));
   }
   }
   free(buffer);
   free(buffer);
 }
 }
 
 
 static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
 static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
-                         curl_socket_t fd, const char *buffer, size_t length)
+                         int sockindex, const char *buffer, size_t length)
 {
 {
   ssize_t tx = 0, len = conn->buffer_size;
   ssize_t tx = 0, len = conn->buffer_size;
 
 
@@ -679,7 +680,7 @@ static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
     if(length < (size_t)len)
     if(length < (size_t)len)
       len = length;
       len = length;
 
 
-    do_sec_send(data, conn, fd, buffer, curlx_sztosi(len));
+    do_sec_send(data, conn, sockindex, buffer, curlx_sztosi(len));
     length -= len;
     length -= len;
     buffer += len;
     buffer += len;
     tx += len;
     tx += len;
@@ -693,10 +694,9 @@ static ssize_t sec_send(struct Curl_easy *data, int sockindex,
                         CURLcode *err)
                         CURLcode *err)
 {
 {
   struct connectdata *conn = data->conn;
   struct connectdata *conn = data->conn;
-  curl_socket_t fd = conn->sock[sockindex];
   (void)eos; /* unused */
   (void)eos; /* unused */
   *err = CURLE_OK;
   *err = CURLE_OK;
-  return sec_write(data, conn, fd, buffer, len);
+  return sec_write(data, conn, sockindex, buffer, len);
 }
 }
 
 
 int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,
 int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,

Some files were not shown because too many files changed in this diff