curl 2024-12-11 (75a2079d)

Code extracted from:

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

at commit 75a2079d5c28debb2eaa848ca9430f1fe0d7844c (curl-8_11_1).
This commit is contained in:
Curl Upstream authored and Brad King committed 2024-12-12 09:42:01 -05:00
1 parent 1a2b208170
commit 4cebf01c70
196 files changed
+9856 -9019

No files matched your search

+19 -33
View File
@@ -21,8 +21,6 @@
# SPDX-License-Identifier: curl
#
###########################################################################
include(CheckCSourceCompiles)
option(CURL_HIDDEN_SYMBOLS "Hide libcurl internal symbols (=hide all symbols that are not officially external)" ON)
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
@@ -33,48 +31,36 @@ if(WIN32 AND (ENABLE_DEBUG OR ENABLE_CURLDEBUG))
set(CURL_HIDDEN_SYMBOLS OFF)
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)
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)
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
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()
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)
set(_supports_symbol_hiding TRUE)
set(CURL_HIDES_PRIVATE_SYMBOLS TRUE)
endif()
set(CURL_HIDES_PRIVATE_SYMBOLS ${_supports_symbol_hiding})
else()
if(MSVC)
# Note: This option is prone to export non-curl extra symbols.
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif()
set(CURL_HIDES_PRIVATE_SYMBOLS FALSE)
endif()
set(CURL_CFLAG_SYMBOLS_HIDE ${_cflag_symbols_hide})
set(CURL_EXTERN_SYMBOL ${_symbol_extern})
+2 -19
View File
@@ -50,6 +50,7 @@ int main(void)
int flags = 0;
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
return 1;
;
return 0;
}
#endif
@@ -159,15 +160,12 @@ int main(void) { return 0; }
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int main(void) { ; return 0; }
int main(void) { return 0; }
#endif
#ifdef HAVE_IOCTLSOCKET
/* includes start */
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <winsock2.h>
#endif
int main(void)
@@ -184,9 +182,6 @@ int main(void)
#ifdef HAVE_IOCTLSOCKET_CAMEL
/* includes start */
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <winsock2.h>
#endif
int main(void)
@@ -202,9 +197,6 @@ int main(void)
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
/* includes start */
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <winsock2.h>
#endif
int main(void)
@@ -221,9 +213,6 @@ int main(void)
#ifdef HAVE_IOCTLSOCKET_FIONBIO
/* includes start */
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <winsock2.h>
#endif
int main(void)
@@ -296,9 +285,6 @@ int main(void)
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
/* includes start */
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <winsock2.h>
#endif
/* includes start */
@@ -409,9 +395,6 @@ int main(void)
#ifdef HAVE_WIN32_WINNT
/* includes start */
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# ifndef NOGDI
# define NOGDI
# endif
+6 -7
View File
@@ -21,19 +21,18 @@
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the bearssl library
# Find the BearSSL library
#
# 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:
#
# 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)
message(WARNING "BEARSSL_INCLUDE_DIRS is deprecated, use BEARSSL_INCLUDE_DIR instead.")
+7 -7
View File
@@ -25,16 +25,16 @@
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
+22 -12
View File
@@ -25,15 +25,15 @@
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
@@ -55,12 +55,22 @@ find_library(CARES_LIBRARY NAMES ${CARES_NAMES} "cares"
if(PC_CARES_VERSION)
set(CARES_VERSION ${PC_CARES_VERSION})
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()
include(FindPackageHandleStandardArgs)
+58 -22
View File
@@ -25,20 +25,21 @@
#
# 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:
#
# 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(_heimdal_modname "heimdal-gssapi")
@@ -55,7 +56,7 @@ set(_gss_root_hints
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
if(CURL_USE_PKGCONFIG)
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}")
endif()
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
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
# Should also work in an odd case when multiple directories are given
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
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
# 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.*")
string(REGEX REPLACE "^-L" "" _val "${_flag}")
list(APPEND _GSS_LIBRARY_DIRS "${_val}")
else()
list(APPEND _GSS_LDFLAGS "${_flag}")
endif()
endforeach()
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
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}")
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)
set(GSS_FLAVOUR "Heimdal")
endif()
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__")
endif()
cmake_pop_check_state()
else()
# 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"
@@ -203,6 +203,18 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
if(_GSS_INCLUDE_DIRS)
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()
@@ -216,14 +228,18 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
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")
else()
set(_gss_libname "libgssapi")
endif()
else()
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")
else()
set(_gss_libname "libgssapi")
@@ -231,7 +247,9 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
endif()
else()
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")
else()
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()
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_PC_REQUIRES "mit-krb5-gssapi")
if(NOT _GSS_VERSION) # for old CMake versions?
set(_GSS_VERSION ${_GSS_${_mit_modname}_VERSION})
endif()
else()
set(GSS_FLAVOUR "Heimdal")
set(GSS_PC_REQUIRES "heimdal-gssapi")
if(NOT _GSS_VERSION) # for old CMake versions?
set(_GSS_VERSION ${_GSS_${_heimdal_modname}_VERSION})
endif()
@@ -261,10 +288,11 @@ else()
message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_GSS_INCLUDE_DIRS} (found version \"${_GSS_VERSION}\")")
endif()
string(REPLACE ";" " " _GSS_CFLAGS "${_GSS_CFLAGS}")
set(GSS_INCLUDE_DIRS ${_GSS_INCLUDE_DIRS})
set(GSS_LIBRARIES ${_GSS_LIBRARIES})
set(GSS_LIBRARY_DIRS ${_GSS_LIBRARY_DIRS})
set(GSS_LDFLAGS ${_GSS_LDFLAGS})
set(GSS_CFLAGS ${_GSS_CFLAGS})
set(GSS_VERSION ${_GSS_VERSION})
@@ -294,6 +322,15 @@ if(GSS_FLAVOUR)
else()
set(GSS_VERSION "MIT Unknown")
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()
@@ -312,7 +349,6 @@ mark_as_advanced(
_GSS_CFLAGS
_GSS_FOUND
_GSS_INCLUDE_DIRS
_GSS_LDFLAGS
_GSS_LIBRARIES
_GSS_LIBRARY_DIRS
_GSS_MODULE_NAME
+9 -8
View File
@@ -25,17 +25,17 @@
#
# 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:
#
# 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
NOT DEFINED LIBGSASL_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
find_path(LIBGSASL_INCLUDE_DIR NAMES "gsasl.h")
find_library(LIBGSASL_LIBRARY NAMES "gsasl" "libgsasl")
unset(LIBGSASL_VERSION CACHE)
if(LIBGSASL_INCLUDE_DIR AND EXISTS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h")
set(_version_regex "#[\t ]*define[\t ]+GSASL_VERSION[\t ]+\"([^\"]*)\"")
file(STRINGS "${LIBGSASL_INCLUDE_DIR}/gsasl-version.h" _version_str REGEX "${_version_regex}")
+9 -8
View File
@@ -25,17 +25,17 @@
#
# 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:
#
# 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
NOT DEFINED LIBIDN2_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
find_path(LIBIDN2_INCLUDE_DIR NAMES "idn2.h")
find_library(LIBIDN2_LIBRARY NAMES "idn2" "libidn2")
unset(LIBIDN2_VERSION CACHE)
if(LIBIDN2_INCLUDE_DIR AND EXISTS "${LIBIDN2_INCLUDE_DIR}/idn2.h")
set(_version_regex "#[\t ]*define[\t ]+IDN2_VERSION[\t ]+\"([^\"]*)\"")
file(STRINGS "${LIBIDN2_INCLUDE_DIR}/idn2.h" _version_str REGEX "${_version_regex}")
+6 -6
View File
@@ -25,15 +25,15 @@
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
+9 -8
View File
@@ -25,17 +25,17 @@
#
# 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:
#
# 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
NOT DEFINED LIBSSH_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
find_path(LIBSSH_INCLUDE_DIR NAMES "libssh/libssh.h")
find_library(LIBSSH_LIBRARY NAMES "ssh" "libssh")
unset(LIBSSH_VERSION CACHE)
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_regex2 "#[\t ]*define[\t ]+LIBSSH_VERSION_MINOR[\t ]+([0-9]+).*")
+6 -6
View File
@@ -25,15 +25,15 @@
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
+9 -8
View File
@@ -25,17 +25,17 @@
#
# 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:
#
# 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
NOT DEFINED LIBUV_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
find_path(LIBUV_INCLUDE_DIR NAMES "uv.h")
find_library(LIBUV_LIBRARY NAMES "uv" "libuv")
unset(LIBUV_VERSION CACHE)
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_regex2 "#[\t ]*define[\t ]+UV_VERSION_MINOR[\t ]+([0-9]+).*")
+33 -37
View File
@@ -25,49 +25,45 @@
#
# 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:
#
# 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)
pkg_check_modules(PC_MSH3 "libmsh3")
pkg_check_modules(MSH3 "libmsh3")
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(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
VERSION_VAR
MSH3_VERSION
)
if(MSH3_FOUND)
set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
set(MSH3_LIBRARIES ${MSH3_LIBRARY})
endif()
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")
mark_as_advanced(MSH3_INCLUDE_DIR MSH3_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MSH3
REQUIRED_VARS
MSH3_INCLUDE_DIR
MSH3_LIBRARY
)
if(MSH3_FOUND)
set(MSH3_INCLUDE_DIRS ${MSH3_INCLUDE_DIR})
set(MSH3_LIBRARIES ${MSH3_LIBRARY})
endif()
mark_as_advanced(MSH3_INCLUDE_DIR MSH3_LIBRARY)
endif()
+66 -68
View File
@@ -21,22 +21,24 @@
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the mbedtls library
# Find the mbedTLS library
#
# 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:
#
# 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)
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)
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)
pkg_check_modules(PC_MBEDTLS "mbedtls")
pkg_check_modules(MBEDTLS "mbedtls")
pkg_check_modules(MBEDX509 "mbedx509")
pkg_check_modules(MBEDCRYPTO "mbedcrypto")
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)
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()
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)
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()
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
endif()
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()
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
+6 -6
View File
@@ -25,15 +25,15 @@
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
+6 -6
View File
@@ -25,15 +25,15 @@
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
+15 -10
View File
@@ -26,22 +26,22 @@
# This module accepts optional COMPONENTS to control the crypto library (these are
# 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:
#
# 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:
#
# 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)
find_package(PkgConfig QUIET)
@@ -84,14 +84,19 @@ if(NGTCP2_FIND_COMPONENTS)
if(_ngtcp2_crypto_backend)
string(TOLOWER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library)
if(CURL_USE_PKGCONFIG)
pkg_check_modules(PC_${_crypto_library} "lib${_crypto_library}")
endif()
get_filename_component(_ngtcp2_library_dir "${NGTCP2_LIBRARY}" DIRECTORY)
find_library(${_crypto_library}_LIBRARY NAMES ${_crypto_library}
HINTS
${_ngtcp2_library_dir}
${PC_${_crypto_library}_LIBDIR}
${PC_${_crypto_library}_LIBRARY_DIRS}
)
if(${_crypto_library}_LIBRARY)
set(NGTCP2_${_ngtcp2_crypto_backend}_FOUND TRUE)
set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
+9 -8
View File
@@ -25,17 +25,17 @@
#
# 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:
#
# 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
NOT DEFINED NETTLE_INCLUDE_DIR AND
@@ -51,6 +51,7 @@ else()
find_path(NETTLE_INCLUDE_DIR NAMES "nettle/sha2.h")
find_library(NETTLE_LIBRARY NAMES "nettle")
unset(NETTLE_VERSION CACHE)
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_regex2 "#[\t ]*define[ \t]+NETTLE_VERSION_MINOR[ \t]+([0-9]+).*")
+31 -37
View File
@@ -25,49 +25,43 @@
#
# 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:
#
# 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)
pkg_check_modules(PC_QUICHE "quiche")
pkg_check_modules(QUICHE "quiche")
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(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
VERSION_VAR
QUICHE_VERSION
)
if(QUICHE_FOUND)
set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
set(QUICHE_LIBRARIES ${QUICHE_LIBRARY})
endif()
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")
mark_as_advanced(QUICHE_INCLUDE_DIR QUICHE_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Quiche
REQUIRED_VARS
QUICHE_INCLUDE_DIR
QUICHE_LIBRARY
)
if(QUICHE_FOUND)
set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
set(QUICHE_LIBRARIES ${QUICHE_LIBRARY})
endif()
mark_as_advanced(QUICHE_INCLUDE_DIR QUICHE_LIBRARY)
endif()
+67 -37
View File
@@ -21,53 +21,83 @@
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the rustls library
# Find the Rustls library
#
# 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:
#
# 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)
pkg_check_modules(PC_RUSTLS "rustls")
pkg_check_modules(RUSTLS "rustls")
endif()
find_path(RUSTLS_INCLUDE_DIR NAMES "rustls.h"
HINTS
${PC_RUSTLS_INCLUDEDIR}
${PC_RUSTLS_INCLUDE_DIRS}
)
find_library(RUSTLS_LIBRARY NAMES "rustls"
HINTS
${PC_RUSTLS_LIBDIR}
${PC_RUSTLS_LIBRARY_DIRS}
)
if(PC_RUSTLS_VERSION)
set(RUSTLS_VERSION ${PC_RUSTLS_VERSION})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Rustls
REQUIRED_VARS
RUSTLS_INCLUDE_DIR
RUSTLS_LIBRARY
VERSION_VAR
RUSTLS_VERSION
)
if(RUSTLS_FOUND)
set(RUSTLS_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR})
set(RUSTLS_LIBRARIES ${RUSTLS_LIBRARY})
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
)
if(RUSTLS_FOUND)
set(RUSTLS_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR})
set(RUSTLS_LIBRARIES ${RUSTLS_LIBRARY})
endif()
mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY)
endif()
mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY)
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")
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)
find_library(_math_library "m")
if(_math_library)
list(APPEND RUSTLS_LIBRARIES "m")
endif()
mark_as_advanced(_math_library)
endif()
+8 -7
View File
@@ -21,23 +21,24 @@
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the wolfssh library
# Find the wolfSSH library
#
# 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:
#
# 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_library(WOLFSSH_LIBRARY NAMES "wolfssh" "libwolfssh")
unset(WOLFSSH_VERSION CACHE)
if(WOLFSSH_INCLUDE_DIR AND EXISTS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h")
set(_version_regex "#[\t ]*define[\t ]+LIBWOLFSSH_VERSION_STRING[\t ]+\"([^\"]*)\"")
file(STRINGS "${WOLFSSH_INCLUDE_DIR}/wolfssh/version.h" _version_str REGEX "${_version_regex}")
+49 -51
View File
@@ -21,21 +21,21 @@
# SPDX-License-Identifier: curl
#
###########################################################################
# Find the wolfssl library
# Find the wolfSSL library
#
# 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:
#
# 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)
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}")
endif()
if(CURL_USE_PKGCONFIG)
if(CURL_USE_PKGCONFIG AND
NOT DEFINED WOLFSSL_INCLUDE_DIR AND
NOT DEFINED WOLFSSL_LIBRARY)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_WOLFSSL "wolfssl")
pkg_check_modules(WOLFSSL "wolfssl")
endif()
find_path(WOLFSSL_INCLUDE_DIR NAMES "wolfssl/ssl.h"
HINTS
${PC_WOLFSSL_INCLUDEDIR}
${PC_WOLFSSL_INCLUDE_DIRS}
)
find_library(WOLFSSL_LIBRARY NAMES "wolfssl"
HINTS
${PC_WOLFSSL_LIBDIR}
${PC_WOLFSSL_LIBRARY_DIRS}
)
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
)
if(WOLFSSL_FOUND)
set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
set(WOLFSSL_LIBRARIES ${WOLFSSL_LIBRARY})
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")
if(NOT WIN32)
find_library(_math_library "m")
if(_math_library)
list(APPEND WOLFSSL_LIBRARIES "m") # for log and pow
endif()
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()
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()
mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)
endif()
mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)
if(NOT WIN32)
find_library(_math_library "m")
if(_math_library)
list(APPEND WOLFSSL_LIBRARIES "m") # for log and pow
endif()
mark_as_advanced(_math_library)
endif()
+6 -8
View File
@@ -25,17 +25,15 @@
#
# 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:
#
# 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)
message(WARNING "Zstd_INCLUDE_DIR is deprecated, use ZSTD_INCLUDE_DIR instead.")
+13 -7
View File
@@ -30,8 +30,7 @@
macro(check_include_file_concat _file _variable)
check_include_files("${CURL_INCLUDES};${_file}" ${_variable})
if(${_variable})
set(CURL_INCLUDES ${CURL_INCLUDES} ${_file})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${_variable}")
list(APPEND CURL_INCLUDES ${_file})
endif()
endmacro()
@@ -39,8 +38,7 @@ endmacro()
# Return result in variable: CURL_TEST_OUTPUT
macro(curl_internal_test _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)
set(_curl_test_add_libraries
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
@@ -48,10 +46,10 @@ macro(curl_internal_test _curl_test)
message(STATUS "Performing Test ${_curl_test}")
try_compile(${_curl_test}
${CMAKE_BINARY_DIR}
${PROJECT_BINARY_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c"
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}"
OUTPUT_VARIABLE CURL_TEST_OUTPUT)
if(${_curl_test})
@@ -64,7 +62,7 @@ macro(curl_internal_test _curl_test)
endif()
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_property(CACHE CURL_${_dependency} PROPERTY STRINGS "AUTO" "ON" "OFF")
@@ -74,3 +72,11 @@ macro(optional_dependency _dependency)
find_package(${_dependency} REQUIRED)
endif()
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
View File
@@ -32,20 +32,21 @@ macro(add_header_include _check _header)
endif()
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)
cmake_push_check_state()
unset(CMAKE_EXTRA_INCLUDE_FILES)
if(WIN32)
set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h")
set(CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN")
set(CMAKE_REQUIRED_LIBRARIES "ws2_32")
elseif(HAVE_SYS_SOCKET_H)
set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
endif()
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
set(HAVE_STRUCT_SOCKADDR_STORAGE ${HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE})
set(CMAKE_EXTRA_INCLUDE_FILES "")
cmake_pop_check_state()
endif()
if(NOT WIN32)
@@ -74,35 +75,8 @@ check_c_source_compiles("${_source_epilogue}
return 0;
}" 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
@@ -118,7 +92,7 @@ elseif(APPLE OR
CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(HAVE_GETADDRINFO_THREADSAFE TRUE)
elseif(CMAKE_SYSTEM_NAME MATCHES "BSD")
elseif(BSD OR CMAKE_SYSTEM_NAME MATCHES "BSD")
set(HAVE_GETADDRINFO_THREADSAFE FALSE)
endif()
@@ -178,3 +152,5 @@ if(NOT WIN32 AND NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
return 0;
}" HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
endif()
unset(_source_epilogue)
+61 -42
View File
@@ -23,24 +23,27 @@
###########################################################################
include(CheckCCompilerFlag)
unset(WPICKY)
unset(_picky)
if(CURL_WERROR AND
((CMAKE_COMPILER_IS_GNUCC 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
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()
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 "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()
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()
if(PICKY_COMPILER)
@@ -49,29 +52,29 @@ if(PICKY_COMPILER)
# https://clang.llvm.org/docs/DiagnosticsReference.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.
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(WPICKY_ENABLE "-Wextra")
set(_picky_enable "-Wextra")
else()
set(WPICKY_ENABLE "-W")
set(_picky_enable "-W")
endif()
list(APPEND WPICKY_ENABLE
list(APPEND _picky_enable
-Wall -pedantic
)
# ----------------------------------
# Add new options here, if in doubt:
# ----------------------------------
set(WPICKY_DETECT
set(_picky_detect
)
# Assume these options always exist with both clang and gcc.
# 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
-Wconversion # clang 2.7 gcc 2.95
-Winline # clang 1.0 gcc 1.0
@@ -89,7 +92,7 @@ if(PICKY_COMPILER)
)
# Always enable with clang, version dependent with gcc
set(WPICKY_COMMON_OLD
set(_picky_common_old
-Waddress # clang 2.7 gcc 4.3
-Wattributes # clang 2.7 gcc 4.1
-Wcast-align # clang 1.0 gcc 4.2
@@ -118,7 +121,7 @@ if(PICKY_COMPILER)
-Wvla # clang 2.8 gcc 4.3
)
set(WPICKY_COMMON
set(_picky_common
-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
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
@@ -126,51 +129,55 @@ if(PICKY_COMPILER)
)
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
-Wshorten-64-to-32 # clang 1.0
-Wlanguage-extension-token # clang 3.0
-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
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))
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
-Wsometimes-uninitialized # clang 3.2 appleclang 4.6
)
endif()
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))
list(APPEND WPICKY_ENABLE
list(APPEND _picky_enable
-Wcomma # clang 3.9 appleclang 8.3
-Wmissing-variable-declarations # clang 3.2 appleclang 4.6
)
endif()
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))
list(APPEND WPICKY_ENABLE
list(APPEND _picky_enable
-Wassign-enum # clang 7.0 appleclang 10.3
-Wextra-semi-stmt # clang 7.0 appleclang 10.3
)
endif()
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))
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
)
endif()
else() # gcc
list(APPEND WPICKY_DETECT
${WPICKY_COMMON}
list(APPEND _picky_detect
${_picky_common}
)
# Enable based on compiler version
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
-Wmissing-parameter-type # gcc 4.3
-Wold-style-declaration # gcc 4.3
@@ -179,22 +186,22 @@ if(PICKY_COMPILER)
)
endif()
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)
)
endif()
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
)
endif()
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)
)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0)
list(APPEND WPICKY_ENABLE
list(APPEND _picky_enable
-Wduplicated-cond # gcc 6.0
-Wnull-dereference # clang 3.0 gcc 6.0 (clang default)
-fdelete-null-pointer-checks
@@ -203,17 +210,16 @@ if(PICKY_COMPILER)
)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0)
list(APPEND WPICKY_ENABLE
list(APPEND _picky_enable
-Walloc-zero # gcc 7.0
-Wduplicated-branches # gcc 7.0
-Wno-format-overflow # gcc 7.0
-Wformat-truncation=2 # gcc 7.0
-Wimplicit-fallthrough # clang 4.0 gcc 7.0
-Wrestrict # gcc 7.0
)
endif()
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0)
list(APPEND WPICKY_ENABLE
list(APPEND _picky_enable
-Warith-conversion # gcc 10.0
)
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()
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)
# GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
# so test for the positive form instead
string(REPLACE "-Wno-" "-W" _ccopt_on "${_ccopt}")
check_c_compiler_flag(${_ccopt_on} ${_optvarname})
if(${_optvarname})
set(WPICKY "${WPICKY} ${_ccopt}")
list(APPEND _picky "${_ccopt}")
endif()
endforeach()
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()
+4 -5
View File
@@ -88,6 +88,7 @@ set(HAVE_FREEADDRINFO 1)
set(HAVE_FCHMOD 0)
set(HAVE_SOCKETPAIR 0)
set(HAVE_SENDMSG 0)
set(HAVE_SENDMMSG 0)
set(HAVE_ALARM 0)
set(HAVE_FCNTL 0)
set(HAVE_GETPPID 0)
@@ -101,13 +102,12 @@ set(HAVE_IF_NAMETOINDEX 0)
set(HAVE_GETRLIMIT 0)
set(HAVE_SETRLIMIT 0)
set(HAVE_FSETXATTR 0)
set(HAVE_LIBSOCKET 0)
set(HAVE_SETLOCALE 1)
set(HAVE_SETMODE 1)
set(HAVE__SETMODE 1)
set(HAVE_GETPEERNAME 1)
set(HAVE_GETSOCKNAME 1)
set(HAVE_GETHOSTNAME 1)
set(HAVE_LIBZ 0)
set(HAVE_RECV 1)
set(HAVE_SEND 1)
@@ -122,12 +122,13 @@ set(HAVE_IFADDRS_H 0)
set(HAVE_IO_H 1)
set(HAVE_NETDB_H 0)
set(HAVE_NETINET_IN_H 0)
set(HAVE_NETINET_IN6_H 0)
set(HAVE_NETINET_TCP_H 0)
set(HAVE_NETINET_UDP_H 0)
set(HAVE_NET_IF_H 0)
set(HAVE_IOCTL_SIOCGIFADDR 0)
set(HAVE_POLL_H 0)
set(HAVE_POLL_FINE 0)
set(HAVE_POLL 0)
set(HAVE_PWD_H 0)
set(HAVE_SYS_EVENTFD_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_FSEEKO 0) # mingw-w64 2.0.0 and newer has it
set(HAVE__FSEEKI64 1)
set(HAVE_SOCKET 1)
set(HAVE_SELECT 1)
set(HAVE_STRDUP 1)
@@ -166,7 +166,6 @@ set(HAVE_GETHOSTBYNAME_R 0)
set(HAVE_SIGNAL 1)
set(HAVE_SIGACTION 0)
set(HAVE_GLIBC_STRERROR_R 0)
set(HAVE_MACH_ABSOLUTE_TIME 0)
set(HAVE_GETIFADDRS 0)
set(HAVE_FCNTL_O_NONBLOCK 0)
set(HAVE_IOCTLSOCKET 1)
+9 -10
View File
@@ -23,20 +23,19 @@
###########################################################################
@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()
option(CURL_USE_PKGCONFIG "Enable pkg-config to detect @PROJECT_NAME@ dependencies" ${_curl_use_pkgconfig_default})
include(CMakeFindDependencyMacro)
if(@USE_OPENSSL@)
find_dependency(OpenSSL @OPENSSL_VERSION_MAJOR@)
if("@USE_OPENSSL@")
find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
endif()
if(@USE_ZLIB@)
find_dependency(ZLIB @ZLIB_VERSION_MAJOR@)
if("@HAVE_LIBZ@")
find_dependency(ZLIB "@ZLIB_VERSION_MAJOR@")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
+539 -371
View File
@@ -48,20 +48,32 @@ message(STATUS "Using CMake version ${CMAKE_VERSION}")
# Collect command-line arguments for buildinfo.txt.
# Must reside at the top of the script to work as expected.
get_cmake_property(_cache_vars CACHE_VARIABLES)
unset(_cmake_args)
foreach(_cache_var ${_cache_vars})
get_property(_cache_var_helpstring CACHE ${_cache_var} PROPERTY HELPSTRING)
if(_cache_var_helpstring STREQUAL "No help, variable specified on the command line.")
get_property(_cache_var_type CACHE ${_cache_var} PROPERTY TYPE)
if(_cache_var_type STREQUAL "UNINITIALIZED")
set(_cache_var_type)
else()
set(_cache_var_type ":${_cache_var_type}")
set(_cmake_args "")
if(NOT "$ENV{CURL_BUILDINFO}$ENV{CURL_CI}$ENV{CI}" STREQUAL "")
get_cmake_property(_cache_vars CACHE_VARIABLES)
foreach(_cache_var IN ITEMS ${_cache_vars})
get_property(_cache_var_helpstring CACHE ${_cache_var} PROPERTY HELPSTRING)
if(_cache_var_helpstring STREQUAL "No help, variable specified on the command line.")
get_property(_cache_var_type CACHE ${_cache_var} PROPERTY TYPE)
get_property(_cache_var_value CACHE ${_cache_var} PROPERTY VALUE)
if(_cache_var_type STREQUAL "UNINITIALIZED")
set(_cache_var_type)
else()
set(_cache_var_type ":${_cache_var_type}")
endif()
set(_cmake_args "${_cmake_args} -D${_cache_var}${_cache_var_type}=\"${_cache_var_value}\"")
endif()
set(_cmake_args "${_cmake_args} -D${_cache_var}${_cache_var_type}=\"${${_cache_var}}\"")
endif()
endforeach()
endforeach()
endif()
function(curl_dumpvars) # Dump all defined variables with their values
message("::group::CMake Variable Dump")
get_cmake_property(_vars VARIABLES)
foreach(_var ${_vars})
message("${_var} = ${${_var}}")
endforeach()
message("::endgroup::")
endfunction()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
include(Utilities)
@@ -69,7 +81,19 @@ include(Macros)
include(CMakeDependentOption)
include(CheckCCompilerFlag)
project(CURL C)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/curl/curlver.h" _curl_version_h_contents REGEX "#define LIBCURL_VERSION( |_NUM )")
string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*" _curl_version ${_curl_version_h_contents})
string(REGEX REPLACE "[^\"]+\"" "" _curl_version ${_curl_version})
string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+" _curl_version_num ${_curl_version_h_contents})
string(REGEX REPLACE "[^0]+0x" "" _curl_version_num ${_curl_version_num})
unset(_curl_version_h_contents)
message(STATUS "curl version=[${_curl_version}]")
string(REGEX REPLACE "([0-9]+\.[0-9]+\.[0-9]+).+" "\\1" _curl_version_sem "${_curl_version}")
project(CURL
VERSION "${_curl_version_sem}"
LANGUAGES C)
unset(_target_flags)
if(APPLE)
@@ -78,9 +102,15 @@ endif()
if(UNIX)
set(_target_flags "${_target_flags} UNIX")
endif()
if(BSD)
set(_target_flags "${_target_flags} BSD")
endif()
if(WIN32)
set(_target_flags "${_target_flags} WIN32")
endif()
if(WINDOWS_STORE)
set(_target_flags "${_target_flags} UWP")
endif()
if(CYGWIN)
set(_target_flags "${_target_flags} CYGWIN")
endif()
@@ -110,36 +140,29 @@ if(CMAKE_CROSSCOMPILING)
"${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}")
endif()
function(curl_dumpvars) # Dump all defined variables with their values
message("::group::CMake Variable Dump")
get_cmake_property(_vars VARIABLES)
foreach(_var ${_vars})
message("${_var} = ${${_var}}")
endforeach()
message("::endgroup::")
endfunction()
file(STRINGS "${CURL_SOURCE_DIR}/include/curl/curlver.h" _curl_version_h_contents REGEX "#define LIBCURL_VERSION( |_NUM )")
string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*" CURL_VERSION ${_curl_version_h_contents})
string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+" CURL_VERSION_NUM ${_curl_version_h_contents})
string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
unset(_curl_version_h_contents)
message(STATUS "curl version=[${CURL_VERSION}]")
if(CMAKE_C_COMPILER_TARGET)
set(OS "\"${CMAKE_C_COMPILER_TARGET}\"")
set(CURL_OS "\"${CMAKE_C_COMPILER_TARGET}\"")
else()
set(OS "\"${CMAKE_SYSTEM_NAME}\"")
set(CURL_OS "\"${CMAKE_SYSTEM_NAME}\"")
endif()
include_directories("${CURL_SOURCE_DIR}/include")
include_directories("${PROJECT_SOURCE_DIR}/include")
if(NOT DEFINED CMAKE_UNITY_BUILD_BATCH_SIZE)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 0)
endif()
# Having CMAKE_TRY_COMPILE_TARGET_TYPE set to STATIC_LIBRARY breaks certain
# 'check_function_exists()' detections (possibly more), by detecting
# non-existing features. This happens by default when using 'ios.toolchain.cmake'.
# Work it around by setting this value to `EXECUTABLE`.
if(CMAKE_TRY_COMPILE_TARGET_TYPE STREQUAL "STATIC_LIBRARY")
message(STATUS "CMAKE_TRY_COMPILE_TARGET_TYPE was found set to STATIC_LIBRARY. "
"Overriding with EXECUTABLE for feature detections to work.")
set(_cmake_try_compile_target_type_save ${CMAKE_TRY_COMPILE_TARGET_TYPE})
set(CMAKE_TRY_COMPILE_TARGET_TYPE "EXECUTABLE")
endif()
option(CURL_WERROR "Turn compiler warnings into errors" OFF)
option(PICKY_COMPILER "Enable picky compiler options" ON)
option(BUILD_CURL_EXE "Build curl executable" ON)
@@ -150,14 +173,17 @@ option(ENABLE_ARES "Enable c-ares support" OFF)
option(CURL_DISABLE_INSTALL "Disable installation targets" OFF)
if(WIN32)
option(CURL_STATIC_CRT "Build libcurl with static CRT on Windows (/MT)" OFF)
if(CURL_STATIC_CRT)
option(CURL_STATIC_CRT "Build libcurl with static CRT with MSVC (/MT)" OFF)
if(CURL_STATIC_CRT AND MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
endif()
option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF)
if(WINDOWS_STORE)
set(ENABLE_UNICODE ON)
endif()
if(ENABLE_UNICODE)
add_definitions("-DUNICODE" "-D_UNICODE")
if(MINGW)
@@ -165,11 +191,12 @@ if(WIN32)
endif()
endif()
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN") # Apply to all feature checks
set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
if(CURL_TARGET_WINDOWS_VERSION)
add_definitions("-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}") # Apply to all feature checks
endif()
# Detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT
@@ -192,8 +219,15 @@ cmake_dependent_option(ENABLE_THREADED_RESOLVER "Enable threaded DNS lookup"
include(PickyWarnings)
option(ENABLE_DEBUG "Enable curl debug features" OFF)
option(ENABLE_CURLDEBUG "Enable TrackMemory feature" ${ENABLE_DEBUG})
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE") # Required for sendmmsg()
endif()
option(ENABLE_DEBUG "Enable curl debug features (for developing curl itself)" OFF)
if(ENABLE_DEBUG)
message(WARNING "This curl build is Debug-enabled, do not use in production.")
endif()
option(ENABLE_CURLDEBUG "Enable TrackMemory debug feature" ${ENABLE_DEBUG})
if(MSVC)
set(ENABLE_CURLDEBUG OFF) # FIXME: TrackMemory + MSVC fails test 558 and 1330. Tested with static build, Debug mode.
@@ -239,14 +273,14 @@ else()
endif()
# Override to force-disable or force-enable the use of pkg-config.
if(UNIX OR (MSVC AND VCPKG_TOOLCHAIN)) # Keep in sync with CMake/curl-config.cmake.in
if(UNIX OR VCPKG_TOOLCHAIN OR (MINGW AND NOT CMAKE_CROSSCOMPILING)) # Keep in sync with CMake/curl-config.cmake.in
set(_curl_use_pkgconfig_default ON)
else()
set(_curl_use_pkgconfig_default OFF)
endif()
option(CURL_USE_PKGCONFIG "Enable pkg-config to detect dependencies" ${_curl_use_pkgconfig_default})
# Initialize CURL_LIBS
# Initialize variables collecting dependency libs, paths, pkg-config names.
set(CURL_LIBS "")
set(CURL_LIBDIRS "")
set(LIBCURL_PC_REQUIRES_PRIVATE "")
@@ -280,7 +314,7 @@ option(CURL_DISABLE_KERBEROS_AUTH "Disable Kerberos authentication" OFF)
mark_as_advanced(CURL_DISABLE_KERBEROS_AUTH)
option(CURL_DISABLE_NEGOTIATE_AUTH "Disable negotiate authentication" OFF)
mark_as_advanced(CURL_DISABLE_NEGOTIATE_AUTH)
option(CURL_DISABLE_AWS "Disable AWS-SIG4" OFF)
option(CURL_DISABLE_AWS "Disable aws-sigv4" OFF)
mark_as_advanced(CURL_DISABLE_AWS)
option(CURL_DISABLE_DICT "Disable DICT" OFF)
mark_as_advanced(CURL_DISABLE_DICT)
@@ -288,10 +322,6 @@ option(CURL_DISABLE_DOH "Disable DNS-over-HTTPS" OFF)
mark_as_advanced(CURL_DISABLE_DOH)
option(CURL_DISABLE_FILE "Disable FILE" OFF)
mark_as_advanced(CURL_DISABLE_FILE)
cmake_dependent_option(CURL_DISABLE_FORM_API "Disable form-api"
OFF "NOT CURL_DISABLE_MIME"
ON)
mark_as_advanced(CURL_DISABLE_FORM_API)
option(CURL_DISABLE_FTP "Disable FTP" OFF)
mark_as_advanced(CURL_DISABLE_FTP)
option(CURL_DISABLE_GETOPTIONS "Disable curl_easy_options API for existing options to curl_easy_setopt" OFF)
@@ -316,10 +346,14 @@ option(CURL_DISABLE_LIBCURL_OPTION "Disable --libcurl option from the curl tool"
mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION)
option(CURL_DISABLE_MIME "Disable MIME support" OFF)
mark_as_advanced(CURL_DISABLE_MIME)
cmake_dependent_option(CURL_DISABLE_FORM_API "Disable form-api"
OFF "NOT CURL_DISABLE_MIME"
ON)
mark_as_advanced(CURL_DISABLE_FORM_API)
option(CURL_DISABLE_MQTT "Disable MQTT" OFF)
mark_as_advanced(CURL_DISABLE_BINDLOCAL)
option(CURL_DISABLE_BINDLOCAL "Disable local binding support" OFF)
mark_as_advanced(CURL_DISABLE_MQTT)
option(CURL_DISABLE_BINDLOCAL "Disable local binding support" OFF)
mark_as_advanced(CURL_DISABLE_BINDLOCAL)
option(CURL_DISABLE_NETRC "Disable netrc parser" OFF)
mark_as_advanced(CURL_DISABLE_NETRC)
option(CURL_DISABLE_NTLM "Disable NTLM support" OFF)
@@ -332,6 +366,8 @@ option(CURL_DISABLE_PROGRESS_METER "Disable built-in progress meter" OFF)
mark_as_advanced(CURL_DISABLE_PROGRESS_METER)
option(CURL_DISABLE_PROXY "Disable proxy support" OFF)
mark_as_advanced(CURL_DISABLE_PROXY)
option(CURL_DISABLE_IPFS "Disable IPFS" OFF)
mark_as_advanced(CURL_DISABLE_IPFS)
option(CURL_DISABLE_RTSP "Disable RTSP" OFF)
mark_as_advanced(CURL_DISABLE_SHA512_256)
option(CURL_DISABLE_SHA512_256 "Disable SHA-512/256 hash algorithm" OFF)
@@ -344,6 +380,8 @@ option(CURL_DISABLE_SMTP "Disable SMTP" OFF)
mark_as_advanced(CURL_DISABLE_SMTP)
option(CURL_DISABLE_SOCKETPAIR "Disable use of socketpair for curl_multi_poll" OFF)
mark_as_advanced(CURL_DISABLE_SOCKETPAIR)
option(CURL_DISABLE_WEBSOCKETS "Disable WebSocket" OFF)
mark_as_advanced(CURL_DISABLE_WEBSOCKETS)
option(CURL_DISABLE_TELNET "Disable Telnet" OFF)
mark_as_advanced(CURL_DISABLE_TELNET)
option(CURL_DISABLE_TFTP "Disable TFTP" OFF)
@@ -352,6 +390,7 @@ option(CURL_DISABLE_VERBOSE_STRINGS "Disable verbose strings" OFF)
mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
if(CURL_DISABLE_HTTP)
set(CURL_DISABLE_IPFS ON)
set(CURL_DISABLE_RTSP ON)
set(CURL_DISABLE_ALTSVC ON)
set(CURL_DISABLE_HSTS ON)
@@ -371,6 +410,7 @@ if(HTTP_ONLY)
set(CURL_DISABLE_LDAPS ON)
set(CURL_DISABLE_MQTT ON)
set(CURL_DISABLE_POP3 ON)
set(CURL_DISABLE_IPFS ON)
set(CURL_DISABLE_RTSP ON)
set(CURL_DISABLE_SMB ON)
set(CURL_DISABLE_SMTP ON)
@@ -386,10 +426,8 @@ option(ENABLE_IPV6 "Enable IPv6 support" ON)
mark_as_advanced(ENABLE_IPV6)
if(ENABLE_IPV6 AND NOT WIN32)
include(CheckStructHasMember)
check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h"
HAVE_SOCKADDR_IN6_SIN6_ADDR)
check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h"
HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_ADDR)
check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
# Force the feature off as this name is used as guard macro...
@@ -454,7 +492,12 @@ include(CheckCSourceCompiles)
# Preload settings on Windows
if(WIN32)
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake")
elseif(APPLE)
# Fast-track predictable feature detections
set(HAVE_EVENTFD 0)
set(HAVE_GETPASS_R 0)
set(HAVE_SENDMMSG 0)
endif()
if(ENABLE_THREADED_RESOLVER)
@@ -469,9 +512,11 @@ if(ENABLE_THREADED_RESOLVER)
endif()
# Check for all needed libraries
check_library_exists("socket" "connect" "" HAVE_LIBSOCKET)
if(HAVE_LIBSOCKET)
set(CURL_LIBS "socket;${CURL_LIBS}")
if(NOT WIN32 AND NOT APPLE)
check_library_exists("socket" "connect" "" HAVE_LIBSOCKET)
if(HAVE_LIBSOCKET)
set(CURL_LIBS "socket;${CURL_LIBS}")
endif()
endif()
check_function_exists("gethostname" HAVE_GETHOSTNAME)
@@ -488,10 +533,10 @@ if(CURL_DEFAULT_SSL_BACKEND)
endif()
if(APPLE)
cmake_dependent_option(CURL_USE_SECTRANSP "Enable Apple OS native SSL/TLS" OFF CURL_ENABLE_SSL OFF)
cmake_dependent_option(CURL_USE_SECTRANSP "Enable Apple OS native SSL/TLS (Secure Transport)" OFF CURL_ENABLE_SSL OFF)
endif()
if(WIN32)
cmake_dependent_option(CURL_USE_SCHANNEL "Enable Windows native SSL/TLS" OFF CURL_ENABLE_SSL OFF)
cmake_dependent_option(CURL_USE_SCHANNEL "Enable Windows native SSL/TLS (Schannel)" OFF CURL_ENABLE_SSL OFF)
option(CURL_WINDOWS_SSPI "Enable SSPI on Windows" ${CURL_USE_SCHANNEL})
endif()
cmake_dependent_option(CURL_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
@@ -500,9 +545,17 @@ cmake_dependent_option(CURL_USE_WOLFSSL "Enable wolfSSL for SSL/TLS" OFF CURL_EN
cmake_dependent_option(CURL_USE_GNUTLS "Enable GnuTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
cmake_dependent_option(CURL_USE_RUSTLS "Enable Rustls for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
set(_openssl_default ON)
if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_WOLFSSL)
if(WIN32 OR
CURL_USE_SECTRANSP OR
CURL_USE_SCHANNEL OR
CURL_USE_MBEDTLS OR
CURL_USE_BEARSSL OR
CURL_USE_WOLFSSL OR
CURL_USE_GNUTLS OR
CURL_USE_RUSTLS)
set(_openssl_default OFF)
else()
set(_openssl_default ON)
endif()
cmake_dependent_option(CURL_USE_OPENSSL "Enable OpenSSL for SSL/TLS" ${_openssl_default} CURL_ENABLE_SSL OFF)
option(USE_OPENSSL_QUIC "Use OpenSSL and nghttp3 libraries for HTTP/3 support" OFF)
@@ -592,6 +645,7 @@ if(CURL_USE_OPENSSL)
endif()
set(_curl_ca_bundle_supported TRUE)
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
if(NOT DEFINED HAVE_BORINGSSL)
check_symbol_exists("OPENSSL_IS_BORINGSSL" "openssl/base.h" HAVE_BORINGSSL)
@@ -599,6 +653,7 @@ if(CURL_USE_OPENSSL)
if(NOT DEFINED HAVE_AWSLC)
check_symbol_exists("OPENSSL_IS_AWSLC" "openssl/base.h" HAVE_AWSLC)
endif()
cmake_pop_check_state()
endif()
if(CURL_USE_MBEDTLS)
@@ -606,8 +661,13 @@ if(CURL_USE_MBEDTLS)
set(_ssl_enabled ON)
set(USE_MBEDTLS ON)
list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "mbedtls")
include_directories(${MBEDTLS_INCLUDE_DIRS})
list(APPEND CURL_LIBDIRS ${MBEDTLS_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${MBEDTLS_PC_REQUIRES})
include_directories(SYSTEM ${MBEDTLS_INCLUDE_DIRS})
link_directories(${MBEDTLS_LIBRARY_DIRS})
if(MBEDTLS_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MBEDTLS_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls")
set(_valid_default_ssl_backend TRUE)
@@ -620,7 +680,7 @@ if(CURL_USE_BEARSSL)
set(_ssl_enabled ON)
set(USE_BEARSSL ON)
list(APPEND CURL_LIBS ${BEARSSL_LIBRARIES})
include_directories(${BEARSSL_INCLUDE_DIRS})
include_directories(SYSTEM ${BEARSSL_INCLUDE_DIRS})
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "bearssl")
set(_valid_default_ssl_backend TRUE)
@@ -635,8 +695,13 @@ if(CURL_USE_WOLFSSL)
set(_ssl_enabled ON)
set(USE_WOLFSSL ON)
list(APPEND CURL_LIBS ${WOLFSSL_LIBRARIES})
list(APPEND CURL_LIBDIRS ${WOLFSSL_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "wolfssl")
include_directories(${WOLFSSL_INCLUDE_DIRS})
include_directories(SYSTEM ${WOLFSSL_INCLUDE_DIRS})
link_directories(${WOLFSSL_LIBRARY_DIRS})
if(WOLFSSL_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WOLFSSL_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl")
set(_valid_default_ssl_backend TRUE)
@@ -661,7 +726,7 @@ if(CURL_USE_GNUTLS)
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} ${NETTLE_LIBRARIES})
list(APPEND CURL_LIBDIRS ${NETTLE_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls" "nettle")
include_directories(${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS})
include_directories(SYSTEM ${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS})
link_directories(${NETTLE_LIBRARY_DIRS})
if(NETTLE_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NETTLE_CFLAGS}")
@@ -686,8 +751,13 @@ if(CURL_USE_RUSTLS)
set(_ssl_enabled ON)
set(USE_RUSTLS ON)
list(APPEND CURL_LIBS ${RUSTLS_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "rustls")
include_directories(${RUSTLS_INCLUDE_DIRS})
list(APPEND CURL_LIBDIRS ${RUSTLS_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${RUSTLS_PC_REQUIRES})
include_directories(SYSTEM ${RUSTLS_INCLUDE_DIRS})
link_directories(${RUSTLS_LIBRARY_DIRS})
if(RUSTLS_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RUSTLS_CFLAGS}")
endif()
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "rustls")
set(_valid_default_ssl_backend TRUE)
@@ -703,17 +773,14 @@ endif()
# and before calling openssl_check_symbol_exists().
set(HAVE_LIBZ OFF)
set(USE_ZLIB OFF)
optional_dependency(ZLIB)
curl_dependency_option(ZLIB)
if(ZLIB_FOUND)
set(HAVE_LIBZ ON)
set(USE_ZLIB ON)
# Depend on ZLIB via imported targets. This allows our dependents to
# get our dependencies transitively.
list(APPEND CURL_LIBS ZLIB::ZLIB)
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "zlib")
list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
endif()
option(CURL_BROTLI "Use brotli" OFF)
@@ -724,8 +791,7 @@ if(CURL_BROTLI)
set(HAVE_BROTLI ON)
list(APPEND CURL_LIBS ${BROTLI_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libbrotlidec")
include_directories(${BROTLI_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${BROTLI_INCLUDE_DIRS})
include_directories(SYSTEM ${BROTLI_INCLUDE_DIRS})
endif()
endif()
@@ -737,7 +803,7 @@ if(CURL_ZSTD)
set(HAVE_ZSTD ON)
list(APPEND CURL_LIBS ${ZSTD_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libzstd")
include_directories(${ZSTD_INCLUDE_DIRS})
include_directories(SYSTEM ${ZSTD_INCLUDE_DIRS})
else()
message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.")
endif()
@@ -759,6 +825,7 @@ macro(openssl_check_symbol_exists _symbol _files _variable _extra_libs)
elseif(USE_WOLFSSL)
set(CMAKE_REQUIRED_INCLUDES "${WOLFSSL_INCLUDE_DIRS}")
set(CMAKE_REQUIRED_LIBRARIES "${WOLFSSL_LIBRARIES}")
curl_required_libpaths("${WOLFSSL_LIBRARY_DIRS}")
if(HAVE_LIBZ)
list(APPEND CMAKE_REQUIRED_INCLUDES "${ZLIB_INCLUDE_DIRS}") # Public wolfSSL headers require zlib headers
list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}")
@@ -789,8 +856,9 @@ macro(openssl_check_quic)
endmacro()
if(USE_WOLFSSL)
openssl_check_symbol_exists("wolfSSL_DES_ecb_encrypt" "wolfssl/openssl/des.h" HAVE_WOLFSSL_DES_ECB_ENCRYPT "")
openssl_check_symbol_exists("wolfSSL_BIO_set_shutdown" "wolfssl/ssl.h" HAVE_WOLFSSL_FULL_BIO "")
openssl_check_symbol_exists("wolfSSL_DES_ecb_encrypt" "wolfssl/options.h;wolfssl/openssl/des.h" HAVE_WOLFSSL_DES_ECB_ENCRYPT "")
openssl_check_symbol_exists("wolfSSL_BIO_new" "wolfssl/options.h;wolfssl/ssl.h" HAVE_WOLFSSL_BIO "")
openssl_check_symbol_exists("wolfSSL_BIO_set_shutdown" "wolfssl/options.h;wolfssl/ssl.h" HAVE_WOLFSSL_FULL_BIO "")
endif()
if(USE_OPENSSL OR USE_WOLFSSL)
@@ -802,13 +870,13 @@ if(USE_OPENSSL OR USE_WOLFSSL)
endif()
endif()
option(USE_HTTPSRR "Enable HTTPS RR support for ECH (experimental)" OFF)
option(USE_HTTPSRR "Enable HTTPS RR support" OFF)
option(USE_ECH "Enable ECH support" OFF)
if(USE_ECH)
if(USE_OPENSSL OR USE_WOLFSSL)
# Be sure that the TLS library actually supports ECH.
if(NOT DEFINED HAVE_ECH)
if(USE_OPENSSL AND HAVE_BORINGSSL)
if(USE_OPENSSL AND (HAVE_BORINGSSL OR HAVE_AWSLC))
openssl_check_symbol_exists("SSL_set1_ech_config_list" "openssl/ssl.h" HAVE_ECH "")
elseif(USE_OPENSSL)
openssl_check_symbol_exists("SSL_ech_set1_echconfig" "openssl/ech.h" HAVE_ECH "")
@@ -817,12 +885,12 @@ if(USE_ECH)
endif()
endif()
if(NOT HAVE_ECH)
message(FATAL_ERROR "ECH support missing in OpenSSL/BoringSSL/wolfSSL")
message(FATAL_ERROR "ECH support missing in OpenSSL/BoringSSL/AWS-LC/wolfSSL")
else()
message(STATUS "ECH enabled.")
endif()
else()
message(FATAL_ERROR "ECH requires ECH-enablded OpenSSL, BoringSSL or wolfSSL")
message(FATAL_ERROR "ECH requires ECH-enablded OpenSSL, BoringSSL, AWS-LC or wolfSSL")
endif()
endif()
@@ -830,7 +898,7 @@ option(USE_NGHTTP2 "Use nghttp2 library" ON)
if(USE_NGHTTP2)
find_package(NGHTTP2)
if(NGHTTP2_FOUND)
include_directories(${NGHTTP2_INCLUDE_DIRS})
include_directories(SYSTEM ${NGHTTP2_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libnghttp2")
else()
@@ -858,14 +926,13 @@ if(USE_NGTCP2)
else()
message(FATAL_ERROR "ngtcp2 requires OpenSSL, wolfSSL or GnuTLS")
endif()
set(USE_NGTCP2 ON)
include_directories(${NGTCP2_INCLUDE_DIRS})
include_directories(SYSTEM ${NGTCP2_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${NGTCP2_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libngtcp2")
find_package(NGHTTP3 REQUIRED)
set(USE_NGHTTP3 ON)
include_directories(${NGHTTP3_INCLUDE_DIRS})
include_directories(SYSTEM ${NGHTTP3_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libnghttp3")
endif()
@@ -873,17 +940,21 @@ endif()
option(USE_QUICHE "Use quiche library for HTTP/3 support" OFF)
if(USE_QUICHE)
if(USE_NGTCP2)
message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
message(FATAL_ERROR "Only one HTTP/3 backend can be selected")
endif()
find_package(Quiche REQUIRED)
if(NOT HAVE_BORINGSSL)
message(FATAL_ERROR "quiche requires BoringSSL")
endif()
openssl_check_quic()
set(USE_QUICHE ON)
include_directories(${QUICHE_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
list(APPEND CURL_LIBDIRS ${QUICHE_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "quiche")
include_directories(SYSTEM ${QUICHE_INCLUDE_DIRS})
link_directories(${QUICHE_LIBRARY_DIRS})
if(QUICHE_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${QUICHE_CFLAGS}")
endif()
if(NOT DEFINED HAVE_QUICHE_CONN_SET_QLOG_FD)
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES "${QUICHE_INCLUDE_DIRS}")
@@ -893,27 +964,37 @@ if(USE_QUICHE)
endif()
endif()
option(USE_MSH3 "Use msquic library for HTTP/3 support" OFF)
option(USE_MSH3 "Use msh3/msquic library for HTTP/3 support" OFF)
if(USE_MSH3)
if(USE_NGTCP2 OR USE_QUICHE)
message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
message(FATAL_ERROR "Only one HTTP/3 backend can be selected")
endif()
if(NOT WIN32)
if(NOT USE_OPENSSL)
message(FATAL_ERROR "msh3/msquic requires OpenSSL fork with QUIC API")
endif()
openssl_check_quic()
endif()
find_package(MSH3 REQUIRED)
set(USE_MSH3 ON)
include_directories(${MSH3_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${MSH3_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libmsh3")
list(APPEND CURL_LIBDIRS ${MSH3_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${MSH3_PC_REQUIRES})
include_directories(SYSTEM ${MSH3_INCLUDE_DIRS})
link_directories(${MSH3_LIBRARY_DIRS})
if(MSH3_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MSH3_CFLAGS}")
endif()
endif()
if(USE_OPENSSL_QUIC)
if(USE_NGTCP2 OR USE_QUICHE OR USE_MSH3)
message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
message(FATAL_ERROR "Only one HTTP/3 backend can be selected")
endif()
find_package(OpenSSL 3.3.0 REQUIRED)
find_package(NGHTTP3 REQUIRED)
set(USE_NGHTTP3 ON)
include_directories(${NGHTTP3_INCLUDE_DIRS})
include_directories(SYSTEM ${NGHTTP3_INCLUDE_DIRS})
list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libnghttp3")
endif()
@@ -937,83 +1018,65 @@ if(NOT CURL_DISABLE_LDAP)
endif()
endif()
set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
# Now that we know, we are not using Windows LDAP...
if(NOT USE_WIN32_LDAP)
# Check for LDAP
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
check_library_exists("${CMAKE_LDAP_LIB}" "ldap_init" "" HAVE_LIBLDAP)
if(HAVE_LIBLDAP)
check_library_exists("${CMAKE_LDAP_LIB};${CMAKE_LBER_LIB}" "ber_init" "" HAVE_LIBLBER)
else()
check_library_exists("${CMAKE_LBER_LIB}" "ber_init" "" HAVE_LIBLBER)
if(NOT DEFINED LDAP_LIBRARY)
set(LDAP_LIBRARY "ldap" CACHE STRING "Name or full path to ldap library")
endif()
if(NOT DEFINED LDAP_LBER_LIBRARY)
set(LDAP_LBER_LIBRARY "lber" CACHE STRING "Name or full path to lber library")
endif()
if(NOT DEFINED LDAP_INCLUDE_DIR)
set(LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
endif()
set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
if(CMAKE_LDAP_INCLUDE_DIR)
list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
# Check for LDAP
cmake_push_check_state()
if(USE_OPENSSL)
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
endif()
check_include_file_concat("ldap.h" HAVE_LDAP_H)
check_include_file_concat("lber.h" HAVE_LBER_H)
check_library_exists("${LDAP_LIBRARY}" "ldap_init" "" HAVE_LIBLDAP)
if(HAVE_LIBLDAP)
check_library_exists("${LDAP_LIBRARY};${LDAP_LBER_LIBRARY}" "ber_init" "" HAVE_LIBLBER)
else()
check_library_exists("${LDAP_LBER_LIBRARY}" "ber_init" "" HAVE_LIBLBER)
endif()
if(LDAP_INCLUDE_DIR)
list(APPEND CMAKE_REQUIRED_INCLUDES ${LDAP_INCLUDE_DIR})
endif()
unset(_include_list)
check_include_file("lber.h" HAVE_LBER_H)
if(HAVE_LBER_H)
list(APPEND _include_list "lber.h")
endif()
check_include_files("${_include_list};ldap.h" HAVE_LDAP_H)
unset(_include_list)
if(NOT HAVE_LDAP_H)
message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) # LDAP includes will not be used
elseif(NOT HAVE_LIBLDAP)
message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON")
message(STATUS "LDAP library '${LDAP_LIBRARY}' not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) # LDAP includes will not be used
else()
if(CMAKE_LDAP_INCLUDE_DIR)
include_directories(${CMAKE_LDAP_INCLUDE_DIR})
if(LDAP_INCLUDE_DIR)
include_directories(SYSTEM ${LDAP_INCLUDE_DIR})
endif()
set(NEED_LBER_H ON)
unset(_header_list)
if(WIN32)
list(APPEND _header_list "windows.h")
endif()
if(HAVE_SYS_TYPES_H)
list(APPEND _header_list "sys/types.h")
endif()
list(APPEND _header_list "ldap.h")
set(_include_string "")
foreach(_header IN LISTS _header_list)
set(_include_string "${_include_string}#include <${_header}>\n")
endforeach()
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1")
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
set(CURL_LIBS "${CMAKE_LDAP_LIB};${CURL_LIBS}")
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LDAP_LIBRARY})
set(CURL_LIBS "${LDAP_LIBRARY};${CURL_LIBS}")
# FIXME: uncomment once pkg-config-based detection landed: https://github.com/curl/curl/pull/15273
# set(LIBCURL_PC_REQUIRES_PRIVATE "${LDAP_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}")
if(HAVE_LIBLBER)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
set(CURL_LIBS "${CMAKE_LBER_LIB};${CURL_LIBS}")
endif()
check_c_source_compiles("
${_include_string}
int main(int argc, char ** argv)
{
BerValue *bvp = NULL;
BerElement *bep = ber_init(bvp);
ber_free(bep, 1);
return 0;
}" NOT_NEED_LBER_H)
if(NOT_NEED_LBER_H)
set(NEED_LBER_H OFF)
else()
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LDAP_LBER_LIBRARY})
set(CURL_LIBS "${LDAP_LBER_LIBRARY};${CURL_LIBS}")
endif()
check_function_exists("ldap_url_parse" HAVE_LDAP_URL_PARSE)
check_function_exists("ldap_init_fd" HAVE_LDAP_INIT_FD)
unset(CMAKE_REQUIRED_LIBRARIES)
check_include_file("ldap_ssl.h" HAVE_LDAP_SSL_H)
if(HAVE_LDAP_INIT_FD)
@@ -1024,6 +1087,7 @@ if(NOT CURL_DISABLE_LDAP)
set(HAVE_LDAP_SSL ON)
endif()
endif()
cmake_pop_check_state()
endif()
endif()
@@ -1071,7 +1135,7 @@ if(USE_LIBIDN2 AND NOT USE_APPLE_IDN AND NOT USE_WIN32_IDN)
set(CURL_LIBS "${LIBIDN2_LIBRARIES};${CURL_LIBS}")
list(APPEND CURL_LIBDIRS ${LIBIDN2_LIBRARY_DIRS})
set(LIBCURL_PC_REQUIRES_PRIVATE "libidn2;${LIBCURL_PC_REQUIRES_PRIVATE}")
include_directories(${LIBIDN2_INCLUDE_DIRS})
include_directories(SYSTEM ${LIBIDN2_INCLUDE_DIRS})
link_directories(${LIBIDN2_LIBRARY_DIRS})
if(LIBIDN2_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBIDN2_CFLAGS}")
@@ -1091,8 +1155,7 @@ if(CURL_USE_LIBPSL)
if(LIBPSL_FOUND)
list(APPEND CURL_LIBS ${LIBPSL_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libpsl")
list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBPSL_INCLUDE_DIRS}")
include_directories(${LIBPSL_INCLUDE_DIRS})
include_directories(SYSTEM ${LIBPSL_INCLUDE_DIRS})
set(USE_LIBPSL ON)
else()
message(WARNING "libpsl is enabled, but not found.")
@@ -1100,7 +1163,7 @@ if(CURL_USE_LIBPSL)
endif()
# libssh2
option(CURL_USE_LIBSSH2 "Use libssh2" ON) # FIXME: default is OFF in autotools
option(CURL_USE_LIBSSH2 "Use libssh2" ON)
mark_as_advanced(CURL_USE_LIBSSH2)
set(USE_LIBSSH2 OFF)
@@ -1109,8 +1172,7 @@ if(CURL_USE_LIBSSH2)
if(LIBSSH2_FOUND)
list(APPEND CURL_LIBS ${LIBSSH2_LIBRARIES})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libssh2")
list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIRS}")
include_directories(${LIBSSH2_INCLUDE_DIRS})
include_directories(SYSTEM ${LIBSSH2_INCLUDE_DIRS})
set(USE_LIBSSH2 ON)
endif()
endif()
@@ -1124,7 +1186,7 @@ if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
list(APPEND CURL_LIBS ${LIBSSH_LIBRARIES})
list(APPEND CURL_LIBDIRS ${LIBSSH_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libssh")
include_directories(${LIBSSH_INCLUDE_DIRS})
include_directories(SYSTEM ${LIBSSH_INCLUDE_DIRS})
link_directories(${LIBSSH_LIBRARY_DIRS})
if(LIBSSH_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBSSH_CFLAGS}")
@@ -1142,8 +1204,7 @@ if(NOT USE_LIBSSH2 AND NOT USE_LIBSSH AND CURL_USE_WOLFSSH)
find_package(WolfSSH)
if(WOLFSSH_FOUND)
list(APPEND CURL_LIBS ${WOLFSSH_LIBRARIES})
list(APPEND CMAKE_REQUIRED_INCLUDES "${WOLFSSH_INCLUDE_DIRS}")
include_directories(${WOLFSSH_INCLUDE_DIRS})
include_directories(SYSTEM ${WOLFSSH_INCLUDE_DIRS})
set(USE_WOLFSSH ON)
endif()
else()
@@ -1159,7 +1220,7 @@ if(CURL_USE_GSASL)
list(APPEND CURL_LIBS ${LIBGSASL_LIBRARIES})
list(APPEND CURL_LIBDIRS ${LIBGSASL_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libgsasl")
include_directories(${LIBGSASL_INCLUDE_DIRS})
include_directories(SYSTEM ${LIBGSASL_INCLUDE_DIRS})
link_directories(${LIBGSASL_LIBRARY_DIRS})
if(LIBGSASL_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBGSASL_CFLAGS}")
@@ -1176,55 +1237,52 @@ if(CURL_USE_GSSAPI)
set(HAVE_GSSAPI ${GSS_FOUND})
if(GSS_FOUND)
list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRS})
if(GSS_FLAVOUR STREQUAL "GNU")
set(HAVE_GSSGNU 1)
else()
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRS})
string(REPLACE ";" " " GSS_CFLAGS "${GSS_CFLAGS}")
string(REPLACE ";" " " GSS_LDFLAGS "${GSS_LDFLAGS}")
foreach(_dir IN LISTS GSS_LIBRARY_DIRS)
set(GSS_LDFLAGS "${GSS_LDFLAGS} -L\"${_dir}\"")
endforeach()
check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H)
check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
if(GSS_FLAVOUR STREQUAL "MIT")
set(_include_list "")
check_include_file("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H)
if(HAVE_GSSAPI_GSSAPI_H)
list(APPEND _include_list "gssapi/gssapi.h")
endif()
if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
list(APPEND _include_list "gssapi/gssapi_generic.h")
endif()
if(HAVE_GSSAPI_GSSAPI_KRB5_H)
list(APPEND _include_list "gssapi/gssapi_krb5.h")
endif()
check_include_files("${_include_list};gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
set(CMAKE_REQUIRED_FLAGS "${GSS_CFLAGS} ${GSS_LDFLAGS}")
set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_include_list} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
unset(CMAKE_REQUIRED_LIBRARIES)
endif()
if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
set(HAVE_OLD_GSSMIT ON)
if(GSS_FLAVOUR STREQUAL "MIT")
check_include_files("${_include_list};gssapi/gssapi_krb5.h" _have_gssapi_gssapi_krb5_h)
if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
list(APPEND _include_list "gssapi/gssapi_generic.h")
endif()
if(_have_gssapi_gssapi_krb5_h)
list(APPEND _include_list "gssapi/gssapi_krb5.h")
endif()
if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
set(CMAKE_REQUIRED_FLAGS ${GSS_CFLAGS})
set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
curl_required_libpaths("${GSS_LIBRARY_DIRS}")
check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" "${_include_list}" HAVE_GSS_C_NT_HOSTBASED_SERVICE)
endif()
if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
set(HAVE_OLD_GSSMIT ON)
endif()
endif()
unset(_include_list)
cmake_pop_check_state()
endif()
include_directories(${GSS_INCLUDE_DIRS})
link_directories(${GSS_LIBRARY_DIRS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_CFLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LDFLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LDFLAGS}")
list(APPEND CURL_LIBS ${GSS_LIBRARIES})
if(GSS_FLAVOUR STREQUAL "MIT")
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "mit-krb5-gssapi")
else() # Heimdal
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "heimdal-gssapi")
list(APPEND CURL_LIBDIRS ${GSS_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${GSS_PC_REQUIRES})
include_directories(SYSTEM ${GSS_INCLUDE_DIRS})
link_directories(${GSS_LIBRARY_DIRS})
if(GSS_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_CFLAGS}")
endif()
else()
message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
message(WARNING "GSSAPI has been requested, but no supporting libraries found. Skipping.")
endif()
endif()
@@ -1239,7 +1297,7 @@ if(CURL_USE_LIBUV)
list(APPEND CURL_LIBS ${LIBUV_LIBRARIES})
list(APPEND CURL_LIBDIRS ${LIBUV_LIBRARY_DIRS})
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libuv")
include_directories(${LIBUV_INCLUDE_DIRS})
include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
link_directories(${LIBUV_LIBRARY_DIRS})
if(LIBUV_CFLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUV_CFLAGS}")
@@ -1251,13 +1309,11 @@ endif()
option(USE_LIBRTMP "Enable librtmp from rtmpdump" OFF)
if(USE_LIBRTMP)
cmake_push_check_state()
set(_extra_libs "rtmp")
if(WIN32)
list(APPEND _extra_libs "winmm")
endif()
openssl_check_symbol_exists("RTMP_Init" "librtmp/rtmp.h" HAVE_LIBRTMP "${_extra_libs}")
cmake_pop_check_state()
if(HAVE_LIBRTMP)
list(APPEND CURL_LIBS "rtmp")
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "librtmp")
@@ -1265,7 +1321,7 @@ if(USE_LIBRTMP)
list(APPEND CURL_LIBS "winmm")
endif()
else()
message(WARNING "librtmp requested, but not found or missing OpenSSL. Skipping.")
message(WARNING "librtmp has been requested, but not found or missing OpenSSL. Skipping.")
set(USE_LIBRTMP OFF)
endif()
endif()
@@ -1289,11 +1345,11 @@ if(_curl_ca_bundle_supported)
set(CURL_CA_BUNDLE "auto" CACHE
STRING "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
set(CURL_CA_FALLBACK OFF CACHE BOOL
"Set ON to use built-in CA store of TLS backend. Defaults to OFF")
"Use built-in CA store of TLS backend. Defaults to OFF")
set(CURL_CA_PATH "auto" CACHE
STRING "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
set(CURL_CA_EMBED "" CACHE
STRING "Path to the CA bundle to embed into the curl tool.")
STRING "Path to the CA bundle to embed in the curl tool.")
if(CURL_CA_BUNDLE STREQUAL "")
message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
@@ -1364,17 +1420,22 @@ if(_curl_ca_bundle_supported)
if(BUILD_CURL_EXE AND NOT CURL_CA_EMBED STREQUAL "")
if(EXISTS "${CURL_CA_EMBED}")
set(CURL_CA_EMBED_SET TRUE)
message(STATUS "Found CA bundle to embed: ${CURL_CA_EMBED}")
else()
message(FATAL_ERROR "CA bundle to embed is missing: '${CURL_CA_EMBED}'")
endif()
endif()
endif()
if(WIN32)
option(CURL_DISABLE_CA_SEARCH "Disable unsafe CA bundle search in PATH on Windows" OFF)
option(CURL_CA_SEARCH_SAFE "Enable safe CA bundle search (within the curl tool directory) on Windows" OFF)
endif()
# Check for header files
if(WIN32)
set(CURL_INCLUDES ${CURL_INCLUDES} "winsock2.h")
set(CURL_INCLUDES ${CURL_INCLUDES} "ws2tcpip.h")
set(CURL_INCLUDES ${CURL_INCLUDES} "windows.h")
list(APPEND CURL_INCLUDES "winsock2.h")
list(APPEND CURL_INCLUDES "ws2tcpip.h")
if(HAVE_WIN32_WINNT)
if(HAVE_WIN32_WINNT LESS 0x0501)
@@ -1397,46 +1458,72 @@ if(WIN32)
endif()
endif()
check_include_file_concat("sys/eventfd.h" HAVE_SYS_EVENTFD_H)
check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H)
check_include_file_concat("sys/wait.h" HAVE_SYS_WAIT_H)
check_include_file_concat("sys/ioctl.h" HAVE_SYS_IOCTL_H)
check_include_file_concat("sys/param.h" HAVE_SYS_PARAM_H)
check_include_file_concat("sys/poll.h" HAVE_SYS_POLL_H)
check_include_file_concat("sys/resource.h" HAVE_SYS_RESOURCE_H)
# Detect headers
# Use check_include_file_concat() for headers required by subsequent
# check_include_file_concat() or check_symbol_exists() detections.
# Order for these is significant.
check_include_file("sys/eventfd.h" HAVE_SYS_EVENTFD_H)
check_include_file("sys/filio.h" HAVE_SYS_FILIO_H)
check_include_file("sys/wait.h" HAVE_SYS_WAIT_H)
check_include_file("sys/ioctl.h" HAVE_SYS_IOCTL_H)
check_include_file("sys/param.h" HAVE_SYS_PARAM_H)
check_include_file("sys/poll.h" HAVE_SYS_POLL_H)
check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H)
check_include_file_concat("sys/select.h" HAVE_SYS_SELECT_H)
check_include_file_concat("sys/socket.h" HAVE_SYS_SOCKET_H)
check_include_file_concat("sys/sockio.h" HAVE_SYS_SOCKIO_H)
check_include_file_concat("sys/stat.h" HAVE_SYS_STAT_H)
check_include_file("sys/sockio.h" HAVE_SYS_SOCKIO_H)
check_include_file("sys/stat.h" HAVE_SYS_STAT_H)
check_include_file_concat("sys/time.h" HAVE_SYS_TIME_H)
check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H)
check_include_file_concat("sys/un.h" HAVE_SYS_UN_H)
check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
check_include_file("sys/un.h" HAVE_SYS_UN_H)
check_include_file("sys/utime.h" HAVE_SYS_UTIME_H)
check_include_file("sys/xattr.h" HAVE_SYS_XATTR_H)
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file_concat("dirent.h" HAVE_DIRENT_H)
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
check_include_file("dirent.h" HAVE_DIRENT_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
check_include_file_concat("io.h" HAVE_IO_H)
check_include_file("io.h" HAVE_IO_H)
check_include_file_concat("libgen.h" HAVE_LIBGEN_H)
check_include_file_concat("locale.h" HAVE_LOCALE_H)
check_include_file_concat("net/if.h" HAVE_NET_IF_H)
check_include_file("linux/tcp.h" HAVE_LINUX_TCP_H)
check_include_file("locale.h" HAVE_LOCALE_H)
check_include_file("net/if.h" HAVE_NET_IF_H)
check_include_file_concat("netdb.h" HAVE_NETDB_H)
check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
check_include_file_concat("netinet/udp.h" HAVE_NETINET_UDP_H)
check_include_file("linux/tcp.h" HAVE_LINUX_TCP_H)
check_include_file_concat("poll.h" HAVE_POLL_H)
check_include_file_concat("pwd.h" HAVE_PWD_H)
check_include_file_concat("stdatomic.h" HAVE_STDATOMIC_H)
check_include_file_concat("stdbool.h" HAVE_STDBOOL_H)
check_include_file_concat("strings.h" HAVE_STRINGS_H)
check_include_file_concat("stropts.h" HAVE_STROPTS_H)
check_include_file_concat("termio.h" HAVE_TERMIO_H)
check_include_file_concat("termios.h" HAVE_TERMIOS_H)
check_include_file("netinet/in6.h" HAVE_NETINET_IN6_H)
check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H) # sys/types.h (e.g. Cygwin) netinet/in.h
check_include_file_concat("netinet/udp.h" HAVE_NETINET_UDP_H) # sys/types.h (e.g. Cygwin)
check_include_file("poll.h" HAVE_POLL_H)
check_include_file("pwd.h" HAVE_PWD_H)
check_include_file("stdatomic.h" HAVE_STDATOMIC_H)
check_include_file("stdbool.h" HAVE_STDBOOL_H)
check_include_file("strings.h" HAVE_STRINGS_H)
check_include_file("stropts.h" HAVE_STROPTS_H)
check_include_file("termio.h" HAVE_TERMIO_H)
check_include_file("termios.h" HAVE_TERMIOS_H)
check_include_file_concat("unistd.h" HAVE_UNISTD_H)
check_include_file_concat("utime.h" HAVE_UTIME_H)
check_include_file("utime.h" HAVE_UTIME_H)
if(CMAKE_SYSTEM_NAME MATCHES "AmigaOS")
check_include_file_concat("proto/bsdsocket.h" HAVE_PROTO_BSDSOCKET_H)
endif()
# Pass these detection results to curl_internal_test() for use in CurlTests.c
# Add here all feature flags referenced from CurlTests.c
foreach(_variable IN ITEMS
HAVE_STDATOMIC_H
HAVE_STDBOOL_H
HAVE_STROPTS_H
HAVE_SYS_IOCTL_H
HAVE_SYS_SOCKET_H
HAVE_SYS_TYPES_H
HAVE_UNISTD_H
)
if(${_variable})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${_variable}")
endif()
endforeach()
check_type_size("size_t" SIZEOF_SIZE_T)
check_type_size("ssize_t" SIZEOF_SSIZE_T)
@@ -1465,94 +1552,107 @@ endif()
# Check for some functions that are used
if(WIN32)
set(CMAKE_REQUIRED_LIBRARIES "ws2_32")
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32") # Apply to all feature checks
elseif(HAVE_LIBSOCKET)
set(CMAKE_REQUIRED_LIBRARIES "socket")
list(APPEND CMAKE_REQUIRED_LIBRARIES "socket") # Apply to all feature checks
endif()
check_symbol_exists("fnmatch" "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH)
check_symbol_exists("basename" "${CURL_INCLUDES};string.h" HAVE_BASENAME)
check_symbol_exists("opendir" "${CURL_INCLUDES};dirent.h" HAVE_OPENDIR)
check_symbol_exists("socket" "${CURL_INCLUDES}" HAVE_SOCKET)
check_symbol_exists("sched_yield" "${CURL_INCLUDES};sched.h" HAVE_SCHED_YIELD)
check_symbol_exists("socketpair" "${CURL_INCLUDES}" HAVE_SOCKETPAIR)
check_symbol_exists("recv" "${CURL_INCLUDES}" HAVE_RECV)
check_symbol_exists("send" "${CURL_INCLUDES}" HAVE_SEND)
check_symbol_exists("sendmsg" "${CURL_INCLUDES}" HAVE_SENDMSG)
check_symbol_exists("select" "${CURL_INCLUDES}" HAVE_SELECT)
check_symbol_exists("strdup" "${CURL_INCLUDES};string.h" HAVE_STRDUP)
check_symbol_exists("strtok_r" "${CURL_INCLUDES};string.h" HAVE_STRTOK_R)
check_symbol_exists("strcasecmp" "${CURL_INCLUDES};string.h" HAVE_STRCASECMP)
check_symbol_exists("stricmp" "${CURL_INCLUDES};string.h" HAVE_STRICMP)
check_symbol_exists("strcmpi" "${CURL_INCLUDES};string.h" HAVE_STRCMPI)
check_symbol_exists("memrchr" "${CURL_INCLUDES};string.h" HAVE_MEMRCHR)
check_symbol_exists("alarm" "${CURL_INCLUDES}" HAVE_ALARM)
check_symbol_exists("arc4random" "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM)
check_symbol_exists("fcntl" "${CURL_INCLUDES}" HAVE_FCNTL)
check_symbol_exists("getppid" "${CURL_INCLUDES}" HAVE_GETPPID)
check_symbol_exists("utimes" "${CURL_INCLUDES}" HAVE_UTIMES)
check_function_exists("fnmatch" HAVE_FNMATCH)
check_symbol_exists("basename" "${CURL_INCLUDES};string.h" HAVE_BASENAME) # libgen.h unistd.h
check_symbol_exists("opendir" "dirent.h" HAVE_OPENDIR)
check_function_exists("poll" HAVE_POLL) # poll.h
check_symbol_exists("socket" "${CURL_INCLUDES}" HAVE_SOCKET) # winsock2.h sys/socket.h
check_function_exists("sched_yield" HAVE_SCHED_YIELD)
check_symbol_exists("socketpair" "${CURL_INCLUDES}" HAVE_SOCKETPAIR) # sys/socket.h
check_symbol_exists("recv" "${CURL_INCLUDES}" HAVE_RECV) # proto/bsdsocket.h sys/types.h sys/socket.h
check_symbol_exists("send" "${CURL_INCLUDES}" HAVE_SEND) # proto/bsdsocket.h sys/types.h sys/socket.h
check_function_exists("sendmsg" HAVE_SENDMSG)
check_function_exists("sendmmsg" HAVE_SENDMMSG)
check_symbol_exists("select" "${CURL_INCLUDES}" HAVE_SELECT) # proto/bsdsocket.h sys/select.h sys/socket.h
check_symbol_exists("strdup" "string.h" HAVE_STRDUP)
check_symbol_exists("strtok_r" "string.h" HAVE_STRTOK_R)
check_symbol_exists("strcasecmp" "string.h" HAVE_STRCASECMP)
check_symbol_exists("stricmp" "string.h" HAVE_STRICMP)
check_symbol_exists("strcmpi" "string.h" HAVE_STRCMPI)
check_symbol_exists("memrchr" "string.h" HAVE_MEMRCHR)
check_symbol_exists("alarm" "unistd.h" HAVE_ALARM)
check_symbol_exists("fcntl" "fcntl.h" HAVE_FCNTL)
check_function_exists("getppid" HAVE_GETPPID)
check_function_exists("utimes" HAVE_UTIMES)
check_symbol_exists("gettimeofday" "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
check_symbol_exists("closesocket" "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
check_symbol_exists("sigsetjmp" "${CURL_INCLUDES};setjmp.h" HAVE_SIGSETJMP)
check_symbol_exists("getpass_r" "${CURL_INCLUDES}" HAVE_GETPASS_R)
check_symbol_exists("getpwuid" "${CURL_INCLUDES}" HAVE_GETPWUID)
check_symbol_exists("getpwuid_r" "${CURL_INCLUDES}" HAVE_GETPWUID_R)
check_symbol_exists("geteuid" "${CURL_INCLUDES}" HAVE_GETEUID)
check_symbol_exists("utime" "${CURL_INCLUDES}" HAVE_UTIME)
check_symbol_exists("gmtime_r" "${CURL_INCLUDES};stdlib.h;time.h" HAVE_GMTIME_R)
check_function_exists("gettimeofday" HAVE_GETTIMEOFDAY) # sys/time.h
check_symbol_exists("closesocket" "${CURL_INCLUDES}" HAVE_CLOSESOCKET) # winsock2.h
check_symbol_exists("sigsetjmp" "setjmp.h" HAVE_SIGSETJMP)
check_function_exists("getpass_r" HAVE_GETPASS_R)
check_function_exists("getpwuid" HAVE_GETPWUID)
check_function_exists("getpwuid_r" HAVE_GETPWUID_R)
check_function_exists("geteuid" HAVE_GETEUID)
check_function_exists("utime" HAVE_UTIME)
check_symbol_exists("gmtime_r" "stdlib.h;time.h" HAVE_GMTIME_R)
check_symbol_exists("gethostbyname_r" "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
check_symbol_exists("gethostbyname_r" "netdb.h" HAVE_GETHOSTBYNAME_R)
check_symbol_exists("signal" "${CURL_INCLUDES};signal.h" HAVE_SIGNAL)
check_symbol_exists("strtoll" "${CURL_INCLUDES};stdlib.h" HAVE_STRTOLL)
check_symbol_exists("strerror_r" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_STRERROR_R)
check_symbol_exists("signal" "signal.h" HAVE_SIGNAL)
check_symbol_exists("strtoll" "stdlib.h" HAVE_STRTOLL)
check_symbol_exists("strerror_r" "stdlib.h;string.h" HAVE_STRERROR_R)
check_symbol_exists("sigaction" "signal.h" HAVE_SIGACTION)
check_symbol_exists("siginterrupt" "${CURL_INCLUDES};signal.h" HAVE_SIGINTERRUPT)
check_symbol_exists("getaddrinfo" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO)
check_symbol_exists("getifaddrs" "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS)
check_symbol_exists("freeaddrinfo" "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
check_symbol_exists("pipe" "${CURL_INCLUDES}" HAVE_PIPE)
check_symbol_exists("eventfd" "${CURL_INCLUDES};sys/eventfd.h" HAVE_EVENTFD)
check_symbol_exists("ftruncate" "${CURL_INCLUDES}" HAVE_FTRUNCATE)
check_symbol_exists("_fseeki64" "${CURL_INCLUDES};stdio.h" HAVE__FSEEKI64)
check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME)
check_symbol_exists("getsockname" "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
check_symbol_exists("if_nametoindex" "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX)
check_symbol_exists("getrlimit" "${CURL_INCLUDES}" HAVE_GETRLIMIT)
check_symbol_exists("setlocale" "${CURL_INCLUDES}" HAVE_SETLOCALE)
check_symbol_exists("setmode" "${CURL_INCLUDES}" HAVE_SETMODE)
check_symbol_exists("setrlimit" "${CURL_INCLUDES}" HAVE_SETRLIMIT)
check_symbol_exists("siginterrupt" "signal.h" HAVE_SIGINTERRUPT)
check_symbol_exists("getaddrinfo" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO) # ws2tcpip.h sys/socket.h netdb.h
check_symbol_exists("getifaddrs" "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS) # ifaddrs.h
check_symbol_exists("freeaddrinfo" "${CURL_INCLUDES}" HAVE_FREEADDRINFO) # ws2tcpip.h sys/socket.h netdb.h
check_function_exists("pipe" HAVE_PIPE)
check_function_exists("eventfd" HAVE_EVENTFD)
check_symbol_exists("ftruncate" "unistd.h" HAVE_FTRUNCATE)
check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME) # winsock2.h unistd.h proto/bsdsocket.h
check_symbol_exists("getsockname" "${CURL_INCLUDES}" HAVE_GETSOCKNAME) # winsock2.h unistd.h proto/bsdsocket.h
check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # winsock2.h net/if.h
check_function_exists("getrlimit" HAVE_GETRLIMIT)
check_function_exists("setlocale" HAVE_SETLOCALE)
check_function_exists("setmode" HAVE_SETMODE)
check_function_exists("setrlimit" HAVE_SETRLIMIT)
if(WIN32 OR CYGWIN)
check_function_exists("_setmode" HAVE__SETMODE)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "AmigaOS")
check_symbol_exists("CloseSocket" "${CURL_INCLUDES}" HAVE_CLOSESOCKET_CAMEL) # sys/socket.h proto/bsdsocket.h
endif()
if(NOT _ssl_enabled)
check_symbol_exists("arc4random" "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM)
endif()
if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900))
# Earlier MSVC compilers had faulty snprintf implementations
check_symbol_exists("snprintf" "stdio.h" HAVE_SNPRINTF)
check_function_exists("snprintf" HAVE_SNPRINTF)
endif()
check_function_exists("mach_absolute_time" HAVE_MACH_ABSOLUTE_TIME)
check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP)
if(APPLE)
check_function_exists("mach_absolute_time" HAVE_MACH_ABSOLUTE_TIME)
endif()
check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) # arpa/inet.h
if(MSVC AND (MSVC_VERSION LESS_EQUAL 1600))
set(HAVE_INET_NTOP OFF)
endif()
check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON)
check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) # arpa/inet.h
check_symbol_exists("fsetxattr" "${CURL_INCLUDES}" HAVE_FSETXATTR)
check_symbol_exists("fsetxattr" "sys/xattr.h" HAVE_FSETXATTR)
if(HAVE_FSETXATTR)
foreach(_curl_test IN ITEMS HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
curl_internal_test(${_curl_test})
endforeach()
curl_internal_test(HAVE_FSETXATTR_5)
curl_internal_test(HAVE_FSETXATTR_6)
endif()
set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
check_type_size("sa_family_t" SIZEOF_SA_FAMILY_T)
set(HAVE_SA_FAMILY_T ${HAVE_SIZEOF_SA_FAMILY_T})
set(CMAKE_EXTRA_INCLUDE_FILES "")
cmake_push_check_state()
if(WIN32)
set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h")
check_type_size("ADDRESS_FAMILY" SIZEOF_ADDRESS_FAMILY)
set(HAVE_ADDRESS_FAMILY ${HAVE_SIZEOF_ADDRESS_FAMILY})
set(CMAKE_EXTRA_INCLUDE_FILES "")
elseif(HAVE_SYS_SOCKET_H)
set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
check_type_size("sa_family_t" SIZEOF_SA_FAMILY_T)
set(HAVE_SA_FAMILY_T ${HAVE_SIZEOF_SA_FAMILY_T})
endif()
cmake_pop_check_state()
# Do curl specific tests
foreach(_curl_test IN ITEMS
@@ -1580,9 +1680,10 @@ foreach(_curl_test IN ITEMS
curl_internal_test(${_curl_test})
endforeach()
cmake_push_check_state()
if(HAVE_FILE_OFFSET_BITS)
set(_FILE_OFFSET_BITS 64)
set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
set(CMAKE_REQUIRED_DEFINITIONS "-D_FILE_OFFSET_BITS=64")
endif()
check_type_size("off_t" SIZEOF_OFF_T)
@@ -1596,12 +1697,14 @@ if(HAVE_FSEEKO)
endif()
# Include this header to get the type
set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCE_DIR}/include")
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/include")
set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h")
check_type_size("curl_off_t" SIZEOF_CURL_OFF_T)
set(CMAKE_EXTRA_INCLUDE_FILES "curl/curl.h")
check_type_size("curl_socket_t" SIZEOF_CURL_SOCKET_T)
set(CMAKE_EXTRA_INCLUDE_FILES "")
cmake_pop_check_state() # pop curl system headers
cmake_pop_check_state() # pop -D_FILE_OFFSET_BITS=64
if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING)
# On non-Windows and not cross-compiling, check for writable argv[]
@@ -1615,24 +1718,8 @@ if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING)
}" HAVE_WRITABLE_ARGV)
endif()
unset(CMAKE_REQUIRED_FLAGS)
option(ENABLE_WEBSOCKETS "Enable WebSockets (experimental)" OFF)
if(ENABLE_WEBSOCKETS)
if(SIZEOF_CURL_OFF_T GREATER 4)
set(USE_WEBSOCKETS ON)
else()
message(WARNING "curl_off_t is too small to enable WebSockets")
endif()
endif()
foreach(_curl_test IN ITEMS
HAVE_GLIBC_STRERROR_R
HAVE_POSIX_STRERROR_R
)
curl_internal_test(${_curl_test})
endforeach()
curl_internal_test(HAVE_GLIBC_STRERROR_R)
curl_internal_test(HAVE_POSIX_STRERROR_R)
# Check for reentrant
foreach(_curl_test IN ITEMS
@@ -1659,13 +1746,11 @@ if(NEED_REENTRANT)
endif()
if(NOT WIN32)
# Check clock_gettime(CLOCK_MONOTONIC, x) support
curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC)
curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC) # Check clock_gettime(CLOCK_MONOTONIC, x) support
endif()
if(APPLE)
# Check compiler support of __builtin_available()
curl_internal_test(HAVE_BUILTIN_AVAILABLE)
curl_internal_test(HAVE_BUILTIN_AVAILABLE) # Check compiler support of __builtin_available()
endif()
# Some other minor tests
@@ -1699,6 +1784,11 @@ if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
endif()
endif()
if(_cmake_try_compile_target_type_save)
set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_cmake_try_compile_target_type_save})
unset(_cmake_try_compile_target_type_save)
endif()
include(CMake/OtherTests.cmake)
add_definitions("-DHAVE_CONFIG_H")
@@ -1733,7 +1823,7 @@ if(MSVC)
endif()
# Use multithreaded compilation on VS 2008+
if(MSVC_VERSION GREATER_EQUAL 1500)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER_EQUAL 1500)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
endif()
endif()
@@ -1749,17 +1839,17 @@ endif()
if(CURL_LTO)
if(CMAKE_VERSION VERSION_LESS 3.9)
message(FATAL_ERROR "Requested LTO but your cmake version ${CMAKE_VERSION} is to old. You need at least 3.9")
message(FATAL_ERROR "LTO has been requested, but your cmake version ${CMAKE_VERSION} is to old. You need at least 3.9")
endif()
cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported)
check_ipo_supported(RESULT CURL_HAS_LTO OUTPUT CURL_LTO_ERROR LANGUAGES C)
check_ipo_supported(RESULT CURL_HAS_LTO OUTPUT _lto_error LANGUAGES C)
if(CURL_HAS_LTO)
message(STATUS "LTO supported and enabled")
else()
message(FATAL_ERROR "LTO was requested - but compiler does not support it\n${CURL_LTO_ERROR}")
message(FATAL_ERROR "LTO has been requested, but the compiler does not support it\n${_lto_error}")
endif()
endif()
@@ -1768,8 +1858,8 @@ endif()
# (= regenerate it).
function(transform_makefile_inc _input_file _output_file)
file(READ ${_input_file} _makefile_inc_text)
string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" _makefile_inc_text ${_makefile_inc_text})
string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" _makefile_inc_text ${_makefile_inc_text})
string(REPLACE "$(top_srcdir)" "\${PROJECT_SOURCE_DIR}" _makefile_inc_text ${_makefile_inc_text})
string(REPLACE "$(top_builddir)" "\${PROJECT_BINARY_DIR}" _makefile_inc_text ${_makefile_inc_text})
string(REGEX REPLACE "\\\\\n" "!π!α!" _makefile_inc_text ${_makefile_inc_text})
string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "set(\\1 \\2)" _makefile_inc_text ${_makefile_inc_text})
@@ -1786,17 +1876,22 @@ endfunction()
include(GNUInstallDirs)
set(CURL_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
set(_install_cmake_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(_project_config "${_generated_dir}/${PROJECT_NAME}Config.cmake")
set(_version_config "${_generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
cmake_dependent_option(BUILD_TESTING "Build tests"
ON "PERL_FOUND;NOT CURL_DISABLE_TESTS"
OFF)
option(BUILD_TESTING "Build tests" ON)
if(BUILD_TESTING AND PERL_FOUND AND NOT CURL_DISABLE_TESTS)
set(CURL_BUILD_TESTING ON)
else()
set(CURL_BUILD_TESTING OFF)
endif()
if(HAVE_MANUAL_TOOLS)
set(CURL_MANPAGE "${PROJECT_BINARY_DIR}/docs/cmdline-opts/curl.1")
set(CURL_ASCIIPAGE "${PROJECT_BINARY_DIR}/docs/cmdline-opts/curl.txt")
add_subdirectory(docs)
endif()
@@ -1806,12 +1901,12 @@ if(BUILD_CURL_EXE)
add_subdirectory(src)
endif()
option(BUILD_EXAMPLES "Build libcurl examples" OFF)
option(BUILD_EXAMPLES "Build libcurl examples" ON)
if(BUILD_EXAMPLES)
add_subdirectory(docs/examples)
endif()
if(BUILD_TESTING)
if(CURL_BUILD_TESTING)
add_subdirectory(tests)
endif()
@@ -1839,8 +1934,6 @@ endif()
# Clear list and try to detect available protocols
unset(_items)
_add_if("HTTP" NOT CURL_DISABLE_HTTP)
_add_if("IPFS" NOT CURL_DISABLE_HTTP)
_add_if("IPNS" NOT CURL_DISABLE_HTTP)
_add_if("HTTPS" NOT CURL_DISABLE_HTTP AND _ssl_enabled)
_add_if("FTP" NOT CURL_DISABLE_FTP)
_add_if("FTPS" NOT CURL_DISABLE_FTP AND _ssl_enabled)
@@ -1867,11 +1960,13 @@ _add_if("SMTP" NOT CURL_DISABLE_SMTP)
_add_if("SMTPS" NOT CURL_DISABLE_SMTP AND _ssl_enabled)
_add_if("SCP" USE_LIBSSH2 OR USE_LIBSSH OR USE_WOLFSSH)
_add_if("SFTP" USE_LIBSSH2 OR USE_LIBSSH OR USE_WOLFSSH)
_add_if("IPFS" NOT CURL_DISABLE_IPFS)
_add_if("IPNS" NOT CURL_DISABLE_IPFS)
_add_if("RTSP" NOT CURL_DISABLE_RTSP)
_add_if("RTMP" USE_LIBRTMP)
_add_if("MQTT" NOT CURL_DISABLE_MQTT)
_add_if("WS" USE_WEBSOCKETS)
_add_if("WSS" USE_WEBSOCKETS AND _ssl_enabled)
_add_if("WS" NOT CURL_DISABLE_WEBSOCKETS)
_add_if("WSS" NOT CURL_DISABLE_WEBSOCKETS AND _ssl_enabled)
if(_items)
list(SORT _items)
endif()
@@ -1911,7 +2006,7 @@ _add_if("MultiSSL" CURL_WITH_MULTI_SSL)
_add_if("HTTPS-proxy" _ssl_enabled AND (USE_OPENSSL OR USE_GNUTLS
OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR
USE_MBEDTLS OR USE_SECTRANSP OR
(USE_WOLFSSL AND HAVE_WOLFSSL_FULL_BIO)))
(USE_WOLFSSL AND HAVE_WOLFSSL_BIO)))
_add_if("Unicode" ENABLE_UNICODE)
_add_if("threadsafe" HAVE_ATOMIC OR
(USE_THREADS_POSIX AND HAVE_PTHREAD_H) OR
@@ -1962,19 +2057,47 @@ if(NOT CURL_DISABLE_INSTALL)
set(CC "${CMAKE_C_COMPILER}")
# TODO: probably put a -D... options here?
set(CONFIGURE_OPTIONS "")
set(CURLVERSION "${CURL_VERSION}")
set(VERSIONNUM "${CURL_VERSION_NUM}")
set(CURLVERSION "${_curl_version}")
set(VERSIONNUM "${_curl_version_num}")
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
set(includedir "\${prefix}/include")
set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
if(IS_ABSOLUTE ${CMAKE_INSTALL_INCLUDEDIR})
set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
else()
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
if(IS_ABSOLUTE ${CMAKE_INSTALL_LIBDIR})
set(libdir "${CMAKE_INSTALL_LIBDIR}")
else()
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()
# "a" (Linux) or "lib" (Windows)
string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
set(_ldflags "")
set(LIBCURL_PC_LIBS_PRIVATE "")
# Filter CMAKE_SHARED_LINKER_FLAGS for libs and libpaths
string(STRIP "${CMAKE_SHARED_LINKER_FLAGS}" _custom_ldflags)
string(REGEX REPLACE " +-([^ \\t;]*)" ";-\\1" _custom_ldflags "${_custom_ldflags}")
set(_custom_libs "")
set(_custom_libdirs "")
foreach(_flag IN LISTS _custom_ldflags)
if(_flag MATCHES "^-l")
string(REGEX REPLACE "^-l" "" _flag "${_flag}")
list(APPEND _custom_libs "${_flag}")
elseif(_flag MATCHES "^-framework|^-F")
list(APPEND _custom_libs "${_flag}")
elseif(_flag MATCHES "^-L")
string(REGEX REPLACE "^-L" "" _flag "${_flag}")
list(APPEND _custom_libdirs "${_flag}")
elseif(_flag MATCHES "^--library-path=")
string(REGEX REPLACE "^--library-path=" "" _flag "${_flag}")
list(APPEND _custom_libdirs "${_flag}")
endif()
endforeach()
# Avoid getting unnecessary -L options for known system directories.
unset(_sys_libdirs)
foreach(_libdir IN LISTS CMAKE_SYSTEM_PREFIX_PATH)
@@ -1994,14 +2117,19 @@ if(NOT CURL_DISABLE_INSTALL)
endif()
endforeach()
foreach(_libdir IN LISTS CURL_LIBDIRS)
foreach(_libdir IN LISTS _custom_libdirs CURL_LIBDIRS)
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
endif()
endforeach()
foreach(_lib IN LISTS CMAKE_C_IMPLICIT_LINK_LIBRARIES CURL_LIBS)
unset(_implicit_libs)
if(NOT MINGW AND NOT UNIX)
set(_implicit_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
endif()
foreach(_lib IN LISTS _implicit_libs _custom_libs CURL_LIBS)
if(TARGET "${_lib}")
set(_libname "${_lib}")
get_target_property(_imported "${_libname}" IMPORTED)
@@ -2047,8 +2175,10 @@ if(NOT CURL_DISABLE_INSTALL)
if(_ldflags)
list(REMOVE_DUPLICATES _ldflags)
string(REPLACE ";" " " _ldflags "${_ldflags}")
set(LIBCURL_PC_LIBS_PRIVATE "${_ldflags} ${LIBCURL_PC_LIBS_PRIVATE}")
string(STRIP "${LIBCURL_PC_LIBS_PRIVATE}" LIBCURL_PC_LIBS_PRIVATE)
set(LIBCURL_PC_LDFLAGS_PRIVATE "${_ldflags}")
string(STRIP "${LIBCURL_PC_LDFLAGS_PRIVATE}" LIBCURL_PC_LDFLAGS_PRIVATE)
else()
set(LIBCURL_PC_LDFLAGS_PRIVATE "")
endif()
set(LIBCURL_PC_CFLAGS_PRIVATE "-DCURL_STATICLIB")
@@ -2070,7 +2200,7 @@ if(NOT CURL_DISABLE_INSTALL)
set(ENABLE_STATIC "no")
endif()
# Finally generate a "curl-config" matching this config.
# Generate a "curl-config" matching this config.
# Consumed variables:
# CC
# CONFIGURE_OPTIONS
@@ -2080,8 +2210,8 @@ if(NOT CURL_DISABLE_INSTALL)
# ENABLE_STATIC
# exec_prefix
# includedir
# LDFLAGS
# LIBCURL_PC_CFLAGS
# LIBCURL_PC_LDFLAGS_PRIVATE
# LIBCURL_PC_LIBS_PRIVATE
# libdir
# libext
@@ -2091,22 +2221,23 @@ if(NOT CURL_DISABLE_INSTALL)
# SUPPORT_PROTOCOLS
# VERSIONNUM
configure_file(
"${CURL_SOURCE_DIR}/curl-config.in"
"${CURL_BINARY_DIR}/curl-config" @ONLY)
install(FILES "${CURL_BINARY_DIR}/curl-config"
"${PROJECT_SOURCE_DIR}/curl-config.in"
"${PROJECT_BINARY_DIR}/curl-config" @ONLY)
install(FILES "${PROJECT_BINARY_DIR}/curl-config"
DESTINATION ${CMAKE_INSTALL_BINDIR}
PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
# Finally generate a pkg-config file matching this config
# Generate a pkg-config file matching this config.
# Consumed variables:
# CURLVERSION
# exec_prefix
# includedir
# LIBCURL_PC_CFLAGS
# LIBCURL_PC_CFLAGS_PRIVATE
# LIBCURL_PC_LDFLAGS_PRIVATE
# LIBCURL_PC_LIBS
# LIBCURL_PC_LIBS_PRIVATE
# LIBCURL_PC_REQUIRES
@@ -2115,21 +2246,26 @@ if(NOT CURL_DISABLE_INSTALL)
# prefix
# SUPPORT_FEATURES
# SUPPORT_PROTOCOLS
# Documentation:
# https://people.freedesktop.org/~dbn/pkg-config-guide.html
# https://manpages.debian.org/unstable/pkgconf/pkg-config.1.en.html
# https://manpages.debian.org/unstable/pkg-config/pkg-config.1.en.html
# https://www.msys2.org/docs/pkgconfig/
configure_file(
"${CURL_SOURCE_DIR}/libcurl.pc.in"
"${CURL_BINARY_DIR}/libcurl.pc" @ONLY)
install(FILES "${CURL_BINARY_DIR}/libcurl.pc"
"${PROJECT_SOURCE_DIR}/libcurl.pc.in"
"${PROJECT_BINARY_DIR}/libcurl.pc" @ONLY)
install(FILES "${PROJECT_BINARY_DIR}/libcurl.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
# Install headers
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/curl"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h")
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${_version_config}"
VERSION ${CURL_VERSION}
VERSION ${_curl_version}
COMPATIBILITY SameMajorVersion)
file(READ "${_version_config}" _generated_version_config)
file(WRITE "${_version_config}" "
@@ -2144,20 +2280,20 @@ if(NOT CURL_DISABLE_INSTALL)
# LIB_SELECTED
# TARGETS_EXPORT_NAME
# USE_OPENSSL
# USE_ZLIB
# HAVE_LIBZ
configure_package_config_file("CMake/curl-config.cmake.in"
"${_project_config}"
INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR}
INSTALL_DESTINATION ${_install_cmake_dir}
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
if(CURL_ENABLE_EXPORT_TARGET)
install(EXPORT "${TARGETS_EXPORT_NAME}"
NAMESPACE "${PROJECT_NAME}::"
DESTINATION ${CURL_INSTALL_CMAKE_DIR})
DESTINATION ${_install_cmake_dir})
endif()
install(FILES ${_version_config} ${_project_config}
DESTINATION ${CURL_INSTALL_CMAKE_DIR})
DESTINATION ${_install_cmake_dir})
# Workaround for MSVS10 to avoid the Dialog Hell
# FIXME: This could be removed with future version of CMake.
@@ -2172,7 +2308,7 @@ if(NOT CURL_DISABLE_INSTALL)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
@ONLY)
add_custom_target(curl_uninstall
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake")
@@ -2184,4 +2320,36 @@ if(NOT CURL_DISABLE_INSTALL)
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
# The `-DEV` part is important
string(REGEX REPLACE "([0-9]+\.[0-9]+)\.([0-9]+.*)" "\\2" CPACK_PACKAGE_VERSION_PATCH "${_curl_version}")
set(CPACK_GENERATOR "TGZ")
include(CPack)
endif()
# Save build info for test runner to pick up and log
if(CMAKE_OSX_SYSROOT)
set(_cmake_sysroot ${CMAKE_OSX_SYSROOT})
elseif(CMAKE_SYSROOT)
set(_cmake_sysroot ${CMAKE_SYSROOT})
endif()
set(_buildinfo "\
buildinfo.configure.tool: cmake
buildinfo.configure.command: ${CMAKE_COMMAND}
buildinfo.configure.version: ${CMAKE_VERSION}
buildinfo.configure.args:${_cmake_args}
buildinfo.configure.generator: ${CMAKE_GENERATOR}
buildinfo.configure.make: ${CMAKE_MAKE_PROGRAM}
buildinfo.host.cpu: ${CMAKE_HOST_SYSTEM_PROCESSOR}
buildinfo.host.os: ${CMAKE_HOST_SYSTEM_NAME}
buildinfo.target.cpu: ${CMAKE_SYSTEM_PROCESSOR}
buildinfo.target.os: ${CMAKE_SYSTEM_NAME}
buildinfo.target.flags:${_target_flags}
buildinfo.compiler: ${CMAKE_C_COMPILER_ID}
buildinfo.compiler.version: ${CMAKE_C_COMPILER_VERSION}
buildinfo.sysroot: ${_cmake_sysroot}
")
file(WRITE "${PROJECT_BINARY_DIR}/buildinfo.txt" "# This is a generated file. Do not edit.\n${_buildinfo}")
if(NOT "$ENV{CURL_BUILDINFO}$ENV{CURL_CI}$ENV{CI}" STREQUAL "")
message(STATUS "\n${_buildinfo}")
endif()
+25 -19
View File
@@ -30,14 +30,15 @@
*/
#ifdef CURL_NO_OLDIES
#define CURL_STRICTER
#define CURL_STRICTER /* not used since 8.11.0 */
#endif
/* 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)
#define CURL_DEPRECATED(version, message) \
__attribute__((deprecated("since " # version ". " message)))
@@ -113,13 +114,8 @@
extern "C" {
#endif
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
typedef struct Curl_easy CURL;
typedef struct Curl_share CURLSH;
#else
typedef void CURL;
typedef void CURLSH;
#endif
/*
* libcurl external API function linkage decorations.
@@ -253,12 +249,12 @@ typedef int (*curl_xferinfo_callback)(void *clientp,
#endif
#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
#endif
@@ -555,14 +551,14 @@ typedef enum {
CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */
CURLE_OBSOLETE32, /* 32 - NOT USED */
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_BAD_DOWNLOAD_RESUME, /* 36 - could not resume download */
CURLE_FILE_COULDNT_READ_FILE, /* 37 */
CURLE_LDAP_CANNOT_BIND, /* 38 */
CURLE_LDAP_SEARCH_FAILED, /* 39 */
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_BAD_FUNCTION_ARGUMENT, /* 43 */
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
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 */
#define CURLE_OBSOLETE16 CURLE_HTTP2
@@ -942,6 +944,9 @@ typedef enum {
a client certificate for authentication. (Schannel) */
#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.
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
this value, keep them in sync. */
@@ -2953,7 +2958,8 @@ typedef enum {
CURLINFO_QUEUE_TIME_T = CURLINFO_OFF_T + 65,
CURLINFO_USED_PROXY = CURLINFO_LONG + 66,
CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67,
CURLINFO_LASTONE = 67
CURLINFO_EARLYDATA_SENT_T = CURLINFO_OFF_T + 68,
CURLINFO_LASTONE = 68
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+3 -3
View File
@@ -32,12 +32,12 @@
/* This is the version number of the libcurl package from which this header
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
defines: */
#define LIBCURL_VERSION_MAJOR 8
#define LIBCURL_VERSION_MINOR 10
#define LIBCURL_VERSION_MINOR 11
#define LIBCURL_VERSION_PATCH 1
/* 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
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
+7 -11
View File
@@ -54,11 +54,7 @@
extern "C" {
#endif
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
typedef struct Curl_multi CURLM;
#else
typedef void CURLM;
#endif
typedef enum {
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
* 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
* of structs. It also writes the number of messages left in the
+25 -21
View File
@@ -21,8 +21,8 @@
# 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")
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
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)
include_directories(${CARES_INCLUDE_DIRS})
include_directories(SYSTEM ${CARES_INCLUDE_DIRS})
endif()
if(BUILD_TESTING)
if(CURL_BUILD_TESTING)
add_library(
curlu # special libcurlu library just for unittests
STATIC
@@ -112,7 +112,7 @@ if(SHARE_LIB_OBJECT)
target_include_directories(${LIB_OBJECT} INTERFACE
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
"$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>")
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
set(LIB_SOURCE $<TARGET_OBJECTS:${LIB_OBJECT}>)
else()
@@ -125,7 +125,7 @@ if(BUILD_STATIC_LIBS)
add_library(${LIB_STATIC} STATIC ${LIB_SOURCE})
add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
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()
target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
# 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
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
"$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>")
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
endif()
if(BUILD_SHARED_LIBS)
@@ -156,15 +156,14 @@ if(BUILD_SHARED_LIBS)
if(CYGWIN)
# For Cygwin always compile dllmain.c as a separate unit since it
# 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()
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "dllmain.c")
endif()
if(WIN32)
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libcurl.rc")
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()
target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS})
@@ -185,7 +184,7 @@ if(BUILD_SHARED_LIBS)
target_include_directories(${LIB_SHARED} INTERFACE
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
"$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>")
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
if(CMAKE_DLL_NAME_WITH_SOVERSION OR
CYGWIN OR
@@ -238,16 +237,21 @@ if(BUILD_SHARED_LIBS)
set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "WOLFSSL_")
elseif(CURL_USE_GNUTLS)
set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "GNUTLS_")
elseif(CURL_USE_RUSTLS)
set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "RUSTLS_")
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)
cmake_push_check_state()
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)
if(HAVE_VERSIONED_SYMBOLS)
@@ -256,7 +260,7 @@ if(BUILD_SHARED_LIBS)
else()
message(WARNING "Versioned symbols requested, but not supported by the toolchain.")
endif()
unset(CMAKE_REQUIRED_LINK_OPTIONS)
cmake_pop_check_state()
endif()
endif()
+3 -3
View File
@@ -97,9 +97,11 @@ LIB_VQUIC_HFILES = \
LIB_VSSH_CFILES = \
vssh/libssh.c \
vssh/libssh2.c \
vssh/curl_path.c \
vssh/wolfssh.c
LIB_VSSH_HFILES = \
LIB_VSSH_HFILES = \
vssh/curl_path.h \
vssh/ssh.h
LIB_CFILES = \
@@ -131,7 +133,6 @@ LIB_CFILES = \
curl_memrchr.c \
curl_multibyte.c \
curl_ntlm_core.c \
curl_path.c \
curl_range.c \
curl_rtmp.c \
curl_sasl.c \
@@ -273,7 +274,6 @@ LIB_HFILES = \
curl_memrchr.h \
curl_multibyte.h \
curl_ntlm_core.h \
curl_path.h \
curl_printf.h \
curl_range.h \
curl_rtmp.h \
+16 -18
View File
@@ -64,6 +64,8 @@ static enum alpnid alpn2alpnid(char *name)
return ALPN_h2;
if(strcasecompare(name, H3VERSION))
return ALPN_h3;
if(strcasecompare(name, "http/1.1"))
return ALPN_h1;
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,
const char *dsthost,
size_t dlen, /* dsthost length */
enum alpnid srcalpnid,
enum alpnid dstalpnid,
unsigned int srcport,
@@ -99,11 +102,9 @@ static struct altsvc *altsvc_createid(const char *srchost,
{
struct altsvc *as = calloc(1, sizeof(struct altsvc));
size_t hlen;
size_t dlen;
if(!as)
return NULL;
hlen = strlen(srchost);
dlen = strlen(dsthost);
DEBUGASSERT(hlen);
DEBUGASSERT(dlen);
if(!hlen || !dlen) {
@@ -155,7 +156,8 @@ static struct altsvc *altsvc_create(char *srchost,
enum alpnid srcalpnid = alpn2alpnid(srcalpn);
if(!srcalpnid || !dstalpnid)
return NULL;
return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
return altsvc_createid(srchost, dsthost, strlen(dsthost),
srcalpnid, dstalpnid,
srcport, dstport);
}
@@ -315,10 +317,8 @@ struct altsvcinfo *Curl_altsvc_init(void)
*/
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
{
CURLcode result;
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)
{
const char *p = value;
size_t len;
char namebuf[MAX_ALTSVC_HOSTLEN] = "";
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
struct altsvc *as;
unsigned short dstport = srcport; /* the same by default */
@@ -521,6 +519,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
p++;
if(*p == '\"') {
const char *dsthost = "";
size_t dstlen = 0; /* destination hostname length */
const char *value_ptr;
char option[32];
unsigned long num;
@@ -535,32 +534,31 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
const char *hostp = p;
if(*p == '[') {
/* 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 */
break;
/* we store the IPv6 numerical address *with* brackets */
len += 2;
p = &p[len-1];
dstlen += 2;
p = &p[dstlen-1];
}
else {
while(*p && (ISALNUM(*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.");
valid = FALSE;
}
else {
memcpy(namebuf, hostp, len);
namebuf[len] = 0;
dsthost = namebuf;
dsthost = hostp;
}
}
else {
/* no destination name, use source host */
dsthost = srchost;
dstlen = strlen(srchost);
}
if(*p == ':') {
unsigned long port = 0;
@@ -635,7 +633,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
this is the first entry of the line. */
altsvc_flush(asi, srcalpnid, srchost, srcport);
as = altsvc_createid(srchost, dsthost,
as = altsvc_createid(srchost, dsthost, dstlen,
srcalpnid, dstalpnid,
srcport, dstport);
if(as) {
+9 -18
View File
@@ -290,23 +290,14 @@ static void destroy_async_data(struct Curl_async *async)
int Curl_resolver_getsock(struct Curl_easy *data,
curl_socket_t *socks)
{
struct timeval maxtime;
struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 };
struct timeval timebuf;
struct timeval *timeout;
long milli;
int max = ares_getsock((ares_channel)data->state.async.resolver,
(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);
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 */
for(i = 0; i < num; i++)
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;
}
@@ -801,7 +792,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
}
#endif /* CURLRES_IPV6 */
hints.ai_family = pf;
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ?
SOCK_STREAM : SOCK_DGRAM;
/* Since the service is a numerical one, set the hint flags
* accordingly to save a call to getservbyname in inside C-Ares
+4 -4
View File
@@ -286,7 +286,7 @@ static CURLcode getaddrinfo_complete(struct Curl_easy *data)
* and wait on it.
*/
static
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
DWORD
#else
unsigned int
@@ -311,7 +311,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg)
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
if(rc) {
tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
tsd->sock_error = SOCKERRNO ? SOCKERRNO : rc;
if(tsd->sock_error == 0)
tsd->sock_error = RESOLVER_ENOMEM;
}
@@ -354,7 +354,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg)
* gethostbyname_thread() resolves a name and then exits.
*/
static
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
DWORD
#else
unsigned int
@@ -728,7 +728,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
memset(&hints, 0, sizeof(hints));
hints.ai_family = pf;
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)?
hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP) ?
SOCK_STREAM : SOCK_DGRAM;
reslv->start = Curl_now();
+4 -4
View File
@@ -484,17 +484,17 @@ CURLcode Curl_bufq_cwrite(struct bufq *q,
ssize_t n;
CURLcode 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;
}
CURLcode Curl_bufq_unwrite(struct bufq *q, size_t len)
{
while(len && q->tail) {
len -= chunk_unwrite(q->head, len);
len -= chunk_unwrite(q->tail, len);
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,
@@ -526,7 +526,7 @@ CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
ssize_t n;
CURLcode 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;
}
+4 -4
View File
@@ -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
a single place. */
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);
if(data->state.hconnect)
/* CONNECT */
@@ -481,8 +481,8 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
goto out;
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(http_status == 101) {
/* verify the response */
@@ -1035,7 +1035,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
}
p_accept = Curl_checkheaders(data,
STRCONST("Accept"))?NULL:"Accept: */*\r\n";
STRCONST("Accept")) ? NULL : "Accept: */*\r\n";
if(p_accept) {
result = Curl_hyper_header(data, headers, p_accept);
if(result)
+3 -3
View File
@@ -299,7 +299,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
(checkprefix("Proxy-authenticate:", header) &&
(407 == k->httpcode))) {
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
bool proxy = (k->httpcode == 407);
char *auth = Curl_copy_header_value(header);
if(!auth)
return CURLE_OUT_OF_MEMORY;
@@ -547,8 +547,8 @@ static CURLcode CONNECT_host(struct Curl_cfilter *cf,
if(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)
return CURLE_OUT_OF_MEMORY;
+19 -18
View File
@@ -98,7 +98,8 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
return result;
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)
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;
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);
if(rc)
@@ -288,7 +291,7 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf,
HTTP field value. */
nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
#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);
return rc;
}
@@ -429,7 +432,7 @@ static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
return result;
}
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,
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
}
case NGHTTP2_PUSH_PROMISE: {
case NGHTTP2_PUSH_PROMISE:
return msnprintf(buffer, blen,
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
(int)frame->hd.length,
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
}
case NGHTTP2_PING: {
case NGHTTP2_PING:
return msnprintf(buffer, blen,
"FRAME[PING, len=%d, ack=%d]",
(int)frame->hd.length,
frame->hd.flags&NGHTTP2_FLAG_ACK);
}
frame->hd.flags & NGHTTP2_FLAG_ACK);
case NGHTTP2_GOAWAY: {
char scratch[128];
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: {
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 &&
!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
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,
@@ -1586,7 +1587,7 @@ static CURLcode cf_h2_proxy_query(struct Curl_cfilter *cf,
default:
break;
}
return cf->next?
return cf->next ?
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
CURLE_UNKNOWN_OPTION;
}
+2 -2
View File
@@ -93,7 +93,7 @@ static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
client_ip = ipquad.local_ip;
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,
ipquad.local_port, ipquad.remote_port);
@@ -231,7 +231,7 @@ static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf,
out:
cf_haproxy_ctx_free(ctx);
*pcf = result? NULL : cf;
*pcf = result ? NULL : cf;
return result;
}
+17 -10
View File
@@ -174,6 +174,7 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
{
struct cf_hc_ctx *ctx = cf->ctx;
CURLcode result = CURLE_OK;
int reply_ms;
DEBUGASSERT(winner->cf);
if(winner != &ctx->h3_baller)
@@ -181,9 +182,15 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
if(winner != &ctx->h21_baller)
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;
winner->cf = NULL;
@@ -275,7 +282,7 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
}
else if(ctx->h21_baller.enabled)
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
cf->conn->transport);
cf->conn->transport);
ctx->state = CF_HC_CONNECT;
FALLTHROUGH();
@@ -306,8 +313,8 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
(!ctx->h21_baller.enabled || ctx->h21_baller.result)) {
/* both failed or disabled. we give up */
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;
goto out;
}
@@ -420,13 +427,13 @@ static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
memset(&tmax, 0, sizeof(tmax));
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((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
tmax = 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((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
tmax = t;
@@ -464,7 +471,7 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
break;
}
}
return cf->next?
return cf->next ?
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
CURLE_UNKNOWN_OPTION;
}
@@ -553,7 +560,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
cf_hc_reset(cf, data);
out:
*pcf = result? NULL : cf;
*pcf = result ? NULL : cf;
free(ctx);
return result;
}
+214 -116
View File
@@ -177,7 +177,7 @@ static void
tcpkeepalive(struct Curl_easy *data,
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 */
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))
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,
@@ -355,11 +355,11 @@ static CURLcode socket_open(struct Curl_easy *data,
* might have been changed and this 'new' address will actually be used
* here to connect.
*/
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
*sockfd = data->set.fopensocket(data->set.opensocket_client,
CURLSOCKTYPE_IPCXN,
(struct curl_sockaddr *)addr);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
}
else {
/* 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(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;
}
#endif
@@ -413,9 +413,9 @@ static int socket_close(struct Curl_easy *data, struct connectdata *conn,
if(use_callback && conn && conn->fclosesocket) {
int rc;
Curl_multi_closed(data, sock);
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
rc = conn->fclosesocket(conn->closesocket_client, sock);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
return rc;
}
@@ -600,36 +600,39 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
if(!iface && !host && !port)
/* no local kind of binding was requested */
return CURLE_OK;
else if(iface && (strlen(iface) >= 255) )
return CURLE_BAD_FUNCTION_ARGUMENT;
memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
if(iface && (strlen(iface)<255) ) {
if(iface || host) {
char myhost[256] = "";
int done = 0; /* -1 for error, 1 for address found */
if2ip_result_t if2ip_result = IF2IP_NOT_FOUND;
/* interface */
#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
@@ -1088,13 +1091,14 @@ static CURLcode set_remote_ip(struct Curl_cfilter *cf,
struct cf_socket_ctx *ctx = cf->ctx;
/* 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)) {
char buffer[STRERROR_LEN];
ctx->error = errno;
/* 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)));
return CURLE_FAILED_INIT;
}
@@ -1163,11 +1167,11 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
if(data->set.fsockopt) {
/* 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,
ctx->sock,
CURLSOCKTYPE_IPCXN);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
isconnected = TRUE;
@@ -1185,7 +1189,7 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
#endif
) {
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 == CURLE_UNSUPPORTED_PROTOCOL) {
/* 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_srcaddr = NULL;
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;
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);
}
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
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 */
#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
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,
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 */
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
rc = 0; /* Do nothing */
#endif
}
else {
rc = connect(ctx->sock, &ctx->addr.sa_addr,
rc = connect(ctx->sock, &ctx->addr.curl_sa_addr,
(curl_socklen_t)ctx->addr.addrlen);
}
return rc;
@@ -1309,7 +1313,7 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
if(blocking)
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) {
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(cf->conn->bits.tcp_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->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->remote_addr = &ctx->addr;
#ifdef USE_IPV6
cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6)? TRUE : FALSE;
cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6);
#endif
}
else {
@@ -1725,7 +1729,7 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
case CF_QUERY_CONNECT_REPLY_MS:
if(ctx->got_first_byte) {
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
*pres1 = -1;
@@ -1750,7 +1754,7 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
}
case CF_QUERY_IP_INFO:
#ifdef USE_IPV6
*pres1 = (ctx->addr.family == AF_INET6)? TRUE : FALSE;
*pres1 = (ctx->addr.family == AF_INET6);
#else
*pres1 = FALSE;
#endif
@@ -1759,7 +1763,7 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
default:
break;
}
return cf->next?
return cf->next ?
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
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);
out:
*pcf = (!result)? cf : NULL;
*pcf = (!result) ? cf : NULL;
if(result) {
Curl_safefree(cf);
Curl_safefree(ctx);
@@ -1827,7 +1831,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
/* QUIC needs a connected socket, nonblocking */
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);
if(-1 == rc) {
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);
CURL_TRC_CF(data, cf, "%s socket %" FMT_SOCKET_T
" 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->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);
out:
*pcf = (!result)? cf : NULL;
*pcf = (!result) ? cf : NULL;
if(result) {
Curl_safefree(cf);
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);
out:
*pcf = (!result)? cf : NULL;
*pcf = (!result) ? cf : NULL;
if(result) {
Curl_safefree(cf);
Curl_safefree(ctx);
@@ -2016,10 +2020,84 @@ out:
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,
struct Curl_easy *data,
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 */
(void)data;
(void)blocking;
@@ -2027,7 +2105,79 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
*done = TRUE;
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 = {
@@ -2075,13 +2225,12 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
goto out;
Curl_conn_cf_add(data, conn, sockindex, cf);
ctx->started_at = Curl_now();
conn->sock[sockindex] = ctx->sock;
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:
if(result) {
@@ -2091,67 +2240,16 @@ out:
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;
struct Curl_cfilter *cf = data->conn->cfilter[sockindex];
while(cf) {
if(cf->cft == &Curl_cft_tcp_accept)
return TRUE;
cf = cf->next;
}
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
}
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
View File
@@ -52,7 +52,7 @@ struct Curl_sockaddr_ex {
struct Curl_sockaddr_storage buff;
} _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.
@@ -147,12 +147,11 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
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.
+31 -28
View File
@@ -96,7 +96,7 @@ void Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
return cf->next?
return cf->next ?
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,
CURLcode *err)
{
return cf->next?
return cf->next ?
cf->next->cft->do_send(cf->next, data, buf, len, eos, err) :
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,
char *buf, size_t len, CURLcode *err)
{
return cf->next?
return cf->next ?
cf->next->cft->do_recv(cf->next, data, buf, len, err) :
CURLE_SEND_ERROR;
}
@@ -121,7 +121,7 @@ bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *input_pending)
{
return cf->next?
return cf->next ?
cf->next->cft->is_alive(cf->next, data, input_pending) :
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,
struct Curl_easy *data)
{
return cf->next?
return cf->next ?
cf->next->cft->keep_alive(cf->next, data) :
CURLE_OK;
}
@@ -138,7 +138,7 @@ CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
struct Curl_easy *data,
int query, int *pres1, void *pres2)
{
return cf->next?
return cf->next ?
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
CURLE_UNKNOWN_OPTION;
}
@@ -204,13 +204,14 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
now = Curl_now();
if(!Curl_shutdown_started(data, sockindex)) {
DEBUGF(infof(data, "shutdown start on%s connection",
sockindex? " secondary" : ""));
sockindex ? " secondary" : ""));
Curl_shutdown_start(data, sockindex, &now);
}
else {
timeout_ms = Curl_shutdown_timeleft(data->conn, sockindex, &now);
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;
}
}
@@ -483,12 +484,12 @@ bool Curl_conn_cf_is_ssl(struct Curl_cfilter *cf)
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)
{
struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
struct Curl_cfilter *cf = conn ? conn->cfilter[sockindex] : NULL;
for(; cf; cf = cf->next) {
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)
{
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)
@@ -672,13 +673,13 @@ curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
{
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)
* for the socket. Otherwise conn->sock[sockindex] should have it.
*/
if(cf && !cf->connected)
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)
@@ -807,7 +808,7 @@ CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
int 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,
@@ -818,9 +819,9 @@ size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
int n = 0;
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,
@@ -831,9 +832,9 @@ int Curl_conn_get_stream_error(struct Curl_easy *data,
int n = 0;
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)
@@ -854,7 +855,7 @@ CURLcode Curl_conn_recv(struct Curl_easy *data, int sockindex,
nread = data->conn->recv[sockindex](data, sockindex, buf, blen, &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;
}
@@ -889,7 +890,7 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
nwritten = conn->send[sockindex](data, sockindex, buf, write_len, eos,
&result);
DEBUGASSERT((nwritten >= 0) || result);
*pnwritten = (nwritten < 0)? 0 : (size_t)nwritten;
*pnwritten = (nwritten < 0) ? 0 : (size_t)nwritten;
return result;
}
@@ -899,7 +900,7 @@ void Curl_pollset_reset(struct Curl_easy *data,
size_t i;
(void)data;
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;
}
@@ -961,8 +962,10 @@ void Curl_pollset_set(struct Curl_easy *data,
bool do_in, bool do_out)
{
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,
+12 -24
View File
@@ -72,7 +72,7 @@
} while(0)
/* A list of connections to the same destinationn. */
/* A list of connections to the same destination. */
struct cpool_bundle {
struct Curl_llist conns; /* connections in the bundle */
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();
if(!cpool->idata)
return 1; /* bad */
cpool->idata->state.internal = true;
cpool->idata->state.internal = TRUE;
/* 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).
* 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
* can be used for cpool operations. */
cpool->idata->multi = multi;
#ifdef DEBUGBUILD
#ifdef DEBUGBUILD
if(getenv("CURL_DEBUG"))
cpool->idata->set.verbose = true;
cpool->idata->set.verbose = TRUE;
#endif
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,
struct cpool_bundle *bundle)
{
struct Curl_hash_iterator iter;
struct Curl_hash_element *he;
if(!cpool)
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 *
@@ -329,6 +314,9 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
"limit of %zu", oldest_idle->connection_id,
Curl_llist_count(&bundle->conns), dest_limit));
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)) {
result = CPOOL_LIMIT_DEST;
@@ -409,7 +397,7 @@ static void cpool_remove_conn(struct cpool *cpool,
cpool->num_conn--;
}
else {
/* Not in a bundle, already in the shutdown list? */
/* Not in a bundle, already in the shutdown list? */
DEBUGASSERT(list == &cpool->shutdowns);
}
}
@@ -491,7 +479,7 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
struct connectdata *conn)
{
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 cpool *cpool = cpool_get_instance(data);
bool kept = TRUE;
@@ -820,7 +808,7 @@ void Curl_cpool_disconnect(struct Curl_easy *data,
if(data->multi) {
/* Add it to the multi's cpool for shutdown handling */
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);
}
else {
@@ -1180,7 +1168,7 @@ static void cpool_shutdown_all(struct cpool *cpool,
timespent = Curl_timediff(Curl_now(), started);
if(timespent >= (timediff_t)timeout_ms) {
DEBUGF(infof(data, "cpool shutdown %s",
(timeout_ms > 0)? "timeout" : "best effort done"));
(timeout_ms > 0) ? "timeout" : "best effort done"));
break;
}
+8 -8
View File
@@ -139,7 +139,7 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
return ctimeleft_ms; /* no general timeout, this is it */
}
/* 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,
@@ -172,7 +172,7 @@ timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
}
left_ms = conn->shutdown.timeout_ms -
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,
@@ -414,9 +414,9 @@ static CURLcode eyeballer_new(struct eyeballer **pballer,
if(!baller)
return CURLE_OUT_OF_MEMORY;
baller->name = ((ai_family == AF_INET)? "ipv4" : (
baller->name = ((ai_family == AF_INET) ? "ipv4" : (
#ifdef USE_IPV6
(ai_family == AF_INET6)? "ipv6" :
(ai_family == AF_INET6) ? "ipv6" :
#endif
"ip"));
baller->cf_create = cf_create;
@@ -424,7 +424,7 @@ static CURLcode eyeballer_new(struct eyeballer **pballer,
baller->ai_family = ai_family;
baller->primary = primary;
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;
baller->timeout_id = timeout_id;
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'
* cot ballers in a QUIC appropriate way. */
evaluate:
*connected = FALSE; /* a very negative world view is best */
*connected = FALSE; /* a negative world view is best */
now = Curl_now();
ongoing = not_started = 0;
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) :
CURLE_UNKNOWN_OPTION;
}
@@ -1417,7 +1417,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
ctx = NULL;
out:
*pcf = result? NULL : cf;
*pcf = result ? NULL : cf;
free(ctx);
return result;
}
+8 -8
View File
@@ -33,13 +33,13 @@
#endif
#ifdef HAVE_BROTLI
#if defined(__GNUC__)
#if defined(__GNUC__) || defined(__clang__)
/* Ignore -Wvla warnings in brotli headers */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvla"
#endif
#include <brotli/decode.h>
#if defined(__GNUC__)
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
#endif
@@ -154,7 +154,7 @@ static CURLcode process_trailer(struct Curl_easy *data,
{
z_stream *z = &zp->z;
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.
Issue an error if unexpected bytes follow. */
@@ -654,7 +654,7 @@ static CURLcode brotli_do_init(struct Curl_easy *data,
(void) data;
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,
@@ -971,8 +971,8 @@ static const struct Curl_cwtype *find_unencode_writer(const char *name,
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
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;
do {
@@ -995,7 +995,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
struct Curl_cwriter *writer;
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) &&
strncasecompare(name, "chunked", 7));
/* 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);
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)
return result;
+699 -758
View File
@@ -28,33 +28,20 @@
RECEIVING COOKIE INFORMATION
============================
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
const char *file, struct CookieInfo *inc, bool newsession);
Curl_cookie_init()
Inits a cookie struct to store data in a local file. This is always
called before any cookies are set.
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
struct CookieInfo *c, bool httpheader, bool noexpire,
char *lineptr, const char *domain, const char *path,
bool secure);
Curl_cookie_add()
The 'lineptr' parameter is a full "Set-cookie:" line as
received from a server.
The function need to replace previously stored lines that this new
line supersedes.
It may remove lines that are expired.
It should return an indication of success/error.
Adds a cookie to the in-memory cookie jar.
SENDING COOKIE INFORMATION
==========================
struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
char *host, char *path, bool secure);
Curl_cookie_getlist()
For a given host and path, return a linked list of cookies that
the client should send to the server if used now. The secure
@@ -63,7 +50,6 @@ struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
It shall only return cookies that have not expired.
Example set of cookies:
Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
@@ -102,6 +88,7 @@ Example set of cookies:
#include "rename.h"
#include "fopen.h"
#include "strdup.h"
#include "llist.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -245,7 +232,7 @@ static const char *get_top_domain(const char * const domain, size_t *outlen)
if(outlen)
*outlen = len;
return first? first: domain;
return first ? first : domain;
}
/* Avoid C1001, an "internal error" with MSVC14 */
@@ -335,17 +322,17 @@ void Curl_cookie_loadfiles(struct Curl_easy *data)
if(list) {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
while(list) {
struct CookieInfo *newcookies =
struct CookieInfo *ci =
Curl_cookie_init(data, list->data, data->cookies,
data->set.cookiesession);
if(!newcookies)
if(!ci)
/*
* Failure may be due to OOM or a bad cookie; both are ignored
* but only the first should be
*/
infof(data, "ignoring failed cookie_init for %s", list->data);
else
data->cookies = newcookies;
data->cookies = ci;
list = list->next;
}
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
@@ -378,9 +365,9 @@ static void strstore(char **str, const char *newstr, size_t len)
* more cookies expire, then processing will exit early in case this timestamp
* is in the future.
*/
static void remove_expired(struct CookieInfo *cookies)
static void remove_expired(struct CookieInfo *ci)
{
struct Cookie *co, *nx;
struct Cookie *co;
curl_off_t now = (curl_off_t)time(NULL);
unsigned int i;
@@ -392,37 +379,32 @@ static void remove_expired(struct CookieInfo *cookies)
* recorded first expiration is the max offset, then perform the safe
* fallback of checking all cookies.
*/
if(now < cookies->next_expiration &&
cookies->next_expiration != CURL_OFF_T_MAX)
if(now < ci->next_expiration &&
ci->next_expiration != CURL_OFF_T_MAX)
return;
else
cookies->next_expiration = CURL_OFF_T_MAX;
ci->next_expiration = CURL_OFF_T_MAX;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
struct Cookie *pv = NULL;
co = cookies->cookies[i];
while(co) {
nx = co->next;
struct Curl_llist_node *n;
struct Curl_llist_node *e = NULL;
for(n = Curl_llist_head(&ci->cookielist[i]); n; n = e) {
co = Curl_node_elem(n);
e = Curl_node_next(n);
if(co->expires && co->expires < now) {
if(!pv) {
cookies->cookies[i] = co->next;
}
else {
pv->next = co->next;
}
cookies->numcookies--;
Curl_node_remove(n);
freecookie(co);
ci->numcookies--;
}
else {
/*
* If this cookie has an expiration timestamp earlier than what we have
* seen so far then record it for the next round of expirations.
* If this cookie has an expiration timestamp earlier than what we
* have seen so far then record it for the next round of expirations.
*/
if(co->expires && co->expires < cookies->next_expiration)
cookies->next_expiration = co->expires;
pv = co;
if(co->expires && co->expires < ci->next_expiration)
ci->next_expiration = co->expires;
}
co = nx;
}
}
}
@@ -470,558 +452,489 @@ static int invalid_octets(const char *p)
return (p[len] != '\0');
}
/*
* Curl_cookie_add
*
* Add a single cookie line to the cookie keeping object. Be aware that
* sometimes we get an IP-only hostname, and that might also be a numerical
* IPv6 address.
*
* Returns NULL on out of memory or invalid cookie. This is suboptimal,
* as they should be treated separately.
*/
struct Cookie *
Curl_cookie_add(struct Curl_easy *data,
struct CookieInfo *c,
bool httpheader, /* TRUE if HTTP header-style line */
bool noexpire, /* if TRUE, skip remove_expired() */
const char *lineptr, /* first character of the line */
const char *domain, /* default domain */
const char *path, /* full path used when this cookie is set,
used to get default path for the cookie
unless set */
bool secure) /* TRUE if connection is over secure origin */
#define CERR_OK 0
#define CERR_TOO_LONG 1 /* input line too long */
#define CERR_TAB 2 /* in a wrong place */
#define CERR_TOO_BIG 3 /* name/value too large */
#define CERR_BAD 4 /* deemed incorrect */
#define CERR_NO_SEP 5 /* semicolon problem */
#define CERR_NO_NAME_VALUE 6 /* name or value problem */
#define CERR_INVALID_OCTET 7 /* bad content */
#define CERR_BAD_SECURE 8 /* secure in a bad place */
#define CERR_OUT_OF_MEMORY 9
#define CERR_NO_TAILMATCH 10
#define CERR_COMMENT 11 /* a commented line */
#define CERR_RANGE 12 /* expire range problem */
#define CERR_FIELDS 13 /* incomplete netscape line */
#define CERR_PSL 14 /* a public suffix */
#define CERR_LIVE_WINS 15
static int
parse_cookie_header(struct Curl_easy *data,
struct Cookie *co,
struct CookieInfo *ci,
const char *ptr,
const char *domain, /* default domain */
const char *path, /* full path used when this cookie is
set, used to get default path for
the cookie unless set */
bool secure) /* TRUE if connection is over secure
origin */
{
struct Cookie *clist;
struct Cookie *co;
struct Cookie *lastc = NULL;
struct Cookie *replace_co = NULL;
struct Cookie *replace_clist = NULL;
time_t now = time(NULL);
bool replace_old = FALSE;
bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
size_t myhash;
/* This line was read off an HTTP-header */
time_t now;
size_t linelength = strlen(ptr);
if(linelength > MAX_COOKIE_LINE)
/* discard overly long lines at once */
return CERR_TOO_LONG;
DEBUGASSERT(data);
DEBUGASSERT(MAX_SET_COOKIE_AMOUNT <= 255); /* counter is an unsigned char */
if(data->req.setcookies >= MAX_SET_COOKIE_AMOUNT)
return NULL;
now = time(NULL);
do {
size_t vlen;
size_t nlen;
/* First, alloc and init a new struct for it */
co = calloc(1, sizeof(struct Cookie));
if(!co)
return NULL; /* bail out if we are this low on memory */
while(*ptr && ISBLANK(*ptr))
ptr++;
if(httpheader) {
/* This line was read off an HTTP-header */
const char *ptr;
/* we have a <name>=<value> pair or a stand-alone word here */
nlen = strcspn(ptr, ";\t\r\n=");
if(nlen) {
bool done = FALSE;
bool sep = FALSE;
const char *namep = ptr;
const char *valuep;
size_t linelength = strlen(lineptr);
if(linelength > MAX_COOKIE_LINE) {
/* discard overly long lines at once */
free(co);
return NULL;
}
ptr += nlen;
ptr = lineptr;
do {
size_t vlen;
size_t nlen;
/* trim trailing spaces and tabs after name */
while(nlen && ISBLANK(namep[nlen - 1]))
nlen--;
while(*ptr && ISBLANK(*ptr))
ptr++;
if(*ptr == '=') {
vlen = strcspn(++ptr, ";\r\n");
valuep = ptr;
sep = TRUE;
ptr = &valuep[vlen];
/* we have a <name>=<value> pair or a stand-alone word here */
nlen = strcspn(ptr, ";\t\r\n=");
if(nlen) {
bool done = FALSE;
bool sep = FALSE;
const char *namep = ptr;
const char *valuep;
/* Strip off trailing whitespace from the value */
while(vlen && ISBLANK(valuep[vlen-1]))
vlen--;
ptr += nlen;
/* trim trailing spaces and tabs after name */
while(nlen && ISBLANK(namep[nlen - 1]))
nlen--;
if(*ptr == '=') {
vlen = strcspn(++ptr, ";\r\n");
valuep = ptr;
sep = TRUE;
ptr = &valuep[vlen];
/* Strip off trailing whitespace from the value */
while(vlen && ISBLANK(valuep[vlen-1]))
vlen--;
/* Skip leading whitespace from the value */
while(vlen && ISBLANK(*valuep)) {
valuep++;
vlen--;
}
/* Reject cookies with a TAB inside the value */
if(memchr(valuep, '\t', vlen)) {
freecookie(co);
infof(data, "cookie contains TAB, dropping");
return NULL;
}
}
else {
valuep = NULL;
vlen = 0;
/* Skip leading whitespace from the value */
while(vlen && ISBLANK(*valuep)) {
valuep++;
vlen--;
}
/*
* Check for too long individual name or contents, or too long
* combination of name + contents. Chrome and Firefox support 4095 or
* 4096 bytes combo
*/
if(nlen >= (MAX_NAME-1) || vlen >= (MAX_NAME-1) ||
((nlen + vlen) > MAX_NAME)) {
freecookie(co);
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes",
nlen, vlen);
return NULL;
/* Reject cookies with a TAB inside the value */
if(memchr(valuep, '\t', vlen)) {
infof(data, "cookie contains TAB, dropping");
return CERR_TAB;
}
/*
* Check if we have a reserved prefix set before anything else, as we
* otherwise have to test for the prefix in both the cookie name and
* "the rest". Prefixes must start with '__' and end with a '-', so
* only test for names where that can possibly be true.
*/
if(nlen >= 7 && namep[0] == '_' && namep[1] == '_') {
if(strncasecompare("__Secure-", namep, 9))
co->prefix |= COOKIE_PREFIX__SECURE;
else if(strncasecompare("__Host-", namep, 7))
co->prefix |= COOKIE_PREFIX__HOST;
}
/*
* Use strstore() below to properly deal with received cookie
* headers that have the same string property set more than once,
* and then we use the last one.
*/
if(!co->name) {
/* The very first name/value pair is the actual cookie name */
if(!sep) {
/* Bad name/value pair. */
badcookie = TRUE;
break;
}
strstore(&co->name, namep, nlen);
strstore(&co->value, valuep, vlen);
done = TRUE;
if(!co->name || !co->value) {
badcookie = TRUE;
break;
}
if(invalid_octets(co->value) || invalid_octets(co->name)) {
infof(data, "invalid octets in name/value, cookie dropped");
badcookie = TRUE;
break;
}
}
else if(!vlen) {
/*
* this was a "<name>=" with no content, and we must allow
* 'secure' and 'httponly' specified this weirdly
*/
done = TRUE;
/*
* secure cookies are only allowed to be set when the connection is
* using a secure protocol, or when the cookie is being set by
* reading from file
*/
if((nlen == 6) && strncasecompare("secure", namep, 6)) {
if(secure || !c->running) {
co->secure = TRUE;
}
else {
badcookie = TRUE;
break;
}
}
else if((nlen == 8) && strncasecompare("httponly", namep, 8))
co->httponly = TRUE;
else if(sep)
/* there was a '=' so we are not done parsing this field */
done = FALSE;
}
if(done)
;
else if((nlen == 4) && strncasecompare("path", namep, 4)) {
strstore(&co->path, valuep, vlen);
if(!co->path) {
badcookie = TRUE; /* out of memory bad */
break;
}
free(co->spath); /* if this is set again */
co->spath = sanitize_cookie_path(co->path);
if(!co->spath) {
badcookie = TRUE; /* out of memory bad */
break;
}
}
else if((nlen == 6) &&
strncasecompare("domain", namep, 6) && vlen) {
bool is_ip;
/*
* Now, we make sure that our host is within the given domain, or
* the given domain is not valid and thus cannot be set.
*/
if('.' == valuep[0]) {
valuep++; /* ignore preceding dot */
vlen--;
}
#ifndef USE_LIBPSL
/*
* Without PSL we do not know when the incoming cookie is set on a
* TLD or otherwise "protected" suffix. To reduce risk, we require a
* dot OR the exact hostname being "localhost".
*/
if(bad_domain(valuep, vlen))
domain = ":";
#endif
is_ip = Curl_host_is_ipnum(domain ? domain : valuep);
if(!domain
|| (is_ip && !strncmp(valuep, domain, vlen) &&
(vlen == strlen(domain)))
|| (!is_ip && cookie_tailmatch(valuep, vlen, domain))) {
strstore(&co->domain, valuep, vlen);
if(!co->domain) {
badcookie = TRUE;
break;
}
if(!is_ip)
co->tailmatch = TRUE; /* we always do that if the domain name was
given */
}
else {
/*
* We did not get a tailmatch and then the attempted set domain is
* not a domain to which the current host belongs. Mark as bad.
*/
badcookie = TRUE;
infof(data, "skipped cookie with bad tailmatch domain: %s",
valuep);
}
}
else if((nlen == 7) && strncasecompare("version", namep, 7)) {
/* just ignore */
}
else if((nlen == 7) && strncasecompare("max-age", namep, 7)) {
/*
* Defined in RFC2109:
*
* Optional. The Max-Age attribute defines the lifetime of the
* cookie, in seconds. The delta-seconds value is a decimal non-
* negative integer. After delta-seconds seconds elapse, the
* client should discard the cookie. A value of zero means the
* cookie should be discarded immediately.
*/
CURLofft offt;
const char *maxage = valuep;
offt = curlx_strtoofft((*maxage == '\"')?
&maxage[1]:&maxage[0], NULL, 10,
&co->expires);
switch(offt) {
case CURL_OFFT_FLOW:
/* overflow, used max value */
co->expires = CURL_OFF_T_MAX;
break;
case CURL_OFFT_INVAL:
/* negative or otherwise bad, expire */
co->expires = 1;
break;
case CURL_OFFT_OK:
if(!co->expires)
/* already expired */
co->expires = 1;
else if(CURL_OFF_T_MAX - now < co->expires)
/* would overflow */
co->expires = CURL_OFF_T_MAX;
else
co->expires += now;
break;
}
}
else if((nlen == 7) && strncasecompare("expires", namep, 7)) {
char date[128];
if(!co->expires && (vlen < sizeof(date))) {
/* copy the date so that it can be null terminated */
memcpy(date, valuep, vlen);
date[vlen] = 0;
/*
* Let max-age have priority.
*
* If the date cannot get parsed for whatever reason, the cookie
* will be treated as a session cookie
*/
co->expires = Curl_getdate_capped(date);
/*
* Session cookies have expires set to 0 so if we get that back
* from the date parser let's add a second to make it a
* non-session cookie
*/
if(co->expires == 0)
co->expires = 1;
else if(co->expires < 0)
co->expires = 0;
}
}
/*
* Else, this is the second (or more) name we do not know about!
*/
}
else {
/* this is an "illegal" <what>=<this> pair */
valuep = NULL;
vlen = 0;
}
while(*ptr && ISBLANK(*ptr))
ptr++;
if(*ptr == ';')
ptr++;
else
break;
} while(1);
if(!badcookie && !co->domain) {
if(domain) {
/* no domain was given in the header line, set the default */
co->domain = strdup(domain);
if(!co->domain)
badcookie = TRUE;
/*
* Check for too long individual name or contents, or too long
* combination of name + contents. Chrome and Firefox support 4095 or
* 4096 bytes combo
*/
if(nlen >= (MAX_NAME-1) || vlen >= (MAX_NAME-1) ||
((nlen + vlen) > MAX_NAME)) {
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes",
nlen, vlen);
return CERR_TOO_BIG;
}
}
if(!badcookie && !co->path && path) {
/*
* No path was given in the header line, set the default. Note that the
* passed-in path to this function MAY have a '?' and following part that
* MUST NOT be stored as part of the path.
*/
char *queryp = strchr(path, '?');
/*
* queryp is where the interesting part of the path ends, so now we
* want to the find the last
* Check if we have a reserved prefix set before anything else, as we
* otherwise have to test for the prefix in both the cookie name and
* "the rest". Prefixes must start with '__' and end with a '-', so
* only test for names where that can possibly be true.
*/
char *endslash;
if(!queryp)
endslash = strrchr(path, '/');
else
endslash = memrchr(path, '/', (queryp - path));
if(endslash) {
size_t pathlen = (endslash-path + 1); /* include end slash */
co->path = Curl_memdup0(path, pathlen);
if(co->path) {
co->spath = sanitize_cookie_path(co->path);
if(!co->spath)
badcookie = TRUE; /* out of memory bad */
if(nlen >= 7 && namep[0] == '_' && namep[1] == '_') {
if(strncasecompare("__Secure-", namep, 9))
co->prefix_secure = TRUE;
else if(strncasecompare("__Host-", namep, 7))
co->prefix_host = TRUE;
}
/*
* Use strstore() below to properly deal with received cookie
* headers that have the same string property set more than once,
* and then we use the last one.
*/
if(!co->name) {
/* The very first name/value pair is the actual cookie name */
if(!sep)
/* Bad name/value pair. */
return CERR_NO_SEP;
strstore(&co->name, namep, nlen);
strstore(&co->value, valuep, vlen);
done = TRUE;
if(!co->name || !co->value)
return CERR_NO_NAME_VALUE;
if(invalid_octets(co->value) || invalid_octets(co->name)) {
infof(data, "invalid octets in name/value, cookie dropped");
return CERR_INVALID_OCTET;
}
else
badcookie = TRUE;
}
}
/*
* If we did not get a cookie name, or a bad one, the this is an illegal
* line so bail out.
*/
if(badcookie || !co->name) {
freecookie(co);
return NULL;
}
data->req.setcookies++;
}
else {
/*
* This line is NOT an HTTP header style line, we do offer support for
* reading the odd netscape cookies-file format here
*/
char *ptr;
char *firstptr;
char *tok_buf = NULL;
int fields;
/*
* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies marked
* with httpOnly after the domain name are not accessible from javascripts,
* but since curl does not operate at javascript level, we include them
* anyway. In Firefox's cookie files, these lines are preceded with
* #HttpOnly_ and then everything is as usual, so we skip 10 characters of
* the line..
*/
if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
lineptr += 10;
co->httponly = TRUE;
}
if(lineptr[0]=='#') {
/* do not even try the comments */
free(co);
return NULL;
}
/* strip off the possible end-of-line characters */
ptr = strchr(lineptr, '\r');
if(ptr)
*ptr = 0; /* clear it */
ptr = strchr(lineptr, '\n');
if(ptr)
*ptr = 0; /* clear it */
firstptr = strtok_r((char *)lineptr, "\t", &tok_buf); /* tokenize on TAB */
/*
* Now loop through the fields and init the struct we already have
* allocated
*/
fields = 0;
for(ptr = firstptr; ptr && !badcookie;
ptr = strtok_r(NULL, "\t", &tok_buf), fields++) {
switch(fields) {
case 0:
if(ptr[0]=='.') /* skip preceding dots */
ptr++;
co->domain = strdup(ptr);
if(!co->domain)
badcookie = TRUE;
break;
case 1:
else if(!vlen) {
/*
* flag: A TRUE/FALSE value indicating if all machines within a given
* domain can access the variable. Set TRUE when the cookie says
* .domain.com and to false when the domain is complete www.domain.com
* this was a "<name>=" with no content, and we must allow
* 'secure' and 'httponly' specified this weirdly
*/
co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
break;
case 2:
/* The file format allows the path field to remain not filled in */
if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
/* only if the path does not look like a boolean option! */
co->path = strdup(ptr);
if(!co->path)
badcookie = TRUE;
else {
co->spath = sanitize_cookie_path(co->path);
if(!co->spath) {
badcookie = TRUE; /* out of memory bad */
}
done = TRUE;
/*
* secure cookies are only allowed to be set when the connection is
* using a secure protocol, or when the cookie is being set by
* reading from file
*/
if((nlen == 6) && strncasecompare("secure", namep, 6)) {
if(secure || !ci->running) {
co->secure = TRUE;
}
else {
return CERR_BAD_SECURE;
}
}
else if((nlen == 8) && strncasecompare("httponly", namep, 8))
co->httponly = TRUE;
else if(sep)
/* there was a '=' so we are not done parsing this field */
done = FALSE;
}
if(done)
;
else if((nlen == 4) && strncasecompare("path", namep, 4)) {
strstore(&co->path, valuep, vlen);
if(!co->path)
return CERR_OUT_OF_MEMORY;
free(co->spath); /* if this is set again */
co->spath = sanitize_cookie_path(co->path);
if(!co->spath)
return CERR_OUT_OF_MEMORY;
}
else if((nlen == 6) &&
strncasecompare("domain", namep, 6) && vlen) {
bool is_ip;
/*
* Now, we make sure that our host is within the given domain, or
* the given domain is not valid and thus cannot be set.
*/
if('.' == valuep[0]) {
valuep++; /* ignore preceding dot */
vlen--;
}
#ifndef USE_LIBPSL
/*
* Without PSL we do not know when the incoming cookie is set on a
* TLD or otherwise "protected" suffix. To reduce risk, we require a
* dot OR the exact hostname being "localhost".
*/
if(bad_domain(valuep, vlen))
domain = ":";
#endif
is_ip = Curl_host_is_ipnum(domain ? domain : valuep);
if(!domain
|| (is_ip && !strncmp(valuep, domain, vlen) &&
(vlen == strlen(domain)))
|| (!is_ip && cookie_tailmatch(valuep, vlen, domain))) {
strstore(&co->domain, valuep, vlen);
if(!co->domain)
return CERR_OUT_OF_MEMORY;
if(!is_ip)
co->tailmatch = TRUE; /* we always do that if the domain name was
given */
}
else {
/*
* We did not get a tailmatch and then the attempted set domain is
* not a domain to which the current host belongs. Mark as bad.
*/
infof(data, "skipped cookie with bad tailmatch domain: %s",
valuep);
return CERR_NO_TAILMATCH;
}
}
else if((nlen == 7) && strncasecompare("version", namep, 7)) {
/* just ignore */
}
else if((nlen == 7) && strncasecompare("max-age", namep, 7)) {
/*
* Defined in RFC2109:
*
* Optional. The Max-Age attribute defines the lifetime of the
* cookie, in seconds. The delta-seconds value is a decimal non-
* negative integer. After delta-seconds seconds elapse, the
* client should discard the cookie. A value of zero means the
* cookie should be discarded immediately.
*/
CURLofft offt;
const char *maxage = valuep;
offt = curlx_strtoofft((*maxage == '\"') ?
&maxage[1] : &maxage[0], NULL, 10,
&co->expires);
switch(offt) {
case CURL_OFFT_FLOW:
/* overflow, used max value */
co->expires = CURL_OFF_T_MAX;
break;
case CURL_OFFT_INVAL:
/* negative or otherwise bad, expire */
co->expires = 1;
break;
case CURL_OFFT_OK:
if(!co->expires)
/* already expired */
co->expires = 1;
else if(CURL_OFF_T_MAX - now < co->expires)
/* would overflow */
co->expires = CURL_OFF_T_MAX;
else
co->expires += now;
break;
}
/* this does not look like a path, make one up! */
co->path = strdup("/");
if(!co->path)
badcookie = TRUE;
co->spath = strdup("/");
if(!co->spath)
badcookie = TRUE;
fields++; /* add a field and fall down to secure */
FALLTHROUGH();
case 3:
co->secure = FALSE;
if(strcasecompare(ptr, "TRUE")) {
if(secure || c->running)
co->secure = TRUE;
else
badcookie = TRUE;
}
break;
case 4:
if(curlx_strtoofft(ptr, NULL, 10, &co->expires))
badcookie = TRUE;
break;
case 5:
co->name = strdup(ptr);
if(!co->name)
badcookie = TRUE;
else {
/* For Netscape file format cookies we check prefix on the name */
if(strncasecompare("__Secure-", co->name, 9))
co->prefix |= COOKIE_PREFIX__SECURE;
else if(strncasecompare("__Host-", co->name, 7))
co->prefix |= COOKIE_PREFIX__HOST;
}
break;
case 6:
co->value = strdup(ptr);
if(!co->value)
badcookie = TRUE;
break;
}
}
if(6 == fields) {
/* we got a cookie with blank contents, fix it */
co->value = strdup("");
if(!co->value)
badcookie = TRUE;
else
fields++;
}
else if((nlen == 7) && strncasecompare("expires", namep, 7)) {
if(!co->expires) {
/*
* Let max-age have priority.
*
* If the date cannot get parsed for whatever reason, the cookie
* will be treated as a session cookie
*/
co->expires = Curl_getdate_capped(valuep);
if(!badcookie && (7 != fields))
/* we did not find the sufficient number of fields */
badcookie = TRUE;
/*
* Session cookies have expires set to 0 so if we get that back
* from the date parser let's add a second to make it a
* non-session cookie
*/
if(co->expires == 0)
co->expires = 1;
else if(co->expires < 0)
co->expires = 0;
}
}
if(badcookie) {
freecookie(co);
return NULL;
/*
* Else, this is the second (or more) name we do not know about!
*/
}
}
if(co->prefix & COOKIE_PREFIX__SECURE) {
/* The __Secure- prefix only requires that the cookie be set secure */
if(!co->secure) {
freecookie(co);
return NULL;
}
}
if(co->prefix & COOKIE_PREFIX__HOST) {
/*
* The __Host- prefix requires the cookie to be secure, have a "/" path
* and not have a domain set.
*/
if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch)
;
else {
freecookie(co);
return NULL;
/* this is an "illegal" <what>=<this> pair */
}
while(*ptr && ISBLANK(*ptr))
ptr++;
if(*ptr == ';')
ptr++;
else
break;
} while(1);
if(!co->domain && domain) {
/* no domain was given in the header line, set the default */
co->domain = strdup(domain);
if(!co->domain)
return CERR_OUT_OF_MEMORY;
}
if(!co->path && path) {
/*
* No path was given in the header line, set the default. Note that the
* passed-in path to this function MAY have a '?' and following part that
* MUST NOT be stored as part of the path.
*/
char *queryp = strchr(path, '?');
/*
* queryp is where the interesting part of the path ends, so now we
* want to the find the last
*/
char *endslash;
if(!queryp)
endslash = strrchr(path, '/');
else
endslash = memrchr(path, '/', (queryp - path));
if(endslash) {
size_t pathlen = (endslash-path + 1); /* include end slash */
co->path = Curl_memdup0(path, pathlen);
if(co->path) {
co->spath = sanitize_cookie_path(co->path);
if(!co->spath)
return CERR_OUT_OF_MEMORY;
}
else
return CERR_OUT_OF_MEMORY;
}
}
if(!c->running && /* read from a file */
c->newsession && /* clean session cookies */
!co->expires) { /* this is a session cookie since it does not expire! */
freecookie(co);
return NULL;
}
co->livecookie = c->running;
co->creationtime = ++c->lastct;
/*
* Now we have parsed the incoming line, we must now check if this supersedes
* an already existing cookie, which it may if the previous have the same
* domain and path as this.
* If we did not get a cookie name, or a bad one, the this is an illegal
* line so bail out.
*/
if(!co->name)
return CERR_BAD;
/* at first, remove expired cookies */
if(!noexpire)
remove_expired(c);
data->req.setcookies++;
return CERR_OK;
}
static int
parse_netscape(struct Cookie *co,
struct CookieInfo *ci,
const char *lineptr,
bool secure) /* TRUE if connection is over secure
origin */
{
/*
* This line is NOT an HTTP header style line, we do offer support for
* reading the odd netscape cookies-file format here
*/
char *ptr;
char *firstptr;
char *tok_buf = NULL;
int fields;
/*
* In 2008, Internet Explorer introduced HTTP-only cookies to prevent XSS
* attacks. Cookies marked httpOnly are not accessible to JavaScript. In
* Firefox's cookie files, they are prefixed #HttpOnly_ and the rest
* remains as usual, so we skip 10 characters of the line.
*/
if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
lineptr += 10;
co->httponly = TRUE;
}
if(lineptr[0]=='#')
/* do not even try the comments */
return CERR_COMMENT;
/* strip off the possible end-of-line characters */
ptr = strchr(lineptr, '\r');
if(ptr)
*ptr = 0; /* clear it */
ptr = strchr(lineptr, '\n');
if(ptr)
*ptr = 0; /* clear it */
/* tokenize on TAB */
firstptr = Curl_strtok_r((char *)lineptr, "\t", &tok_buf);
/*
* Now loop through the fields and init the struct we already have
* allocated
*/
fields = 0;
for(ptr = firstptr; ptr;
ptr = Curl_strtok_r(NULL, "\t", &tok_buf), fields++) {
switch(fields) {
case 0:
if(ptr[0]=='.') /* skip preceding dots */
ptr++;
co->domain = strdup(ptr);
if(!co->domain)
return CERR_OUT_OF_MEMORY;
break;
case 1:
/*
* flag: A TRUE/FALSE value indicating if all machines within a given
* domain can access the variable. Set TRUE when the cookie says
* .domain.com and to false when the domain is complete www.domain.com
*/
co->tailmatch = !!strcasecompare(ptr, "TRUE");
break;
case 2:
/* The file format allows the path field to remain not filled in */
if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
/* only if the path does not look like a boolean option! */
co->path = strdup(ptr);
if(!co->path)
return CERR_OUT_OF_MEMORY;
else {
co->spath = sanitize_cookie_path(co->path);
if(!co->spath)
return CERR_OUT_OF_MEMORY;
}
break;
}
/* this does not look like a path, make one up! */
co->path = strdup("/");
if(!co->path)
return CERR_OUT_OF_MEMORY;
co->spath = strdup("/");
if(!co->spath)
return CERR_OUT_OF_MEMORY;
fields++; /* add a field and fall down to secure */
FALLTHROUGH();
case 3:
co->secure = FALSE;
if(strcasecompare(ptr, "TRUE")) {
if(secure || ci->running)
co->secure = TRUE;
else
return CERR_BAD_SECURE;
}
break;
case 4:
if(curlx_strtoofft(ptr, NULL, 10, &co->expires))
return CERR_RANGE;
break;
case 5:
co->name = strdup(ptr);
if(!co->name)
return CERR_OUT_OF_MEMORY;
else {
/* For Netscape file format cookies we check prefix on the name */
if(strncasecompare("__Secure-", co->name, 9))
co->prefix_secure = TRUE;
else if(strncasecompare("__Host-", co->name, 7))
co->prefix_host = TRUE;
}
break;
case 6:
co->value = strdup(ptr);
if(!co->value)
return CERR_OUT_OF_MEMORY;
break;
}
}
if(6 == fields) {
/* we got a cookie with blank contents, fix it */
co->value = strdup("");
if(!co->value)
return CERR_OUT_OF_MEMORY;
else
fields++;
}
if(7 != fields)
/* we did not find the sufficient number of fields */
return CERR_FIELDS;
return CERR_OK;
}
static int
is_public_suffix(struct Curl_easy *data,
struct Cookie *co,
const char *domain)
{
#ifdef USE_LIBPSL
/*
* Check if the domain is a Public Suffix and if yes, ignore the cookie. We
@@ -1051,21 +964,34 @@ Curl_cookie_add(struct Curl_easy *data,
if(!acceptable) {
infof(data, "cookie '%s' dropped, domain '%s' must not "
"set cookies for '%s'", co->name, domain, co->domain);
freecookie(co);
return NULL;
"set cookies for '%s'", co->name, domain, co->domain);
return CERR_PSL;
}
}
#else
(void)data;
(void)co;
(void)domain;
DEBUGF(infof(data, "NO PSL to check set-cookie '%s' for domain=%s in %s",
co->name, co->domain, domain));
#endif
return CERR_OK;
}
/* A non-secure cookie may not overlay an existing secure cookie. */
myhash = cookiehash(co->domain);
clist = c->cookies[myhash];
while(clist) {
if(strcasecompare(clist->name, co->name)) {
static int
replace_existing(struct Curl_easy *data,
struct Cookie *co,
struct CookieInfo *ci,
bool secure,
bool *replacep)
{
bool replace_old = FALSE;
struct Curl_llist_node *replace_n = NULL;
struct Curl_llist_node *n;
size_t myhash = cookiehash(co->domain);
for(n = Curl_llist_head(&ci->cookielist[myhash]); n; n = Curl_node_next(n)) {
struct Cookie *clist = Curl_node_elem(n);
if(!strcmp(clist->name, co->name)) {
/* the names are identical */
bool matching_domains = FALSE;
@@ -1100,13 +1026,12 @@ Curl_cookie_add(struct Curl_easy *data,
if(strncasecompare(clist->spath, co->spath, cllen)) {
infof(data, "cookie '%s' for domain '%s' dropped, would "
"overlay an existing cookie", co->name, co->domain);
freecookie(co);
return NULL;
return CERR_BAD_SECURE;
}
}
}
if(!replace_co && strcasecompare(clist->name, co->name)) {
if(!replace_n && !strcmp(clist->name, co->name)) {
/* the names are identical */
if(clist->domain && co->domain) {
@@ -1135,62 +1060,137 @@ Curl_cookie_add(struct Curl_easy *data,
* was read from a file and thus is not "live". "live" cookies are
* preferred so the new cookie is freed.
*/
freecookie(co);
return NULL;
}
if(replace_old) {
replace_co = co;
replace_clist = clist;
return CERR_LIVE_WINS;
}
if(replace_old)
replace_n = n;
}
lastc = clist;
clist = clist->next;
}
if(replace_co) {
co = replace_co;
clist = replace_clist;
co->next = clist->next; /* get the next-pointer first */
if(replace_n) {
struct Cookie *repl = Curl_node_elem(replace_n);
/* when replacing, creationtime is kept from old */
co->creationtime = clist->creationtime;
co->creationtime = repl->creationtime;
/* then free all the old pointers */
free(clist->name);
free(clist->value);
free(clist->domain);
free(clist->path);
free(clist->spath);
/* unlink the old */
Curl_node_remove(replace_n);
*clist = *co; /* then store all the new data */
/* free the old cookie */
freecookie(repl);
}
*replacep = replace_old;
return CERR_OK;
}
free(co); /* free the newly allocated memory */
co = clist;
/*
* Curl_cookie_add
*
* Add a single cookie line to the cookie keeping object. Be aware that
* sometimes we get an IP-only hostname, and that might also be a numerical
* IPv6 address.
*
* Returns NULL on out of memory or invalid cookie. This is suboptimal,
* as they should be treated separately.
*/
struct Cookie *
Curl_cookie_add(struct Curl_easy *data,
struct CookieInfo *ci,
bool httpheader, /* TRUE if HTTP header-style line */
bool noexpire, /* if TRUE, skip remove_expired() */
const char *lineptr, /* first character of the line */
const char *domain, /* default domain */
const char *path, /* full path used when this cookie is set,
used to get default path for the cookie
unless set */
bool secure) /* TRUE if connection is over secure origin */
{
struct Cookie *co;
size_t myhash;
int rc;
bool replaces = FALSE;
DEBUGASSERT(data);
DEBUGASSERT(MAX_SET_COOKIE_AMOUNT <= 255); /* counter is an unsigned char */
if(data->req.setcookies >= MAX_SET_COOKIE_AMOUNT)
return NULL;
/* First, alloc and init a new struct for it */
co = calloc(1, sizeof(struct Cookie));
if(!co)
return NULL; /* bail out if we are this low on memory */
if(httpheader)
rc = parse_cookie_header(data, co, ci, lineptr, domain, path, secure);
else
rc = parse_netscape(co, ci, lineptr, secure);
if(rc)
goto fail;
if(co->prefix_secure && !co->secure)
/* The __Secure- prefix only requires that the cookie be set secure */
goto fail;
if(co->prefix_host) {
/*
* The __Host- prefix requires the cookie to be secure, have a "/" path
* and not have a domain set.
*/
if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch)
;
else
goto fail;
}
if(c->running)
if(!ci->running && /* read from a file */
ci->newsession && /* clean session cookies */
!co->expires) /* this is a session cookie since it does not expire */
goto fail;
co->livecookie = ci->running;
co->creationtime = ++ci->lastct;
/*
* Now we have parsed the incoming line, we must now check if this supersedes
* an already existing cookie, which it may if the previous have the same
* domain and path as this.
*/
/* remove expired cookies */
if(!noexpire)
remove_expired(ci);
if(is_public_suffix(data, co, domain))
goto fail;
if(replace_existing(data, co, ci, secure, &replaces))
goto fail;
/* add this cookie to the list */
myhash = cookiehash(co->domain);
Curl_llist_append(&ci->cookielist[myhash], co, &co->node);
if(ci->running)
/* Only show this when NOT reading the cookies from a file */
infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, "
"expire %" FMT_OFF_T,
replace_old?"Replaced":"Added", co->name, co->value,
replaces ? "Replaced":"Added", co->name, co->value,
co->domain, co->path, co->expires);
if(!replace_old) {
/* then make the last item point on this new one */
if(lastc)
lastc->next = co;
else
c->cookies[myhash] = co;
c->numcookies++; /* one more cookie in the jar */
}
if(!replaces)
ci->numcookies++; /* one more cookie in the jar */
/*
* Now that we have added a new cookie to the jar, update the expiration
* tracker in case it is the next one to expire.
*/
if(co->expires && (co->expires < c->next_expiration))
c->next_expiration = co->expires;
if(co->expires && (co->expires < ci->next_expiration))
ci->next_expiration = co->expires;
return co;
fail:
freecookie(co);
return NULL;
}
@@ -1210,28 +1210,30 @@ Curl_cookie_add(struct Curl_easy *data,
*/
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
const char *file,
struct CookieInfo *inc,
struct CookieInfo *ci,
bool newsession)
{
struct CookieInfo *c;
FILE *handle = NULL;
if(!inc) {
if(!ci) {
int i;
/* we did not get a struct, create one */
c = calloc(1, sizeof(struct CookieInfo));
if(!c)
ci = calloc(1, sizeof(struct CookieInfo));
if(!ci)
return NULL; /* failed to get memory */
/* This does not use the destructor callback since we want to add
and remove to lists while keeping the cookie struct intact */
for(i = 0; i < COOKIE_HASH_SIZE; i++)
Curl_llist_init(&ci->cookielist[i], NULL);
/*
* Initialize the next_expiration time to signal that we do not have enough
* information yet.
*/
c->next_expiration = CURL_OFF_T_MAX;
ci->next_expiration = CURL_OFF_T_MAX;
}
else {
/* we got an already existing one, use that */
c = inc;
}
c->newsession = newsession; /* new session? */
ci->newsession = newsession; /* new session? */
if(data) {
FILE *fp = NULL;
@@ -1247,7 +1249,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
}
}
c->running = FALSE; /* this is not running, this is init */
ci->running = FALSE; /* this is not running, this is init */
if(fp) {
struct dynbuf buf;
Curl_dyn_init(&buf, MAX_COOKIE_LINE);
@@ -1262,7 +1264,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
lineptr++;
}
Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE);
Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL, NULL, TRUE);
}
Curl_dyn_free(&buf); /* free the line buffer */
@@ -1270,16 +1272,16 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
* Remove expired cookies from the hash. We must make sure to run this
* after reading the file, and not on every cookie.
*/
remove_expired(c);
remove_expired(ci);
if(handle)
fclose(handle);
}
data->state.cookie_engine = TRUE;
}
c->running = TRUE; /* now, we are running */
ci->running = TRUE; /* now, we are running */
return c;
return ci;
}
/*
@@ -1334,38 +1336,6 @@ static int cookie_sort_ct(const void *p1, const void *p2)
return (c2->creationtime > c1->creationtime) ? 1 : -1;
}
#define CLONE(field) \
do { \
if(src->field) { \
d->field = strdup(src->field); \
if(!d->field) \
goto fail; \
} \
} while(0)
static struct Cookie *dup_cookie(struct Cookie *src)
{
struct Cookie *d = calloc(1, sizeof(struct Cookie));
if(d) {
CLONE(domain);
CLONE(path);
CLONE(spath);
CLONE(name);
CLONE(value);
d->expires = src->expires;
d->tailmatch = src->tailmatch;
d->secure = src->secure;
d->livecookie = src->livecookie;
d->httponly = src->httponly;
d->creationtime = src->creationtime;
}
return d;
fail:
freecookie(d);
return NULL;
}
/*
* Curl_cookie_getlist
*
@@ -1374,33 +1344,37 @@ fail:
* if a secure connection is achieved or not.
*
* It shall only return cookies that have not expired.
*
* Returns 0 when there is a list returned. Otherwise non-zero.
*/
struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
struct CookieInfo *c,
const char *host, const char *path,
bool secure)
int Curl_cookie_getlist(struct Curl_easy *data,
struct CookieInfo *ci,
const char *host, const char *path,
bool secure,
struct Curl_llist *list)
{
struct Cookie *newco;
struct Cookie *co;
struct Cookie *mainco = NULL;
size_t matches = 0;
bool is_ip;
const size_t myhash = cookiehash(host);
struct Curl_llist_node *n;
if(!c || !c->cookies[myhash])
return NULL; /* no cookie struct or no cookies in the struct */
Curl_llist_init(list, NULL);
if(!ci || !Curl_llist_count(&ci->cookielist[myhash]))
return 1; /* no cookie struct or no cookies in the struct */
/* at first, remove expired cookies */
remove_expired(c);
remove_expired(ci);
/* check if host is an IP(v4|v6) address */
is_ip = Curl_host_is_ipnum(host);
co = c->cookies[myhash];
for(n = Curl_llist_head(&ci->cookielist[myhash]);
n; n = Curl_node_next(n)) {
struct Cookie *co = Curl_node_elem(n);
while(co) {
/* if the cookie requires we are secure we must only continue if we are! */
if(co->secure?secure:TRUE) {
if(co->secure ? secure : TRUE) {
/* now check if the domain is correct */
if(!co->domain ||
@@ -1419,31 +1393,18 @@ struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
if(!co->spath || pathmatch(co->spath, path) ) {
/*
* and now, we know this is a match and we should create an
* entry for the return-linked-list
* This is a match and we add it to the return-linked-list
*/
newco = dup_cookie(co);
if(newco) {
/* then modify our next */
newco->next = mainco;
/* point the main to us */
mainco = newco;
matches++;
if(matches >= MAX_COOKIE_SEND_AMOUNT) {
infof(data, "Included max number of cookies (%zu) in request!",
matches);
break;
}
Curl_llist_append(list, co, &co->getnode);
matches++;
if(matches >= MAX_COOKIE_SEND_AMOUNT) {
infof(data, "Included max number of cookies (%zu) in request!",
matches);
break;
}
else
goto fail;
}
}
}
co = co->next;
}
if(matches) {
@@ -1460,30 +1421,29 @@ struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
if(!array)
goto fail;
co = mainco;
n = Curl_llist_head(list);
for(i = 0; co; co = co->next)
array[i++] = co;
for(i = 0; n; n = Curl_node_next(n))
array[i++] = Curl_node_elem(n);
/* now sort the cookie pointers in path length order */
qsort(array, matches, sizeof(struct Cookie *), cookie_sort);
/* remake the linked list order according to the new order */
Curl_llist_destroy(list, NULL);
mainco = array[0]; /* start here */
for(i = 0; i<matches-1; i++)
array[i]->next = array[i + 1];
array[matches-1]->next = NULL; /* terminate the list */
for(i = 0; i < matches; i++)
Curl_llist_append(list, array[i], &array[i]->getnode);
free(array); /* remove the temporary data again */
}
return mainco; /* return the new list */
return 0; /* success */
fail:
/* failure, clear up the allocated chain and return NULL */
Curl_cookie_freelist(mainco);
return NULL;
Curl_llist_destroy(list, NULL);
return 2; /* error */
}
/*
@@ -1491,30 +1451,21 @@ fail:
*
* Clear all existing cookies and reset the counter.
*/
void Curl_cookie_clearall(struct CookieInfo *cookies)
void Curl_cookie_clearall(struct CookieInfo *ci)
{
if(cookies) {
if(ci) {
unsigned int i;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
Curl_cookie_freelist(cookies->cookies[i]);
cookies->cookies[i] = NULL;
struct Curl_llist_node *n;
for(n = Curl_llist_head(&ci->cookielist[i]); n;) {
struct Cookie *c = Curl_node_elem(n);
struct Curl_llist_node *e = Curl_node_next(n);
Curl_node_remove(n);
freecookie(c);
n = e;
}
}
cookies->numcookies = 0;
}
}
/*
* Curl_cookie_freelist
*
* Free a list of cookies previously returned by Curl_cookie_getlist();
*/
void Curl_cookie_freelist(struct Cookie *co)
{
struct Cookie *next;
while(co) {
next = co->next;
freecookie(co);
co = next;
ci->numcookies = 0;
}
}
@@ -1523,39 +1474,26 @@ void Curl_cookie_freelist(struct Cookie *co)
*
* Free all session cookies in the cookies list.
*/
void Curl_cookie_clearsess(struct CookieInfo *cookies)
void Curl_cookie_clearsess(struct CookieInfo *ci)
{
struct Cookie *first, *curr, *next, *prev = NULL;
unsigned int i;
if(!cookies)
if(!ci)
return;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
if(!cookies->cookies[i])
continue;
struct Curl_llist_node *n = Curl_llist_head(&ci->cookielist[i]);
struct Curl_llist_node *e = NULL;
first = curr = prev = cookies->cookies[i];
for(; curr; curr = next) {
next = curr->next;
for(; n; n = e) {
struct Cookie *curr = Curl_node_elem(n);
e = Curl_node_next(n); /* in case the node is removed, get it early */
if(!curr->expires) {
if(first == curr)
first = next;
if(prev == curr)
prev = next;
else
prev->next = next;
Curl_node_remove(n);
freecookie(curr);
cookies->numcookies--;
ci->numcookies--;
}
else
prev = curr;
}
cookies->cookies[i] = first;
}
}
@@ -1564,13 +1502,11 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
*
* Free a "cookie object" previous created with Curl_cookie_init().
*/
void Curl_cookie_cleanup(struct CookieInfo *c)
void Curl_cookie_cleanup(struct CookieInfo *ci)
{
if(c) {
unsigned int i;
for(i = 0; i < COOKIE_HASH_SIZE; i++)
Curl_cookie_freelist(c->cookies[i]);
free(c); /* free the base struct as well */
if(ci) {
Curl_cookie_clearall(ci);
free(ci); /* free the base struct as well */
}
}
@@ -1592,19 +1528,19 @@ static char *get_netscape_format(const struct Cookie *co)
"%" FMT_OFF_T "\t" /* expires */
"%s\t" /* name */
"%s", /* value */
co->httponly?"#HttpOnly_":"",
co->httponly ? "#HttpOnly_" : "",
/*
* Make sure all domains are prefixed with a dot if they allow
* tailmatching. This is Mozilla-style.
*/
(co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
co->domain?co->domain:"unknown",
co->tailmatch?"TRUE":"FALSE",
co->path?co->path:"/",
co->secure?"TRUE":"FALSE",
(co->tailmatch && co->domain && co->domain[0] != '.') ? "." : "",
co->domain ? co->domain : "unknown",
co->tailmatch ? "TRUE" : "FALSE",
co->path ? co->path : "/",
co->secure ? "TRUE" : "FALSE",
co->expires,
co->name,
co->value?co->value:"");
co->value ? co->value : "");
}
/*
@@ -1616,20 +1552,20 @@ static char *get_netscape_format(const struct Cookie *co)
* The function returns non-zero on write failure.
*/
static CURLcode cookie_output(struct Curl_easy *data,
struct CookieInfo *c, const char *filename)
struct CookieInfo *ci,
const char *filename)
{
struct Cookie *co;
FILE *out = NULL;
bool use_stdout = FALSE;
char *tempstore = NULL;
CURLcode error = CURLE_OK;
if(!c)
if(!ci)
/* no cookie engine alive */
return CURLE_OK;
/* at first, remove expired cookies */
remove_expired(c);
remove_expired(ci);
if(!strcmp("-", filename)) {
/* use stdout */
@@ -1647,12 +1583,13 @@ static CURLcode cookie_output(struct Curl_easy *data,
"# This file was generated by libcurl! Edit at your own risk.\n\n",
out);
if(c->numcookies) {
if(ci->numcookies) {
unsigned int i;
size_t nvalid = 0;
struct Cookie **array;
struct Curl_llist_node *n;
array = calloc(1, sizeof(struct Cookie *) * c->numcookies);
array = calloc(1, sizeof(struct Cookie *) * ci->numcookies);
if(!array) {
error = CURLE_OUT_OF_MEMORY;
goto error;
@@ -1660,7 +1597,9 @@ static CURLcode cookie_output(struct Curl_easy *data,
/* only sort the cookies with a domain property */
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
for(co = c->cookies[i]; co; co = co->next) {
for(n = Curl_llist_head(&ci->cookielist[i]); n;
n = Curl_node_next(n)) {
struct Cookie *co = Curl_node_elem(n);
if(!co->domain)
continue;
array[nvalid++] = co;
@@ -1712,15 +1651,17 @@ static struct curl_slist *cookie_list(struct Curl_easy *data)
{
struct curl_slist *list = NULL;
struct curl_slist *beg;
struct Cookie *c;
char *line;
unsigned int i;
struct Curl_llist_node *n;
if(!data->cookies || (data->cookies->numcookies == 0))
return NULL;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
for(c = data->cookies->cookies[i]; c; c = c->next) {
for(n = Curl_llist_head(&data->cookies->cookielist[i]); n;
n = Curl_node_next(n)) {
struct Cookie *c = Curl_node_elem(n);
char *line;
if(!c->domain)
continue;
line = get_netscape_format(c);
+21 -17
View File
@@ -27,20 +27,24 @@
#include <curl/curl.h>
#include "llist.h"
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 *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
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 */
int numcookies; /* number of cookies 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,
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_clearsess(struct CookieInfo *cookies);
+46 -60
View File
@@ -252,6 +252,7 @@ Curl_getaddrinfo_ex(const char *nodename,
* #define h_addr h_addr_list[0]
*/
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
struct Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port)
{
@@ -350,19 +351,7 @@ Curl_he2ai(const struct hostent *he, int port)
return firstai;
}
struct namebuff {
struct hostent hostentry;
union {
struct in_addr ina4;
#ifdef USE_IPV6
struct in6_addr ina6;
#endif
} addrentry;
char *h_addr_list[2];
};
/*
* Curl_ip2addr()
@@ -377,71 +366,68 @@ struct Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
{
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 namelen;
struct sockaddr_in *addr;
#ifdef USE_IPV6
struct sockaddr_in6 *addr6;
#endif
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;
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;
}
/* 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) {
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;
#ifdef USE_IPV6
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;
#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;
}
+2
View File
@@ -71,8 +71,10 @@ Curl_getaddrinfo_ex(const char *nodename,
struct Curl_addrinfo **result);
#endif
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
struct Curl_addrinfo *
Curl_he2ai(const struct hostent *he, int port);
#endif
struct Curl_addrinfo *
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
+34 -20
View File
@@ -21,7 +21,6 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
/* lib/curl_config.h.in. Generated somehow by cmake. */
/* Location of default ca bundle */
#cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}"
@@ -56,7 +55,7 @@
/* disables negotiate authentication */
#cmakedefine CURL_DISABLE_NEGOTIATE_AUTH 1
/* disables AWS-SIG4 */
/* disables aws-sigv4 */
#cmakedefine CURL_DISABLE_AWS 1
/* disables DICT */
@@ -131,6 +130,9 @@
/* disables proxies */
#cmakedefine CURL_DISABLE_PROXY 1
/* disables IPFS from the curl tool */
#cmakedefine CURL_DISABLE_IPFS 1
/* disables RTSP */
#cmakedefine CURL_DISABLE_RTSP 1
@@ -146,6 +148,9 @@
/* disables SMTP */
#cmakedefine CURL_DISABLE_SMTP 1
/* disabled WebSockets */
#cmakedefine CURL_DISABLE_WEBSOCKETS 1
/* disables use of socketpair for curl_multi_poll */
#cmakedefine CURL_DISABLE_SOCKETPAIR 1
@@ -158,6 +163,12 @@
/* disables verbose strings */
#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 */
#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
/* Ensure using CURL_EXTERN_SYMBOL is possible */
@@ -208,6 +219,9 @@
/* Define to 1 if you have the `closesocket' function. */
#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. */
#cmakedefine HAVE_DIRENT_H 1
@@ -232,9 +246,6 @@
/* Define to 1 if you have the fseeko declaration. */
#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. */
#cmakedefine HAVE_FTRUNCATE 1
@@ -307,9 +318,6 @@
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
#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 */
#cmakedefine HAVE_GSSGNU 1
@@ -353,9 +361,6 @@
/* Define to 1 if you have the lber.h header file. */
#cmakedefine HAVE_LBER_H 1
/* Define to 1 if you have the ldap.h header file. */
#cmakedefine HAVE_LDAP_H 1
/* Use LDAPS implementation */
#cmakedefine HAVE_LDAP_SSL 1
@@ -401,6 +406,9 @@
/* Define to 1 if you have the <netinet/in.h> header file. */
#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. */
#cmakedefine HAVE_NETINET_TCP_H 1
@@ -422,8 +430,8 @@
/* Define to 1 if you have the `eventfd' function. */
#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. */
#cmakedefine HAVE_POLL_H 1
@@ -455,6 +463,9 @@
/* Define to 1 if you have the sendmsg function. */
#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. */
#cmakedefine HAVE_FSETXATTR 1
@@ -470,6 +481,9 @@
/* Define to 1 if you have the `setmode' function. */
#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. */
#cmakedefine HAVE_SETRLIMIT 1
@@ -497,6 +511,9 @@
/* Define to 1 if you have the `socket' function. */
#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. */
#cmakedefine HAVE_SOCKETPAIR 1
@@ -608,9 +625,6 @@
/* Define this symbol if your OS supports changing the contents of argv */
#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 */
#cmakedefine NEED_MALLOC_H 1
@@ -618,7 +632,7 @@
#cmakedefine NEED_REENTRANT 1
/* cpu-machine-OS */
#cmakedefine OS ${OS}
#cmakedefine CURL_OS ${CURL_OS}
/* Name of package */
#cmakedefine PACKAGE ${PACKAGE}
@@ -704,6 +718,9 @@ ${SIZEOF_TIME_T_CODE}
/* if wolfSSL has the wolfSSL_DES_ecb_encrypt function. */
#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. */
#cmakedefine HAVE_WOLFSSL_FULL_BIO 1
@@ -810,9 +827,6 @@ ${SIZEOF_TIME_T_CODE}
/* to enable Apple IDN */
#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. */
#cmakedefine HAVE_OPENSSL_SRP 1
+3 -3
View File
@@ -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)
{
setcharset_state state = CURLFNM_SCHS_DEFAULT;
@@ -293,7 +293,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
p++;
break;
case '\0':
return *s? CURL_FNMATCH_NOMATCH: CURL_FNMATCH_MATCH;
return *s ? CURL_FNMATCH_NOMATCH : CURL_FNMATCH_MATCH;
case '\\':
if(p[1])
p++;
@@ -303,7 +303,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
case '[':
pp = p + 1; /* Copy in case of syntax error in set. */
if(setcharset(&pp, charset)) {
int found = FALSE;
bool found = FALSE;
if(!*s)
return CURL_FNMATCH_NOMATCH;
if(charset[(unsigned int)*s])
+1 -1
View File
@@ -35,7 +35,7 @@
#include "memdebug.h"
#if defined(__GNUC__)
#define CURL_ALIGN8 __attribute__ ((aligned(8)))
#define CURL_ALIGN8 __attribute__((aligned(8)))
#else
#define CURL_ALIGN8
#endif
+14 -16
View File
@@ -32,30 +32,28 @@
#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. */
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. */
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
View File
@@ -31,11 +31,11 @@
#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 {
Curl_MD5_init_func md5_init_func; /* Initialize context procedure */
@@ -50,8 +50,8 @@ struct MD5_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,
const size_t len);
+2
View File
@@ -84,6 +84,7 @@
#undef socketpair
#endif
#ifndef CURL_NO_GETADDRINFO_OVERRIDE
#ifdef HAVE_GETADDRINFO
#if defined(getaddrinfo) && defined(__osf__)
#undef ogetaddrinfo
@@ -95,6 +96,7 @@
#ifdef HAVE_FREEADDRINFO
#undef freeaddrinfo
#endif /* HAVE_FREEADDRINFO */
#endif /* !CURL_NO_GETADDRINFO_OVERRIDE */
/* sclose is probably already defined, redefine it! */
#undef sclose
+23 -11
View File
@@ -71,13 +71,6 @@
# include <openssl/md5.h>
# include <openssl/ssl.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) && \
(OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
# define DES_key_schedule des_key_schedule
@@ -95,6 +88,25 @@
# define DESKEYARG(x) *x
# define DESKEY(x) &x
# 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)
@@ -483,7 +495,7 @@ static void time2filetime(struct ms_filetime *ft, time_t t)
134774 days = 11644473600 seconds = 0x2B6109100 */
r = ft->dwLowDateTime;
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. */
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_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);
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 */
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);
if(result) {
free(ptr);
@@ -656,7 +668,7 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
memcpy(&data[0], challenge_server, 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);
if(result)
return result;
+1 -1
View File
@@ -255,7 +255,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
return CURLE_FAILED_INIT;
/* Clients must send a periodic BytesReceived report to the server */
r->m_bSendCounter = true;
r->m_bSendCounter = TRUE;
*done = TRUE;
conn->recv[FIRSTSOCKET] = rtmp_recv;
+33 -11
View File
@@ -33,7 +33,7 @@
/* FIXME: Delete this once the warnings have been fixed. */
#if !defined(CURL_WARN_SIGN_CONVERSION)
#ifdef __GNUC__
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#endif
@@ -43,21 +43,24 @@
#include <_mingw.h>
#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
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
definition
error: expected ',' or '}' before
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)
#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
#if defined(__APPLE__)
@@ -109,7 +112,7 @@
# include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define CURL_WINDOWS_APP
# define CURL_WINDOWS_UWP
# endif
# endif
#endif
@@ -208,6 +211,11 @@
/* 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.
*/
@@ -282,6 +290,14 @@
# define CURL_DISABLE_HTTP_AUTH 1
#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 */
/* point. */
@@ -449,6 +465,12 @@
#include <curl/stdcheaders.h>
#endif
#ifdef _WIN32
#define Curl_getpid() GetCurrentProcessId()
#else
#define Curl_getpid() getpid()
#endif
/*
* Large file (>2Gb) support using Win32 functions.
*/
+1 -1
View File
@@ -31,7 +31,7 @@
#include <curl/curl.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
#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
+1 -1
View File
@@ -34,7 +34,7 @@
* * GnuTLS
* * wolfSSL
* * Schannel SSPI
* * SecureTransport (Darwin)
* * Secure Transport (Darwin)
* * mbedTLS
* * BearSSL
* * Rustls
+3 -3
View File
@@ -103,7 +103,7 @@ int Curl_thread_join(curl_thread_t *hnd)
#elif defined(USE_THREADS_WIN32)
curl_thread_t Curl_thread_create(
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
DWORD
#else
unsigned int
@@ -111,14 +111,14 @@ curl_thread_t Curl_thread_create(
(CURL_STDCALL *func) (void *),
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;
#else
typedef uintptr_t curl_win_thread_handle_t;
#endif
curl_thread_t t;
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);
#else
thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
+1 -1
View File
@@ -53,7 +53,7 @@
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
curl_thread_t Curl_thread_create(
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_UWP)
DWORD
#else
unsigned int
+7 -7
View File
@@ -65,7 +65,7 @@ void Curl_debug(struct Curl_easy *data, curl_infotype type,
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
if(data->set.fdebug) {
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);
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 */
#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 = {
"WS",
CURL_LOG_LVL_NONE,
@@ -255,7 +255,7 @@ void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
va_end(ap);
}
}
#endif /* USE_WEBSOCKETS && !CURL_DISABLE_HTTP */
#endif /* !CURL_DISABLE_WEBSOCKETS && !CURL_DISABLE_HTTP */
#define TRC_CT_NONE (0)
#define TRC_CT_PROTOCOL (1<<(0))
@@ -279,7 +279,7 @@ static struct trc_feat_def trc_feats[] = {
#ifndef CURL_DISABLE_SMTP
{ &Curl_trc_feat_smtp, TRC_CT_PROTOCOL },
#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 },
#endif
};
@@ -365,7 +365,7 @@ static CURLcode trc_opt(const char *config)
if(!tmp)
return CURLE_OUT_OF_MEMORY;
token = strtok_r(tmp, ", ", &tok_buf);
token = Curl_strtok_r(tmp, ", ", &tok_buf);
while(token) {
switch(*token) {
case '-':
@@ -391,7 +391,7 @@ static CURLcode trc_opt(const char *config)
else
trc_apply_level_by_name(token, lvl);
token = strtok_r(NULL, ", ", &tok_buf);
token = Curl_strtok_r(NULL, ", ", &tok_buf);
}
free(tmp);
return CURLE_OK;
@@ -399,7 +399,7 @@ static CURLcode 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
/* CURL_DEBUG can override anything */
if(!result) {
+11 -14
View File
@@ -94,11 +94,11 @@ void Curl_failf(struct Curl_easy *data,
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) \
Curl_trc_smtp(data, __VA_ARGS__); } while(0)
#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)) \
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 */
@@ -113,7 +113,7 @@ void Curl_failf(struct Curl_easy *data,
#ifndef CURL_DISABLE_SMTP
#define CURL_TRC_SMTP Curl_trc_smtp
#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
#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,
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,
const char *fmt, ...) CURL_PRINTF(2, 3);
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,
const char *fmt, ...) CURL_PRINTF(2, 3);
#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;
void Curl_trc_ws(struct Curl_easy *data,
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;
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, ...)
{
(void)data; (void)fmt;
@@ -226,6 +217,12 @@ static void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
(void)data; (void)fmt;
}
#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) */
-9
View File
@@ -66,13 +66,4 @@
#include "version_win32.h"
/* "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 */
+6 -7
View File
@@ -177,8 +177,8 @@ static void cw_get_writefunc(struct Curl_easy *data, cw_out_type otype,
*pmin_write = 0;
break;
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;
*pmax_write = 0; /* do not chunk-write headers, write them as they are */
*pmin_write = 0;
@@ -218,12 +218,12 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
while(blen && !ctx->paused) {
if(!flush_all && blen < min_write)
break;
wlen = max_write? CURLMIN(blen, max_write) : blen;
wlen = max_write ? CURLMIN(blen, max_write) : blen;
Curl_set_in_callback(data, TRUE);
nwritten = wcb((char *)buf, 1, wlen, wcb_data);
Curl_set_in_callback(data, FALSE);
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);
if(CURL_WRITEFUNC_PAUSE == nwritten) {
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;
CURLcode result;
bool flush_all;
bool flush_all = !!(type & CLIENTWRITE_EOS);
flush_all = (type & CLIENTWRITE_EOS)? TRUE:FALSE;
if((type & CLIENTWRITE_BODY) ||
((type & CLIENTWRITE_HEADER) && data->set.include_header)) {
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;
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;
}
+21 -22
View File
@@ -165,7 +165,7 @@ UNITTEST DOHcode doh_req_encode(const char *host,
*dnsp++ = 0; /* append zero-length label for root */
/* 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++ = '\0'; /* upper 8 bit CLASS */
@@ -180,7 +180,7 @@ UNITTEST DOHcode doh_req_encode(const char *host,
}
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;
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];
size_t hlen = LOCAL_PB_HEXMAX;
bool truncated = false;
bool truncated = FALSE;
if(len > (LOCAL_PB_HEXMAX / 2))
truncated = true;
truncated = TRUE;
Curl_hexencode(buf, len, hexstr, hlen);
if(!truncated)
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;
}
#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,
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
the gcc typecheck helpers */
doh->state.internal = true;
doh->state.internal = TRUE;
#ifndef CURL_DISABLE_VERBOSE_STRINGS
doh->state.feat = &Curl_doh_trc;
#endif
@@ -301,7 +301,7 @@ static CURLcode doh_run_probe(struct Curl_easy *data,
ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
#endif
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)
ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err);
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) {
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;
for(j = 0; j < 16; j += 2) {
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]);
l = strlen(ptr);
len -= l;
@@ -1305,7 +1303,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data,
if(dohp->probe[DOH_SLOT_IPV4].easy_mid < 0 &&
dohp->probe[DOH_SLOT_IPV6].easy_mid < 0) {
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;
}
else if(!dohp->pending) {
@@ -1415,7 +1413,8 @@ void Curl_doh_close(struct Curl_easy *data)
doh->probe[slot].easy_mid = -1;
/* should have been called before data is removed from multi handle */
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) {
DEBUGF(infof(data, "Curl_doh_close: xfer for mid=%"
FMT_OFF_T " not found!",
+2 -2
View File
@@ -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)
{
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,
@@ -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)
{
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
+36 -29
View File
@@ -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
* 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;
struct Curl_easy *data;
@@ -398,9 +398,9 @@ struct events {
* Callback that gets called with a new value when the timeout should be
* updated.
*/
static int events_timer(struct Curl_multi *multi, /* multi handle */
static int events_timer(CURLM *multi, /* multi handle */
long timeout_ms, /* see above */
void *userp) /* private callback pointer */
void *userp) /* private callback pointer */
{
struct events *ev = userp;
(void)multi;
@@ -449,7 +449,7 @@ static short socketcb2poll(int pollmask)
* Callback that gets called with information about socket activity to
* monitor.
*/
static int events_socket(struct Curl_easy *easy, /* easy handle */
static int events_socket(CURL *easy, /* easy handle */
curl_socket_t s, /* socket */
int what, /* see above */
void *userp, /* private callback
@@ -461,6 +461,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
struct socketmonitor *m;
struct socketmonitor *prev = NULL;
bool found = FALSE;
struct Curl_easy *data = easy;
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
(void) easy;
@@ -479,16 +480,16 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
else
ev->list = nxt;
free(m);
infof(easy, "socket cb: socket %" FMT_SOCKET_T " REMOVED", s);
infof(data, "socket cb: socket %" FMT_SOCKET_T " REMOVED", s);
}
else {
/* The socket 's' is already being monitored, update the activity
mask. Convert from libcurl bitmask to the poll one. */
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,
(what&CURL_POLL_IN)?"IN":"",
(what&CURL_POLL_OUT)?"OUT":"");
(what&CURL_POLL_IN) ? "IN" : "",
(what&CURL_POLL_OUT) ? "OUT" : "");
}
break;
}
@@ -499,7 +500,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
if(!found) {
if(what == CURL_POLL_REMOVE) {
/* 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));
DEBUGASSERT(0);
}
@@ -511,9 +512,9 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
m->socket.events = socketcb2poll(what);
m->socket.revents = 0;
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
return CURLE_OUT_OF_MEMORY;
@@ -617,7 +618,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
DEBUGASSERT(data);
/* 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) {
/* socket activity, tell libcurl */
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
* transfer as previously setup.
*/
CURLcode curl_easy_perform(struct Curl_easy *data)
CURLcode curl_easy_perform(CURL *data)
{
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
* 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)) {
SIGPIPE_VARIABLE(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.
*/
#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;
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 *));
/* 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]);
if(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
* 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));
if(!outcurl)
goto fail;
@@ -937,6 +940,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
goto fail;
Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
Curl_netrc_init(&outcurl->state.netrc);
/* the connection pool is setup on demand */
outcurl->state.lastconnect_id = -1;
@@ -1066,8 +1070,9 @@ fail:
* curl_easy_reset() is an external interface that allows an app to re-
* 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);
/* 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
* within a callback.
*/
CURLcode curl_easy_pause(struct Curl_easy *data, int action)
CURLcode curl_easy_pause(CURL *d, int action)
{
struct SingleRequest *k;
CURLcode result = CURLE_OK;
@@ -1115,6 +1120,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
int newstate;
bool recursive = FALSE;
bool keep_changed, unpause_read, not_all_paused;
struct Curl_easy *data = d;
if(!GOOD_EASY_HANDLE(data) || !data->conn)
/* 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 */
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);
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.
* 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;
ssize_t n1;
struct connectdata *c;
struct Curl_easy *data = d;
if(Curl_is_in_callback(data))
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;
}
#ifdef USE_WEBSOCKETS
#ifndef CURL_DISABLE_WEBSOCKETS
CURLcode Curl_connect_only_attach(struct Curl_easy *data)
{
CURLcode result;
@@ -1264,7 +1270,7 @@ CURLcode Curl_connect_only_attach(struct Curl_easy *data)
return CURLE_OK;
}
#endif /* USE_WEBSOCKETS */
#endif /* !CURL_DISABLE_WEBSOCKETS */
/*
* 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
* 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;
CURLcode result;
struct Curl_easy *data = d;
if(Curl_is_in_callback(data))
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.
*/
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. */
if(!GOOD_EASY_HANDLE(data))
return CURLE_BAD_FUNCTION_ARGUMENT;
+1 -1
View File
@@ -30,7 +30,7 @@
CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer,
size_t buflen, size_t *n);
#ifdef USE_WEBSOCKETS
#ifndef CURL_DISABLE_WEBSOCKETS
CURLcode Curl_connect_only_attach(struct Curl_easy *data);
#endif
+8 -6
View File
@@ -29,6 +29,8 @@
#include <curl/curl.h>
struct Curl_easy;
#include "urldata.h"
#include "warnless.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.
* '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)
{
size_t length;
@@ -63,7 +65,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
if(!string || (inlength < 0))
return NULL;
length = (inlength?(size_t)inlength:strlen(string));
length = (inlength ? (size_t)inlength : strlen(string));
if(!length)
return strdup("");
@@ -82,7 +84,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
/* encode it */
const char hex[] = "0123456789ABCDEF";
char out[3]={'%'};
out[1] = hex[in>>4];
out[1] = hex[in >> 4];
out[2] = hex[in & 0xf];
if(Curl_dyn_addn(&d, out, 3))
return NULL;
@@ -128,7 +130,7 @@ CURLcode Curl_urldecode(const char *string, size_t length,
DEBUGASSERT(string);
DEBUGASSERT(ctrl >= REJECT_NADA); /* crash on TRUE/FALSE */
alloc = (length?length:strlen(string));
alloc = (length ? length : strlen(string));
ns = malloc(alloc + 1);
if(!ns)
@@ -176,7 +178,7 @@ CURLcode Curl_urldecode(const char *string, size_t length,
* If olen == NULL, no output length is stored.
* '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)
{
char *str = NULL;
@@ -223,7 +225,7 @@ void Curl_hexencode(const unsigned char *src, size_t len, /* input length */
while(len-- && (olen >= 3)) {
/* clang-tidy warns on this line without this comment: */
/* 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];
++src;
olen -= 2;
+1 -1
View File
@@ -489,7 +489,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
headerlen =
msnprintf(header, sizeof(header),
"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,
Curl_month[tm->tm_mon],
tm->tm_year + 1900,
+26 -22
View File
@@ -26,6 +26,8 @@
#include <curl/curl.h>
struct Curl_easy;
#include "formdata.h"
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API)
@@ -282,8 +284,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(current_form->name)
return_value = CURL_FORMADD_OPTION_TWICE;
else {
char *name = array_state?
array_value:va_arg(params, char *);
char *name = array_state ?
array_value : va_arg(params, char *);
if(name)
current_form->name = name; /* store for the moment */
else
@@ -295,7 +297,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE;
else
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;
/*
@@ -309,7 +311,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE;
else {
char *value =
array_state?array_value:va_arg(params, char *);
array_state ? array_value : va_arg(params, char *);
if(value)
current_form->value = value; /* store for the moment */
else
@@ -318,13 +320,14 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
break;
case CURLFORM_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;
case CURLFORM_CONTENTLEN:
current_form->flags |= CURL_HTTPPOST_LARGE;
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;
/* Get contents from a given filename */
@@ -332,8 +335,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
return_value = CURL_FORMADD_OPTION_TWICE;
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) {
current_form->value = strdup(filename);
if(!current_form->value)
@@ -351,7 +354,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
/* We upload a file */
case CURLFORM_FILE:
{
const char *filename = array_state?array_value:
const char *filename = array_state ? array_value :
va_arg(params, char *);
if(current_form->value) {
@@ -401,7 +404,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE;
else {
char *buffer =
array_state?array_value:va_arg(params, char *);
array_state ? array_value : va_arg(params, char *);
if(buffer) {
current_form->buffer = buffer; /* store for the moment */
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;
else
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;
case CURLFORM_STREAM:
@@ -426,7 +429,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
return_value = CURL_FORMADD_OPTION_TWICE;
else {
char *userp =
array_state?array_value:va_arg(params, char *);
array_state ? array_value : va_arg(params, char *);
if(userp) {
current_form->userp = userp;
current_form->value = userp; /* this is not strictly true but we
@@ -442,7 +445,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
case CURLFORM_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->flags & HTTPPOST_FILENAME) {
if(contenttype) {
@@ -485,8 +488,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
{
/* this "cast increases required alignment of target type" but
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 *);
if(current_form->contentheader)
@@ -499,7 +502,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
case CURLFORM_FILENAME:
case CURLFORM_BUFFER:
{
const char *filename = array_state?array_value:
const char *filename = array_state ? array_value :
va_arg(params, char *);
if(current_form->showfilename)
return_value = CURL_FORMADD_OPTION_TWICE;
@@ -569,7 +572,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype) {
char *f = (form->flags & HTTPPOST_BUFFER)?
char *f = (form->flags & HTTPPOST_BUFFER) ?
form->showfilename : form->value;
char const *type;
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. */
if(form->name) {
/* 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));
}
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 */
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);
#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
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.
*/
CURLcode Curl_getformdata(struct Curl_easy *data,
CURLcode Curl_getformdata(CURL *data,
curl_mimepart *finalform,
struct curl_httppost *post,
curl_read_callback fread_func)
@@ -896,7 +899,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
}
else if(post->flags & HTTPPOST_BUFFER)
result = curl_mime_data(part, post->buffer,
post->bufferlength? post->bufferlength: -1);
post->bufferlength ?
post->bufferlength : -1);
else if(post->flags & HTTPPOST_CALLBACK) {
/* the contents should be read with the callback and the size is set
with the contentslength */
+1 -1
View File
@@ -49,7 +49,7 @@ struct FormInfo {
bool showfilename_alloc;
};
CURLcode Curl_getformdata(struct Curl_easy *data,
CURLcode Curl_getformdata(CURL *data,
curl_mimepart *,
struct curl_httppost *post,
curl_read_callback fread_func);
+129 -293
View File
@@ -302,10 +302,10 @@ static void close_secondarysocket(struct Curl_easy *data)
* requests on files respond with headers passed to the client/stdout that
* 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
@@ -419,138 +419,19 @@ static const struct Curl_cwtype ftp_cw_lc = {
#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
* ftp_check_ctrl_on_data_wait()
*
*/
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
*
*/
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;
curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
int socketstate = 0;
timediff_t timeout_ms;
ssize_t nread;
int ftpcode;
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 */
if(Curl_dyn_len(&pp->recvbuf) && (*Curl_dyn_ptr(&pp->recvbuf) > '3')) {
/* 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)
/* there is pending control data still in the buffer to read */
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) {
infof(data, "Ctrl conn has data while waiting for data conn");
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
the data socket. */
infof(data, "Got 226 before data activity");
*received = TRUE;
return CURLE_OK;
}
}
@@ -619,7 +495,6 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received)
return CURLE_OK;
}
/***********************************************************************
*
* InitiateTransfer()
@@ -635,12 +510,6 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
bool connected;
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);
if(result || !connected)
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 */
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 {
/* FTP download: */
/* FTP download, shutdown, do not ignore errors */
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 */
@@ -667,60 +538,6 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
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,
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)) {
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);
if(ev < 0) {
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,
&conn->proto.ftpc.pp, "USER %s",
conn->user?conn->user:"");
conn->user ? conn->user : "");
if(!result) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
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 */
switch(Curl_if2ip(conn->remote_addr->family,
#ifdef USE_IPV6
Curl_ipv6_scope(&conn->remote_addr->sa_addr),
Curl_ipv6_scope(&conn->remote_addr->curl_sa_addr),
conn->scope_id,
#endif
ipstr, hbuf, sizeof(hbuf))) {
@@ -1304,12 +1121,6 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
conn->bits.ftp_use_eprt = TRUE;
#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++) {
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],
sa->sa_family == AF_INET?1:2,
sa->sa_family == AF_INET ? 1 : 2,
myhost, port);
if(result) {
failf(data, "Failure sending EPRT command: %s",
@@ -1368,7 +1179,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
source++;
}
*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);
if(result) {
@@ -1382,9 +1193,13 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
/* store which command was sent */
ftpc->count1 = fcmd;
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:
/* If we looked up a dns_entry, now is the time to safely release it */
if(dns_entry)
@@ -1392,6 +1207,18 @@ out:
if(result) {
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)
Curl_socket_close(data, conn, portsock);
return result;
@@ -1426,7 +1253,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
conn->bits.ftp_use_epsv = TRUE;
#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]);
if(!result) {
@@ -1469,9 +1296,9 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(!conn->proto.ftpc.file)
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)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
conn->proto.ftpc.file);
@@ -1576,11 +1403,11 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
}
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);
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. */
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,
data->state.resume_from, SEEK_SET);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
}
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);
}
/* now, decrease the size of the read */
if(data->state.infilesize>0) {
if(data->state.infilesize > 0) {
data->state.infilesize -= data->state.resume_from;
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 */
} /* 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);
if(!result)
ftp_state(data, FTP_STOR);
@@ -1804,7 +1631,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
int i = 0;
/* Skip count1 items in the linked list */
while((i< ftpc->count1) && item) {
while((i < ftpc->count1) && item) {
item = item->next;
i++;
}
@@ -2038,7 +1865,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
if(!ftpc->newhost)
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) {
/* 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,
conn->bits.ftp_use_data_ssl?
conn->bits.ftp_use_data_ssl ?
CURL_CF_SSL_ENABLE : CURL_CF_SSL_DISABLE);
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
* output. */
CURLcode result;
int save = data->set.include_header;
bool save = data->set.include_header;
data->set.include_header = TRUE;
result = Curl_client_write(data, CLIENTWRITE_HEADER, buf, blen);
data->set.include_header = save? TRUE:FALSE;
data->set.include_header = save;
return result;
}
@@ -2267,15 +2094,16 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
return result;
/* 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);
if(result)
return result;
@@ -2387,7 +2215,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
else {
/* 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. */
if(data->state.resume_from< 0) {
if(data->state.resume_from < 0) {
/* We are supposed to download the last abs(from) bytes */
if(filesize < -data->state.resume_from) {
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. */
if(data->set.ftp_use_port) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
bool connected;
ftp_state(data, FTP_STOP); /* no longer in STOR state */
result = AllowServerConnect(data, &connected);
result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
if(result)
return result;
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately");
ftpc->wait_data_conn = TRUE;
return ftp_check_ctrl_on_data_wait(data);
}
return CURLE_OK;
ftpc->wait_data_conn = FALSE;
}
return InitiateTransfer(data);
}
@@ -2626,10 +2454,10 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
!data->set.ignorecl &&
(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 */
char *bytes;
@@ -2676,21 +2504,22 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
conn->proto.ftpc.retr_size_saved = size;
if(data->set.ftp_use_port) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
bool connected;
result = AllowServerConnect(data, &connected);
result = Curl_conn_connect(data, SECONDARYSOCKET, FALSE, &connected);
if(result)
return result;
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately");
ftp_state(data, FTP_STOP);
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 {
if((instate == FTP_LIST) && (ftpcode == 450)) {
@@ -2700,8 +2529,8 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
}
else {
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;
}
}
@@ -2753,7 +2582,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
/* 331 Password required for ...
(the server requires to send the user's password too) */
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
conn->passwd?conn->passwd:"");
conn->passwd ? conn->passwd : "");
if(!result)
ftp_state(data, FTP_PASS);
}
@@ -2964,7 +2793,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
if(ftpcode/100 == 2)
/* We have enabled SSL for the data connection! */
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
our 'P' request */
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
since at times we are in fact already in this state when this function
gets called. */
*done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
*done = (ftpc->state == FTP_STOP);
return result;
}
@@ -3403,9 +3232,9 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
if(data->state.wildcardmatch) {
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);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
}
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)
pathLen = 0; /* relative path => working directory is FTP home */
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';
ftpc->prevpath = rawPath;
@@ -3550,7 +3380,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
}
else if(!ftpc->dont_check &&
!data->req.bytecount &&
(data->req.size>0)) {
(data->req.size > 0)) {
failf(data, "No data was received");
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,
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;
CURLcode result;
char want = (char)(ascii?'A':'I');
char want = (char)(ascii ? 'A' : 'I');
if(ftpc->transfertype == want) {
ftp_state(data, newstate);
@@ -3714,20 +3544,25 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
* complete */
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]) {
bool is_eptr = Curl_conn_is_tcp_listen(data, SECONDARYSOCKET);
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 */
/* this is a EPSV connect failing, try PASV instead */
return ftp_epsv_disable(data, conn);
}
*completep = (int)complete;
return result;
}
}
@@ -3760,16 +3595,14 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
if(ftpc->wait_data_conn) {
bool serv_conned;
result = ReceivedServerConnect(data, &serv_conned);
result = Curl_conn_connect(data, SECONDARYSOCKET, TRUE, &serv_conned);
if(result)
return result; /* Failed to accept data connection */
if(serv_conned) {
/* It looks data connection is established */
result = AcceptServerConnect(data);
ftpc->wait_data_conn = FALSE;
if(!result)
result = InitiateTransfer(data);
result = InitiateTransfer(data);
if(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
connected back to us */
}
else {
result = ftp_check_ctrl_on_data_wait(data);
if(result)
return result;
}
}
else if(data->state.upload) {
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++;
if(last_slash[0] == '\0') {
wildcard->state = CURLWC_CLEAN;
result = ftp_parse_url_path(data);
return result;
return ftp_parse_url_path(data);
}
wildcard->pattern = strdup(last_slash);
if(!wildcard->pattern)
@@ -3929,8 +3766,7 @@ static CURLcode init_wc_data(struct Curl_easy *data)
}
else { /* only list */
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);
if(data->set.chunk_bgn) {
long userresponse;
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
userresponse = data->set.chunk_bgn(
finfo, data->set.wildcardptr,
(int)Curl_llist_count(&wildcard->filelist));
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
switch(userresponse) {
case CURL_CHUNK_BGN_FUNC_SKIP:
infof(data, "Wildcard - \"%s\" skipped by user",
@@ -4093,9 +3929,9 @@ static CURLcode wc_statemach(struct Curl_easy *data)
case CURLWC_SKIP: {
if(data->set.chunk_end) {
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
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));
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)
n = 0; /* CWD to entry for relative paths */
else
n -= ftpc->file?strlen(ftpc->file):0;
n -= ftpc->file ? strlen(ftpc->file) : 0;
if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
infof(data, "Request has same path as previous transfer");
+2 -2
View File
@@ -334,7 +334,7 @@ static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
compare = Curl_fnmatch;
/* filter pattern-corresponding filenames */
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
if(compare(data->set.fnmatch_data, wc->pattern,
finfo->filename) == 0) {
/* discard symlink which is containing multiple " -> " */
@@ -346,7 +346,7 @@ static CURLcode ftp_pl_insert_finfo(struct Curl_easy *data,
else {
add = FALSE;
}
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
if(add) {
Curl_llist_append(llist, finfo, &infop->list);
+2 -2
View File
@@ -31,7 +31,7 @@
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 */
(void)variable;
return NULL;
@@ -70,7 +70,7 @@ static char *GetEnv(const char *variable)
}
#else
char *env = getenv(variable);
return (env && env[0])?strdup(env):NULL;
return (env && env[0]) ? strdup(env) : NULL;
#endif
}
+14 -11
View File
@@ -57,7 +57,7 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
pro->t_starttransfer = 0;
pro->timespent = 0;
pro->t_redirect = 0;
pro->is_t_startransfer_set = false;
pro->is_t_startransfer_set = FALSE;
info->httpcode = 0;
info->httpproxycode = 0;
@@ -96,7 +96,7 @@ static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
{
switch(info) {
case CURLINFO_EFFECTIVE_URL:
*param_charp = data->state.url?data->state.url:(char *)"";
*param_charp = data->state.url ? data->state.url : (char *)"";
break;
case CURLINFO_EFFECTIVE_METHOD: {
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;
break;
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;
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;
case CURLINFO_TOTAL_TIME_T:
*param_offt = data->progress.timespent;
@@ -446,9 +446,12 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
*param_offt = data->id;
break;
case CURLINFO_CONN_ID:
*param_offt = data->conn?
*param_offt = data->conn ?
data->conn->connection_id : data->state.recent_conn_id;
break;
case CURLINFO_EARLYDATA_SENT_T:
*param_offt = data->progress.earlydata_sent;
break;
default:
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;
break;
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;
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;
case CURLINFO_REDIRECT_TIME:
*param_doublep = DOUBLE_SECS(data->progress.t_redirect);
+1 -1
View File
@@ -54,7 +54,7 @@ static void copy_header_external(struct Curl_header_store *hs,
impossible for applications to do == comparisons, as that would otherwise
be very tempting and then lead to the reserved bits not being reserved
anymore. */
h->origin = (unsigned int)(hs->type | (1<<27));
h->origin = (unsigned int)(hs->type | (1 << 27));
h->anchor = e;
}
+32 -38
View File
@@ -49,8 +49,6 @@
static const unsigned char hmac_ipad = 0x36;
static const unsigned char hmac_opad = 0x5C;
struct HMAC_context *
Curl_HMAC_init(const struct HMAC_params *hashparams,
const unsigned char *key,
@@ -62,42 +60,40 @@ Curl_HMAC_init(const struct HMAC_params *hashparams,
unsigned char b;
/* Create HMAC context. */
i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize +
hashparams->hmac_resultlen;
i = sizeof(*ctxt) + 2 * hashparams->ctxtsize + hashparams->resultlen;
ctxt = malloc(i);
if(!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(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;
keylen = hashparams->hmac_resultlen;
keylen = hashparams->resultlen;
}
/* 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++) {
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);
(*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. */
@@ -105,31 +101,29 @@ Curl_HMAC_init(const struct HMAC_params *hashparams,
}
int Curl_HMAC_update(struct HMAC_context *ctxt,
const unsigned char *data,
const unsigned char *ptr,
unsigned int len)
{
/* Update first hash calculation. */
(*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len);
ctxt->hash->hupdate(ctxt->hashctxt1, ptr, len);
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. */
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;
}
@@ -144,15 +138,15 @@ int Curl_HMAC_final(struct HMAC_context *ctxt, unsigned char *result)
* hashparams [in] - The hash function (Curl_HMAC_MD5).
* key [in] - The key to use.
* 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.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
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)
{
struct HMAC_context *ctxt =
@@ -162,7 +156,7 @@ CURLcode Curl_hmacit(const struct HMAC_params *hashparams,
return CURLE_OUT_OF_MEMORY;
/* 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 */
Curl_HMAC_final(ctxt, output);
+13 -11
View File
@@ -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 */
if(dns && data->conn->ip_version != CURL_IPRESOLVE_WHATEVER) {
int pf = PF_INET;
bool found = false;
bool found = FALSE;
struct Curl_addrinfo *addr = dns->addr;
#ifdef PF_INET6
@@ -323,7 +323,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data,
while(addr) {
if(addr->ai_family == pf) {
found = true;
found = TRUE;
break;
}
addr = addr->ai_next;
@@ -630,7 +630,7 @@ bool Curl_ipv6works(struct Curl_easy *data)
ipv6_works = 1;
sclose(s);
}
return (ipv6_works>0)?TRUE:FALSE;
return (ipv6_works > 0);
}
}
#endif /* USE_IPV6 */
@@ -739,7 +739,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
/* notify the resolver start callback */
if(data->set.resolver_start) {
int st;
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
st = data->set.resolver_start(
#ifdef USE_CURL_ASYNC
data->state.async.resolver,
@@ -748,7 +748,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
#endif
NULL,
data->set.resolver_start_client);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
if(st)
return CURLRESOLV_ERROR;
}
@@ -798,7 +798,9 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
return CURLRESOLV_ERROR;
if(strcasecompare(hostname, "localhost") ||
tailmatch(hostname, ".localhost"))
strcasecompare(hostname, "localhost.") ||
tailmatch(hostname, ".localhost") ||
tailmatch(hostname, ".localhost."))
addr = get_localhost(port, hostname);
#ifndef CURL_DISABLE_DOH
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)
{
struct Curl_dns_entry *dns = (struct Curl_dns_entry *) entry;
DEBUGASSERT(dns && (dns->refcount>0));
DEBUGASSERT(dns && (dns->refcount > 0));
dns->refcount--;
if(dns->refcount == 0) {
@@ -1129,7 +1131,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
char *host_end;
/* Default is no wildcard found */
data->state.wildcard_resolve = false;
data->state.wildcard_resolve = FALSE;
for(hostp = data->state.resolve; hostp; hostp = hostp->next) {
char entry_id[MAX_HOSTCACHE_LEN];
@@ -1179,7 +1181,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
char *end_ptr;
bool permanent = TRUE;
unsigned long tmp_port;
bool error = true;
bool error = TRUE;
char *host_begin = hostp->data;
size_t hlen = 0;
@@ -1256,7 +1258,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
if(!head)
goto err;
error = false;
error = FALSE;
err:
if(error) {
failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'",
@@ -1316,7 +1318,7 @@ err:
/* Wildcard hostname */
if((hlen == 1) && (host_begin[0] == '*')) {
infof(data, "RESOLVE *:%d using wildcard", port);
data->state.wildcard_resolve = true;
data->state.wildcard_resolve = TRUE;
}
}
}
+4
View File
@@ -126,8 +126,10 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
int res;
#endif
struct Curl_addrinfo *ai = NULL;
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
struct hostent *h = NULL;
struct hostent *buf = NULL;
#endif
#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE)
struct addrinfo hints;
@@ -288,12 +290,14 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
#endif /* (HAVE_GETADDRINFO && HAVE_GETADDRINFO_THREADSAFE) ||
HAVE_GETHOSTBYNAME_R */
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
if(h) {
ai = Curl_he2ai(h, port);
if(buf) /* used a *_r() function */
free(buf);
}
#endif
return ai;
}
+23 -16
View File
@@ -159,7 +159,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
do {
while(*p && ISBLANK(*p))
p++;
if(strncasecompare("max-age=", p, 8)) {
if(strncasecompare("max-age", p, 7)) {
bool quoted = FALSE;
CURLofft offt;
char *endp;
@@ -167,9 +167,14 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
if(gotma)
return CURLE_BAD_FUNCTION_ARGUMENT;
p += 8;
p += 7;
while(*p && ISBLANK(*p))
p++;
if(*p++ != '=')
return CURLE_BAD_FUNCTION_ARGUMENT;
while(*p && ISBLANK(*p))
p++;
if(*p == '\"') {
p++;
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,
bool subdomain)
{
struct stsentry *bestsub = NULL;
if(h) {
char buffer[MAX_HSTS_HOSTLEN + 1];
time_t now = time(NULL);
size_t hlen = strlen(hostname);
struct Curl_llist_node *e;
struct Curl_llist_node *n;
size_t blen = 0;
if((hlen > MAX_HSTS_HOSTLEN) || !hlen)
return NULL;
memcpy(buffer, hostname, hlen);
if(hostname[hlen-1] == '.')
/* remove the trailing dot */
--hlen;
buffer[hlen] = 0;
hostname = buffer;
for(e = Curl_llist_head(&h->list); e; e = n) {
struct stsentry *sts = Curl_node_elem(e);
size_t ntail;
n = Curl_node_next(e);
if(sts->expires <= now) {
/* remove expired entries */
@@ -274,20 +278,23 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
hsts_free(sts);
continue;
}
if(subdomain && sts->includeSubDomains) {
size_t ntail = strlen(sts->host);
if(ntail < hlen) {
size_t offs = hlen - ntail;
if((hostname[offs-1] == '.') &&
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 NULL; /* no match */
return bestsub;
}
/*
@@ -439,7 +446,7 @@ static CURLcode hsts_add(struct hsts *h, char *line)
e = Curl_hsts(h, p, subdomain);
if(!e)
result = hsts_create(h, p, subdomain, expires);
else {
else if(strcasecompare(p, e->host)) {
/* the same hostname, use the largest expire time */
if(expires > e->expires)
e->expires = expires;
+84 -243
View File
@@ -407,7 +407,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data,
{
curl_off_t bytessent = data->req.writebytecount;
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 needs_rewind = Curl_creader_needs_rewind(data);
/* 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(upload_remain >= 0)
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);
else
infof(data, "%s%sclose instead of sending unknown amount "
"of more bytes",
ongoing_auth? ongoing_auth : "",
ongoing_auth? " send, " : "");
ongoing_auth ? ongoing_auth : "",
ongoing_auth ? " send, " : "");
/* We decided to abort the ongoing transfer */
streamclose(conn, "Mid-auth HTTP and much data left to send");
/* 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;
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]) &&
((data->req.httpcode == 401) ||
@@ -677,7 +677,7 @@ output_auth_headers(struct Curl_easy *data,
auth, data->state.aptr.user ?
data->state.aptr.user : "");
#endif
authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
authstatus->multipass = !authstatus->done;
}
else
authstatus->multipass = FALSE;
@@ -1229,163 +1229,6 @@ static const char *get_http_string(const struct Curl_easy *data,
}
#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,
bool is_connect,
#ifndef USE_HYPER
@@ -1403,13 +1246,13 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
int i;
#ifndef CURL_DISABLE_PROXY
enum proxy_use proxy;
enum Curl_proxy_use proxy;
if(is_connect)
proxy = HEADER_CONNECT;
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) {
case HEADER_SERVER:
@@ -1602,7 +1445,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
msnprintf(datestr, sizeof(datestr),
"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
condp,
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
Curl_wkday[tm->tm_wday ? tm->tm_wday-1 : 6],
tm->tm_mday,
Curl_month[tm->tm_mon],
tm->tm_year + 1900,
@@ -1755,11 +1598,12 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
(conn->remote_port == PORT_HTTP)) )
/* if(HTTPS on port 443) OR (HTTP on port 80) then do not include
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
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);
if(!aptr->host)
@@ -1836,8 +1680,8 @@ CURLcode Curl_http_target(struct Curl_easy *data,
curl_url_cleanup(h);
/* 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);
if(result)
return (result);
@@ -1973,11 +1817,8 @@ static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq)
switch(httpreq) {
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)
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:"),
STRCONST("chunked"));
}
result = Curl_creader_set_fread(data, chunked? -1 : postsize);
result = Curl_creader_set_fread(data, chunked ? -1 : postsize);
}
return result;
@@ -2250,8 +2091,9 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
addcookies = data->set.str[STRING_COOKIE];
if(data->cookies || addcookies) {
struct Cookie *co = NULL; /* no cookies from start */
struct Curl_llist list;
int count = 0;
int rc = 1;
if(data->cookies && data->state.cookie_engine) {
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) ||
strcasecompare("localhost", host) ||
!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);
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);
}
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 */
/* 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) {
size_t add;
if(!count) {
@@ -2285,22 +2129,21 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
linecap = TRUE;
break;
}
result = Curl_dyn_addf(r, "%s%s=%s", count?"; ":"",
result = Curl_dyn_addf(r, "%s%s=%s", count ? "; " : "",
co->name, co->value);
if(result)
break;
clen += add + (count ? 2 : 0);
count++;
}
co = co->next; /* next cookie please */
}
Curl_cookie_freelist(store);
Curl_llist_destroy(&list, NULL);
}
if(addcookies && !result && !linecap) {
if(!count)
result = Curl_dyn_addn(r, STRCONST("Cookie: "));
if(!result) {
result = Curl_dyn_addf(r, "%s%s", count?"; ":"", addcookies);
result = Curl_dyn_addf(r, "%s%s", count ? "; " : "", addcookies);
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
* negotiation, but test1084 checks for it. In which case we have a
* "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.resume_from + req_clen);
data->state.aptr.rangeline =
@@ -2582,7 +2425,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
goto fail;
p_accept = Curl_checkheaders(data,
STRCONST("Accept"))?NULL:"Accept: */*\r\n";
STRCONST("Accept")) ? NULL : "Accept: */*\r\n";
result = Curl_http_range(data, httpreq);
if(result)
@@ -2634,35 +2477,34 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
"%s",/* Alt-Used */
httpstring,
(data->state.aptr.host?data->state.aptr.host:""),
(data->state.aptr.host ? data->state.aptr.host : ""),
#ifndef CURL_DISABLE_PROXY
data->state.aptr.proxyuserpwd?
data->state.aptr.proxyuserpwd:"",
data->state.aptr.proxyuserpwd ?
data->state.aptr.proxyuserpwd : "",
#else
"",
#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->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->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
(conn->bits.httpproxy &&
!conn->bits.tunnel_proxy &&
!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":"",
#else
"",
@@ -2697,7 +2539,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
}
result = Curl_http_cookies(data, conn, &req);
#ifdef USE_WEBSOCKETS
#ifndef CURL_DISABLE_WEBSOCKETS
if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS))
result = Curl_ws_request(data, &req);
#endif
@@ -2754,7 +2596,7 @@ checkhttpprefix(struct Curl_easy *data,
{
struct curl_slist *head = data->set.http200aliases;
statusline rc = STATUS_BAD;
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
statusline onmatch = len >= 5 ? STATUS_DONE : STATUS_UNKNOWN;
while(head) {
if(checkprefixmax(head->data, s, len)) {
@@ -2776,7 +2618,7 @@ checkrtspprefix(struct Curl_easy *data,
const char *s, size_t len)
{
statusline result = STATUS_BAD;
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
statusline onmatch = len >= 5 ? STATUS_DONE : STATUS_UNKNOWN;
(void)data; /* unused */
if(checkprefixmax("RTSP/", s, len))
result = onmatch;
@@ -2837,10 +2679,10 @@ CURLcode Curl_http_header(struct Curl_easy *data,
#else
0
#endif
))? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL;
)) ? HD_VAL(hd, hdlen, "Alt-Svc:") : NULL;
if(v) {
/* 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;
return Curl_altsvc_parse(data, data->asi, v, id, conn->host.name,
curlx_uitous((unsigned int)conn->remote_port));
@@ -2850,8 +2692,8 @@ CURLcode Curl_http_header(struct Curl_easy *data,
case 'c':
case 'C':
/* 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) {
curl_off_t contentlength;
CURLofft offt = curlx_strtoofft(v, NULL, 10, &contentlength);
@@ -2876,8 +2718,8 @@ CURLcode Curl_http_header(struct Curl_easy *data,
}
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) {
/*
* 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");
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) {
/* Content-Range: bytes [num]-
Content-Range: bytes: [num]-
@@ -2959,7 +2801,7 @@ CURLcode Curl_http_header(struct Curl_easy *data,
case 'l':
case 'L':
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;
if(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);
if(!persistentauth)
return CURLE_OUT_OF_MEMORY;
negdata->noauthpersist = checkprefix("false", persistentauth)?
TRUE:FALSE;
negdata->noauthpersist = !!checkprefix("false", persistentauth);
negdata->havenoauthpersist = TRUE;
infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
negdata->noauthpersist, persistentauth);
@@ -3073,18 +2914,18 @@ CURLcode Curl_http_header(struct Curl_easy *data,
case 's':
case 'S':
#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;
if(v) {
/* If there is a custom-set Host: name, use it here, or else use
* 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 =
conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
strcasecompare("localhost", host) ||
!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);
@@ -3105,7 +2946,7 @@ CURLcode Curl_http_header(struct Curl_easy *data,
0
#endif
)
)? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL;
) ? HD_VAL(hd, hdlen, "Strict-Transport-Security:") : NULL;
if(v) {
CURLcode check =
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 &&
(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) {
/* One or more encodings. We check for chunked and/or a compression
algorithm. */
@@ -3372,8 +3213,8 @@ static CURLcode http_write_header(struct Curl_easy *data,
return result;
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;
}
@@ -3449,7 +3290,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
goto out;
*pconsumed += blen;
}
#ifdef USE_WEBSOCKETS
#ifndef CURL_DISABLE_WEBSOCKETS
else if(k->upgr101 == UPGR101_WS) {
/* verify the response. Any passed `buf` bytes are already in
* WebSockets format and taken in by the protocol handler. */
@@ -3534,7 +3375,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
}
#endif
#ifdef USE_WEBSOCKETS
#ifndef CURL_DISABLE_WEBSOCKETS
/* All >=200 HTTP status codes are errors when wanting WebSockets */
if(data->req.upgr101 == UPGR101_WS) {
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;
out:
*pstatus = result? -1 : status;
*pstatus = result ? -1 : status;
return result;
}
@@ -4095,7 +3936,7 @@ CURLcode Curl_http_req_make(struct httpreq **preq,
out:
if(result && req)
Curl_http_req_free(req);
*preq = result? NULL : req;
*preq = result ? NULL : req;
return result;
}
@@ -4253,7 +4094,7 @@ CURLcode Curl_http_req_make2(struct httpreq **preq,
out:
if(result && req)
Curl_http_req_free(req);
*preq = result? NULL : req;
*preq = result ? NULL : req;
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);
}
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:
if(result && resp)
Curl_http_resp_free(resp);
*presp = result? NULL : resp;
*presp = result ? NULL : resp;
return result;
}
@@ -4479,7 +4320,7 @@ static void cr_exp100_done(struct Curl_easy *data,
struct Curl_creader *reader, int premature)
{
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;
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)
{
struct Curl_creader *r = Curl_creader_get_by_type(data, &cr_exp100);
return r? TRUE : FALSE;
return !!r;
}
#endif /* CURL_DISABLE_HTTP */
-3
View File
@@ -89,9 +89,6 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
void *headers
#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,
const char **method, Curl_HttpReq *);
+5 -5
View File
@@ -128,7 +128,7 @@ static ssize_t next_line(struct h1_req_parser *parser,
else if(*err == CURLE_AGAIN) {
/* no line end in `buf`, add it to our scratch */
*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;
}
@@ -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",
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);
if(result)
goto out;
+103 -49
View File
@@ -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)
{
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]);
Curl_safefree(stream->push_headers);
stream->push_headers_used = 0;
@@ -299,7 +299,7 @@ static CURLcode cf_h2_update_local_win(struct Curl_cfilter *cf,
int32_t dwsize;
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) {
int32_t wsize = nghttp2_session_get_stream_effective_local_window_size(
ctx->h2, stream->id);
@@ -433,6 +433,8 @@ static int h2_client_new(struct Curl_cfilter *cf,
{
struct cf_h2_ctx *ctx = cf->ctx;
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);
if(rc)
@@ -445,7 +447,7 @@ static int h2_client_new(struct Curl_cfilter *cf,
HTTP field value. */
nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
#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);
return rc;
}
@@ -498,9 +500,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
const uint8_t *value, size_t valuelen,
uint8_t flags,
void *userp);
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
static int error_callback(nghttp2_session *session, const char *msg,
size_t len, void *userp);
#endif
static CURLcode cf_h2_ctx_open(struct Curl_cfilter *cf,
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(
cbs, on_begin_headers);
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);
#endif
/* The nghttp2 session is not yet setup, do it */
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 */
result = CURLE_OK;
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:
if(cbs)
@@ -764,7 +769,7 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
}
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;
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(result == CURLE_AGAIN) {
ctx->nw_out_blocked = 1;
@@ -852,7 +860,7 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
return NULL;
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)) {
/* sub-match, make sure that it is followed by a colon */
if(stream->push_headers[i][len] != ':')
@@ -990,11 +998,11 @@ static int push_promise(struct Curl_cfilter *cf,
}
DEBUGASSERT(stream);
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
rv = data->multi->push_cb(data, newhandle,
stream->push_headers_used, &heads,
data->multi->push_userp);
Curl_set_in_callback(data, false);
Curl_set_in_callback(data, FALSE);
/* free the headers again */
free_push_headers(stream);
@@ -1113,9 +1121,6 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
return CURLE_RECV_ERROR;
}
}
if(frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
drain_stream(cf, data, stream);
}
break;
case NGHTTP2_HEADERS:
if(stream->bodystarted) {
@@ -1131,10 +1136,10 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
return CURLE_RECV_ERROR;
/* Only final status code signals the end of header */
if(stream->status_code / 100 != 1) {
if(stream->status_code / 100 != 1)
stream->bodystarted = TRUE;
else
stream->status_code = -1;
}
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:
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;
}
@@ -1235,14 +1256,14 @@ static int fr_print(const nghttp2_frame *frame, char *buffer, size_t blen)
case NGHTTP2_GOAWAY: {
char scratch[128];
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: {
return msnprintf(buffer, blen,
@@ -1350,7 +1371,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
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,
@@ -1402,8 +1423,8 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
DEBUGASSERT(call_data);
/* 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) {
CURL_TRC_CF(call_data, cf,
"[%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;
return nread;
}
return (nread == 0)? NGHTTP2_ERR_DEFERRED : nread;
return (nread == 0) ? NGHTTP2_ERR_DEFERRED : nread;
}
#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) {
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;
}
@@ -1826,14 +1847,14 @@ out:
static int sweight_wanted(const struct Curl_easy *data)
{
/* 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;
}
static int sweight_in_effect(const struct Curl_easy *data)
{
/* 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;
}
@@ -1849,7 +1870,7 @@ static void h2_pri_spec(struct cf_h2_ctx *ctx,
{
struct Curl_data_priority *prio = &data->set.priority;
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,
sweight_wanted(data),
data->set.priority.exclusive);
@@ -1895,6 +1916,11 @@ out:
nghttp2_strerror(rv), rv);
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);
}
@@ -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->rcvd_goaway && ctx->remote_max_sid < 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;
}
@@ -1978,8 +2004,8 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
}
else {
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))
@@ -2244,7 +2270,7 @@ static ssize_t h2_submit(struct h2_stream_ctx **pstream,
out:
CURL_TRC_CF(data, cf, "[%d] submit -> %zd, %d",
stream? stream->id : -1, nwritten, *err);
stream ? stream->id : -1, nwritten, *err);
Curl_safefree(nva);
*pstream = stream;
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;
CURLcode result = CURLE_OK;
struct cf_call_data save;
bool first_time = FALSE;
if(cf->connected) {
*done = TRUE;
@@ -2457,11 +2484,14 @@ static CURLcode cf_h2_connect(struct Curl_cfilter *cf,
result = cf_h2_ctx_open(cf, data);
if(result)
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
* 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_TRC_CF(data, cf, "[%d] stream now %spaused", stream->id,
pause? "" : "un");
pause ? "" : "un");
}
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)
|| (stream && !Curl_bufq_is_empty(&stream->sendbuf))))
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,
@@ -2681,12 +2711,12 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf,
else {
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);
return CURLE_OK;
case CF_QUERY_STREAM_ERROR: {
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;
}
case CF_QUERY_NEED_FLUSH: {
@@ -2701,7 +2731,7 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf,
default:
break;
}
return cf->next?
return cf->next ?
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
CURLE_UNKNOWN_OPTION;
}
@@ -2751,7 +2781,7 @@ static CURLcode http2_cfilter_add(struct Curl_cfilter **pcf,
out:
if(result)
cf_h2_ctx_free(ctx);
*pcf = result? NULL : cf;
*pcf = result ? NULL : cf;
return result;
}
@@ -2782,8 +2812,8 @@ out:
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;
for(; cf; cf = cf->next) {
@@ -2799,7 +2829,7 @@ bool Curl_conn_is_http2(const struct Curl_easy *data,
const struct connectdata *conn,
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,
@@ -2851,7 +2881,7 @@ CURLcode Curl_http2_switch_at(struct Curl_cfilter *cf, struct Curl_easy *data)
struct Curl_cfilter *cf_h2;
CURLcode result;
DEBUGASSERT(!Curl_cf_is_http2(cf, data));
DEBUGASSERT(!cf_is_http2(cf, data));
result = http2_cfilter_insert_after(cf, data, FALSE);
if(result)
@@ -2932,6 +2962,30 @@ bool Curl_h2_http_1_1_error(struct Curl_easy *data)
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 */
/* Satisfy external references even if http2 is not compiled in. */
+5
View File
@@ -60,6 +60,11 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data,
struct connectdata *conn, int sockindex,
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;
#else /* USE_NGHTTP2 */
+18 -31
View File
@@ -47,7 +47,7 @@
#define HMAC_SHA256(k, kl, d, dl, o) \
do { \
result = Curl_hmacit(Curl_HMAC_SHA256, \
result = Curl_hmacit(&Curl_HMAC_SHA256, \
(unsigned char *)k, \
kl, \
(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 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 ':' */
#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;
CURLcode ret = CURLE_OUT_OF_MEMORY;
struct curl_slist *l;
int again = 1;
bool again = TRUE;
/* provider1 mid */
Curl_strntolower(provider1, provider1, strlen(provider1));
@@ -190,31 +186,22 @@ static CURLcode make_headers(struct Curl_easy *data,
"x-%s-date:%s", provider1, timestamp);
if(!Curl_checkheaders(data, STRCONST("Host"))) {
char full_host[FULL_HOST_LEN + 1];
char *fullhost;
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' */
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;
}
}
@@ -300,7 +287,7 @@ static CURLcode make_headers(struct Curl_easy *data,
/* alpha-sort by header name in a case sensitive manner */
do {
again = 0;
again = FALSE;
for(l = head; l; l = l->next) {
struct curl_slist *next = l->next;
@@ -309,7 +296,7 @@ static CURLcode make_headers(struct Curl_easy *data,
l->data = next->data;
next->data = tmp;
again = 1;
again = TRUE;
}
}
} while(again);
@@ -507,12 +494,12 @@ static CURLcode canon_string(const char *q, size_t len,
/* allowed as-is */
if(*q == '=') {
result = Curl_dyn_addn(dq, q, 1);
*found_equals = true;
*found_equals = TRUE;
break;
}
}
/* URL encode */
out[1] = hex[((unsigned char)*q)>>4];
out[1] = hex[((unsigned char)*q) >> 4];
out[2] = hex[*q & 0xf];
result = Curl_dyn_addn(dq, out, 3);
break;
@@ -562,7 +549,7 @@ static CURLcode canon_query(struct Curl_easy *data,
ap = &array[0];
for(i = 0; !result && (i < entry); i++, ap++) {
const char *q = ap->p;
bool found_equals = false;
bool found_equals = FALSE;
if(!ap->len)
continue;
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 region[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;
time_t clock;
struct tm tm;
+2 -2
View File
@@ -516,9 +516,9 @@ static CURLcode add_last_chunk(struct Curl_easy *data,
if(result)
goto out;
Curl_set_in_callback(data, true);
Curl_set_in_callback(data, TRUE);
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) {
failf(data, "operation aborted by trailing headers callback");
+2 -2
View File
@@ -121,9 +121,9 @@ CURLcode Curl_output_digest(struct Curl_easy *data,
passwdp = "";
#if defined(USE_WINDOWS_SSPI)
have_chlg = digest->input_token ? TRUE : FALSE;
have_chlg = !!digest->input_token;
#else
have_chlg = digest->nonce ? TRUE : FALSE;
have_chlg = !!digest->nonce;
#endif
if(!have_chlg) {
+3 -3
View File
@@ -108,9 +108,9 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
neg_ctx->sslContext = conn->sslContext;
#endif
/* 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) {
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(
data, FIRSTSOCKET, &neg_ctx->channel_binding_data);
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,
host, header, neg_ctx);
#ifdef HAVE_GSSAPI
#if defined(USE_SSL) && defined(HAVE_GSSAPI)
Curl_dyn_free(&neg_ctx->channel_binding_data);
#endif
+148 -5
View File
@@ -45,12 +45,155 @@
#include "vtls/vtls.h"
#include "transfer.h"
#include "multiif.h"
#include "vauth/vauth.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.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,
const char **phostname,
@@ -97,8 +240,8 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
if(result)
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) {
result = CURLE_OUT_OF_MEMORY;
goto out;
@@ -146,7 +289,7 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
goto out;
}
result = Curl_dynhds_add_custom(data, TRUE, &req->headers);
result = dynhds_add_custom(data, TRUE, &req->headers);
out:
if(result && req) {
@@ -185,7 +328,7 @@ connect_sub:
*done = FALSE;
if(!ctx->cf_protocol) {
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;
/* First time call after the subchain connected */
@@ -195,7 +338,7 @@ connect_sub:
case CURL_HTTP_VERSION_1_1:
CURL_TRC_CF(data, cf, "installing subfilter for HTTP/1.1");
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);
if(result)
goto out;
+6
View File
@@ -30,6 +30,12 @@
#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,
const char **phostname,
int *pport, bool *pipv6_ip);
+13 -13
View File
@@ -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 */
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 */
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 : "");
else {
/* 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("");
if(!mailbox)
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 */
mailbox = imap_atom(imap->mailbox, false);
mailbox = imap_atom(imap->mailbox, FALSE);
if(!mailbox)
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 */
mailbox = imap_atom(imap->mailbox, false);
mailbox = imap_atom(imap->mailbox, FALSE);
if(!mailbox)
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);
*done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
*done = (imapc->state == IMAP_STOP);
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
arithmetic */
if(ISALNUM(ch))
return true;
return TRUE;
switch(ch) {
/* bchar */
@@ -1873,10 +1873,10 @@ static bool imap_is_bchar(char ch)
case '+': case ',':
/* bchar -> achar -> uchar -> pct-encoded */
case '%': /* HEXDIG chars are already included above */
return true;
return TRUE;
default:
return false;
return FALSE;
}
}
@@ -1891,7 +1891,7 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
const char *ptr = conn->options;
bool prefer_login = false;
bool prefer_login = FALSE;
while(!result && ptr && *ptr) {
const char *key = ptr;
@@ -1907,16 +1907,16 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
if(strncasecompare(key, "AUTH=+LOGIN", 11)) {
/* User prefers plaintext LOGIN over any SASL, including SASL LOGIN */
prefer_login = true;
prefer_login = TRUE;
imapc->sasl.prefmech = SASL_AUTH_NONE;
}
else if(strncasecompare(key, "AUTH=", 5)) {
prefer_login = false;
prefer_login = FALSE;
result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
value, ptr - value);
}
else {
prefer_login = false;
prefer_login = FALSE;
result = CURLE_URL_MALFORMAT;
}
+25 -25
View File
@@ -202,14 +202,15 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
data->set.str[STRING_SERVICE_NAME] :
"ftp";
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;
gss_name_t gssname;
gss_ctx_id_t *context = app_data;
struct gss_channel_bindings_struct chan;
size_t base64_sz = 0;
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;
if(getsockname(conn->sock[FIRSTSOCKET],
@@ -363,7 +364,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
free(_gssresp.value);
if(ret == AUTH_OK || service == srv_host)
return ret;
break;
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)
{
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 = {
@@ -612,10 +613,10 @@ static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
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,
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 */
char *buffer = NULL;
@@ -623,7 +624,7 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
size_t cmd_size = 0;
CURLcode error;
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);
@@ -649,27 +650,27 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
static const char *enc = "ENC ";
static const char *mic = "MIC ";
if(prot_level == PROT_PRIVATE)
socket_write(data, fd, enc, 4);
socket_write(data, sockindex, enc, 4);
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);
free(cmd_buffer);
}
}
else {
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);
}
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;
@@ -679,7 +680,7 @@ static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
if(length < (size_t)len)
len = length;
do_sec_send(data, conn, fd, buffer, curlx_sztosi(len));
do_sec_send(data, conn, sockindex, buffer, curlx_sztosi(len));
length -= len;
buffer += len;
tx += len;
@@ -693,10 +694,9 @@ static ssize_t sec_send(struct Curl_easy *data, int sockindex,
CURLcode *err)
{
struct connectdata *conn = data->conn;
curl_socket_t fd = conn->sock[sockindex];
(void)eos; /* unused */
*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,
Loaded 100 of 196 files, more files were not shown because too many files have changed in this diff. Show more