mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-10-07 04:02:23 +03:00
curl 2026-01-07 (2eebc58c)
Code extracted from:
https://github.com/curl/curl.git
at commit 2eebc58c4b8d68c98c8344381a9f6df4cca838fd (curl-8_18_0).
This commit is contained in:
1 parent
e28c33c159
commit
7bd7b7fa2e
387 files changed
+15080
-17306
No files matched your search
@@ -1,24 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
@CMAKE_CONFIGURABLE_FILE_CONTENT@
|
||||
@@ -29,7 +29,7 @@ if(WIN32 AND (ENABLE_DEBUG OR ENABLE_CURLDEBUG))
|
||||
# e.g. curl_easy_perform_ev() or curl_dbg_*(),
|
||||
# so disable symbol hiding for debug builds and for memory tracking.
|
||||
set(CURL_HIDDEN_SYMBOLS OFF)
|
||||
elseif(DOS OR AMIGA OR MINGW32CE)
|
||||
elseif(DOS OR AMIGA)
|
||||
set(CURL_HIDDEN_SYMBOLS OFF)
|
||||
endif()
|
||||
|
||||
|
||||
+14
-5
@@ -29,7 +29,7 @@
|
||||
#include <fcntl.h>
|
||||
/* */
|
||||
#if defined(sun) || defined(__sun__) || \
|
||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
# if defined(__SVR4) || defined(__srv4__)
|
||||
# define PLATFORM_SOLARIS
|
||||
# else
|
||||
@@ -119,7 +119,10 @@ int main(void)
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
int main(void) { return 0; }
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FILE_OFFSET_BITS
|
||||
@@ -128,7 +131,7 @@ int main(void) { return 0; }
|
||||
We cannot simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T (((off_t)1 << 62) - 1 + ((off_t)1 << 62))
|
||||
static int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 &&
|
||||
LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -272,7 +275,10 @@ int main(void)
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
static void check(char c) { (void)c; }
|
||||
static void check(char c)
|
||||
{
|
||||
(void)c;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -289,7 +295,10 @@ int main(void)
|
||||
#include <errno.h>
|
||||
|
||||
/* Float, because a pointer cannot be implicitly cast to float */
|
||||
static void check(float f) { (void)f; }
|
||||
static void check(float f)
|
||||
{
|
||||
(void)f;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
+26
-14
@@ -29,31 +29,27 @@
|
||||
# - `BROTLICOMMON_LIBRARY`: Absolute path to `brotlicommon` library.
|
||||
# - `BROTLIDEC_LIBRARY`: Absolute path to `brotlidec` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `BROTLI_FOUND`: System has brotli.
|
||||
# - `BROTLI_INCLUDE_DIRS`: The brotli include directories.
|
||||
# - `BROTLI_LIBRARIES`: The brotli library names.
|
||||
# - `BROTLI_LIBRARY_DIRS`: The brotli library directories.
|
||||
# - `BROTLI_PC_REQUIRES`: The brotli pkg-config packages.
|
||||
# - `BROTLI_CFLAGS`: Required compiler flags.
|
||||
# - `BROTLI_VERSION`: Version of brotli.
|
||||
# - `CURL::brotli`: brotli library target.
|
||||
|
||||
set(BROTLI_PC_REQUIRES "libbrotlidec" "libbrotlicommon") # order is significant: brotlidec then brotlicommon
|
||||
set(_brotli_pc_requires "libbrotlidec" "libbrotlicommon") # order is significant: brotlidec then brotlicommon
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED BROTLI_INCLUDE_DIR AND
|
||||
NOT DEFINED BROTLICOMMON_LIBRARY AND
|
||||
NOT DEFINED BROTLIDEC_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(BROTLI ${BROTLI_PC_REQUIRES})
|
||||
pkg_check_modules(_brotli ${_brotli_pc_requires})
|
||||
endif()
|
||||
|
||||
if(BROTLI_FOUND)
|
||||
if(_brotli_FOUND)
|
||||
set(Brotli_FOUND TRUE)
|
||||
set(BROTLI_VERSION ${BROTLI_libbrotlicommon_VERSION})
|
||||
string(REPLACE ";" " " BROTLI_CFLAGS "${BROTLI_CFLAGS}")
|
||||
message(STATUS "Found Brotli (via pkg-config): ${BROTLI_INCLUDE_DIRS} (found version \"${BROTLI_VERSION}\")")
|
||||
set(BROTLI_FOUND TRUE)
|
||||
set(BROTLI_VERSION ${_brotli_libbrotlicommon_VERSION})
|
||||
message(STATUS "Found Brotli (via pkg-config): ${_brotli_INCLUDE_DIRS} (found version \"${BROTLI_VERSION}\")")
|
||||
else()
|
||||
find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
|
||||
find_library(BROTLICOMMON_LIBRARY NAMES "brotlicommon")
|
||||
@@ -68,9 +64,25 @@ else()
|
||||
)
|
||||
|
||||
if(BROTLI_FOUND)
|
||||
set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
|
||||
set(BROTLI_LIBRARIES ${BROTLIDEC_LIBRARY} ${BROTLICOMMON_LIBRARY})
|
||||
set(_brotli_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
|
||||
set(_brotli_LIBRARIES ${BROTLIDEC_LIBRARY} ${BROTLICOMMON_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(BROTLI_INCLUDE_DIR BROTLIDEC_LIBRARY BROTLICOMMON_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(BROTLI_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_brotli_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::brotli)
|
||||
add_library(CURL::brotli INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::brotli PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_brotli_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_brotli_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_brotli_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_brotli_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_brotli_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+32
-19
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `CARES_INCLUDE_DIR`: Absolute path to c-ares include directory.
|
||||
# - `CARES_LIBRARY`: Absolute path to `cares` library.
|
||||
# - `CARES_INCLUDE_DIR`: Absolute path to c-ares include directory.
|
||||
# - `CARES_LIBRARY`: Absolute path to `cares` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `CARES_FOUND`: System has c-ares.
|
||||
# - `CARES_INCLUDE_DIRS`: The c-ares include directories.
|
||||
# - `CARES_LIBRARIES`: The c-ares library names.
|
||||
# - `CARES_LIBRARY_DIRS`: The c-ares library directories.
|
||||
# - `CARES_PC_REQUIRES`: The c-ares pkg-config packages.
|
||||
# - `CARES_CFLAGS`: Required compiler flags.
|
||||
# - `CARES_VERSION`: Version of c-ares.
|
||||
# - `CARES_FOUND`: System has c-ares.
|
||||
# - `CARES_VERSION`: Version of c-ares.
|
||||
# - `CURL::cares`: c-ares library target.
|
||||
|
||||
set(CARES_PC_REQUIRES "libcares")
|
||||
set(_cares_pc_requires "libcares")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED CARES_INCLUDE_DIR AND
|
||||
NOT DEFINED CARES_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(CARES ${CARES_PC_REQUIRES})
|
||||
pkg_check_modules(_cares ${_cares_pc_requires})
|
||||
endif()
|
||||
|
||||
if(CARES_FOUND)
|
||||
if(_cares_FOUND)
|
||||
set(Cares_FOUND TRUE)
|
||||
string(REPLACE ";" " " CARES_CFLAGS "${CARES_CFLAGS}")
|
||||
message(STATUS "Found Cares (via pkg-config): ${CARES_INCLUDE_DIRS} (found version \"${CARES_VERSION}\")")
|
||||
set(CARES_FOUND TRUE)
|
||||
set(CARES_VERSION ${_cares_VERSION})
|
||||
message(STATUS "Found Cares (via pkg-config): ${_cares_INCLUDE_DIRS} (found version \"${CARES_VERSION}\")")
|
||||
else()
|
||||
find_path(CARES_INCLUDE_DIR NAMES "ares.h")
|
||||
find_library(CARES_LIBRARY NAMES ${CARES_NAMES} "cares")
|
||||
@@ -85,13 +82,29 @@ else()
|
||||
)
|
||||
|
||||
if(CARES_FOUND)
|
||||
set(CARES_INCLUDE_DIRS ${CARES_INCLUDE_DIR})
|
||||
set(CARES_LIBRARIES ${CARES_LIBRARY})
|
||||
set(_cares_INCLUDE_DIRS ${CARES_INCLUDE_DIR})
|
||||
set(_cares_LIBRARIES ${CARES_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(CARES_INCLUDE_DIR CARES_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(CARES_FOUND AND WIN32)
|
||||
list(APPEND CARES_LIBRARIES "iphlpapi") # for if_indextoname and others
|
||||
if(CARES_FOUND)
|
||||
if(WIN32)
|
||||
list(APPEND _cares_LIBRARIES "iphlpapi") # for if_indextoname and others
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_cares_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::cares)
|
||||
add_library(CURL::cares INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::cares PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_cares_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_cares_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_cares_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_cares_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_cares_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+40
-33
@@ -25,19 +25,15 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `GSS_ROOT_DIR`: Absolute path to the root installation of GSS. (also supported as environment)
|
||||
# - `GSS_ROOT_DIR`: Absolute path to the root installation of GSS. (also supported as environment)
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `GSS_FOUND`: System has a GSS library.
|
||||
# - `GSS_FLAVOUR`: "GNU" or "MIT" 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"
|
||||
# - `GSS_FOUND`: System has a GSS library.
|
||||
# - `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"
|
||||
# - `CURL::gss`: GSS library target.
|
||||
# - CURL_GSS_FLAVOUR`: Custom property. "GNU" or "MIT" if detected.
|
||||
|
||||
set(_gnu_modname "gss")
|
||||
set(_mit_modname "mit-krb5-gssapi")
|
||||
@@ -140,7 +136,7 @@ if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
|
||||
# Older versions may not have the "--vendor" parameter. In this case we just do not care.
|
||||
if(NOT _gss_configure_failed AND NOT _gss_vendor MATCHES "Heimdal|heimdal")
|
||||
set(GSS_FLAVOUR "MIT") # assume a default, should not really matter
|
||||
set(_gss_flavour "MIT") # assume a default, should not really matter
|
||||
endif()
|
||||
|
||||
else() # Either there is no config script or we are on a platform that does not provide one (Windows?)
|
||||
@@ -156,7 +152,7 @@ if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(_gss_have_mit_headers)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
set(_gss_flavour "MIT")
|
||||
if(WIN32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND _gss_libdir_suffixes "lib/AMD64")
|
||||
@@ -174,14 +170,14 @@ if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
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 ${_gnu_modname})
|
||||
set(_gss_flavour "GNU")
|
||||
set(_gss_pc_requires ${_gnu_modname})
|
||||
set(_gss_libname "gss")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If we have headers, look up libraries
|
||||
if(GSS_FLAVOUR)
|
||||
if(_gss_flavour)
|
||||
set(_gss_libdir_hints ${_gss_root_hints})
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(GET _gss_INCLUDE_DIRS PARENT_PATH _gss_calculated_potential_root)
|
||||
@@ -193,34 +189,28 @@ if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
find_library(_gss_LIBRARIES NAMES ${_gss_libname} HINTS ${_gss_libdir_hints} PATH_SUFFIXES ${_gss_libdir_suffixes})
|
||||
endif()
|
||||
endif()
|
||||
if(NOT GSS_FLAVOUR)
|
||||
if(NOT _gss_flavour)
|
||||
message(FATAL_ERROR "GNU or MIT GSS is required")
|
||||
endif()
|
||||
else()
|
||||
# _gss_MODULE_NAME set since CMake 3.16.
|
||||
# _pkg_check_modules_pkg_name is undocumented and used as a fallback for CMake <3.16 versions.
|
||||
if(_gss_MODULE_NAME STREQUAL _gnu_modname OR _pkg_check_modules_pkg_name STREQUAL _gnu_modname)
|
||||
set(GSS_FLAVOUR "GNU")
|
||||
set(GSS_PC_REQUIRES ${_gnu_modname})
|
||||
set(_gss_flavour "GNU")
|
||||
set(_gss_pc_requires ${_gnu_modname})
|
||||
elseif(_gss_MODULE_NAME STREQUAL _mit_modname OR _pkg_check_modules_pkg_name STREQUAL _mit_modname)
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
set(GSS_PC_REQUIRES ${_mit_modname})
|
||||
set(_gss_flavour "MIT")
|
||||
set(_gss_pc_requires ${_mit_modname})
|
||||
else()
|
||||
message(FATAL_ERROR "GNU or MIT GSS is required")
|
||||
endif()
|
||||
message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_gss_INCLUDE_DIRS} (found version \"${_gss_version}\")")
|
||||
message(STATUS "Found GSS/${_gss_flavour} (via pkg-config): ${_gss_INCLUDE_DIRS} (found version \"${_gss_version}\")")
|
||||
endif()
|
||||
|
||||
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_CFLAGS ${_gss_CFLAGS})
|
||||
set(GSS_VERSION ${_gss_version})
|
||||
|
||||
if(NOT GSS_VERSION)
|
||||
if(GSS_FLAVOUR STREQUAL "MIT")
|
||||
if(_gss_flavour STREQUAL "MIT")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
|
||||
cmake_host_system_information(RESULT _mit_version QUERY WINDOWS_REGISTRY
|
||||
"HKLM/SOFTWARE/MIT/Kerberos/SDK/CurrentVersion" VALUE "VersionString")
|
||||
@@ -234,9 +224,9 @@ if(NOT GSS_VERSION)
|
||||
set(GSS_VERSION "MIT Unknown")
|
||||
endif()
|
||||
else() # GNU
|
||||
if(GSS_INCLUDE_DIRS AND EXISTS "${GSS_INCLUDE_DIRS}/gss.h")
|
||||
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}")
|
||||
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)
|
||||
@@ -248,8 +238,8 @@ endif()
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(GSS
|
||||
REQUIRED_VARS
|
||||
GSS_FLAVOUR
|
||||
GSS_LIBRARIES
|
||||
_gss_flavour
|
||||
_gss_LIBRARIES
|
||||
VERSION_VAR
|
||||
GSS_VERSION
|
||||
FAIL_MESSAGE
|
||||
@@ -266,3 +256,20 @@ mark_as_advanced(
|
||||
_gss_PREFIX
|
||||
_gss_version
|
||||
)
|
||||
|
||||
if(GSS_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_gss_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::gss)
|
||||
add_library(CURL::gss INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::gss PROPERTIES
|
||||
INTERFACE_CURL_GSS_FLAVOUR "${_gss_flavour}"
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_gss_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_gss_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_gss_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_gss_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_gss_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `GNUTLS_INCLUDE_DIR`: Absolute path to GnuTLS include directory.
|
||||
# - `GNUTLS_LIBRARY`: Absolute path to `gnutls` library.
|
||||
# - `GNUTLS_INCLUDE_DIR`: Absolute path to GnuTLS include directory.
|
||||
# - `GNUTLS_LIBRARY`: Absolute path to `gnutls` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `GNUTLS_FOUND`: System has GnuTLS.
|
||||
# - `GNUTLS_INCLUDE_DIRS`: The GnuTLS include directories.
|
||||
# - `GNUTLS_LIBRARIES`: The GnuTLS library names.
|
||||
# - `GNUTLS_LIBRARY_DIRS`: The GnuTLS library directories.
|
||||
# - `GNUTLS_PC_REQUIRES`: The GnuTLS pkg-config packages.
|
||||
# - `GNUTLS_CFLAGS`: Required compiler flags.
|
||||
# - `GNUTLS_VERSION`: Version of GnuTLS.
|
||||
# - `GNUTLS_FOUND`: System has GnuTLS.
|
||||
# - `GNUTLS_VERSION`: Version of GnuTLS.
|
||||
# - `CURL::gnutls`: GnuTLS library target.
|
||||
|
||||
set(GNUTLS_PC_REQUIRES "gnutls")
|
||||
set(_gnutls_pc_requires "gnutls")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED GNUTLS_INCLUDE_DIR AND
|
||||
NOT DEFINED GNUTLS_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(GNUTLS ${GNUTLS_PC_REQUIRES})
|
||||
pkg_check_modules(_gnutls ${_gnutls_pc_requires})
|
||||
endif()
|
||||
|
||||
if(GNUTLS_FOUND)
|
||||
if(_gnutls_FOUND)
|
||||
set(GnuTLS_FOUND TRUE)
|
||||
string(REPLACE ";" " " GNUTLS_CFLAGS "${GNUTLS_CFLAGS}")
|
||||
message(STATUS "Found GnuTLS (via pkg-config): ${GNUTLS_INCLUDE_DIRS} (found version \"${GNUTLS_VERSION}\")")
|
||||
set(GNUTLS_FOUND TRUE)
|
||||
set(GNUTLS_VERSION ${_gnutls_VERSION})
|
||||
message(STATUS "Found GnuTLS (via pkg-config): ${_gnutls_INCLUDE_DIRS} (found version \"${GNUTLS_VERSION}\")")
|
||||
else()
|
||||
find_path(GNUTLS_INCLUDE_DIR NAMES "gnutls/gnutls.h")
|
||||
find_library(GNUTLS_LIBRARY NAMES "gnutls" "libgnutls")
|
||||
@@ -75,9 +72,25 @@ else()
|
||||
)
|
||||
|
||||
if(GNUTLS_FOUND)
|
||||
set(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
|
||||
set(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY})
|
||||
set(_gnutls_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
|
||||
set(_gnutls_LIBRARIES ${GNUTLS_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(GNUTLS_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_gnutls_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::gnutls)
|
||||
add_library(CURL::gnutls INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::gnutls PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_gnutls_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_gnutls_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_gnutls_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_gnutls_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_gnutls_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+27
-15
@@ -29,32 +29,28 @@
|
||||
# - `LDAP_LIBRARY`: Absolute path to `ldap` library.
|
||||
# - `LDAP_LBER_LIBRARY`: Absolute path to `lber` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `LDAP_FOUND`: System has ldap.
|
||||
# - `LDAP_INCLUDE_DIRS`: The ldap include directories.
|
||||
# - `LDAP_LIBRARIES`: The ldap library names.
|
||||
# - `LDAP_LIBRARY_DIRS`: The ldap library directories.
|
||||
# - `LDAP_PC_REQUIRES`: The ldap pkg-config packages.
|
||||
# - `LDAP_CFLAGS`: Required compiler flags.
|
||||
# - `LDAP_VERSION`: Version of ldap.
|
||||
# - `CURL::ldap`: ldap library target.
|
||||
|
||||
set(LDAP_PC_REQUIRES "ldap" "lber")
|
||||
set(_ldap_pc_requires "ldap" "lber")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LDAP_INCLUDE_DIR AND
|
||||
NOT DEFINED LDAP_LIBRARY AND
|
||||
NOT DEFINED LDAP_LBER_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LDAP ${LDAP_PC_REQUIRES})
|
||||
pkg_check_modules(_ldap ${_ldap_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LDAP_FOUND)
|
||||
set(LDAP_VERSION ${LDAP_ldap_VERSION})
|
||||
string(REPLACE ";" " " LDAP_CFLAGS "${LDAP_CFLAGS}")
|
||||
message(STATUS "Found LDAP (via pkg-config): ${LDAP_INCLUDE_DIRS} (found version \"${LDAP_VERSION}\")")
|
||||
if(_ldap_FOUND)
|
||||
set(LDAP_FOUND TRUE)
|
||||
set(LDAP_VERSION ${_ldap_ldap_VERSION})
|
||||
message(STATUS "Found LDAP (via pkg-config): ${_ldap_INCLUDE_DIRS} (found version \"${LDAP_VERSION}\")")
|
||||
else()
|
||||
set(LDAP_PC_REQUIRES "") # Depend on pkg-config only when found via pkg-config
|
||||
set(_ldap_pc_requires "") # Depend on pkg-config only when found via pkg-config
|
||||
|
||||
# On Apple the SDK LDAP gets picked up from
|
||||
# 'MacOSX.sdk/System/Library/Frameworks/LDAP.framework/Headers', which contains
|
||||
@@ -99,9 +95,25 @@ else()
|
||||
)
|
||||
|
||||
if(LDAP_FOUND)
|
||||
set(LDAP_INCLUDE_DIRS ${LDAP_INCLUDE_DIR})
|
||||
set(LDAP_LIBRARIES ${LDAP_LIBRARY} ${LDAP_LBER_LIBRARY})
|
||||
set(_ldap_INCLUDE_DIRS ${LDAP_INCLUDE_DIR})
|
||||
set(_ldap_LIBRARIES ${LDAP_LIBRARY} ${LDAP_LBER_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LDAP_INCLUDE_DIR LDAP_LIBRARY LDAP_LBER_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LDAP_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_ldap_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::ldap)
|
||||
add_library(CURL::ldap INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::ldap PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_ldap_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_ldap_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_ldap_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_ldap_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_ldap_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,65 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
# Find the libbacktrace library
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBBACKTRACE_INCLUDE_DIR`: Absolute path to libbacktrace include directory.
|
||||
# - `LIBBACKTRACE_LIBRARY`: Absolute path to `libbacktrace` library.
|
||||
#
|
||||
# Defines:
|
||||
#
|
||||
# - `LIBBACKTRACE_FOUND`: System has libbacktrace.
|
||||
# - `CURL::libbacktrace`: libbacktrace library target.
|
||||
|
||||
find_path(LIBBACKTRACE_INCLUDE_DIR NAMES "backtrace.h")
|
||||
find_library(LIBBACKTRACE_LIBRARY NAMES "backtrace" "libbacktrace")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libbacktrace
|
||||
REQUIRED_VARS
|
||||
LIBBACKTRACE_INCLUDE_DIR
|
||||
LIBBACKTRACE_LIBRARY
|
||||
)
|
||||
|
||||
if(LIBBACKTRACE_FOUND)
|
||||
set(_libbacktrace_INCLUDE_DIRS ${LIBBACKTRACE_INCLUDE_DIR})
|
||||
set(_libbacktrace_LIBRARIES ${LIBBACKTRACE_LIBRARY})
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libbacktrace_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libbacktrace)
|
||||
add_library(CURL::libbacktrace INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libbacktrace PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libbacktrace_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libbacktrace_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libbacktrace_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libbacktrace_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libbacktrace_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBBACKTRACE_INCLUDE_DIR LIBBACKTRACE_LIBRARY)
|
||||
+29
-17
@@ -25,32 +25,28 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBGSASL_INCLUDE_DIR`: Absolute path to libgsasl include directory.
|
||||
# - `LIBGSASL_LIBRARY`: Absolute path to `libgsasl` library.
|
||||
# - `LIBGSASL_INCLUDE_DIR`: Absolute path to libgsasl include directory.
|
||||
# - `LIBGSASL_LIBRARY`: Absolute path to `libgsasl` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The libgsasl pkg-config packages.
|
||||
# - `LIBGSASL_CFLAGS`: Required compiler flags.
|
||||
# - `LIBGSASL_VERSION`: Version of libgsasl.
|
||||
# - `LIBGSASL_FOUND`: System has libgsasl.
|
||||
# - `LIBGSASL_VERSION`: Version of libgsasl.
|
||||
# - `CURL::libgsasl`: libgsasl library target.
|
||||
|
||||
set(LIBGSASL_PC_REQUIRES "libgsasl")
|
||||
set(_libgsasl_pc_requires "libgsasl")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBGSASL_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBGSASL_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBGSASL ${LIBGSASL_PC_REQUIRES})
|
||||
pkg_check_modules(_libgsasl ${_libgsasl_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBGSASL_FOUND)
|
||||
if(_libgsasl_FOUND)
|
||||
set(Libgsasl_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBGSASL_CFLAGS "${LIBGSASL_CFLAGS}")
|
||||
message(STATUS "Found Libgsasl (via pkg-config): ${LIBGSASL_INCLUDE_DIRS} (found version \"${LIBGSASL_VERSION}\")")
|
||||
set(LIBGSASL_FOUND TRUE)
|
||||
message(STATUS "Found Libgsasl (via pkg-config): ${_libgsasl_INCLUDE_DIRS} (found version \"${LIBGSASL_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBGSASL_INCLUDE_DIR NAMES "gsasl.h")
|
||||
find_library(LIBGSASL_LIBRARY NAMES "gsasl" "libgsasl")
|
||||
@@ -75,9 +71,25 @@ else()
|
||||
)
|
||||
|
||||
if(LIBGSASL_FOUND)
|
||||
set(LIBGSASL_INCLUDE_DIRS ${LIBGSASL_INCLUDE_DIR})
|
||||
set(LIBGSASL_LIBRARIES ${LIBGSASL_LIBRARY})
|
||||
set(_libgsasl_INCLUDE_DIRS ${LIBGSASL_INCLUDE_DIR})
|
||||
set(_libgsasl_LIBRARIES ${LIBGSASL_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBGSASL_INCLUDE_DIR LIBGSASL_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LIBGSASL_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libgsasl_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libgsasl)
|
||||
add_library(CURL::libgsasl INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libgsasl PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libgsasl_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libgsasl_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libgsasl_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libgsasl_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libgsasl_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBIDN2_INCLUDE_DIR`: Absolute path to libidn2 include directory.
|
||||
# - `LIBIDN2_LIBRARY`: Absolute path to `libidn2` library.
|
||||
# - `LIBIDN2_INCLUDE_DIR`: Absolute path to libidn2 include directory.
|
||||
# - `LIBIDN2_LIBRARY`: Absolute path to `libidn2` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The libidn2 pkg-config packages.
|
||||
# - `LIBIDN2_CFLAGS`: Required compiler flags.
|
||||
# - `LIBIDN2_VERSION`: Version of libidn2.
|
||||
# - `LIBIDN2_FOUND`: System has libidn2.
|
||||
# - `LIBIDN2_VERSION`: Version of libidn2.
|
||||
# - `CURL::libidn2`: libidn2 library target.
|
||||
|
||||
set(LIBIDN2_PC_REQUIRES "libidn2")
|
||||
set(_libidn2_pc_requires "libidn2")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBIDN2_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBIDN2_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBIDN2 ${LIBIDN2_PC_REQUIRES})
|
||||
pkg_check_modules(_libidn2 ${_libidn2_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBIDN2_FOUND)
|
||||
if(_libidn2_FOUND)
|
||||
set(Libidn2_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBIDN2_CFLAGS "${LIBIDN2_CFLAGS}")
|
||||
message(STATUS "Found Libidn2 (via pkg-config): ${LIBIDN2_INCLUDE_DIRS} (found version \"${LIBIDN2_VERSION}\")")
|
||||
set(LIBIDN2_FOUND TRUE)
|
||||
set(LIBIDN2_VERSION ${_libidn2_VERSION})
|
||||
message(STATUS "Found Libidn2 (via pkg-config): ${_libidn2_INCLUDE_DIRS} (found version \"${LIBIDN2_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBIDN2_INCLUDE_DIR NAMES "idn2.h")
|
||||
find_library(LIBIDN2_LIBRARY NAMES "idn2" "libidn2")
|
||||
@@ -75,9 +72,25 @@ else()
|
||||
)
|
||||
|
||||
if(LIBIDN2_FOUND)
|
||||
set(LIBIDN2_INCLUDE_DIRS ${LIBIDN2_INCLUDE_DIR})
|
||||
set(LIBIDN2_LIBRARIES ${LIBIDN2_LIBRARY})
|
||||
set(_libidn2_INCLUDE_DIRS ${LIBIDN2_INCLUDE_DIR})
|
||||
set(_libidn2_LIBRARIES ${LIBIDN2_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBIDN2_INCLUDE_DIR LIBIDN2_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LIBIDN2_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libidn2_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libidn2)
|
||||
add_library(CURL::libidn2 INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libidn2 PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libidn2_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libidn2_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libidn2_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libidn2_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libidn2_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBPSL_INCLUDE_DIR`: Absolute path to libpsl include directory.
|
||||
# - `LIBPSL_LIBRARY`: Absolute path to `libpsl` library.
|
||||
# - `LIBPSL_INCLUDE_DIR`: Absolute path to libpsl include directory.
|
||||
# - `LIBPSL_LIBRARY`: Absolute path to `libpsl` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `LIBPSL_FOUND`: System has libpsl.
|
||||
# - `LIBPSL_INCLUDE_DIRS`: The libpsl include directories.
|
||||
# - `LIBPSL_LIBRARIES`: The libpsl library names.
|
||||
# - `LIBPSL_LIBRARY_DIRS`: The libpsl library directories.
|
||||
# - `LIBPSL_PC_REQUIRES`: The libpsl pkg-config packages.
|
||||
# - `LIBPSL_CFLAGS`: Required compiler flags.
|
||||
# - `LIBPSL_VERSION`: Version of libpsl.
|
||||
# - `LIBPSL_FOUND`: System has libpsl.
|
||||
# - `LIBPSL_VERSION`: Version of libpsl.
|
||||
# - `CURL::libpsl`: libpsl library target.
|
||||
|
||||
set(LIBPSL_PC_REQUIRES "libpsl")
|
||||
set(_libpsl_pc_requires "libpsl")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBPSL_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBPSL_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBPSL ${LIBPSL_PC_REQUIRES})
|
||||
pkg_check_modules(_libpsl ${_libpsl_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBPSL_FOUND AND LIBPSL_INCLUDE_DIRS)
|
||||
if(_libpsl_FOUND AND _libpsl_INCLUDE_DIRS)
|
||||
set(Libpsl_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBPSL_CFLAGS "${LIBPSL_CFLAGS}")
|
||||
message(STATUS "Found Libpsl (via pkg-config): ${LIBPSL_INCLUDE_DIRS} (found version \"${LIBPSL_VERSION}\")")
|
||||
set(LIBPSL_FOUND TRUE)
|
||||
set(LIBPSL_VERSION ${_libpsl_VERSION})
|
||||
message(STATUS "Found Libpsl (via pkg-config): ${_libpsl_INCLUDE_DIRS} (found version \"${LIBPSL_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBPSL_INCLUDE_DIR NAMES "libpsl.h")
|
||||
find_library(LIBPSL_LIBRARY NAMES "psl" "libpsl")
|
||||
@@ -75,9 +72,25 @@ else()
|
||||
)
|
||||
|
||||
if(LIBPSL_FOUND)
|
||||
set(LIBPSL_INCLUDE_DIRS ${LIBPSL_INCLUDE_DIR})
|
||||
set(LIBPSL_LIBRARIES ${LIBPSL_LIBRARY})
|
||||
set(_libpsl_INCLUDE_DIRS ${LIBPSL_INCLUDE_DIR})
|
||||
set(_libpsl_LIBRARIES ${LIBPSL_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LIBPSL_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libpsl_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libpsl)
|
||||
add_library(CURL::libpsl INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libpsl PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libpsl_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libpsl_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libpsl_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libpsl_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libpsl_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+34
-21
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBRTMP_INCLUDE_DIR`: Absolute path to librtmp include directory.
|
||||
# - `LIBRTMP_LIBRARY`: Absolute path to `librtmp` library.
|
||||
# - `LIBRTMP_INCLUDE_DIR`: Absolute path to librtmp include directory.
|
||||
# - `LIBRTMP_LIBRARY`: Absolute path to `librtmp` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `LIBRTMP_FOUND`: System has librtmp.
|
||||
# - `LIBRTMP_INCLUDE_DIRS`: The librtmp include directories.
|
||||
# - `LIBRTMP_LIBRARIES`: The librtmp library names.
|
||||
# - `LIBRTMP_LIBRARY_DIRS`: The librtmp library directories.
|
||||
# - `LIBRTMP_PC_REQUIRES`: The librtmp pkg-config packages.
|
||||
# - `LIBRTMP_CFLAGS`: Required compiler flags.
|
||||
# - `LIBRTMP_VERSION`: Version of librtmp.
|
||||
# - `LIBRTMP_FOUND`: System has librtmp.
|
||||
# - `LIBRTMP_VERSION`: Version of librtmp.
|
||||
# - `CURL::librtmp`: librtmp library target.
|
||||
|
||||
set(LIBRTMP_PC_REQUIRES "librtmp")
|
||||
set(_librtmp_pc_requires "librtmp")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBRTMP_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBRTMP_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBRTMP ${LIBRTMP_PC_REQUIRES})
|
||||
pkg_check_modules(_librtmp ${_librtmp_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBRTMP_FOUND AND LIBRTMP_INCLUDE_DIRS)
|
||||
if(_librtmp_FOUND AND _librtmp_INCLUDE_DIRS)
|
||||
set(Librtmp_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBRTMP_CFLAGS "${LIBRTMP_CFLAGS}")
|
||||
message(STATUS "Found Librtmp (via pkg-config): ${LIBRTMP_INCLUDE_DIRS} (found version \"${LIBRTMP_VERSION}\")")
|
||||
set(LIBRTMP_FOUND TRUE)
|
||||
set(LIBRTMP_VERSION ${_librtmp_VERSION})
|
||||
message(STATUS "Found Librtmp (via pkg-config): ${_librtmp_INCLUDE_DIRS} (found version \"${LIBRTMP_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBRTMP_INCLUDE_DIR NAMES "librtmp/rtmp.h")
|
||||
find_library(LIBRTMP_LIBRARY NAMES "rtmp")
|
||||
@@ -85,19 +82,35 @@ else()
|
||||
)
|
||||
|
||||
if(LIBRTMP_FOUND)
|
||||
set(LIBRTMP_INCLUDE_DIRS ${LIBRTMP_INCLUDE_DIR})
|
||||
set(LIBRTMP_LIBRARIES ${LIBRTMP_LIBRARY})
|
||||
set(_librtmp_INCLUDE_DIRS ${LIBRTMP_INCLUDE_DIR})
|
||||
set(_librtmp_LIBRARIES ${LIBRTMP_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBRTMP_INCLUDE_DIR LIBRTMP_LIBRARY)
|
||||
|
||||
# Necessary when linking a static librtmp
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
list(APPEND LIBRTMP_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
||||
if(OpenSSL_FOUND)
|
||||
list(APPEND _librtmp_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBRTMP_FOUND AND WIN32)
|
||||
list(APPEND LIBRTMP_LIBRARIES "winmm")
|
||||
if(LIBRTMP_FOUND)
|
||||
if(WIN32)
|
||||
list(APPEND _librtmp_LIBRARIES "winmm")
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_librtmp_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::librtmp)
|
||||
add_library(CURL::librtmp INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::librtmp PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_librtmp_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_librtmp_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_librtmp_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_librtmp_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_librtmp_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+32
-19
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBSSH_INCLUDE_DIR`: Absolute path to libssh include directory.
|
||||
# - `LIBSSH_LIBRARY`: Absolute path to `libssh` library.
|
||||
# - `LIBSSH_INCLUDE_DIR`: Absolute path to libssh include directory.
|
||||
# - `LIBSSH_LIBRARY`: Absolute path to `libssh` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The libssh pkg-config packages.
|
||||
# - `LIBSSH_CFLAGS`: Required compiler flags.
|
||||
# - `LIBSSH_VERSION`: Version of libssh.
|
||||
# - `LIBSSH_FOUND`: System has libssh.
|
||||
# - `LIBSSH_VERSION`: Version of libssh.
|
||||
# - `CURL::libssh`: libssh library target.
|
||||
|
||||
set(LIBSSH_PC_REQUIRES "libssh")
|
||||
set(_libssh_pc_requires "libssh")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBSSH_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBSSH_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBSSH ${LIBSSH_PC_REQUIRES})
|
||||
pkg_check_modules(_libssh ${_libssh_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBSSH_FOUND)
|
||||
if(_libssh_FOUND)
|
||||
set(Libssh_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBSSH_CFLAGS "${LIBSSH_CFLAGS}")
|
||||
message(STATUS "Found Libssh (via pkg-config): ${LIBSSH_INCLUDE_DIRS} (found version \"${LIBSSH_VERSION}\")")
|
||||
set(LIBSSH_FOUND TRUE)
|
||||
set(LIBSSH_VERSION ${_libssh_VERSION})
|
||||
message(STATUS "Found Libssh (via pkg-config): ${_libssh_INCLUDE_DIRS} (found version \"${LIBSSH_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBSSH_INCLUDE_DIR NAMES "libssh/libssh.h")
|
||||
find_library(LIBSSH_LIBRARY NAMES "ssh" "libssh")
|
||||
@@ -85,13 +82,29 @@ else()
|
||||
)
|
||||
|
||||
if(LIBSSH_FOUND)
|
||||
set(LIBSSH_INCLUDE_DIRS ${LIBSSH_INCLUDE_DIR})
|
||||
set(LIBSSH_LIBRARIES ${LIBSSH_LIBRARY})
|
||||
set(_libssh_INCLUDE_DIRS ${LIBSSH_INCLUDE_DIR})
|
||||
set(_libssh_LIBRARIES ${LIBSSH_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBSSH_INCLUDE_DIR LIBSSH_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LIBSSH_FOUND AND WIN32)
|
||||
list(APPEND LIBSSH_LIBRARIES "iphlpapi") # for if_nametoindex
|
||||
if(LIBSSH_FOUND)
|
||||
if(WIN32)
|
||||
list(APPEND _libssh_LIBRARIES "iphlpapi") # for if_nametoindex
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libssh_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libssh)
|
||||
add_library(CURL::libssh INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libssh PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libssh_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libssh_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libssh_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libssh_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libssh_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBSSH2_INCLUDE_DIR`: Absolute path to libssh2 include directory.
|
||||
# - `LIBSSH2_LIBRARY`: Absolute path to `libssh2` library.
|
||||
# - `LIBSSH2_INCLUDE_DIR`: Absolute path to libssh2 include directory.
|
||||
# - `LIBSSH2_LIBRARY`: Absolute path to `libssh2` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `LIBSSH2_FOUND`: System has libssh2.
|
||||
# - `LIBSSH2_INCLUDE_DIRS`: The libssh2 include directories.
|
||||
# - `LIBSSH2_LIBRARIES`: The libssh2 library names.
|
||||
# - `LIBSSH2_LIBRARY_DIRS`: The libssh2 library directories.
|
||||
# - `LIBSSH2_PC_REQUIRES`: The libssh2 pkg-config packages.
|
||||
# - `LIBSSH2_CFLAGS`: Required compiler flags.
|
||||
# - `LIBSSH2_VERSION`: Version of libssh2.
|
||||
# - `LIBSSH2_FOUND`: System has libssh2.
|
||||
# - `LIBSSH2_VERSION`: Version of libssh2.
|
||||
# - `CURL::libssh2`: libssh2 library target.
|
||||
|
||||
set(LIBSSH2_PC_REQUIRES "libssh2")
|
||||
set(_libssh2_pc_requires "libssh2")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBSSH2_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBSSH2_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBSSH2 ${LIBSSH2_PC_REQUIRES})
|
||||
pkg_check_modules(_libssh2 ${_libssh2_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBSSH2_FOUND AND LIBSSH2_INCLUDE_DIRS)
|
||||
if(_libssh2_FOUND AND _libssh2_INCLUDE_DIRS)
|
||||
set(Libssh2_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBSSH2_CFLAGS "${LIBSSH2_CFLAGS}")
|
||||
message(STATUS "Found Libssh2 (via pkg-config): ${LIBSSH2_INCLUDE_DIRS} (found version \"${LIBSSH2_VERSION}\")")
|
||||
set(LIBSSH2_FOUND TRUE)
|
||||
set(LIBSSH2_VERSION ${_libssh2_VERSION})
|
||||
message(STATUS "Found Libssh2 (via pkg-config): ${_libssh2_INCLUDE_DIRS} (found version \"${LIBSSH2_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBSSH2_INCLUDE_DIR NAMES "libssh2.h")
|
||||
find_library(LIBSSH2_LIBRARY NAMES "ssh2" "libssh2")
|
||||
@@ -75,9 +72,25 @@ else()
|
||||
)
|
||||
|
||||
if(LIBSSH2_FOUND)
|
||||
set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR})
|
||||
set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY})
|
||||
set(_libssh2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR})
|
||||
set(_libssh2_LIBRARIES ${LIBSSH2_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LIBSSH2_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libssh2_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libssh2)
|
||||
add_library(CURL::libssh2 INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libssh2 PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libssh2_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libssh2_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libssh2_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libssh2_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libssh2_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBUV_INCLUDE_DIR`: Absolute path to libuv include directory.
|
||||
# - `LIBUV_LIBRARY`: Absolute path to `libuv` library.
|
||||
# - `LIBUV_INCLUDE_DIR`: Absolute path to libuv include directory.
|
||||
# - `LIBUV_LIBRARY`: Absolute path to `libuv` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The libuv pkg-config packages.
|
||||
# - `LIBUV_CFLAGS`: Required compiler flags.
|
||||
# - `LIBUV_VERSION`: Version of libuv.
|
||||
# - `LIBUV_FOUND`: System has libuv.
|
||||
# - `LIBUV_VERSION`: Version of libuv.
|
||||
# - `CURL::libuv`: libuv library target.
|
||||
|
||||
set(LIBUV_PC_REQUIRES "libuv")
|
||||
set(_libuv_pc_requires "libuv")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED LIBUV_INCLUDE_DIR AND
|
||||
NOT DEFINED LIBUV_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBUV ${LIBUV_PC_REQUIRES})
|
||||
pkg_check_modules(_libuv ${_libuv_pc_requires})
|
||||
endif()
|
||||
|
||||
if(LIBUV_FOUND)
|
||||
if(_libuv_FOUND)
|
||||
set(Libuv_FOUND TRUE)
|
||||
string(REPLACE ";" " " LIBUV_CFLAGS "${LIBUV_CFLAGS}")
|
||||
message(STATUS "Found Libuv (via pkg-config): ${LIBUV_INCLUDE_DIRS} (found version \"${LIBUV_VERSION}\")")
|
||||
set(LIBUV_FOUND TRUE)
|
||||
set(LIBUV_VERSION ${_libuv_VERSION})
|
||||
message(STATUS "Found Libuv (via pkg-config): ${_libuv_INCLUDE_DIRS} (found version \"${LIBUV_VERSION}\")")
|
||||
else()
|
||||
find_path(LIBUV_INCLUDE_DIR NAMES "uv.h")
|
||||
find_library(LIBUV_LIBRARY NAMES "uv" "libuv")
|
||||
@@ -85,9 +82,25 @@ else()
|
||||
)
|
||||
|
||||
if(LIBUV_FOUND)
|
||||
set(LIBUV_INCLUDE_DIRS ${LIBUV_INCLUDE_DIR})
|
||||
set(LIBUV_LIBRARIES ${LIBUV_LIBRARY})
|
||||
set(_libuv_INCLUDE_DIRS ${LIBUV_INCLUDE_DIR})
|
||||
set(_libuv_LIBRARIES ${LIBUV_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(LIBUV_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_libuv_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::libuv)
|
||||
add_library(CURL::libuv INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::libuv PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_libuv_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_libuv_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_libuv_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_libuv_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_libuv_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+33
-21
@@ -25,20 +25,16 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `MBEDTLS_INCLUDE_DIR`: Absolute path to mbedTLS include directory.
|
||||
# - `MBEDTLS_LIBRARY`: Absolute path to `mbedtls` library.
|
||||
# - `MBEDX509_LIBRARY`: Absolute path to `mbedx509` library.
|
||||
# - `MBEDCRYPTO_LIBRARY`: Absolute path to `mbedcrypto` library.
|
||||
# - `MBEDTLS_INCLUDE_DIR`: Absolute path to mbedTLS include directory.
|
||||
# - `MBEDTLS_LIBRARY`: Absolute path to `mbedtls` library.
|
||||
# - `MBEDX509_LIBRARY`: Absolute path to `mbedx509` library.
|
||||
# - `MBEDCRYPTO_LIBRARY`: Absolute path to `mbedcrypto` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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.
|
||||
# - `MBEDTLS_FOUND`: System has mbedTLS.
|
||||
# - `MBEDTLS_VERSION`: Version of mbedTLS.
|
||||
# - `CURL::mbedtls`: mbedTLS library target.
|
||||
|
||||
if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
|
||||
message(WARNING "MBEDTLS_INCLUDE_DIRS is deprecated, use MBEDTLS_INCLUDE_DIR instead.")
|
||||
@@ -46,7 +42,7 @@ if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
|
||||
unset(MBEDTLS_INCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
set(MBEDTLS_PC_REQUIRES "mbedtls" "mbedx509" "mbedcrypto")
|
||||
set(_mbedtls_pc_requires "mbedtls" "mbedx509" "mbedcrypto")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED MBEDTLS_INCLUDE_DIR AND
|
||||
@@ -54,16 +50,16 @@ if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED MBEDX509_LIBRARY AND
|
||||
NOT DEFINED MBEDCRYPTO_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(MBEDTLS ${MBEDTLS_PC_REQUIRES})
|
||||
pkg_check_modules(_mbedtls ${_mbedtls_pc_requires})
|
||||
endif()
|
||||
|
||||
if(MBEDTLS_FOUND)
|
||||
if(_mbedtls_FOUND)
|
||||
set(MbedTLS_FOUND TRUE)
|
||||
set(MBEDTLS_VERSION ${MBEDTLS_mbedtls_VERSION})
|
||||
string(REPLACE ";" " " MBEDTLS_CFLAGS "${MBEDTLS_CFLAGS}")
|
||||
message(STATUS "Found MbedTLS (via pkg-config): ${MBEDTLS_INCLUDE_DIRS} (found version \"${MBEDTLS_VERSION}\")")
|
||||
set(MBEDTLS_FOUND TRUE)
|
||||
set(MBEDTLS_VERSION ${_mbedtls_mbedtls_VERSION})
|
||||
message(STATUS "Found MbedTLS (via pkg-config): ${_mbedtls_INCLUDE_DIRS} (found version \"${MBEDTLS_VERSION}\")")
|
||||
else()
|
||||
set(MBEDTLS_PC_REQUIRES "") # Depend on pkg-config only when found via pkg-config
|
||||
set(_mbedtls_pc_requires "") # Depend on pkg-config only when found via pkg-config
|
||||
|
||||
find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h")
|
||||
find_library(MBEDTLS_LIBRARY NAMES "mbedtls" "libmbedtls")
|
||||
@@ -92,9 +88,25 @@ else()
|
||||
)
|
||||
|
||||
if(MBEDTLS_FOUND)
|
||||
set(MBEDTLS_INCLUDE_DIRS ${MBEDTLS_INCLUDE_DIR})
|
||||
set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||
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()
|
||||
|
||||
if(MBEDTLS_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_mbedtls_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::mbedtls)
|
||||
add_library(CURL::mbedtls INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::mbedtls PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_mbedtls_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_mbedtls_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_mbedtls_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_mbedtls_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_mbedtls_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,31 +25,28 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NGHTTP2_INCLUDE_DIR`: Absolute path to nghttp2 include directory.
|
||||
# - `NGHTTP2_LIBRARY`: Absolute path to `nghttp2` library.
|
||||
# - `NGHTTP2_INCLUDE_DIR`: Absolute path to nghttp2 include directory.
|
||||
# - `NGHTTP2_LIBRARY`: Absolute path to `nghttp2` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `NGHTTP2_FOUND`: System has nghttp2.
|
||||
# - `NGHTTP2_INCLUDE_DIRS`: The nghttp2 include directories.
|
||||
# - `NGHTTP2_LIBRARIES`: The nghttp2 library names.
|
||||
# - `NGHTTP2_LIBRARY_DIRS`: The nghttp2 library directories.
|
||||
# - `NGHTTP2_PC_REQUIRES`: The nghttp2 pkg-config packages.
|
||||
# - `NGHTTP2_CFLAGS`: Required compiler flags.
|
||||
# - `NGHTTP2_VERSION`: Version of nghttp2.
|
||||
# - `NGHTTP2_FOUND`: System has nghttp2.
|
||||
# - `NGHTTP2_VERSION`: Version of nghttp2.
|
||||
# - `CURL::nghttp2`: nghttp2 library target.
|
||||
|
||||
set(NGHTTP2_PC_REQUIRES "libnghttp2")
|
||||
set(_nghttp2_pc_requires "libnghttp2")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED NGHTTP2_INCLUDE_DIR AND
|
||||
NOT DEFINED NGHTTP2_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(NGHTTP2 ${NGHTTP2_PC_REQUIRES})
|
||||
pkg_check_modules(_nghttp2 ${_nghttp2_pc_requires})
|
||||
endif()
|
||||
|
||||
if(NGHTTP2_FOUND)
|
||||
string(REPLACE ";" " " NGHTTP2_CFLAGS "${NGHTTP2_CFLAGS}")
|
||||
message(STATUS "Found NGHTTP2 (via pkg-config): ${NGHTTP2_INCLUDE_DIRS} (found version \"${NGHTTP2_VERSION}\")")
|
||||
if(_nghttp2_FOUND)
|
||||
set(NGHTTP2_FOUND TRUE)
|
||||
set(NGHTTP2_VERSION ${_nghttp2_VERSION})
|
||||
message(STATUS "Found NGHTTP2 (via pkg-config): ${_nghttp2_INCLUDE_DIRS} (found version \"${NGHTTP2_VERSION}\")")
|
||||
else()
|
||||
find_path(NGHTTP2_INCLUDE_DIR NAMES "nghttp2/nghttp2.h")
|
||||
find_library(NGHTTP2_LIBRARY NAMES "nghttp2" "nghttp2_static")
|
||||
@@ -74,9 +71,25 @@ else()
|
||||
)
|
||||
|
||||
if(NGHTTP2_FOUND)
|
||||
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
|
||||
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
|
||||
set(_nghttp2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
|
||||
set(_nghttp2_LIBRARIES ${NGHTTP2_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGHTTP2_INCLUDE_DIR NGHTTP2_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(NGHTTP2_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_nghttp2_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::nghttp2)
|
||||
add_library(CURL::nghttp2 INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::nghttp2 PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_nghttp2_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_nghttp2_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_nghttp2_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_nghttp2_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_nghttp2_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,31 +25,28 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NGHTTP3_INCLUDE_DIR`: Absolute path to nghttp3 include directory.
|
||||
# - `NGHTTP3_LIBRARY`: Absolute path to `nghttp3` library.
|
||||
# - `NGHTTP3_INCLUDE_DIR`: Absolute path to nghttp3 include directory.
|
||||
# - `NGHTTP3_LIBRARY`: Absolute path to `nghttp3` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `NGHTTP3_FOUND`: System has nghttp3.
|
||||
# - `NGHTTP3_INCLUDE_DIRS`: The nghttp3 include directories.
|
||||
# - `NGHTTP3_LIBRARIES`: The nghttp3 library names.
|
||||
# - `NGHTTP3_LIBRARY_DIRS`: The nghttp3 library directories.
|
||||
# - `NGHTTP3_PC_REQUIRES`: The nghttp3 pkg-config packages.
|
||||
# - `NGHTTP3_CFLAGS`: Required compiler flags.
|
||||
# - `NGHTTP3_VERSION`: Version of nghttp3.
|
||||
# - `NGHTTP3_FOUND`: System has nghttp3.
|
||||
# - `NGHTTP3_VERSION`: Version of nghttp3.
|
||||
# - `CURL::nghttp3`: nghttp3 library target.
|
||||
|
||||
set(NGHTTP3_PC_REQUIRES "libnghttp3")
|
||||
set(_nghttp3_pc_requires "libnghttp3")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED NGHTTP3_INCLUDE_DIR AND
|
||||
NOT DEFINED NGHTTP3_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(NGHTTP3 ${NGHTTP3_PC_REQUIRES})
|
||||
pkg_check_modules(_nghttp3 ${_nghttp3_pc_requires})
|
||||
endif()
|
||||
|
||||
if(NGHTTP3_FOUND)
|
||||
string(REPLACE ";" " " NGHTTP3_CFLAGS "${NGHTTP3_CFLAGS}")
|
||||
message(STATUS "Found NGHTTP3 (via pkg-config): ${NGHTTP3_INCLUDE_DIRS} (found version \"${NGHTTP3_VERSION}\")")
|
||||
if(_nghttp3_FOUND)
|
||||
set(NGHTTP3_FOUND TRUE)
|
||||
set(NGHTTP3_VERSION ${_nghttp3_VERSION})
|
||||
message(STATUS "Found NGHTTP3 (via pkg-config): ${_nghttp3_INCLUDE_DIRS} (found version \"${NGHTTP3_VERSION}\")")
|
||||
else()
|
||||
find_path(NGHTTP3_INCLUDE_DIR NAMES "nghttp3/nghttp3.h")
|
||||
find_library(NGHTTP3_LIBRARY NAMES "nghttp3")
|
||||
@@ -74,9 +71,25 @@ else()
|
||||
)
|
||||
|
||||
if(NGHTTP3_FOUND)
|
||||
set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
|
||||
set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY})
|
||||
set(_nghttp3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
|
||||
set(_nghttp3_LIBRARIES ${NGHTTP3_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGHTTP3_INCLUDE_DIR NGHTTP3_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(NGHTTP3_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_nghttp3_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::nghttp3)
|
||||
add_library(CURL::nghttp3 INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::nghttp3 PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_nghttp3_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_nghttp3_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_nghttp3_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_nghttp3_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_nghttp3_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+27
-15
@@ -44,15 +44,11 @@
|
||||
# - `NGTCP2_CRYPTO_QUICTLS_LIBRARY`: Absolute path to `ngtcp2_crypto_quictls` library.
|
||||
# - `NGTCP2_CRYPTO_WOLFSSL_LIBRARY`: Absolute path to `ngtcp2_crypto_wolfssl` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `NGTCP2_FOUND`: System has ngtcp2.
|
||||
# - `NGTCP2_INCLUDE_DIRS`: The ngtcp2 include directories.
|
||||
# - `NGTCP2_LIBRARIES`: The ngtcp2 library names.
|
||||
# - `NGTCP2_LIBRARY_DIRS`: The ngtcp2 library directories.
|
||||
# - `NGTCP2_PC_REQUIRES`: The ngtcp2 pkg-config packages.
|
||||
# - `NGTCP2_CFLAGS`: Required compiler flags.
|
||||
# - `NGTCP2_VERSION`: Version of ngtcp2.
|
||||
# - `CURL::ngtcp2`: ngtcp2 library target.
|
||||
|
||||
if(NGTCP2_FIND_COMPONENTS)
|
||||
set(_ngtcp2_crypto_backend "")
|
||||
@@ -71,9 +67,9 @@ if(NGTCP2_FIND_COMPONENTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(NGTCP2_PC_REQUIRES "libngtcp2")
|
||||
set(_ngtcp2_pc_requires "libngtcp2")
|
||||
if(_ngtcp2_crypto_backend)
|
||||
list(APPEND NGTCP2_PC_REQUIRES "lib${_crypto_library_lower}")
|
||||
list(APPEND _ngtcp2_pc_requires "lib${_crypto_library_lower}")
|
||||
endif()
|
||||
|
||||
set(_tried_pkgconfig FALSE)
|
||||
@@ -81,14 +77,14 @@ if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED NGTCP2_INCLUDE_DIR AND
|
||||
NOT DEFINED NGTCP2_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(NGTCP2 ${NGTCP2_PC_REQUIRES})
|
||||
pkg_check_modules(_ngtcp2 ${_ngtcp2_pc_requires})
|
||||
set(_tried_pkgconfig TRUE)
|
||||
endif()
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
set(NGTCP2_VERSION ${NGTCP2_libngtcp2_VERSION})
|
||||
string(REPLACE ";" " " NGTCP2_CFLAGS "${NGTCP2_CFLAGS}")
|
||||
message(STATUS "Found NGTCP2 (via pkg-config): ${NGTCP2_INCLUDE_DIRS} (found version \"${NGTCP2_VERSION}\")")
|
||||
if(_ngtcp2_FOUND)
|
||||
set(NGTCP2_FOUND TRUE)
|
||||
set(NGTCP2_VERSION ${_ngtcp2_libngtcp2_VERSION})
|
||||
message(STATUS "Found NGTCP2 (via pkg-config): ${_ngtcp2_INCLUDE_DIRS} (found version \"${NGTCP2_VERSION}\")")
|
||||
else()
|
||||
find_path(NGTCP2_INCLUDE_DIR NAMES "ngtcp2/ngtcp2.h")
|
||||
find_library(NGTCP2_LIBRARY NAMES "ngtcp2")
|
||||
@@ -128,8 +124,8 @@ else()
|
||||
)
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
|
||||
set(NGTCP2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
|
||||
set(_ngtcp2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
|
||||
set(_ngtcp2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGTCP2_INCLUDE_DIR NGTCP2_LIBRARY NGTCP2_CRYPTO_LIBRARY)
|
||||
@@ -139,3 +135,19 @@ else()
|
||||
unset(NGTCP2_LIBRARY CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_ngtcp2_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::ngtcp2)
|
||||
add_library(CURL::ngtcp2 INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::ngtcp2 PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_ngtcp2_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_ngtcp2_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_ngtcp2_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_ngtcp2_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_ngtcp2_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `NETTLE_INCLUDE_DIR`: Absolute path to nettle include directory.
|
||||
# - `NETTLE_LIBRARY`: Absolute path to `nettle` library.
|
||||
# - `NETTLE_INCLUDE_DIR`: Absolute path to nettle include directory.
|
||||
# - `NETTLE_LIBRARY`: Absolute path to `nettle` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The nettle pkg-config packages.
|
||||
# - `NETTLE_CFLAGS`: Required compiler flags.
|
||||
# - `NETTLE_VERSION`: Version of nettle.
|
||||
# - `NETTLE_FOUND`: System has nettle.
|
||||
# - `NETTLE_VERSION`: Version of nettle.
|
||||
# - `CURL::nettle`: nettle library target.
|
||||
|
||||
set(NETTLE_PC_REQUIRES "nettle")
|
||||
set(_nettle_pc_requires "nettle")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED NETTLE_INCLUDE_DIR AND
|
||||
NOT DEFINED NETTLE_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(NETTLE ${NETTLE_PC_REQUIRES})
|
||||
pkg_check_modules(_nettle ${_nettle_pc_requires})
|
||||
endif()
|
||||
|
||||
if(NETTLE_FOUND)
|
||||
if(_nettle_FOUND)
|
||||
set(Nettle_FOUND TRUE)
|
||||
string(REPLACE ";" " " NETTLE_CFLAGS "${NETTLE_CFLAGS}")
|
||||
message(STATUS "Found Nettle (via pkg-config): ${NETTLE_INCLUDE_DIRS} (found version \"${NETTLE_VERSION}\")")
|
||||
set(NETTLE_FOUND TRUE)
|
||||
set(NETTLE_VERSION ${_nettle_VERSION})
|
||||
message(STATUS "Found Nettle (via pkg-config): ${_nettle_INCLUDE_DIRS} (found version \"${NETTLE_VERSION}\")")
|
||||
else()
|
||||
find_path(NETTLE_INCLUDE_DIR NAMES "nettle/sha2.h")
|
||||
find_library(NETTLE_LIBRARY NAMES "nettle")
|
||||
@@ -80,9 +77,25 @@ else()
|
||||
)
|
||||
|
||||
if(NETTLE_FOUND)
|
||||
set(NETTLE_INCLUDE_DIRS ${NETTLE_INCLUDE_DIR})
|
||||
set(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
|
||||
set(_nettle_INCLUDE_DIRS ${NETTLE_INCLUDE_DIR})
|
||||
set(_nettle_LIBRARIES ${NETTLE_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(NETTLE_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_nettle_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::nettle)
|
||||
add_library(CURL::nettle INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::nettle PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_nettle_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_nettle_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_nettle_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_nettle_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_nettle_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,32 +25,29 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `QUICHE_INCLUDE_DIR`: Absolute path to quiche include directory.
|
||||
# - `QUICHE_LIBRARY`: Absolute path to `quiche` library.
|
||||
# - `QUICHE_INCLUDE_DIR`: Absolute path to quiche include directory.
|
||||
# - `QUICHE_LIBRARY`: Absolute path to `quiche` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The quiche pkg-config packages.
|
||||
# - `QUICHE_CFLAGS`: Required compiler flags.
|
||||
# - `QUICHE_VERSION`: Version of quiche.
|
||||
# - `QUICHE_FOUND`: System has quiche.
|
||||
# - `QUICHE_VERSION`: Version of quiche.
|
||||
# - `CURL::quiche`: quiche library target.
|
||||
|
||||
set(QUICHE_PC_REQUIRES "quiche")
|
||||
set(_quiche_pc_requires "quiche")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED QUICHE_INCLUDE_DIR AND
|
||||
NOT DEFINED QUICHE_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(QUICHE ${QUICHE_PC_REQUIRES})
|
||||
pkg_check_modules(_quiche ${_quiche_pc_requires})
|
||||
endif()
|
||||
|
||||
if(QUICHE_FOUND)
|
||||
if(_quiche_FOUND)
|
||||
set(Quiche_FOUND TRUE)
|
||||
string(REPLACE ";" " " QUICHE_CFLAGS "${QUICHE_CFLAGS}")
|
||||
message(STATUS "Found Quiche (via pkg-config): ${QUICHE_INCLUDE_DIRS} (found version \"${QUICHE_VERSION}\")")
|
||||
set(QUICHE_FOUND TRUE)
|
||||
set(QUICHE_VERSION ${_quiche_VERSION})
|
||||
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")
|
||||
@@ -63,9 +60,25 @@ else()
|
||||
)
|
||||
|
||||
if(QUICHE_FOUND)
|
||||
set(QUICHE_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
|
||||
set(QUICHE_LIBRARIES ${QUICHE_LIBRARY})
|
||||
set(_quiche_INCLUDE_DIRS ${QUICHE_INCLUDE_DIR})
|
||||
set(_quiche_LIBRARIES ${QUICHE_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(QUICHE_INCLUDE_DIR QUICHE_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(QUICHE_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_quiche_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::quiche)
|
||||
add_library(CURL::quiche INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::quiche PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_quiche_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_quiche_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_quiche_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_quiche_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_quiche_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+34
-23
@@ -25,34 +25,31 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `RUSTLS_INCLUDE_DIR`: Absolute path to Rustls include directory.
|
||||
# - `RUSTLS_LIBRARY`: Absolute path to `rustls` library.
|
||||
# - `RUSTLS_INCLUDE_DIR`: Absolute path to Rustls include directory.
|
||||
# - `RUSTLS_LIBRARY`: Absolute path to `rustls` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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.
|
||||
# - `RUSTLS_FOUND`: System has Rustls.
|
||||
# - `RUSTLS_VERSION`: Version of Rustls.
|
||||
# - `CURL::rustls`: Rustls library target.
|
||||
|
||||
set(RUSTLS_PC_REQUIRES "rustls")
|
||||
set(_rustls_pc_requires "rustls")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED RUSTLS_INCLUDE_DIR AND
|
||||
NOT DEFINED RUSTLS_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(RUSTLS ${RUSTLS_PC_REQUIRES})
|
||||
pkg_check_modules(_rustls ${_rustls_pc_requires})
|
||||
endif()
|
||||
|
||||
if(RUSTLS_FOUND)
|
||||
if(_rustls_FOUND)
|
||||
set(Rustls_FOUND TRUE)
|
||||
string(REPLACE ";" " " RUSTLS_CFLAGS "${RUSTLS_CFLAGS}")
|
||||
message(STATUS "Found Rustls (via pkg-config): ${RUSTLS_INCLUDE_DIRS} (found version \"${RUSTLS_VERSION}\")")
|
||||
set(RUSTLS_FOUND TRUE)
|
||||
set(RUSTLS_VERSION ${_rustls_VERSION})
|
||||
message(STATUS "Found Rustls (via pkg-config): ${_rustls_INCLUDE_DIRS} (found version \"${RUSTLS_VERSION}\")")
|
||||
else()
|
||||
set(RUSTLS_PC_REQUIRES "") # Depend on pkg-config only when found via pkg-config
|
||||
set(_rustls_pc_requires "") # Depend on pkg-config only when found via pkg-config
|
||||
|
||||
find_path(RUSTLS_INCLUDE_DIR NAMES "rustls.h")
|
||||
find_library(RUSTLS_LIBRARY NAMES "rustls")
|
||||
@@ -65,8 +62,8 @@ else()
|
||||
)
|
||||
|
||||
if(RUSTLS_FOUND)
|
||||
set(RUSTLS_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR})
|
||||
set(RUSTLS_LIBRARIES ${RUSTLS_LIBRARY})
|
||||
set(_rustls_INCLUDE_DIRS ${RUSTLS_INCLUDE_DIR})
|
||||
set(_rustls_LIBRARIES ${RUSTLS_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY)
|
||||
@@ -79,31 +76,45 @@ if(RUSTLS_FOUND)
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
list(APPEND RUSTLS_LIBRARIES "-framework Security")
|
||||
list(APPEND _rustls_LIBRARIES "-framework Security")
|
||||
|
||||
find_library(FOUNDATION_FRAMEWORK NAMES "Foundation")
|
||||
mark_as_advanced(FOUNDATION_FRAMEWORK)
|
||||
if(NOT FOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "Foundation framework not found")
|
||||
endif()
|
||||
list(APPEND RUSTLS_LIBRARIES "-framework Foundation")
|
||||
list(APPEND _rustls_LIBRARIES "-framework Foundation")
|
||||
elseif(NOT WIN32)
|
||||
find_library(PTHREAD_LIBRARY NAMES "pthread")
|
||||
if(PTHREAD_LIBRARY)
|
||||
list(APPEND RUSTLS_LIBRARIES ${PTHREAD_LIBRARY})
|
||||
list(APPEND _rustls_LIBRARIES ${PTHREAD_LIBRARY})
|
||||
endif()
|
||||
mark_as_advanced(PTHREAD_LIBRARY)
|
||||
|
||||
find_library(DL_LIBRARY NAMES "dl")
|
||||
if(DL_LIBRARY)
|
||||
list(APPEND RUSTLS_LIBRARIES ${DL_LIBRARY})
|
||||
list(APPEND _rustls_LIBRARIES ${DL_LIBRARY})
|
||||
endif()
|
||||
mark_as_advanced(DL_LIBRARY)
|
||||
|
||||
find_library(MATH_LIBRARY NAMES "m")
|
||||
if(MATH_LIBRARY)
|
||||
list(APPEND RUSTLS_LIBRARIES ${MATH_LIBRARY})
|
||||
list(APPEND _rustls_LIBRARIES ${MATH_LIBRARY})
|
||||
endif()
|
||||
mark_as_advanced(MATH_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_rustls_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::rustls)
|
||||
add_library(CURL::rustls INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::rustls PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_rustls_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_rustls_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_rustls_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_rustls_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_rustls_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+34
-21
@@ -25,18 +25,14 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `WOLFSSL_INCLUDE_DIR`: Absolute path to wolfSSL include directory.
|
||||
# - `WOLFSSL_LIBRARY`: Absolute path to `wolfssl` library.
|
||||
# - `WOLFSSL_INCLUDE_DIR`: Absolute path to wolfSSL include directory.
|
||||
# - `WOLFSSL_LIBRARY`: Absolute path to `wolfssl` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `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_PC_REQUIRES`: The wolfSSL pkg-config packages.
|
||||
# - `WOLFSSL_CFLAGS`: Required compiler flags.
|
||||
# - `WOLFSSL_VERSION`: Version of wolfSSL.
|
||||
# - `WOLFSSL_FOUND`: System has wolfSSL.
|
||||
# - `WOLFSSL_VERSION`: Version of wolfSSL.
|
||||
# - `CURL::wolfssl`: wolfSSL library target.
|
||||
|
||||
if(DEFINED WolfSSL_INCLUDE_DIR AND NOT DEFINED WOLFSSL_INCLUDE_DIR)
|
||||
message(WARNING "WolfSSL_INCLUDE_DIR is deprecated, use WOLFSSL_INCLUDE_DIR instead.")
|
||||
@@ -47,19 +43,20 @@ if(DEFINED WolfSSL_LIBRARY AND NOT DEFINED WOLFSSL_LIBRARY)
|
||||
set(WOLFSSL_LIBRARY "${WolfSSL_LIBRARY}")
|
||||
endif()
|
||||
|
||||
set(WOLFSSL_PC_REQUIRES "wolfssl")
|
||||
set(_wolfssl_pc_requires "wolfssl")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED WOLFSSL_INCLUDE_DIR AND
|
||||
NOT DEFINED WOLFSSL_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(WOLFSSL ${WOLFSSL_PC_REQUIRES})
|
||||
pkg_check_modules(_wolfssl ${_wolfssl_pc_requires})
|
||||
endif()
|
||||
|
||||
if(WOLFSSL_FOUND)
|
||||
if(_wolfssl_FOUND)
|
||||
set(WolfSSL_FOUND TRUE)
|
||||
string(REPLACE ";" " " WOLFSSL_CFLAGS "${WOLFSSL_CFLAGS}")
|
||||
message(STATUS "Found WolfSSL (via pkg-config): ${WOLFSSL_INCLUDE_DIRS} (found version \"${WOLFSSL_VERSION}\")")
|
||||
set(WOLFSSL_FOUND TRUE)
|
||||
set(WOLFSSL_VERSION ${_wolfssl_VERSION})
|
||||
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")
|
||||
@@ -84,8 +81,8 @@ else()
|
||||
)
|
||||
|
||||
if(WOLFSSL_FOUND)
|
||||
set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
|
||||
set(WOLFSSL_LIBRARIES ${WOLFSSL_LIBRARY})
|
||||
set(_wolfssl_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
|
||||
set(_wolfssl_LIBRARIES ${WOLFSSL_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)
|
||||
@@ -98,19 +95,35 @@ if(WOLFSSL_FOUND)
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
list(APPEND WOLFSSL_LIBRARIES "-framework Security")
|
||||
list(APPEND _wolfssl_LIBRARIES "-framework Security")
|
||||
|
||||
find_library(COREFOUNDATION_FRAMEWORK NAMES "CoreFoundation")
|
||||
mark_as_advanced(COREFOUNDATION_FRAMEWORK)
|
||||
if(NOT COREFOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "CoreFoundation framework not found")
|
||||
endif()
|
||||
list(APPEND WOLFSSL_LIBRARIES "-framework CoreFoundation")
|
||||
elseif(NOT WIN32)
|
||||
list(APPEND _wolfssl_LIBRARIES "-framework CoreFoundation")
|
||||
elseif(WIN32)
|
||||
list(APPEND _wolfssl_LIBRARIES "crypt32")
|
||||
else()
|
||||
find_library(MATH_LIBRARY NAMES "m")
|
||||
if(MATH_LIBRARY)
|
||||
list(APPEND WOLFSSL_LIBRARIES ${MATH_LIBRARY}) # for log and pow
|
||||
list(APPEND _wolfssl_LIBRARIES ${MATH_LIBRARY}) # for log and pow
|
||||
endif()
|
||||
mark_as_advanced(MATH_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_wolfssl_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::wolfssl)
|
||||
add_library(CURL::wolfssl INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::wolfssl PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_wolfssl_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_wolfssl_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_wolfssl_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_wolfssl_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_wolfssl_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+30
-17
@@ -25,18 +25,14 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `ZSTD_INCLUDE_DIR`: Absolute path to zstd include directory.
|
||||
# - `ZSTD_LIBRARY`: Absolute path to `zstd` library.
|
||||
# - `ZSTD_INCLUDE_DIR`: Absolute path to zstd include directory.
|
||||
# - `ZSTD_LIBRARY`: Absolute path to `zstd` library.
|
||||
#
|
||||
# Result variables:
|
||||
# Defines:
|
||||
#
|
||||
# - `ZSTD_FOUND`: System has zstd.
|
||||
# - `ZSTD_INCLUDE_DIRS`: The zstd include directories.
|
||||
# - `ZSTD_LIBRARIES`: The zstd library names.
|
||||
# - `ZSTD_LIBRARY_DIRS`: The zstd library directories.
|
||||
# - `ZSTD_PC_REQUIRES`: The zstd pkg-config packages.
|
||||
# - `ZSTD_CFLAGS`: Required compiler flags.
|
||||
# - `ZSTD_VERSION`: Version of zstd.
|
||||
# - `ZSTD_FOUND`: System has zstd.
|
||||
# - `ZSTD_VERSION`: Version of zstd.
|
||||
# - `CURL::zstd`: zstd library target.
|
||||
|
||||
if(DEFINED Zstd_INCLUDE_DIR AND NOT DEFINED ZSTD_INCLUDE_DIR)
|
||||
message(WARNING "Zstd_INCLUDE_DIR is deprecated, use ZSTD_INCLUDE_DIR instead.")
|
||||
@@ -47,19 +43,20 @@ if(DEFINED Zstd_LIBRARY AND NOT DEFINED ZSTD_LIBRARY)
|
||||
set(ZSTD_LIBRARY "${Zstd_LIBRARY}")
|
||||
endif()
|
||||
|
||||
set(ZSTD_PC_REQUIRES "libzstd")
|
||||
set(_zstd_pc_requires "libzstd")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED ZSTD_INCLUDE_DIR AND
|
||||
NOT DEFINED ZSTD_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(ZSTD ${ZSTD_PC_REQUIRES})
|
||||
pkg_check_modules(_zstd ${_zstd_pc_requires})
|
||||
endif()
|
||||
|
||||
if(ZSTD_FOUND)
|
||||
if(_zstd_FOUND)
|
||||
set(Zstd_FOUND TRUE)
|
||||
string(REPLACE ";" " " ZSTD_CFLAGS "${ZSTD_CFLAGS}")
|
||||
message(STATUS "Found Zstd (via pkg-config): ${ZSTD_INCLUDE_DIRS} (found version \"${ZSTD_VERSION}\")")
|
||||
set(ZSTD_FOUND TRUE)
|
||||
set(ZSTD_VERSION ${_zstd_VERSION})
|
||||
message(STATUS "Found Zstd (via pkg-config): ${_zstd_INCLUDE_DIRS} (found version \"${ZSTD_VERSION}\")")
|
||||
else()
|
||||
find_path(ZSTD_INCLUDE_DIR NAMES "zstd.h")
|
||||
find_library(ZSTD_LIBRARY NAMES "zstd")
|
||||
@@ -94,9 +91,25 @@ else()
|
||||
)
|
||||
|
||||
if(ZSTD_FOUND)
|
||||
set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR})
|
||||
set(ZSTD_LIBRARIES ${ZSTD_LIBRARY})
|
||||
set(_zstd_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR})
|
||||
set(_zstd_LIBRARIES ${ZSTD_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(ZSTD_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
link_directories(${_zstd_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
if(NOT TARGET CURL::zstd)
|
||||
add_library(CURL::zstd INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::zstd PROPERTIES
|
||||
INTERFACE_LIBCURL_PC_MODULES "${_zstd_pc_requires}"
|
||||
INTERFACE_COMPILE_OPTIONS "${_zstd_CFLAGS}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_zstd_INCLUDE_DIRS}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_zstd_LIBRARY_DIRS}"
|
||||
INTERFACE_LINK_LIBRARIES "${_zstd_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
+6
-2
@@ -56,10 +56,10 @@ macro(curl_internal_test _curl_test)
|
||||
"${_curl_test_add_libraries}"
|
||||
OUTPUT_VARIABLE CURL_TEST_OUTPUT)
|
||||
if(${_curl_test})
|
||||
set(${_curl_test} 1 CACHE INTERNAL "Curl test")
|
||||
set(${_curl_test} 1 CACHE INTERNAL "curl test")
|
||||
message(STATUS "Performing Test ${_curl_test} - Success")
|
||||
else()
|
||||
set(${_curl_test} "" CACHE INTERNAL "Curl test")
|
||||
set(${_curl_test} "" CACHE INTERNAL "curl test")
|
||||
message(STATUS "Performing Test ${_curl_test} - Failed")
|
||||
endif()
|
||||
endif()
|
||||
@@ -74,6 +74,10 @@ macro(curl_dependency_option _option_name _find_name _desc_name)
|
||||
find_package(${_find_name})
|
||||
elseif(${_option_name})
|
||||
find_package(${_find_name} REQUIRED)
|
||||
else()
|
||||
string(TOUPPER "${_find_name}" _find_name_upper)
|
||||
set(${_find_name}_FOUND OFF) # cmake-lint: disable=C0103
|
||||
set(${_find_name_upper}_FOUND OFF) # cmake-lint: disable=C0103
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
+23
-10
@@ -75,9 +75,15 @@ if(PICKY_COMPILER)
|
||||
set(_picky_enable "-W")
|
||||
endif()
|
||||
|
||||
list(APPEND _picky_enable
|
||||
-Wall -pedantic
|
||||
)
|
||||
list(APPEND _picky_enable "-Wall")
|
||||
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 3.2) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.2) OR
|
||||
CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8)
|
||||
list(APPEND _picky_enable "-Wpedantic") # clang 3.2 gcc 4.8 appleclang 4.2
|
||||
else()
|
||||
list(APPEND _picky_enable "-pedantic")
|
||||
endif()
|
||||
|
||||
# ----------------------------------
|
||||
# Add new options here, if in doubt:
|
||||
@@ -232,20 +238,26 @@ if(PICKY_COMPILER)
|
||||
-Wcast-function-type-strict # clang 16.0 appleclang 16.0
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 21.0)
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.1) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 17.0))
|
||||
list(APPEND _picky_enable
|
||||
-Warray-compare # clang 20.0 gcc 12.0 appleclang ?
|
||||
-Wc++-hidden-decl # clang 21.0 appleclang ?
|
||||
-Wno-implicit-void-ptr-cast # clang 21.0 appleclang ?
|
||||
-Wtentative-definition-compat # clang 21.0 appleclang ?
|
||||
-Wno-format-signedness # clang 19.1 gcc 5.1 appleclang 17.0 # In clang-cl enums are signed ints by default
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 21.1)
|
||||
list(APPEND _picky_enable
|
||||
-Warray-compare # clang 20.1 gcc 12.0 appleclang ?
|
||||
-Wc++-hidden-decl # clang 21.1 appleclang ?
|
||||
-Wno-implicit-void-ptr-cast # clang 21.1 appleclang ?
|
||||
-Wtentative-definition-compat # clang 21.1 appleclang ?
|
||||
)
|
||||
if(WIN32)
|
||||
list(APPEND _picky_enable
|
||||
-Wno-c++-keyword # clang 21.0 appleclang ? # `wchar_t` triggers it on Windows
|
||||
-Wno-c++-keyword # clang 21.1 appleclang ? # `wchar_t` triggers it on Windows
|
||||
)
|
||||
else()
|
||||
list(APPEND _picky_enable
|
||||
-Wc++-keyword # clang 21.0 appleclang ?
|
||||
-Wc++-keyword # clang 21.1 appleclang ?
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -282,6 +294,7 @@ if(PICKY_COMPILER)
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.0)
|
||||
list(APPEND _picky_enable
|
||||
-Warray-bounds=2 # clang 3.0 gcc 5.0 (clang default: -Warray-bounds)
|
||||
-Wno-format-signedness # clang 19.1 gcc 5.1 appleclang 17.0
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
|
||||
|
||||
@@ -59,6 +59,7 @@ function(curl_dumptargetprops _target)
|
||||
string(REPLACE "\n" ";" _cmake_property_list "${_cmake_property_list}")
|
||||
list(REMOVE_DUPLICATES _cmake_property_list)
|
||||
list(REMOVE_ITEM _cmake_property_list "")
|
||||
list(APPEND _cmake_property_list "INTERFACE_LIBCURL_PC_MODULES")
|
||||
foreach(_prop IN LISTS _cmake_property_list)
|
||||
if(_prop MATCHES "<CONFIG>")
|
||||
foreach(_config IN ITEMS "DEBUG" "RELEASE" "MINSIZEREL" "RELWITHDEBINFO")
|
||||
|
||||
File renamed without changes.
@@ -1,77 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
if("@USE_OPENSSL@")
|
||||
if("@OPENSSL_VERSION_MAJOR@")
|
||||
find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
|
||||
else()
|
||||
find_dependency(OpenSSL)
|
||||
endif()
|
||||
endif()
|
||||
if("@HAVE_LIBZ@")
|
||||
find_dependency(ZLIB "@ZLIB_VERSION_MAJOR@")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
||||
|
||||
# Alias for either shared or static library
|
||||
if(NOT TARGET @PROJECT_NAME@::@LIB_NAME@)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.11 AND CMAKE_VERSION VERSION_LESS 3.18)
|
||||
set_target_properties(@PROJECT_NAME@::@LIB_SELECTED@ PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
endif()
|
||||
add_library(@PROJECT_NAME@::@LIB_NAME@ ALIAS @PROJECT_NAME@::@LIB_SELECTED@)
|
||||
endif()
|
||||
|
||||
# For compatibility with CMake's FindCURL.cmake
|
||||
set(CURL_VERSION_STRING "@CURLVERSION@")
|
||||
set(CURL_LIBRARIES @PROJECT_NAME@::@LIB_NAME@)
|
||||
set_and_check(CURL_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
|
||||
|
||||
set(CURL_SUPPORTED_PROTOCOLS "@CURL_SUPPORTED_PROTOCOLS_LIST@")
|
||||
set(CURL_SUPPORTED_FEATURES "@CURL_SUPPORTED_FEATURES_LIST@")
|
||||
|
||||
foreach(_item IN LISTS CURL_SUPPORTED_PROTOCOLS CURL_SUPPORTED_FEATURES)
|
||||
set(CURL_SUPPORTS_${_item} TRUE)
|
||||
endforeach()
|
||||
|
||||
set(_missing_req "")
|
||||
foreach(_item IN LISTS CURL_FIND_COMPONENTS)
|
||||
if(CURL_SUPPORTS_${_item})
|
||||
set(CURL_${_item}_FOUND TRUE)
|
||||
elseif(CURL_FIND_REQUIRED_${_item})
|
||||
list(APPEND _missing_req ${_item})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_missing_req)
|
||||
string(REPLACE ";" " " _missing_req "${_missing_req}")
|
||||
if(CURL_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "CURL: missing required components: ${_missing_req}")
|
||||
endif()
|
||||
unset(_missing_req)
|
||||
endif()
|
||||
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
@@ -0,0 +1,207 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
@PACKAGE_INIT@
|
||||
|
||||
option(CURL_USE_PKGCONFIG "Enable pkg-config to detect @PROJECT_NAME@ dependencies. Default: @CURL_USE_PKGCONFIG@"
|
||||
"@CURL_USE_PKGCONFIG@")
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS @CMAKE_MINIMUM_REQUIRED_VERSION@)
|
||||
message(STATUS "@PROJECT_NAME@: @PROJECT_NAME@-specific Find modules require "
|
||||
"CMake @CMAKE_MINIMUM_REQUIRED_VERSION@ or upper, found: ${CMAKE_VERSION}.")
|
||||
endif()
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
if("@USE_OPENSSL@")
|
||||
if("@OPENSSL_VERSION_MAJOR@")
|
||||
find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
|
||||
else()
|
||||
find_dependency(OpenSSL)
|
||||
endif()
|
||||
endif()
|
||||
if("@HAVE_LIBZ@")
|
||||
find_dependency(ZLIB "@ZLIB_VERSION_MAJOR@")
|
||||
endif()
|
||||
|
||||
set(_curl_cmake_module_path_save ${CMAKE_MODULE_PATH})
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_MODULE_PATH})
|
||||
|
||||
set(_curl_libs "")
|
||||
|
||||
if("@HAVE_BROTLI@")
|
||||
find_dependency(Brotli)
|
||||
list(APPEND _curl_libs CURL::brotli)
|
||||
endif()
|
||||
if("@USE_ARES@")
|
||||
find_dependency(Cares)
|
||||
list(APPEND _curl_libs CURL::cares)
|
||||
endif()
|
||||
if("@HAVE_GSSAPI@")
|
||||
find_dependency(GSS)
|
||||
list(APPEND _curl_libs CURL::gss)
|
||||
endif()
|
||||
if("@USE_BACKTRACE@")
|
||||
find_dependency(Libbacktrace)
|
||||
list(APPEND _curl_libs CURL::libbacktrace)
|
||||
endif()
|
||||
if("@USE_GSASL@")
|
||||
find_dependency(Libgsasl)
|
||||
list(APPEND _curl_libs CURL::libgsasl)
|
||||
endif()
|
||||
if(NOT "@USE_WIN32_LDAP@" AND NOT "@CURL_DISABLE_LDAP@")
|
||||
find_dependency(LDAP)
|
||||
list(APPEND _curl_libs CURL::ldap)
|
||||
endif()
|
||||
if("@HAVE_LIBIDN2@")
|
||||
find_dependency(Libidn2)
|
||||
list(APPEND _curl_libs CURL::libidn2)
|
||||
endif()
|
||||
if("@USE_LIBPSL@")
|
||||
find_dependency(Libpsl)
|
||||
list(APPEND _curl_libs CURL::libpsl)
|
||||
endif()
|
||||
if("@USE_LIBRTMP@")
|
||||
find_dependency(Librtmp)
|
||||
list(APPEND _curl_libs CURL::librtmp)
|
||||
endif()
|
||||
if("@USE_LIBSSH@")
|
||||
find_dependency(Libssh)
|
||||
list(APPEND _curl_libs CURL::libssh)
|
||||
endif()
|
||||
if("@USE_LIBSSH2@")
|
||||
find_dependency(Libssh2)
|
||||
list(APPEND _curl_libs CURL::libssh2)
|
||||
endif()
|
||||
if("@USE_LIBUV@")
|
||||
find_dependency(Libuv)
|
||||
list(APPEND _curl_libs CURL::libuv)
|
||||
endif()
|
||||
if("@USE_MBEDTLS@")
|
||||
find_dependency(MbedTLS)
|
||||
list(APPEND _curl_libs CURL::mbedtls)
|
||||
endif()
|
||||
if("@USE_NGHTTP2@")
|
||||
find_dependency(NGHTTP2)
|
||||
list(APPEND _curl_libs CURL::nghttp2)
|
||||
endif()
|
||||
if("@USE_NGHTTP3@")
|
||||
find_dependency(NGHTTP3)
|
||||
list(APPEND _curl_libs CURL::nghttp3)
|
||||
endif()
|
||||
if("@USE_NGTCP2@")
|
||||
find_dependency(NGTCP2)
|
||||
list(APPEND _curl_libs CURL::ngtcp2)
|
||||
endif()
|
||||
if("@USE_GNUTLS@")
|
||||
find_dependency(GnuTLS)
|
||||
list(APPEND _curl_libs CURL::gnutls)
|
||||
find_dependency(Nettle)
|
||||
list(APPEND _curl_libs CURL::nettle)
|
||||
endif()
|
||||
if("@USE_QUICHE@")
|
||||
find_dependency(Quiche)
|
||||
list(APPEND _curl_libs CURL::quiche)
|
||||
endif()
|
||||
if("@USE_RUSTLS@")
|
||||
find_dependency(Rustls)
|
||||
list(APPEND _curl_libs CURL::rustls)
|
||||
endif()
|
||||
if("@USE_WOLFSSL@")
|
||||
find_dependency(WolfSSL)
|
||||
list(APPEND _curl_libs CURL::wolfssl)
|
||||
endif()
|
||||
if("@HAVE_ZSTD@")
|
||||
find_dependency(Zstd)
|
||||
list(APPEND _curl_libs CURL::zstd)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${_curl_cmake_module_path_save})
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND WIN32 AND NOT TARGET CURL::win32_winsock)
|
||||
add_library(CURL::win32_winsock INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::win32_winsock PROPERTIES INTERFACE_LINK_LIBRARIES "ws2_32")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
||||
|
||||
# Alias for either shared or static library
|
||||
if(NOT TARGET @PROJECT_NAME@::@LIB_NAME@)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.11 AND CMAKE_VERSION VERSION_LESS 3.18)
|
||||
set_target_properties(@PROJECT_NAME@::@LIB_SELECTED@ PROPERTIES IMPORTED_GLOBAL TRUE)
|
||||
endif()
|
||||
add_library(@PROJECT_NAME@::@LIB_NAME@ ALIAS @PROJECT_NAME@::@LIB_SELECTED@)
|
||||
endif()
|
||||
|
||||
if(TARGET @PROJECT_NAME@::@LIB_STATIC@)
|
||||
# CMake before CMP0099 (CMake 3.17 2020-03-20) did not propagate libdirs to
|
||||
# targets. It expected libs to have an absolute filename. As a workaround,
|
||||
# manually apply dependency libdirs, for CMake consumers without this policy.
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17)
|
||||
cmake_policy(GET CMP0099 _has_CMP0099) # https://cmake.org/cmake/help/latest/policy/CMP0099.html
|
||||
endif()
|
||||
if(NOT _has_CMP0099 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.13 AND _curl_libs)
|
||||
set(_curl_libdirs "")
|
||||
foreach(_curl_lib IN LISTS _curl_libs)
|
||||
get_target_property(_curl_libdir "${_curl_lib}" INTERFACE_LINK_DIRECTORIES)
|
||||
if(_curl_libdir)
|
||||
list(APPEND _curl_libdirs "${_curl_libdir}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(_curl_libdirs)
|
||||
target_link_directories(@PROJECT_NAME@::@LIB_STATIC@ INTERFACE ${_curl_libdirs})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# For compatibility with CMake's FindCURL.cmake
|
||||
set(CURL_VERSION_STRING "@CURLVERSION@")
|
||||
set(CURL_LIBRARIES @PROJECT_NAME@::@LIB_NAME@)
|
||||
set(CURL_LIBRARIES_PRIVATE "@LIBCURL_PC_LIBS_PRIVATE_LIST@")
|
||||
set_and_check(CURL_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
|
||||
|
||||
set(CURL_SUPPORTED_PROTOCOLS "@CURL_SUPPORTED_PROTOCOLS_LIST@")
|
||||
set(CURL_SUPPORTED_FEATURES "@CURL_SUPPORTED_FEATURES_LIST@")
|
||||
|
||||
foreach(_curl_item IN LISTS CURL_SUPPORTED_PROTOCOLS CURL_SUPPORTED_FEATURES)
|
||||
set(CURL_SUPPORTS_${_curl_item} TRUE)
|
||||
endforeach()
|
||||
|
||||
set(_curl_missing_req "")
|
||||
foreach(_curl_item IN LISTS CURL_FIND_COMPONENTS)
|
||||
if(CURL_SUPPORTS_${_curl_item})
|
||||
set(CURL_${_curl_item}_FOUND TRUE)
|
||||
elseif(CURL_FIND_REQUIRED_${_curl_item})
|
||||
list(APPEND _curl_missing_req ${_curl_item})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_curl_missing_req)
|
||||
string(REPLACE ";" " " _curl_missing_req "${_curl_missing_req}")
|
||||
if(CURL_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "@PROJECT_NAME@: missing required components: ${_curl_missing_req}")
|
||||
endif()
|
||||
unset(_curl_missing_req)
|
||||
endif()
|
||||
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
@@ -169,6 +169,7 @@ else()
|
||||
set(HAVE_LINUX_TCP_H 0)
|
||||
endif()
|
||||
set(HAVE_LOCALE_H 1)
|
||||
set(HAVE_LOCALTIME_R 1)
|
||||
set(HAVE_LONGLONG 1)
|
||||
if(APPLE)
|
||||
set(HAVE_MACH_ABSOLUTE_TIME 1)
|
||||
|
||||
+3
-28
@@ -53,11 +53,7 @@ else()
|
||||
if(MSVC)
|
||||
set(HAVE_UNISTD_H 0)
|
||||
set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size()
|
||||
if(MSVC_VERSION GREATER_EQUAL 1600)
|
||||
set(HAVE_STDINT_H 1) # detected by CMake internally in check_type_size()
|
||||
else()
|
||||
set(HAVE_STDINT_H 0) # detected by CMake internally in check_type_size()
|
||||
endif()
|
||||
set(HAVE_STDINT_H 1) # detected by CMake internally in check_type_size()
|
||||
if(MSVC_VERSION GREATER_EQUAL 1800)
|
||||
set(HAVE_STDBOOL_H 1)
|
||||
else()
|
||||
@@ -127,6 +123,7 @@ set(HAVE_IOCTL_SIOCGIFADDR 0)
|
||||
set(HAVE_IO_H 1)
|
||||
set(HAVE_LINUX_TCP_H 0)
|
||||
set(HAVE_LOCALE_H 1)
|
||||
set(HAVE_LOCALTIME_R 0)
|
||||
set(HAVE_MEMRCHR 0)
|
||||
set(HAVE_MSG_NOSIGNAL 0)
|
||||
set(HAVE_NETDB_H 0)
|
||||
@@ -193,7 +190,7 @@ if(MINGW OR MSVC)
|
||||
curl_prefill_type_size("CURL_OFF_T" 8)
|
||||
curl_prefill_type_size("CURL_SOCKET_T" ${CMAKE_SIZEOF_VOID_P})
|
||||
curl_prefill_type_size("SIZE_T" ${CMAKE_SIZEOF_VOID_P})
|
||||
# TIME_T: 8 for _WIN64 or UCRT or MSVC and not Windows CE, 4 otherwise
|
||||
# TIME_T: 8 for _WIN64 or UCRT or MSVC, 4 otherwise
|
||||
# Also 4 for non-UCRT 32-bit when _USE_32BIT_TIME_T is set.
|
||||
# mingw-w64 sets _USE_32BIT_TIME_T unless __MINGW_USE_VC2005_COMPAT is explicit defined.
|
||||
if(MSVC)
|
||||
@@ -206,25 +203,3 @@ if(MINGW OR MSVC)
|
||||
curl_prefill_type_size("OFF_T" 8) # mingw-w64 v3+
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Windows CE exceptions
|
||||
|
||||
if(WINCE)
|
||||
set(HAVE_FREEADDRINFO 0)
|
||||
set(HAVE_GETADDRINFO 0)
|
||||
set(HAVE_LOCALE_H 0)
|
||||
set(HAVE_SETLOCALE 0)
|
||||
set(HAVE_SETMODE 0)
|
||||
set(HAVE_SIGNAL 0)
|
||||
set(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 0)
|
||||
curl_prefill_type_size("CURL_SOCKET_T" 4)
|
||||
curl_prefill_type_size("TIME_T" 4)
|
||||
curl_prefill_type_size("SIZE_T" 4)
|
||||
if(MINGW32CE)
|
||||
set(HAVE_STRTOK_R 0)
|
||||
set(HAVE__SETMODE 0)
|
||||
set(HAVE_FILE_OFFSET_BITS 0)
|
||||
curl_prefill_type_size("SSIZE_T" 4)
|
||||
curl_prefill_type_size("OFF_T" 4)
|
||||
endif()
|
||||
endif()
|
||||
+257
-364
@@ -21,7 +21,6 @@
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
# by Tetetest and Sukender (Benoit Neil)
|
||||
|
||||
cmake_minimum_required(VERSION 3.7...3.16 FATAL_ERROR)
|
||||
message(STATUS "Using CMake version ${CMAKE_VERSION}")
|
||||
@@ -67,41 +66,10 @@ project(CURL
|
||||
LANGUAGES C)
|
||||
|
||||
# CMake does not recognize some targets accurately. Touch up configuration manually as a workaround.
|
||||
if(WINDOWS_STORE AND MINGW) # mingw UWP build
|
||||
if(WINDOWS_STORE AND MINGW) # MinGW UWP build
|
||||
# CMake (as of v3.31.2) gets confused and applies the MSVC rc.exe command-line
|
||||
# template to windres. Reset it to the windres template via 'Modules/Platform/Windows-windres.cmake':
|
||||
# template to windres. Reset it to the windres template as in 'Modules/Platform/Windows-windres.cmake':
|
||||
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
|
||||
elseif(WIN32 AND WINCE AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # mingw32ce build
|
||||
if(NOT MINGW32CE_LIBRARY_DIR)
|
||||
message(FATAL_ERROR "Set MINGW32CE_LIBRARY_DIR variable to the mingw32ce platform library directory.")
|
||||
endif()
|
||||
|
||||
set(MINGW 1)
|
||||
set(MINGW32CE 1)
|
||||
|
||||
# Build implib with libcurl DLL. Copied from CMake's 'Modules/Platform/Windows-GNU.cmake'.
|
||||
set(CMAKE_C_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS>")
|
||||
string(APPEND CMAKE_C_CREATE_SHARED_LIBRARY " <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB>")
|
||||
string(APPEND CMAKE_C_CREATE_SHARED_LIBRARY " ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
|
||||
|
||||
# Build resources. Copied from CMake's 'Modules/Platform/Windows-windres.cmake'.
|
||||
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <DEFINES> <INCLUDES> <FLAGS> <SOURCE> <OBJECT>")
|
||||
enable_language(RC)
|
||||
|
||||
# To compile long long integer literals
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-std=gnu99")
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -std=gnu99")
|
||||
|
||||
set(CMAKE_C_COMPILE_OPTIONS_PIC "") # CMake sets it to '-fPIC', confusing the toolchain and breaking builds. Zap it.
|
||||
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
|
||||
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
|
||||
set(CMAKE_IMPORT_LIBRARY_PREFIX "lib")
|
||||
set(CMAKE_IMPORT_LIBRARY_SUFFIX ".dll.a")
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib")
|
||||
elseif(DOS AND CMAKE_C_COMPILER_ID STREQUAL "GNU") # DJGPP
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||
@@ -130,9 +98,6 @@ endif()
|
||||
if(WIN32)
|
||||
string(APPEND _target_flags " WIN32")
|
||||
endif()
|
||||
if(WINCE)
|
||||
string(APPEND _target_flags " WINCE")
|
||||
endif()
|
||||
if(WINDOWS_STORE)
|
||||
string(APPEND _target_flags " UWP")
|
||||
endif()
|
||||
@@ -204,7 +169,8 @@ 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)
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
get_property(_has_shared GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ${_has_shared})
|
||||
option(BUILD_STATIC_LIBS "Build static libraries" OFF)
|
||||
option(BUILD_STATIC_CURL "Build curl executable with static libcurl" OFF)
|
||||
option(ENABLE_ARES "Enable c-ares support" OFF)
|
||||
@@ -212,12 +178,12 @@ option(CURL_DISABLE_INSTALL "Disable installation targets" OFF)
|
||||
|
||||
if(WIN32)
|
||||
option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF)
|
||||
if(WINDOWS_STORE OR WINCE)
|
||||
if(WINDOWS_STORE)
|
||||
set(ENABLE_UNICODE ON)
|
||||
endif()
|
||||
if(ENABLE_UNICODE)
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "UNICODE" "_UNICODE")
|
||||
if(MINGW AND NOT MINGW32CE)
|
||||
if(MINGW)
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-municode")
|
||||
endif()
|
||||
endif()
|
||||
@@ -260,7 +226,7 @@ if(WIN32)
|
||||
endif()
|
||||
unset(MINGW64_VERSION CACHE) # Avoid storing in CMake cache
|
||||
endif()
|
||||
elseif(DOS OR AMIGA)
|
||||
elseif(DOS)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(BUILD_STATIC_LIBS ON)
|
||||
endif()
|
||||
@@ -300,9 +266,9 @@ endif()
|
||||
option(CURL_CLANG_TIDY "Run the build through clang-tidy" OFF)
|
||||
if(CURL_CLANG_TIDY)
|
||||
set(CMAKE_UNITY_BUILD OFF) # clang-tidy is not looking into #included sources, thus not compatible with unity builds.
|
||||
set(CURL_DISABLE_TYPECHECK ON) # to improve performance and avoid potential interference.
|
||||
set(_tidy_checks "")
|
||||
list(APPEND _tidy_checks "-clang-analyzer-security.insecureAPI.bzero") # for FD_ZERO() (seen on macOS)
|
||||
list(APPEND _tidy_checks "-clang-analyzer-security.insecureAPI.strcpy")
|
||||
list(APPEND _tidy_checks "-clang-analyzer-optin.performance.Padding")
|
||||
list(APPEND _tidy_checks "-clang-analyzer-security.ArrayBound") # false positives with clang-tidy v21.1.0
|
||||
list(APPEND _tidy_checks "-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling")
|
||||
@@ -392,23 +358,14 @@ else()
|
||||
endif()
|
||||
option(CURL_USE_PKGCONFIG "Enable pkg-config to detect dependencies" ${_curl_use_pkgconfig_default})
|
||||
|
||||
# Initialize variables collecting dependency libs, paths, pkg-config names.
|
||||
# Initialize variables collecting system and dependency libs.
|
||||
set(CURL_NETWORK_AND_TIME_LIBS "")
|
||||
set(CURL_LIBS "")
|
||||
set(CURL_LIBDIRS "")
|
||||
set(LIBCURL_PC_REQUIRES_PRIVATE "")
|
||||
|
||||
if(ENABLE_ARES)
|
||||
set(USE_ARES 1)
|
||||
find_package(Cares REQUIRED)
|
||||
list(APPEND CURL_LIBS ${CARES_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${CARES_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${CARES_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${CARES_INCLUDE_DIRS})
|
||||
link_directories(${CARES_LIBRARY_DIRS})
|
||||
if(CARES_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${CARES_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::cares)
|
||||
endif()
|
||||
|
||||
include(CurlSymbolHiding)
|
||||
@@ -496,7 +453,7 @@ option(CURL_DISABLE_SMB "Disable SMB" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SMB)
|
||||
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)
|
||||
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)
|
||||
@@ -504,6 +461,8 @@ option(CURL_DISABLE_TELNET "Disable Telnet" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TELNET)
|
||||
option(CURL_DISABLE_TFTP "Disable TFTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TFTP)
|
||||
option(CURL_DISABLE_TYPECHECK "Disable curl_easy_setopt()/curl_easy_getinfo() type checking" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_TYPECHECK)
|
||||
option(CURL_DISABLE_VERBOSE_STRINGS "Disable verbose strings" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
|
||||
@@ -537,7 +496,7 @@ if(HTTP_ONLY)
|
||||
set(CURL_DISABLE_TFTP ON)
|
||||
endif()
|
||||
|
||||
if(WINDOWS_STORE OR WINCE)
|
||||
if(WINDOWS_STORE)
|
||||
set(CURL_DISABLE_TELNET ON) # telnet code needs fixing to compile for UWP.
|
||||
endif()
|
||||
|
||||
@@ -560,7 +519,7 @@ option(BUILD_LIBCURL_DOCS "Build libcurl man pages" ON)
|
||||
option(BUILD_MISC_DOCS "Build misc man pages (e.g. curl-config and mk-ca-bundle)" ON)
|
||||
option(ENABLE_CURL_MANUAL "Build the man page for curl and enable its -M/--manual option" ON)
|
||||
|
||||
if((ENABLE_CURL_MANUAL OR BUILD_LIBCURL_DOCS) AND NOT PERL_FOUND)
|
||||
if((ENABLE_CURL_MANUAL OR BUILD_LIBCURL_DOCS) AND NOT Perl_FOUND)
|
||||
message(WARNING "Perl not found. Will not build manuals.")
|
||||
endif()
|
||||
|
||||
@@ -623,21 +582,7 @@ if(ENABLE_THREADED_RESOLVER)
|
||||
endif()
|
||||
|
||||
# Check for all needed libraries
|
||||
if(WIN32)
|
||||
if(WINCE)
|
||||
set(_win32_winsock "ws2")
|
||||
else()
|
||||
set(_win32_winsock "ws2_32")
|
||||
endif()
|
||||
set(_win32_crypt32 "crypt32")
|
||||
set(_win32_secur32 "secur32")
|
||||
|
||||
if(MINGW32CE) # FIXME upstream: must specify the full path to avoid CMake converting "ws2" to "ws2.lib"
|
||||
set(_win32_winsock "${MINGW32CE_LIBRARY_DIR}/lib${_win32_winsock}.a")
|
||||
set(_win32_crypt32 "${MINGW32CE_LIBRARY_DIR}/lib${_win32_crypt32}.a")
|
||||
set(_win32_secur32 "${MINGW32CE_LIBRARY_DIR}/lib${_win32_secur32}.a")
|
||||
endif()
|
||||
elseif(DOS)
|
||||
if(DOS)
|
||||
if(WATT_ROOT)
|
||||
set(USE_WATT32 ON)
|
||||
# FIXME upstream: must specify the full path to avoid CMake converting "watt" to "watt.lib"
|
||||
@@ -658,7 +603,7 @@ elseif(AMIGA)
|
||||
set(CURL_USE_OPENSSL ON)
|
||||
set(CURL_CA_FALLBACK ON CACHE BOOL "")
|
||||
endif()
|
||||
elseif(NOT APPLE)
|
||||
elseif(NOT WIN32 AND NOT APPLE)
|
||||
check_library_exists("socket" "connect" "" HAVE_LIBSOCKET)
|
||||
if(HAVE_LIBSOCKET)
|
||||
set(CURL_NETWORK_AND_TIME_LIBS "socket" ${CURL_NETWORK_AND_TIME_LIBS})
|
||||
@@ -693,7 +638,7 @@ if(ENABLE_IPV6)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(ENABLE_IPV6 AND NOT WINCE)
|
||||
if(ENABLE_IPV6)
|
||||
set(USE_IPV6 ON)
|
||||
endif()
|
||||
|
||||
@@ -808,7 +753,7 @@ if(CURL_USE_OPENSSL)
|
||||
# Depend on OpenSSL via imported targets. This allows our dependents to
|
||||
# get our dependencies transitively.
|
||||
list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "openssl")
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES INTERFACE_LIBCURL_PC_MODULES "openssl")
|
||||
|
||||
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "openssl")
|
||||
set(_valid_default_ssl_backend TRUE)
|
||||
@@ -855,14 +800,7 @@ if(CURL_USE_MBEDTLS)
|
||||
endif()
|
||||
set(_ssl_enabled ON)
|
||||
set(USE_MBEDTLS ON)
|
||||
list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
|
||||
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)
|
||||
string(APPEND CMAKE_C_FLAGS " ${MBEDTLS_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::mbedtls)
|
||||
|
||||
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls")
|
||||
set(_valid_default_ssl_backend TRUE)
|
||||
@@ -874,9 +812,7 @@ if(CURL_USE_MBEDTLS)
|
||||
endif()
|
||||
if(NOT DEFINED HAVE_MBEDTLS_DES_CRYPT_ECB)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${MBEDTLS_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${MBEDTLS_LIBRARIES}")
|
||||
curl_required_libpaths("${MBEDTLS_LIBRARY_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::mbedtls)
|
||||
check_function_exists("mbedtls_des_crypt_ecb" HAVE_MBEDTLS_DES_CRYPT_ECB) # in mbedTLS <4
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
@@ -886,14 +822,7 @@ if(CURL_USE_WOLFSSL)
|
||||
find_package(WolfSSL REQUIRED)
|
||||
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_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${WOLFSSL_INCLUDE_DIRS})
|
||||
link_directories(${WOLFSSL_LIBRARY_DIRS})
|
||||
if(WOLFSSL_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${WOLFSSL_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::wolfssl)
|
||||
|
||||
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl")
|
||||
set(_valid_default_ssl_backend TRUE)
|
||||
@@ -903,26 +832,11 @@ endif()
|
||||
|
||||
if(CURL_USE_GNUTLS)
|
||||
find_package(GnuTLS REQUIRED)
|
||||
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${GNUTLS_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${GNUTLS_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${GNUTLS_INCLUDE_DIRS})
|
||||
link_directories(${GNUTLS_LIBRARY_DIRS})
|
||||
if(GNUTLS_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${GNUTLS_CFLAGS}")
|
||||
endif()
|
||||
|
||||
list(APPEND CURL_LIBS CURL::gnutls)
|
||||
find_package(Nettle REQUIRED)
|
||||
list(APPEND CURL_LIBS CURL::nettle)
|
||||
set(_ssl_enabled ON)
|
||||
set(USE_GNUTLS ON)
|
||||
list(APPEND CURL_LIBS ${NETTLE_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${NETTLE_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${NETTLE_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${NETTLE_INCLUDE_DIRS})
|
||||
link_directories(${NETTLE_LIBRARY_DIRS})
|
||||
if(NETTLE_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${NETTLE_CFLAGS}")
|
||||
endif()
|
||||
|
||||
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls")
|
||||
set(_valid_default_ssl_backend TRUE)
|
||||
@@ -931,9 +845,9 @@ if(CURL_USE_GNUTLS)
|
||||
|
||||
if(NOT DEFINED HAVE_GNUTLS_SRP AND NOT CURL_DISABLE_SRP)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${GNUTLS_LIBRARIES}")
|
||||
curl_required_libpaths("${GNUTLS_LIBRARY_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::gnutls)
|
||||
# In GnuTLS 3.8.0 (2023-02-10) and upper, this check always succeeds.
|
||||
# Detecting actual TLS-SRP support needs poking the API at runtime.
|
||||
check_symbol_exists("gnutls_srp_verifier" "gnutls/gnutls.h" HAVE_GNUTLS_SRP)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
@@ -943,23 +857,14 @@ if(CURL_USE_RUSTLS)
|
||||
find_package(Rustls REQUIRED)
|
||||
set(_ssl_enabled ON)
|
||||
set(USE_RUSTLS ON)
|
||||
list(APPEND CURL_LIBS ${RUSTLS_LIBRARIES})
|
||||
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)
|
||||
string(APPEND CMAKE_C_FLAGS " ${RUSTLS_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::rustls)
|
||||
|
||||
if(NOT DEFINED HAVE_RUSTLS_SUPPORTED_HPKE)
|
||||
if(RUSTLS_VERSION AND RUSTLS_VERSION VERSION_GREATER_EQUAL 0.15)
|
||||
set(HAVE_RUSTLS_SUPPORTED_HPKE TRUE)
|
||||
elseif(NOT RUSTLS_VERSION)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${RUSTLS_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${RUSTLS_LIBRARIES}")
|
||||
curl_required_libpaths("${RUSTLS_LIBRARY_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::rustls)
|
||||
check_symbol_exists("rustls_supported_hpke" "rustls.h" HAVE_RUSTLS_SUPPORTED_HPKE)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
@@ -988,21 +893,14 @@ if(ZLIB_FOUND)
|
||||
# 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")
|
||||
set_target_properties(ZLIB::ZLIB PROPERTIES INTERFACE_LIBCURL_PC_MODULES "zlib")
|
||||
endif()
|
||||
|
||||
set(HAVE_BROTLI OFF)
|
||||
curl_dependency_option(CURL_BROTLI Brotli "brotli")
|
||||
if(BROTLI_FOUND)
|
||||
set(HAVE_BROTLI ON)
|
||||
list(APPEND CURL_LIBS ${BROTLI_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${BROTLI_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${BROTLI_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${BROTLI_INCLUDE_DIRS})
|
||||
link_directories(${BROTLI_LIBRARY_DIRS})
|
||||
if(BROTLI_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${BROTLI_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::brotli)
|
||||
endif()
|
||||
|
||||
set(HAVE_ZSTD OFF)
|
||||
@@ -1010,14 +908,7 @@ curl_dependency_option(CURL_ZSTD Zstd "zstd")
|
||||
if(ZSTD_FOUND)
|
||||
if(ZSTD_VERSION VERSION_GREATER_EQUAL 1.0.0)
|
||||
set(HAVE_ZSTD ON)
|
||||
list(APPEND CURL_LIBS ${ZSTD_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${ZSTD_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${ZSTD_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${ZSTD_INCLUDE_DIRS})
|
||||
link_directories(${ZSTD_LIBRARY_DIRS})
|
||||
if(ZSTD_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${ZSTD_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::zstd)
|
||||
else()
|
||||
message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.")
|
||||
endif()
|
||||
@@ -1032,21 +923,19 @@ macro(curl_openssl_check_exists)
|
||||
if(HAVE_LIBZ)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB)
|
||||
endif()
|
||||
if(WIN32 AND NOT WINCE)
|
||||
if(WIN32)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "bcrypt") # for OpenSSL/LibreSSL
|
||||
endif()
|
||||
endif()
|
||||
if(USE_WOLFSSL)
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${WOLFSSL_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${WOLFSSL_LIBRARIES}")
|
||||
curl_required_libpaths("${WOLFSSL_LIBRARY_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::wolfssl)
|
||||
if(HAVE_LIBZ)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB) # Public wolfSSL headers also require zlib headers
|
||||
endif()
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DHAVE_UINTPTR_T") # to pull in stdint.h (as of wolfSSL v5.5.4)
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${_win32_winsock}" "${_win32_crypt32}") # for OpenSSL/wolfSSL
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32" "crypt32") # for OpenSSL/wolfSSL
|
||||
endif()
|
||||
if(${ARGC} EQUAL 2)
|
||||
check_function_exists(${ARGN})
|
||||
@@ -1141,14 +1030,7 @@ option(USE_NGHTTP2 "Use nghttp2 library" ON)
|
||||
if(USE_NGHTTP2)
|
||||
find_package(NGHTTP2)
|
||||
if(NGHTTP2_FOUND)
|
||||
list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${NGHTTP2_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${NGHTTP2_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${NGHTTP2_INCLUDE_DIRS})
|
||||
link_directories(${NGHTTP2_LIBRARY_DIRS})
|
||||
if(NGHTTP2_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${NGHTTP2_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::nghttp2)
|
||||
else()
|
||||
set(USE_NGHTTP2 OFF)
|
||||
endif()
|
||||
@@ -1184,25 +1066,11 @@ if(USE_NGTCP2)
|
||||
else()
|
||||
message(FATAL_ERROR "ngtcp2 requires a supported TLS-backend")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS ${NGTCP2_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${NGTCP2_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${NGTCP2_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${NGTCP2_INCLUDE_DIRS})
|
||||
link_directories(${NGTCP2_LIBRARY_DIRS})
|
||||
if(NGTCP2_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${NGTCP2_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::ngtcp2)
|
||||
|
||||
find_package(NGHTTP3 REQUIRED)
|
||||
set(USE_NGHTTP3 ON)
|
||||
list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${NGHTTP3_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${NGHTTP3_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${NGHTTP3_INCLUDE_DIRS})
|
||||
link_directories(${NGHTTP3_LIBRARY_DIRS})
|
||||
if(NGHTTP3_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${NGHTTP3_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::nghttp3)
|
||||
endif()
|
||||
|
||||
option(USE_QUICHE "Use quiche library for HTTP/3 support" OFF)
|
||||
@@ -1217,18 +1085,10 @@ if(USE_QUICHE)
|
||||
message(FATAL_ERROR "quiche requires BoringSSL")
|
||||
endif()
|
||||
curl_openssl_check_quic()
|
||||
list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${QUICHE_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${QUICHE_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${QUICHE_INCLUDE_DIRS})
|
||||
link_directories(${QUICHE_LIBRARY_DIRS})
|
||||
if(QUICHE_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${QUICHE_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::quiche)
|
||||
if(NOT DEFINED HAVE_QUICHE_CONN_SET_QLOG_FD)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${QUICHE_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${QUICHE_LIBRARIES}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::quiche)
|
||||
check_symbol_exists("quiche_conn_set_qlog_fd" "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
@@ -1244,14 +1104,7 @@ if(USE_OPENSSL_QUIC)
|
||||
|
||||
find_package(NGHTTP3 REQUIRED)
|
||||
set(USE_NGHTTP3 ON)
|
||||
list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${NGHTTP3_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${NGHTTP3_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${NGHTTP3_INCLUDE_DIRS})
|
||||
link_directories(${NGHTTP3_LIBRARY_DIRS})
|
||||
if(NGHTTP3_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${NGHTTP3_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::nghttp3)
|
||||
endif()
|
||||
|
||||
if(NOT CURL_DISABLE_SRP AND (HAVE_GNUTLS_SRP OR HAVE_OPENSSL_SRP))
|
||||
@@ -1259,7 +1112,7 @@ if(NOT CURL_DISABLE_SRP AND (HAVE_GNUTLS_SRP OR HAVE_OPENSSL_SRP))
|
||||
endif()
|
||||
|
||||
if(NOT CURL_DISABLE_LDAP)
|
||||
if(WIN32 AND NOT WINDOWS_STORE AND NOT WINCE)
|
||||
if(WIN32 AND NOT WINDOWS_STORE)
|
||||
option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
|
||||
if(USE_WIN32_LDAP)
|
||||
list(APPEND CURL_LIBS "wldap32")
|
||||
@@ -1279,22 +1132,12 @@ if(NOT CURL_DISABLE_LDAP)
|
||||
find_package(LDAP)
|
||||
if(LDAP_FOUND)
|
||||
set(HAVE_LBER_H 1)
|
||||
set(CURL_LIBS ${LDAP_LIBRARIES} ${CURL_LIBS})
|
||||
list(APPEND CURL_LIBDIRS ${LDAP_LIBRARY_DIRS})
|
||||
if(LDAP_PC_REQUIRES)
|
||||
set(LIBCURL_PC_REQUIRES_PRIVATE ${LDAP_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
|
||||
endif()
|
||||
include_directories(SYSTEM ${LDAP_INCLUDE_DIRS})
|
||||
link_directories(${LDAP_LIBRARY_DIRS})
|
||||
if(LDAP_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LDAP_CFLAGS}")
|
||||
endif()
|
||||
set(CURL_LIBS CURL::ldap ${CURL_LIBS})
|
||||
|
||||
# LDAP feature checks
|
||||
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LDAP_LIBRARIES}")
|
||||
curl_required_libpaths("${LDAP_LIBRARY_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES CURL::ldap)
|
||||
|
||||
check_function_exists("ldap_url_parse" HAVE_LDAP_URL_PARSE)
|
||||
check_function_exists("ldap_init_fd" HAVE_LDAP_INIT_FD)
|
||||
@@ -1356,14 +1199,7 @@ set(HAVE_LIBIDN2 OFF)
|
||||
if(USE_LIBIDN2 AND NOT USE_APPLE_IDN AND NOT USE_WIN32_IDN)
|
||||
find_package(Libidn2)
|
||||
if(LIBIDN2_FOUND)
|
||||
set(CURL_LIBS ${LIBIDN2_LIBRARIES} ${CURL_LIBS})
|
||||
list(APPEND CURL_LIBDIRS ${LIBIDN2_LIBRARY_DIRS})
|
||||
set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBIDN2_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
|
||||
include_directories(SYSTEM ${LIBIDN2_INCLUDE_DIRS})
|
||||
link_directories(${LIBIDN2_LIBRARY_DIRS})
|
||||
if(LIBIDN2_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBIDN2_CFLAGS}")
|
||||
endif()
|
||||
set(CURL_LIBS CURL::libidn2 ${CURL_LIBS})
|
||||
set(HAVE_IDN2_H 1)
|
||||
set(HAVE_LIBIDN2 1)
|
||||
endif()
|
||||
@@ -1373,17 +1209,9 @@ endif()
|
||||
option(CURL_USE_LIBPSL "Use libpsl" ON)
|
||||
mark_as_advanced(CURL_USE_LIBPSL)
|
||||
set(USE_LIBPSL OFF)
|
||||
|
||||
if(CURL_USE_LIBPSL)
|
||||
find_package(Libpsl REQUIRED)
|
||||
list(APPEND CURL_LIBS ${LIBPSL_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${LIBPSL_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBPSL_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${LIBPSL_INCLUDE_DIRS})
|
||||
link_directories(${LIBPSL_LIBRARY_DIRS})
|
||||
if(LIBPSL_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBPSL_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::libpsl)
|
||||
set(USE_LIBPSL ON)
|
||||
endif()
|
||||
|
||||
@@ -1391,18 +1219,10 @@ endif()
|
||||
option(CURL_USE_LIBSSH2 "Use libssh2" ON)
|
||||
mark_as_advanced(CURL_USE_LIBSSH2)
|
||||
set(USE_LIBSSH2 OFF)
|
||||
|
||||
if(CURL_USE_LIBSSH2)
|
||||
find_package(Libssh2)
|
||||
if(LIBSSH2_FOUND)
|
||||
set(CURL_LIBS ${LIBSSH2_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression
|
||||
list(APPEND CURL_LIBDIRS ${LIBSSH2_LIBRARY_DIRS})
|
||||
set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH2_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
|
||||
include_directories(SYSTEM ${LIBSSH2_INCLUDE_DIRS})
|
||||
link_directories(${LIBSSH2_LIBRARY_DIRS})
|
||||
if(LIBSSH2_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBSSH2_CFLAGS}")
|
||||
endif()
|
||||
set(CURL_LIBS CURL::libssh2 ${CURL_LIBS}) # keep it before TLS-crypto, compression
|
||||
set(USE_LIBSSH2 ON)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1412,14 +1232,7 @@ option(CURL_USE_LIBSSH "Use libssh" OFF)
|
||||
mark_as_advanced(CURL_USE_LIBSSH)
|
||||
if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
|
||||
find_package(Libssh REQUIRED)
|
||||
set(CURL_LIBS ${LIBSSH_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression
|
||||
list(APPEND CURL_LIBDIRS ${LIBSSH_LIBRARY_DIRS})
|
||||
set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE})
|
||||
include_directories(SYSTEM ${LIBSSH_INCLUDE_DIRS})
|
||||
link_directories(${LIBSSH_LIBRARY_DIRS})
|
||||
if(LIBSSH_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBSSH_CFLAGS}")
|
||||
endif()
|
||||
set(CURL_LIBS CURL::libssh ${CURL_LIBS}) # keep it before TLS-crypto, compression
|
||||
set(USE_LIBSSH ON)
|
||||
endif()
|
||||
|
||||
@@ -1427,14 +1240,7 @@ option(CURL_USE_GSASL "Use libgsasl" OFF)
|
||||
mark_as_advanced(CURL_USE_GSASL)
|
||||
if(CURL_USE_GSASL)
|
||||
find_package(Libgsasl REQUIRED)
|
||||
list(APPEND CURL_LIBS ${LIBGSASL_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${LIBGSASL_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBGSASL_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${LIBGSASL_INCLUDE_DIRS})
|
||||
link_directories(${LIBGSASL_LIBRARY_DIRS})
|
||||
if(LIBGSASL_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBGSASL_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::libgsasl)
|
||||
set(USE_GSASL ON)
|
||||
endif()
|
||||
|
||||
@@ -1446,16 +1252,10 @@ if(CURL_USE_GSSAPI)
|
||||
|
||||
set(HAVE_GSSAPI ${GSS_FOUND})
|
||||
if(GSS_FOUND)
|
||||
list(APPEND CURL_LIBS ${GSS_LIBRARIES})
|
||||
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)
|
||||
string(APPEND CMAKE_C_FLAGS " ${GSS_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::gss)
|
||||
|
||||
if(GSS_FLAVOUR STREQUAL "GNU")
|
||||
get_target_property(_gss_flavour CURL::gss INTERFACE_CURL_GSS_FLAVOUR)
|
||||
if(_gss_flavour STREQUAL "GNU")
|
||||
set(HAVE_GSSGNU 1)
|
||||
elseif(GSS_VERSION) # MIT
|
||||
set(CURL_KRB5_VERSION "\"${GSS_VERSION}\"")
|
||||
@@ -1465,6 +1265,20 @@ if(CURL_USE_GSSAPI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# libbacktrace
|
||||
option(CURL_USE_LIBBACKTRACE "Use libbacktrace. Requires build with TrackMemory and DWARF debug information." OFF)
|
||||
if(CURL_USE_LIBBACKTRACE)
|
||||
if(NOT ENABLE_CURLDEBUG)
|
||||
message(FATAL_ERROR "libbacktrace requires TrackMemory enabled")
|
||||
endif()
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES "(Debug|RelWithDebInfo)")
|
||||
message(FATAL_ERROR "libbacktrace requires debug information")
|
||||
endif()
|
||||
find_package(Libbacktrace REQUIRED)
|
||||
list(APPEND CURL_LIBS CURL::libbacktrace)
|
||||
set(USE_BACKTRACE ON)
|
||||
endif()
|
||||
|
||||
# libuv
|
||||
option(CURL_USE_LIBUV "Use libuv for event-based tests" OFF)
|
||||
if(CURL_USE_LIBUV)
|
||||
@@ -1472,14 +1286,7 @@ if(CURL_USE_LIBUV)
|
||||
message(FATAL_ERROR "Using libuv without debug support enabled is useless")
|
||||
endif()
|
||||
find_package(Libuv REQUIRED)
|
||||
list(APPEND CURL_LIBS ${LIBUV_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${LIBUV_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBUV_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS})
|
||||
link_directories(${LIBUV_LIBRARY_DIRS})
|
||||
if(LIBUV_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBUV_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::libuv)
|
||||
set(USE_LIBUV ON)
|
||||
set(HAVE_UV_H ON)
|
||||
endif()
|
||||
@@ -1487,18 +1294,11 @@ endif()
|
||||
option(USE_LIBRTMP "Enable librtmp from rtmpdump" OFF)
|
||||
if(USE_LIBRTMP)
|
||||
find_package(Librtmp REQUIRED)
|
||||
list(APPEND CURL_LIBS ${LIBRTMP_LIBRARIES})
|
||||
list(APPEND CURL_LIBDIRS ${LIBRTMP_LIBRARY_DIRS})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBRTMP_PC_REQUIRES})
|
||||
include_directories(SYSTEM ${LIBRTMP_INCLUDE_DIRS})
|
||||
link_directories(${LIBRTMP_LIBRARY_DIRS})
|
||||
if(LIBRTMP_CFLAGS)
|
||||
string(APPEND CMAKE_C_FLAGS " ${LIBRTMP_CFLAGS}")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS CURL::librtmp)
|
||||
endif()
|
||||
|
||||
option(ENABLE_UNIX_SOCKETS "Enable Unix domain sockets support" ON)
|
||||
if(ENABLE_UNIX_SOCKETS AND NOT WINCE)
|
||||
if(ENABLE_UNIX_SOCKETS)
|
||||
if(WIN32 OR DOS)
|
||||
set(USE_UNIX_SOCKETS 1)
|
||||
else()
|
||||
@@ -1549,7 +1349,7 @@ if(_curl_ca_bundle_supported)
|
||||
unset(CURL_CA_PATH CACHE)
|
||||
elseif(CURL_CA_PATH STREQUAL "auto")
|
||||
unset(CURL_CA_PATH CACHE)
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32)
|
||||
if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32 AND NOT USE_APPLE_SECTRUST)
|
||||
set(_curl_ca_path_autodetect TRUE)
|
||||
endif()
|
||||
else()
|
||||
@@ -1615,7 +1415,7 @@ if(WIN32)
|
||||
list(APPEND CURL_INCLUDES "winsock2.h")
|
||||
list(APPEND CURL_INCLUDES "ws2tcpip.h")
|
||||
|
||||
if(HAVE_WIN32_WINNT AND HAVE_WIN32_WINNT LESS 0x0501 AND NOT WINCE)
|
||||
if(HAVE_WIN32_WINNT AND HAVE_WIN32_WINNT LESS 0x0501)
|
||||
# Windows XP is required for freeaddrinfo, getaddrinfo
|
||||
message(FATAL_ERROR "Building for Windows XP or newer is required.")
|
||||
endif()
|
||||
@@ -1623,7 +1423,7 @@ if(WIN32)
|
||||
# Pre-fill detection results based on target OS version
|
||||
if(_CURL_PREFILL)
|
||||
if(NOT HAVE_WIN32_WINNT OR HAVE_WIN32_WINNT LESS 0x0600 OR # older than Windows Vista
|
||||
WINCE OR WINDOWS_STORE)
|
||||
WINDOWS_STORE)
|
||||
set(HAVE_IF_NAMETOINDEX 0)
|
||||
unset(HAVE_IF_NAMETOINDEX CACHE)
|
||||
elseif(MSVC OR MINGW)
|
||||
@@ -1731,8 +1531,8 @@ endif()
|
||||
|
||||
# Apply to all feature checks
|
||||
if(WIN32)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${_win32_winsock}")
|
||||
if(NOT WINCE AND NOT WINDOWS_STORE)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32")
|
||||
if(NOT WINDOWS_STORE)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "iphlpapi")
|
||||
endif()
|
||||
elseif(HAVE_LIBSOCKET)
|
||||
@@ -1769,6 +1569,7 @@ 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("localtime_r" "stdlib.h;time.h" HAVE_LOCALTIME_R)
|
||||
|
||||
check_symbol_exists("gethostbyname_r" "netdb.h" HAVE_GETHOSTBYNAME_R)
|
||||
check_symbol_exists("gethostname" "${CURL_INCLUDES}" HAVE_GETHOSTNAME) # winsock2.h unistd.h proto/bsdsocket.h
|
||||
@@ -1786,9 +1587,9 @@ 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("getrlimit" HAVE_GETRLIMIT)
|
||||
check_function_exists("setlocale" HAVE_SETLOCALE)
|
||||
check_function_exists("setrlimit" HAVE_SETRLIMIT)
|
||||
check_function_exists("getrlimit" HAVE_GETRLIMIT)
|
||||
check_function_exists("setlocale" HAVE_SETLOCALE)
|
||||
check_function_exists("setrlimit" HAVE_SETRLIMIT)
|
||||
|
||||
if(WIN32)
|
||||
# include wincrypt.h as a workaround for mingw-w64 __MINGW64_VERSION_MAJOR <= 5 header bug */
|
||||
@@ -1797,16 +1598,14 @@ else()
|
||||
check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # net/if.h
|
||||
check_function_exists("realpath" HAVE_REALPATH)
|
||||
check_function_exists("sched_yield" HAVE_SCHED_YIELD)
|
||||
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("strcasecmp" "string.h" HAVE_STRCASECMP)
|
||||
check_symbol_exists("stricmp" "string.h" HAVE_STRICMP)
|
||||
check_symbol_exists("strcmpi" "string.h" HAVE_STRCMPI)
|
||||
endif()
|
||||
|
||||
if(NOT MINGW32CE) # Avoid false detections
|
||||
check_function_exists("setmode" HAVE_SETMODE)
|
||||
if(WIN32 OR CYGWIN)
|
||||
check_function_exists("_setmode" HAVE__SETMODE)
|
||||
endif()
|
||||
check_function_exists("setmode" HAVE_SETMODE)
|
||||
if(WIN32 OR CYGWIN)
|
||||
check_function_exists("_setmode" HAVE__SETMODE)
|
||||
endif()
|
||||
|
||||
if(AMIGA)
|
||||
@@ -1904,7 +1703,7 @@ check_type_size("off_t" SIZEOF_OFF_T)
|
||||
|
||||
if(NOT WIN32)
|
||||
# fseeko may not exist with _FILE_OFFSET_BITS=64 but can exist with
|
||||
# _FILE_OFFSET_BITS unset or 32 (e.g. Android ARMv7 with NDK 26b and API level < 24)
|
||||
# _FILE_OFFSET_BITS unset or 32 (as in Android ARMv7 with NDK 26b and API level < 24)
|
||||
# so we need to test fseeko after testing for _FILE_OFFSET_BITS
|
||||
check_symbol_exists("fseeko" "${CURL_INCLUDES};stdio.h" HAVE_FSEEKO)
|
||||
|
||||
@@ -1968,17 +1767,11 @@ include(CMake/OtherTests.cmake)
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "HAVE_CONFIG_H")
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND CURL_NETWORK_AND_TIME_LIBS "${_win32_winsock}")
|
||||
if(NOT WINCE AND NOT WINDOWS_STORE)
|
||||
list(APPEND CURL_NETWORK_AND_TIME_LIBS "ws2_32")
|
||||
if(NOT WINDOWS_STORE)
|
||||
list(APPEND CURL_NETWORK_AND_TIME_LIBS "iphlpapi")
|
||||
endif()
|
||||
if(NOT WINCE)
|
||||
list(APPEND CURL_LIBS "bcrypt")
|
||||
endif()
|
||||
|
||||
if(NOT WINCE)
|
||||
set(USE_WIN32_LARGE_FILES ON)
|
||||
endif()
|
||||
list(APPEND CURL_LIBS "bcrypt")
|
||||
|
||||
# We use crypto functions that are not available for UWP apps
|
||||
if(NOT WINDOWS_STORE)
|
||||
@@ -1987,13 +1780,10 @@ if(WIN32)
|
||||
|
||||
# Link required libraries for USE_WIN32_CRYPTO or USE_SCHANNEL
|
||||
if(USE_WIN32_CRYPTO OR USE_SCHANNEL)
|
||||
if(NOT WINCE)
|
||||
list(APPEND CURL_LIBS "advapi32")
|
||||
endif()
|
||||
list(APPEND CURL_LIBS "${_win32_crypt32}")
|
||||
list(APPEND CURL_LIBS "advapi32" "crypt32")
|
||||
endif()
|
||||
if(USE_WINDOWS_SSPI)
|
||||
list(APPEND CURL_LIBS "${_win32_secur32}")
|
||||
list(APPEND CURL_LIBS "secur32")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -2002,6 +1792,28 @@ if(CURL_CODE_COVERAGE)
|
||||
list(APPEND CURL_LIBS ${CURL_COVERAGE_LIBS})
|
||||
endif()
|
||||
|
||||
# Hack to add some libraries to the end of the library list to make binutils ld
|
||||
# for GCC find symbols when linking statically. Necessary for libs detected via
|
||||
# CMake's built-in find modules, which CMake adds to the beginning of the lib
|
||||
# list on the linker command-line for some reason. This makes them appear
|
||||
# before dependencies detected via curl's custom Find modules, and breaks
|
||||
# linkers sensitive to lib order. There must be a better solution to this.
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
foreach(_lib IN ITEMS OpenSSL::Crypto ZLIB::ZLIB)
|
||||
if(TARGET "${_lib}")
|
||||
add_library(CURL::${_lib} INTERFACE IMPORTED)
|
||||
get_target_property(_libname "${_lib}" LOCATION)
|
||||
set_target_properties(${_lib} PROPERTIES INTERFACE_LINK_LIBRARIES "${_libname}")
|
||||
list(APPEND CURL_LIBS ${_lib})
|
||||
endif()
|
||||
endforeach()
|
||||
if(WIN32)
|
||||
add_library(CURL::win32_winsock INTERFACE IMPORTED)
|
||||
set_target_properties(CURL::win32_winsock PROPERTIES INTERFACE_LINK_LIBRARIES "ws2_32")
|
||||
list(APPEND CURL_LIBS CURL::win32_winsock)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") # MSVC but exclude clang-cl
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "-MP") # Parallel compilation
|
||||
endif()
|
||||
@@ -2022,7 +1834,6 @@ if(CURL_LTO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Ugly (but functional) way to include "Makefile.inc" by transforming it
|
||||
# (= regenerate it).
|
||||
function(curl_transform_makefile_inc _input_file _output_file)
|
||||
@@ -2052,13 +1863,13 @@ set(_project_config "${_generated_dir}/${PROJECT_NAME}Config.cmake")
|
||||
set(_version_config "${_generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
|
||||
|
||||
option(BUILD_TESTING "Build tests" ON)
|
||||
if(BUILD_TESTING AND PERL_FOUND)
|
||||
if(BUILD_TESTING AND Perl_FOUND)
|
||||
set(CURL_BUILD_TESTING ON)
|
||||
else()
|
||||
set(CURL_BUILD_TESTING OFF)
|
||||
endif()
|
||||
|
||||
if(PERL_FOUND)
|
||||
if(Perl_FOUND)
|
||||
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)
|
||||
@@ -2066,8 +1877,6 @@ endif()
|
||||
|
||||
add_subdirectory(scripts) # for shell completions
|
||||
|
||||
list(REMOVE_DUPLICATES CURL_LIBDIRS)
|
||||
|
||||
add_subdirectory(lib)
|
||||
|
||||
if(BUILD_CURL_EXE)
|
||||
@@ -2161,8 +1970,7 @@ curl_add_if("asyn-rr" USE_ARES AND ENABLE_THREADED_RESOLVER AND USE_HTTPSR
|
||||
curl_add_if("IDN" (HAVE_LIBIDN2 AND HAVE_IDN2_H) OR
|
||||
USE_WIN32_IDN OR
|
||||
USE_APPLE_IDN)
|
||||
curl_add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND
|
||||
((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
|
||||
curl_add_if("Largefile" (SIZEOF_CURL_OFF_T GREATER 4) AND ((SIZEOF_OFF_T GREATER 4) OR WIN32))
|
||||
curl_add_if("SSPI" USE_WINDOWS_SSPI)
|
||||
curl_add_if("GSS-API" HAVE_GSSAPI)
|
||||
curl_add_if("alt-svc" NOT CURL_DISABLE_ALTSVC)
|
||||
@@ -2206,8 +2014,7 @@ message(STATUS "Features: ${SUPPORT_FEATURES}")
|
||||
# Clear list and collect SSL backends
|
||||
set(_items "")
|
||||
curl_add_if("Schannel" _ssl_enabled AND USE_SCHANNEL)
|
||||
curl_add_if("${_openssl}" _ssl_enabled AND USE_OPENSSL AND OPENSSL_VERSION VERSION_LESS 3.0.0)
|
||||
curl_add_if("${_openssl} v3+" _ssl_enabled AND USE_OPENSSL AND OPENSSL_VERSION VERSION_GREATER_EQUAL 3.0.0)
|
||||
curl_add_if("${_openssl}" _ssl_enabled AND USE_OPENSSL)
|
||||
curl_add_if("mbedTLS" _ssl_enabled AND USE_MBEDTLS)
|
||||
curl_add_if("wolfSSL" _ssl_enabled AND USE_WOLFSSL)
|
||||
curl_add_if("GnuTLS" _ssl_enabled AND USE_GNUTLS)
|
||||
@@ -2291,7 +2098,91 @@ if(NOT CURL_DISABLE_INSTALL)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(_libdir IN LISTS _custom_libdirs CURL_LIBDIRS)
|
||||
set(_implicit_libs "")
|
||||
if(NOT MINGW AND NOT UNIX)
|
||||
set(_implicit_libs "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
set(_explicit_libdirs "")
|
||||
set(LIBCURL_PC_REQUIRES_PRIVATE "")
|
||||
set(LIBCURL_PC_LIBS_PRIVATE_LIST "")
|
||||
foreach(_lib IN LISTS CURL_LIBS _custom_libs _implicit_libs)
|
||||
if(TARGET "${_lib}")
|
||||
set(_explicit_libs "")
|
||||
get_target_property(_imported "${_lib}" IMPORTED)
|
||||
if(NOT _imported)
|
||||
# Reading the LOCATION property on non-imported target will error out.
|
||||
# Assume the user will not need this information in the .pc file.
|
||||
continue()
|
||||
endif()
|
||||
if(_lib MATCHES "CURL::")
|
||||
# This is empty for 'CURL::*' targets and safe to ignore.
|
||||
# Explicitly skip this query to avoid CMake v3.18 and older erroring out.
|
||||
set(_libname "")
|
||||
else()
|
||||
get_target_property(_libname "${_lib}" LOCATION)
|
||||
endif()
|
||||
if(_libname)
|
||||
list(APPEND _explicit_libs "${_libname}")
|
||||
else()
|
||||
get_target_property(_libs "${_lib}" INTERFACE_LINK_LIBRARIES)
|
||||
if(_libs)
|
||||
list(APPEND _explicit_libs "${_libs}")
|
||||
endif()
|
||||
get_target_property(_libdirs "${_lib}" INTERFACE_LINK_DIRECTORIES)
|
||||
if(_libdirs)
|
||||
list(APPEND _explicit_libdirs "${_libdirs}")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT _libname AND NOT _libs AND NOT _libdirs)
|
||||
message(WARNING "Bad lib in library list: ${_lib}")
|
||||
endif()
|
||||
get_target_property(_modules "${_lib}" INTERFACE_LIBCURL_PC_MODULES)
|
||||
if(_modules)
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "${_modules}")
|
||||
endif()
|
||||
|
||||
foreach(_lib IN LISTS _explicit_libs)
|
||||
if(_lib MATCHES "/")
|
||||
# This gets a bit more complex, because we want to specify the
|
||||
# directory separately, and only once per directory
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(GET _lib PARENT_PATH _libdir)
|
||||
cmake_path(GET _lib STEM _libname)
|
||||
else()
|
||||
get_filename_component(_libdir "${_lib}" DIRECTORY)
|
||||
get_filename_component(_libname "${_lib}" NAME_WE)
|
||||
endif()
|
||||
if(_libname MATCHES "^lib")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(SET _libdir NORMALIZE "${_libdir}")
|
||||
endif()
|
||||
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
|
||||
if(_libdir_index LESS 0)
|
||||
list(APPEND _ldflags "-L${_libdir}")
|
||||
endif()
|
||||
string(REGEX REPLACE "^lib" "" _libname "${_libname}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_libname}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE_LIST "${_lib}")
|
||||
else()
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "${_lib}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE_LIST "${_lib}")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_lib}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE_LIST "${_lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
elseif(_lib MATCHES "^-") # '-framework <name>'
|
||||
list(APPEND _ldflags "${_lib}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE_LIST "${_lib}")
|
||||
else()
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_lib}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE_LIST "${_lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(_libdir IN LISTS _custom_libdirs _explicit_libdirs)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(SET _libdir NORMALIZE "${_libdir}")
|
||||
endif()
|
||||
@@ -2301,57 +2192,10 @@ if(NOT CURL_DISABLE_INSTALL)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(_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)
|
||||
if(NOT _imported)
|
||||
# Reading the LOCATION property on non-imported target will error out.
|
||||
# Assume the user will not need this information in the .pc file.
|
||||
continue()
|
||||
endif()
|
||||
get_target_property(_lib "${_libname}" LOCATION)
|
||||
if(NOT _lib)
|
||||
message(WARNING "Bad lib in library list: ${_libname}")
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
if(_lib MATCHES "^-") # '-framework <name>'
|
||||
list(APPEND _ldflags "${_lib}")
|
||||
elseif(_lib MATCHES "/")
|
||||
# This gets a bit more complex, because we want to specify the
|
||||
# directory separately, and only once per directory
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(GET _lib PARENT_PATH _libdir)
|
||||
cmake_path(GET _lib STEM _libname)
|
||||
else()
|
||||
get_filename_component(_libdir "${_lib}" DIRECTORY)
|
||||
get_filename_component(_libname "${_lib}" NAME_WE)
|
||||
endif()
|
||||
if(_libname MATCHES "^lib")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
|
||||
cmake_path(SET _libdir NORMALIZE "${_libdir}")
|
||||
endif()
|
||||
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
|
||||
if(_libdir_index LESS 0)
|
||||
list(APPEND _ldflags "-L${_libdir}")
|
||||
endif()
|
||||
string(REGEX REPLACE "^lib" "" _libname "${_libname}")
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_libname}")
|
||||
else()
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "${_lib}")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND LIBCURL_PC_LIBS_PRIVATE "-l${_lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES _ldflags)
|
||||
|
||||
if(LIBCURL_PC_REQUIRES_PRIVATE)
|
||||
list(REMOVE_DUPLICATES LIBCURL_PC_REQUIRES_PRIVATE)
|
||||
string(REPLACE ";" "," LIBCURL_PC_REQUIRES_PRIVATE "${LIBCURL_PC_REQUIRES_PRIVATE}")
|
||||
endif()
|
||||
if(LIBCURL_PC_LIBS_PRIVATE)
|
||||
@@ -2462,15 +2306,39 @@ if(NOT CURL_DISABLE_INSTALL)
|
||||
${_generated_version_config}")
|
||||
|
||||
# Consumed custom variables:
|
||||
# CMAKE_MINIMUM_REQUIRED_VERSION
|
||||
# CURLVERSION
|
||||
# LIBCURL_PC_LIBS_PRIVATE_LIST
|
||||
# LIB_NAME
|
||||
# LIB_SELECTED
|
||||
# LIB_STATIC
|
||||
# TARGETS_EXPORT_NAME
|
||||
# USE_OPENSSL OPENSSL_VERSION_MAJOR
|
||||
# HAVE_LIBZ ZLIB_VERSION_MAJOR
|
||||
# CURL_SUPPORTED_FEATURES_LIST
|
||||
# CURL_SUPPORTED_PROTOCOLS_LIST
|
||||
configure_package_config_file("CMake/curl-config.cmake.in"
|
||||
# HAVE_BROTLI
|
||||
# HAVE_GSSAPI
|
||||
# HAVE_LIBIDN2
|
||||
# HAVE_LIBZ ZLIB_VERSION_MAJOR
|
||||
# HAVE_ZSTD
|
||||
# USE_ARES
|
||||
# USE_BACKTRACE
|
||||
# USE_GNUTLS
|
||||
# USE_GSASL
|
||||
# USE_LIBPSL
|
||||
# USE_LIBRTMP
|
||||
# USE_LIBSSH
|
||||
# USE_LIBSSH2
|
||||
# USE_LIBUV
|
||||
# USE_MBEDTLS
|
||||
# USE_NGHTTP2
|
||||
# USE_NGHTTP3
|
||||
# USE_NGTCP2
|
||||
# USE_OPENSSL OPENSSL_VERSION_MAJOR
|
||||
# USE_QUICHE
|
||||
# USE_RUSTLS
|
||||
# USE_WIN32_LDAP CURL_DISABLE_LDAP
|
||||
# USE_WOLFSSL
|
||||
configure_package_config_file("CMake/curl-config.in.cmake"
|
||||
"${_project_config}"
|
||||
INSTALL_DESTINATION ${_install_cmake_dir}
|
||||
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
|
||||
@@ -2481,12 +2349,37 @@ if(NOT CURL_DISABLE_INSTALL)
|
||||
DESTINATION ${_install_cmake_dir})
|
||||
endif()
|
||||
|
||||
install(FILES ${_version_config} ${_project_config}
|
||||
install(
|
||||
FILES
|
||||
${_version_config}
|
||||
${_project_config}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindBrotli.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindCares.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindGSS.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindGnuTLS.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLDAP.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibbacktrace.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibgsasl.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibidn2.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibpsl.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibrtmp.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibssh.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibssh2.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindLibuv.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindMbedTLS.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindNGHTTP2.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindNGHTTP3.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindNGTCP2.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindNettle.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindQuiche.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindRustls.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindWolfSSL.cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindZstd.cmake"
|
||||
DESTINATION ${_install_cmake_dir})
|
||||
|
||||
if(NOT TARGET curl_uninstall)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.in.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake"
|
||||
@ONLY)
|
||||
|
||||
|
||||
+102
-114
@@ -202,22 +202,22 @@ struct curl_httppost {
|
||||
long flags; /* as defined below */
|
||||
|
||||
/* specified content is a filename */
|
||||
#define CURL_HTTPPOST_FILENAME (1<<0)
|
||||
#define CURL_HTTPPOST_FILENAME (1 << 0)
|
||||
/* specified content is a filename */
|
||||
#define CURL_HTTPPOST_READFILE (1<<1)
|
||||
#define CURL_HTTPPOST_READFILE (1 << 1)
|
||||
/* name is only stored pointer do not free in formfree */
|
||||
#define CURL_HTTPPOST_PTRNAME (1<<2)
|
||||
#define CURL_HTTPPOST_PTRNAME (1 << 2)
|
||||
/* contents is only stored pointer do not free in formfree */
|
||||
#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
|
||||
#define CURL_HTTPPOST_PTRCONTENTS (1 << 3)
|
||||
/* upload file from buffer */
|
||||
#define CURL_HTTPPOST_BUFFER (1<<4)
|
||||
#define CURL_HTTPPOST_BUFFER (1 << 4)
|
||||
/* upload file from pointer contents */
|
||||
#define CURL_HTTPPOST_PTRBUFFER (1<<5)
|
||||
#define CURL_HTTPPOST_PTRBUFFER (1 << 5)
|
||||
/* upload file contents by using the regular read callback to get the data and
|
||||
pass the given pointer as custom pointer */
|
||||
#define CURL_HTTPPOST_CALLBACK (1<<6)
|
||||
#define CURL_HTTPPOST_CALLBACK (1 << 6)
|
||||
/* use size in 'contentlen', added in 7.46.0 */
|
||||
#define CURL_HTTPPOST_LARGE (1<<7)
|
||||
#define CURL_HTTPPOST_LARGE (1 << 7)
|
||||
|
||||
char *showfilename; /* The filename to show. If not set, the
|
||||
actual filename will be used (if this
|
||||
@@ -229,7 +229,6 @@ struct curl_httppost {
|
||||
set. Added in 7.46.0 */
|
||||
};
|
||||
|
||||
|
||||
/* This is a return code for the progress callback that, when returned, will
|
||||
signal libcurl to continue executing the default progress function */
|
||||
#define CURL_PROGRESSFUNC_CONTINUE 0x10000001
|
||||
@@ -304,14 +303,14 @@ typedef enum {
|
||||
CURLFILETYPE_UNKNOWN /* should never occur */
|
||||
} curlfiletype;
|
||||
|
||||
#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0)
|
||||
#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1)
|
||||
#define CURLFINFOFLAG_KNOWN_TIME (1<<2)
|
||||
#define CURLFINFOFLAG_KNOWN_PERM (1<<3)
|
||||
#define CURLFINFOFLAG_KNOWN_UID (1<<4)
|
||||
#define CURLFINFOFLAG_KNOWN_GID (1<<5)
|
||||
#define CURLFINFOFLAG_KNOWN_SIZE (1<<6)
|
||||
#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7)
|
||||
#define CURLFINFOFLAG_KNOWN_FILENAME (1 << 0)
|
||||
#define CURLFINFOFLAG_KNOWN_FILETYPE (1 << 1)
|
||||
#define CURLFINFOFLAG_KNOWN_TIME (1 << 2)
|
||||
#define CURLFINFOFLAG_KNOWN_PERM (1 << 3)
|
||||
#define CURLFINFOFLAG_KNOWN_UID (1 << 4)
|
||||
#define CURLFINFOFLAG_KNOWN_GID (1 << 5)
|
||||
#define CURLFINFOFLAG_KNOWN_SIZE (1 << 6)
|
||||
#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1 << 7)
|
||||
|
||||
/* Information about a single file, used when doing FTP wildcard matching */
|
||||
struct curl_fileinfo {
|
||||
@@ -827,34 +826,34 @@ typedef enum {
|
||||
*/
|
||||
|
||||
#define CURLAUTH_NONE ((unsigned long)0)
|
||||
#define CURLAUTH_BASIC (((unsigned long)1)<<0)
|
||||
#define CURLAUTH_DIGEST (((unsigned long)1)<<1)
|
||||
#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
|
||||
#define CURLAUTH_BASIC (((unsigned long)1) << 0)
|
||||
#define CURLAUTH_DIGEST (((unsigned long)1) << 1)
|
||||
#define CURLAUTH_NEGOTIATE (((unsigned long)1) << 2)
|
||||
/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
|
||||
#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
|
||||
/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
|
||||
#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE
|
||||
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
|
||||
#define CURLAUTH_NTLM (((unsigned long)1) << 3)
|
||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1) << 4)
|
||||
#ifndef CURL_NO_OLDIES
|
||||
/* functionality removed since 8.8.0 */
|
||||
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
||||
#define CURLAUTH_NTLM_WB (((unsigned long)1) << 5)
|
||||
#endif
|
||||
#define CURLAUTH_BEARER (((unsigned long)1)<<6)
|
||||
#define CURLAUTH_AWS_SIGV4 (((unsigned long)1)<<7)
|
||||
#define CURLAUTH_ONLY (((unsigned long)1)<<31)
|
||||
#define CURLAUTH_BEARER (((unsigned long)1) << 6)
|
||||
#define CURLAUTH_AWS_SIGV4 (((unsigned long)1) << 7)
|
||||
#define CURLAUTH_ONLY (((unsigned long)1) << 31)
|
||||
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
||||
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
|
||||
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC | CURLAUTH_DIGEST_IE))
|
||||
|
||||
#define CURLSSH_AUTH_ANY ~0L /* all types supported by the server */
|
||||
#define CURLSSH_AUTH_NONE 0L /* none allowed, silly but complete */
|
||||
#define CURLSSH_AUTH_PUBLICKEY (1L<<0) /* public/private key files */
|
||||
#define CURLSSH_AUTH_PASSWORD (1L<<1) /* password */
|
||||
#define CURLSSH_AUTH_HOST (1L<<2) /* host key files */
|
||||
#define CURLSSH_AUTH_KEYBOARD (1L<<3) /* keyboard interactive */
|
||||
#define CURLSSH_AUTH_AGENT (1L<<4) /* agent (ssh-agent, pageant...) */
|
||||
#define CURLSSH_AUTH_GSSAPI (1L<<5) /* gssapi (kerberos, ...) */
|
||||
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
|
||||
#define CURLSSH_AUTH_ANY ~0L /* all types supported by server */
|
||||
#define CURLSSH_AUTH_NONE 0L /* none allowed, silly but complete */
|
||||
#define CURLSSH_AUTH_PUBLICKEY (1L << 0) /* public/private key files */
|
||||
#define CURLSSH_AUTH_PASSWORD (1L << 1) /* password */
|
||||
#define CURLSSH_AUTH_HOST (1L << 2) /* host key files */
|
||||
#define CURLSSH_AUTH_KEYBOARD (1L << 3) /* keyboard interactive */
|
||||
#define CURLSSH_AUTH_AGENT (1L << 4) /* agent (ssh-agent, pageant...) */
|
||||
#define CURLSSH_AUTH_GSSAPI (1L << 5) /* gssapi (kerberos, ...) */
|
||||
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
|
||||
|
||||
#define CURLGSSAPI_DELEGATION_NONE 0L /* no delegation (default) */
|
||||
#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1L<<0) /* if permitted by policy */
|
||||
@@ -916,7 +915,6 @@ typedef int
|
||||
/* return CURLE_OK to accept */
|
||||
/* or something else to refuse */
|
||||
|
||||
|
||||
/* parameter for the CURLOPT_USE_SSL option */
|
||||
#define CURLUSESSL_NONE 0L /* do not attempt to use SSL */
|
||||
#define CURLUSESSL_TRY 1L /* try using SSL, proceed anyway otherwise */
|
||||
@@ -934,31 +932,31 @@ typedef enum {
|
||||
have introduced work-arounds for this flaw but those work-arounds sometimes
|
||||
make the SSL communication fail. To regain functionality with those broken
|
||||
servers, a user can this way allow the vulnerability back. */
|
||||
#define CURLSSLOPT_ALLOW_BEAST (1L<<0)
|
||||
#define CURLSSLOPT_ALLOW_BEAST (1L << 0)
|
||||
|
||||
/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
|
||||
SSL backends where such behavior is present. */
|
||||
#define CURLSSLOPT_NO_REVOKE (1L<<1)
|
||||
#define CURLSSLOPT_NO_REVOKE (1L << 1)
|
||||
|
||||
/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain
|
||||
if possible. The OpenSSL backend has this ability. */
|
||||
#define CURLSSLOPT_NO_PARTIALCHAIN (1L<<2)
|
||||
#define CURLSSLOPT_NO_PARTIALCHAIN (1L << 2)
|
||||
|
||||
/* - REVOKE_BEST_EFFORT tells libcurl to ignore certificate revocation offline
|
||||
checks and ignore missing revocation list for those SSL backends where such
|
||||
behavior is present. */
|
||||
#define CURLSSLOPT_REVOKE_BEST_EFFORT (1L<<3)
|
||||
#define CURLSSLOPT_REVOKE_BEST_EFFORT (1L << 3)
|
||||
|
||||
/* - CURLSSLOPT_NATIVE_CA tells libcurl to use standard certificate store of
|
||||
operating system. Currently implemented under MS-Windows. */
|
||||
#define CURLSSLOPT_NATIVE_CA (1L<<4)
|
||||
#define CURLSSLOPT_NATIVE_CA (1L << 4)
|
||||
|
||||
/* - CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use
|
||||
a client certificate for authentication. (Schannel) */
|
||||
#define CURLSSLOPT_AUTO_CLIENT_CERT (1L<<5)
|
||||
#define CURLSSLOPT_AUTO_CLIENT_CERT (1L << 5)
|
||||
|
||||
/* If possible, send data using TLS 1.3 early data */
|
||||
#define CURLSSLOPT_EARLYDATA (1L<<6)
|
||||
#define CURLSSLOPT_EARLYDATA (1L << 6)
|
||||
|
||||
/* The default connection attempt delay in milliseconds for happy eyeballs.
|
||||
CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document
|
||||
@@ -1025,20 +1023,20 @@ typedef enum {
|
||||
|
||||
/* bitmask defines for CURLOPT_HEADEROPT */
|
||||
#define CURLHEADER_UNIFIED 0L
|
||||
#define CURLHEADER_SEPARATE (1L<<0)
|
||||
#define CURLHEADER_SEPARATE (1L << 0)
|
||||
|
||||
/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
|
||||
#define CURLALTSVC_READONLYFILE (1L<<2)
|
||||
#define CURLALTSVC_H1 (1L<<3)
|
||||
#define CURLALTSVC_H2 (1L<<4)
|
||||
#define CURLALTSVC_H3 (1L<<5)
|
||||
#define CURLALTSVC_READONLYFILE (1L << 2)
|
||||
#define CURLALTSVC_H1 (1L << 3)
|
||||
#define CURLALTSVC_H2 (1L << 4)
|
||||
#define CURLALTSVC_H3 (1L << 5)
|
||||
|
||||
/* bitmask values for CURLOPT_UPLOAD_FLAGS */
|
||||
#define CURLULFLAG_ANSWERED (1L<<0)
|
||||
#define CURLULFLAG_DELETED (1L<<1)
|
||||
#define CURLULFLAG_DRAFT (1L<<2)
|
||||
#define CURLULFLAG_FLAGGED (1L<<3)
|
||||
#define CURLULFLAG_SEEN (1L<<4)
|
||||
#define CURLULFLAG_ANSWERED (1L << 0)
|
||||
#define CURLULFLAG_DELETED (1L << 1)
|
||||
#define CURLULFLAG_DRAFT (1L << 2)
|
||||
#define CURLULFLAG_FLAGGED (1L << 3)
|
||||
#define CURLULFLAG_SEEN (1L << 4)
|
||||
|
||||
struct curl_hstsentry {
|
||||
char *name;
|
||||
@@ -1067,41 +1065,41 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
|
||||
void *userp);
|
||||
|
||||
/* CURLHSTS_* are bits for the CURLOPT_HSTS option */
|
||||
#define CURLHSTS_ENABLE (1L<<0)
|
||||
#define CURLHSTS_READONLYFILE (1L<<1)
|
||||
#define CURLHSTS_ENABLE (1L << 0)
|
||||
#define CURLHSTS_READONLYFILE (1L << 1)
|
||||
|
||||
/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS
|
||||
options. Do not use. */
|
||||
#define CURLPROTO_HTTP (1L<<0)
|
||||
#define CURLPROTO_HTTPS (1L<<1)
|
||||
#define CURLPROTO_FTP (1L<<2)
|
||||
#define CURLPROTO_FTPS (1L<<3)
|
||||
#define CURLPROTO_SCP (1L<<4)
|
||||
#define CURLPROTO_SFTP (1L<<5)
|
||||
#define CURLPROTO_TELNET (1L<<6)
|
||||
#define CURLPROTO_LDAP (1L<<7)
|
||||
#define CURLPROTO_LDAPS (1L<<8)
|
||||
#define CURLPROTO_DICT (1L<<9)
|
||||
#define CURLPROTO_FILE (1L<<10)
|
||||
#define CURLPROTO_TFTP (1L<<11)
|
||||
#define CURLPROTO_IMAP (1L<<12)
|
||||
#define CURLPROTO_IMAPS (1L<<13)
|
||||
#define CURLPROTO_POP3 (1L<<14)
|
||||
#define CURLPROTO_POP3S (1L<<15)
|
||||
#define CURLPROTO_SMTP (1L<<16)
|
||||
#define CURLPROTO_SMTPS (1L<<17)
|
||||
#define CURLPROTO_RTSP (1L<<18)
|
||||
#define CURLPROTO_RTMP (1L<<19)
|
||||
#define CURLPROTO_RTMPT (1L<<20)
|
||||
#define CURLPROTO_RTMPE (1L<<21)
|
||||
#define CURLPROTO_RTMPTE (1L<<22)
|
||||
#define CURLPROTO_RTMPS (1L<<23)
|
||||
#define CURLPROTO_RTMPTS (1L<<24)
|
||||
#define CURLPROTO_GOPHER (1L<<25)
|
||||
#define CURLPROTO_SMB (1L<<26)
|
||||
#define CURLPROTO_SMBS (1L<<27)
|
||||
#define CURLPROTO_MQTT (1L<<28)
|
||||
#define CURLPROTO_GOPHERS (1L<<29)
|
||||
#define CURLPROTO_HTTP (1L << 0)
|
||||
#define CURLPROTO_HTTPS (1L << 1)
|
||||
#define CURLPROTO_FTP (1L << 2)
|
||||
#define CURLPROTO_FTPS (1L << 3)
|
||||
#define CURLPROTO_SCP (1L << 4)
|
||||
#define CURLPROTO_SFTP (1L << 5)
|
||||
#define CURLPROTO_TELNET (1L << 6)
|
||||
#define CURLPROTO_LDAP (1L << 7)
|
||||
#define CURLPROTO_LDAPS (1L << 8)
|
||||
#define CURLPROTO_DICT (1L << 9)
|
||||
#define CURLPROTO_FILE (1L << 10)
|
||||
#define CURLPROTO_TFTP (1L << 11)
|
||||
#define CURLPROTO_IMAP (1L << 12)
|
||||
#define CURLPROTO_IMAPS (1L << 13)
|
||||
#define CURLPROTO_POP3 (1L << 14)
|
||||
#define CURLPROTO_POP3S (1L << 15)
|
||||
#define CURLPROTO_SMTP (1L << 16)
|
||||
#define CURLPROTO_SMTPS (1L << 17)
|
||||
#define CURLPROTO_RTSP (1L << 18)
|
||||
#define CURLPROTO_RTMP (1L << 19)
|
||||
#define CURLPROTO_RTMPT (1L << 20)
|
||||
#define CURLPROTO_RTMPE (1L << 21)
|
||||
#define CURLPROTO_RTMPTE (1L << 22)
|
||||
#define CURLPROTO_RTMPS (1L << 23)
|
||||
#define CURLPROTO_RTMPTS (1L << 24)
|
||||
#define CURLPROTO_GOPHER (1L << 25)
|
||||
#define CURLPROTO_SMB (1L << 26)
|
||||
#define CURLPROTO_SMBS (1L << 27)
|
||||
#define CURLPROTO_MQTT (1L << 28)
|
||||
#define CURLPROTO_GOPHERS (1L << 29)
|
||||
#define CURLPROTO_ALL (~0L) /* enable everything */
|
||||
|
||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||
@@ -1115,7 +1113,6 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy,
|
||||
/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
|
||||
string options from the header file */
|
||||
|
||||
|
||||
#define CURLOPT(na,t,nu) na = t + nu
|
||||
#define CURLOPTDEPRECATED(na,t,nu,v,m) na CURL_DEPRECATED(v,m) = t + nu
|
||||
|
||||
@@ -1874,9 +1871,7 @@ typedef enum {
|
||||
|
||||
libcurl will ask for the compressed methods it knows of, and if that
|
||||
is not any, it will not ask for transfer-encoding at all even if this
|
||||
option is set to 1.
|
||||
|
||||
*/
|
||||
option is set to 1. */
|
||||
CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207),
|
||||
|
||||
/* Callback function for closing socket (instead of close(2)). The callback
|
||||
@@ -2294,10 +2289,9 @@ typedef enum {
|
||||
#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
|
||||
#endif
|
||||
|
||||
|
||||
/* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
|
||||
name resolves addresses using more than one IP protocol version, this
|
||||
option might be handy to force libcurl to use a specific IP version. */
|
||||
/* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
|
||||
name resolves addresses using more than one IP protocol version, this
|
||||
option might be handy to force libcurl to use a specific IP version. */
|
||||
#define CURL_IPRESOLVE_WHATEVER 0L /* default, uses addresses to all IP
|
||||
versions that your system allows */
|
||||
#define CURL_IPRESOLVE_V4 1L /* uses only IPv4 addresses/connections */
|
||||
@@ -2381,7 +2375,7 @@ enum CURL_NETRC_OPTION {
|
||||
#define CURL_SSLVERSION_MAX_TLSv1_2 (CURL_SSLVERSION_TLSv1_2 << 16)
|
||||
#define CURL_SSLVERSION_MAX_TLSv1_3 (CURL_SSLVERSION_TLSv1_3 << 16)
|
||||
|
||||
/* never use, keep last */
|
||||
/* never use, keep last */
|
||||
#define CURL_SSLVERSION_MAX_LAST (CURL_SSLVERSION_LAST << 16)
|
||||
|
||||
#define CURL_TLSAUTH_NONE 0L
|
||||
@@ -2403,7 +2397,7 @@ enum CURL_TLSAUTH {
|
||||
#define CURL_REDIR_POST_302 2L
|
||||
#define CURL_REDIR_POST_303 4L
|
||||
#define CURL_REDIR_POST_ALL \
|
||||
(CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
|
||||
(CURL_REDIR_POST_301 | CURL_REDIR_POST_302 | CURL_REDIR_POST_303)
|
||||
|
||||
#define CURL_TIMECOND_NONE 0L
|
||||
#define CURL_TIMECOND_IFMODSINCE 1L
|
||||
@@ -2418,7 +2412,7 @@ typedef enum {
|
||||
} curl_TimeCond;
|
||||
|
||||
/* Special size_t value signaling a null-terminated string. */
|
||||
#define CURL_ZERO_TERMINATED ((size_t) -1)
|
||||
#define CURL_ZERO_TERMINATED ((size_t)-1)
|
||||
|
||||
/* curl_strequal() and curl_strnequal() are subject for removal in a future
|
||||
release */
|
||||
@@ -2430,7 +2424,7 @@ typedef struct curl_mime curl_mime; /* Mime context. */
|
||||
typedef struct curl_mimepart curl_mimepart; /* Mime part context. */
|
||||
|
||||
/* CURLMIMEOPT_ defines are for the CURLOPT_MIME_OPTIONS option. */
|
||||
#define CURLMIMEOPT_FORMESCAPE (1L<<0) /* Use backslash-escaping for forms. */
|
||||
#define CURLMIMEOPT_FORMESCAPE (1L << 0) /* Use backslash-escaping for forms */
|
||||
|
||||
/*
|
||||
* NAME curl_mime_init()
|
||||
@@ -2705,7 +2699,6 @@ CURL_EXTERN char *curl_easy_escape(CURL *handle,
|
||||
CURL_EXTERN char *curl_escape(const char *string,
|
||||
int length);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_unescape()
|
||||
*
|
||||
@@ -2743,10 +2736,9 @@ CURL_EXTERN void curl_free(void *p);
|
||||
*
|
||||
* curl_global_init() should be invoked exactly once for each application that
|
||||
* uses libcurl and before any call of other libcurl functions.
|
||||
|
||||
*
|
||||
* This function is thread-safe if CURL_VERSION_THREADSAFE is set in the
|
||||
* curl_version_info_data.features flag (fetch by curl_version_info()).
|
||||
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_global_init(long flags);
|
||||
|
||||
@@ -2787,10 +2779,9 @@ CURL_EXTERN void curl_global_cleanup(void);
|
||||
*
|
||||
* curl_global_trace() can be invoked at application start to
|
||||
* configure which components in curl should participate in tracing.
|
||||
|
||||
*
|
||||
* This function is thread-safe if CURL_VERSION_THREADSAFE is set in the
|
||||
* curl_version_info_data.features flag (fetch by curl_version_info()).
|
||||
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_global_trace(const char *config);
|
||||
|
||||
@@ -3015,13 +3006,12 @@ typedef enum {
|
||||
CURLCLOSEPOLICY_LAST /* last, never use this */
|
||||
} curl_closepolicy;
|
||||
|
||||
#define CURL_GLOBAL_SSL (1<<0) /* no purpose since 7.57.0 */
|
||||
#define CURL_GLOBAL_WIN32 (1<<1)
|
||||
#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
|
||||
#define CURL_GLOBAL_SSL (1 << 0) /* no purpose since 7.57.0 */
|
||||
#define CURL_GLOBAL_WIN32 (1 << 1)
|
||||
#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL | CURL_GLOBAL_WIN32)
|
||||
#define CURL_GLOBAL_NOTHING 0
|
||||
#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
|
||||
#define CURL_GLOBAL_ACK_EINTR (1<<2)
|
||||
|
||||
#define CURL_GLOBAL_ACK_EINTR (1 << 2)
|
||||
|
||||
/*****************************************************************************
|
||||
* Setup defines, protos etc for the sharing stuff.
|
||||
@@ -3060,7 +3050,6 @@ typedef void (*curl_unlock_function)(CURL *handle,
|
||||
curl_lock_data data,
|
||||
void *userptr);
|
||||
|
||||
|
||||
typedef enum {
|
||||
CURLSHE_OK, /* all is fine */
|
||||
CURLSHE_BAD_OPTION, /* 1 */
|
||||
@@ -3258,14 +3247,14 @@ CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
|
||||
|
||||
#define CURLPAUSE_RECV (1<<0)
|
||||
#define CURLPAUSE_RECV (1 << 0)
|
||||
#define CURLPAUSE_RECV_CONT (0)
|
||||
|
||||
#define CURLPAUSE_SEND (1<<2)
|
||||
#define CURLPAUSE_SEND (1 << 2)
|
||||
#define CURLPAUSE_SEND_CONT (0)
|
||||
|
||||
#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
|
||||
#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
|
||||
#define CURLPAUSE_ALL (CURLPAUSE_RECV | CURLPAUSE_SEND)
|
||||
#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT | CURLPAUSE_SEND_CONT)
|
||||
|
||||
/*
|
||||
* NAME curl_easy_ssls_import()
|
||||
@@ -3310,7 +3299,6 @@ CURL_EXTERN CURLcode curl_easy_ssls_export(CURL *handle,
|
||||
curl_ssls_export_cb *export_fn,
|
||||
void *userptr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "8.17.0-DEV"
|
||||
#define LIBCURL_VERSION "8.18.0-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 8
|
||||
#define LIBCURL_VERSION_MINOR 17
|
||||
#define LIBCURL_VERSION_MINOR 18
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -58,7 +58,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 0x081100
|
||||
#define LIBCURL_VERSION_NUM 0x081200
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@@ -71,8 +71,8 @@
|
||||
*/
|
||||
#define LIBCURL_TIMESTAMP "[unreleased]"
|
||||
|
||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
|
||||
#define CURL_AT_LEAST_VERSION(x,y,z) \
|
||||
#define CURL_VERSION_BITS(x, y, z) ((x) << 16 | (y) << 8 | (z))
|
||||
#define CURL_AT_LEAST_VERSION(x, y, z) \
|
||||
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
|
||||
|
||||
#endif /* CURLINC_CURLVER_H */
|
||||
+2
-4
@@ -50,7 +50,7 @@ CURL_EXTERN void curl_easy_cleanup(CURL *curl);
|
||||
*
|
||||
* Request internal information from the curl session with this function.
|
||||
* The third argument MUST be pointing to the specific type of the used option
|
||||
* which is documented in each manpage of the option. The data pointed to
|
||||
* which is documented in each man page of the option. The data pointed to
|
||||
* will be filled in accordingly and can be relied upon only if the function
|
||||
* returns CURLE_OK. This function is intended to get used *AFTER* a performed
|
||||
* transfer, all results from this function are undefined until the transfer
|
||||
@@ -58,7 +58,6 @@ CURL_EXTERN void curl_easy_cleanup(CURL *curl);
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_duphandle()
|
||||
*
|
||||
@@ -67,7 +66,7 @@ CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
|
||||
* Creates a new curl session handle with the same options set for the handle
|
||||
* passed in. Duplicating a handle could only be a matter of cloning data and
|
||||
* options, internal state info and things like persistent connections cannot
|
||||
* be transferred. It is useful in multithreaded applications when you can run
|
||||
* be transferred. It is useful in multi-threaded applications when you can run
|
||||
* curl_easy_duphandle() for each new thread to avoid a series of identical
|
||||
* curl_easy_setopt() invokes in every thread.
|
||||
*/
|
||||
@@ -108,7 +107,6 @@ CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
|
||||
CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
|
||||
size_t buflen, size_t *n);
|
||||
|
||||
|
||||
/*
|
||||
* NAME curl_easy_upkeep()
|
||||
*
|
||||
|
||||
@@ -38,11 +38,11 @@ struct curl_header {
|
||||
};
|
||||
|
||||
/* 'origin' bits */
|
||||
#define CURLH_HEADER (1<<0) /* plain server header */
|
||||
#define CURLH_TRAILER (1<<1) /* trailers */
|
||||
#define CURLH_CONNECT (1<<2) /* CONNECT headers */
|
||||
#define CURLH_1XX (1<<3) /* 1xx headers */
|
||||
#define CURLH_PSEUDO (1<<4) /* pseudo headers */
|
||||
#define CURLH_HEADER (1 << 0) /* plain server header */
|
||||
#define CURLH_TRAILER (1 << 1) /* trailers */
|
||||
#define CURLH_CONNECT (1 << 2) /* CONNECT headers */
|
||||
#define CURLH_1XX (1 << 3) /* 1xx headers */
|
||||
#define CURLH_PSEUDO (1 << 4) /* pseudo headers */
|
||||
|
||||
typedef enum {
|
||||
CURLHE_OK,
|
||||
|
||||
+49
-51
@@ -136,25 +136,25 @@ CURL_EXTERN CURLM *curl_multi_init(void);
|
||||
CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_remove_handle()
|
||||
*
|
||||
* Desc: removes a curl handle from the multi stack again
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
/*
|
||||
* Name: curl_multi_remove_handle()
|
||||
*
|
||||
* Desc: removes a curl handle from the multi stack again
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_fdset()
|
||||
*
|
||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||
* them are ready.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
/*
|
||||
* Name: curl_multi_fdset()
|
||||
*
|
||||
* Desc: Ask curl for its fd_set sets. The app can use these to select() or
|
||||
* poll() on. We want curl_multi_perform() called as soon as one of
|
||||
* them are ready.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
fd_set *read_fd_set,
|
||||
fd_set *write_fd_set,
|
||||
@@ -198,35 +198,35 @@ CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle,
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_perform()
|
||||
*
|
||||
* Desc: When the app thinks there is data available for curl it calls this
|
||||
* function to read/write whatever there is right now. This returns
|
||||
* as soon as the reads and writes are done. This function does not
|
||||
* require that there actually is data available for reading or that
|
||||
* data can be written, it can be called just in case. It returns
|
||||
* the number of handles that still transfer data in the second
|
||||
* argument's integer-pointer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
||||
* returns errors etc regarding the whole multi stack. There might
|
||||
* still have occurred problems on individual transfers even when
|
||||
* this returns OK.
|
||||
*/
|
||||
/*
|
||||
* Name: curl_multi_perform()
|
||||
*
|
||||
* Desc: When the app thinks there is data available for curl it calls this
|
||||
* function to read/write whatever there is right now. This returns
|
||||
* as soon as the reads and writes are done. This function does not
|
||||
* require that there actually is data available for reading or that
|
||||
* data can be written, it can be called just in case. It returns
|
||||
* the number of handles that still transfer data in the second
|
||||
* argument's integer-pointer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code. *NOTE* that this only
|
||||
* returns errors etc regarding the whole multi stack. There might
|
||||
* still have occurred problems on individual transfers even when
|
||||
* this returns OK.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
|
||||
int *running_handles);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_cleanup()
|
||||
*
|
||||
* Desc: Cleans up and removes a whole multi stack. It does not free or
|
||||
* touch any individual easy handles in any way. We need to define
|
||||
* in what state those handles will be if this function is called
|
||||
* in the middle of a transfer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
/*
|
||||
* Name: curl_multi_cleanup()
|
||||
*
|
||||
* Desc: Cleans up and removes a whole multi stack. It does not free or
|
||||
* touch any individual easy handles in any way. We need to define
|
||||
* in what state those handles will be if this function is called
|
||||
* in the middle of a transfer.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
|
||||
|
||||
/*
|
||||
@@ -278,7 +278,7 @@ CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
|
||||
* Desc: An alternative version of curl_multi_perform() that allows the
|
||||
* application to pass in one of the file descriptors that have been
|
||||
* detected to have "action" on them and let libcurl perform.
|
||||
* See manpage for details.
|
||||
* See man page for details.
|
||||
*/
|
||||
#define CURL_POLL_NONE 0
|
||||
#define CURL_POLL_IN 1
|
||||
@@ -327,8 +327,8 @@ curl_multi_socket_all(CURLM *multi_handle, int *running_handles);
|
||||
|
||||
#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
|
||||
/* This macro below was added in 7.16.3 to push users who recompile to use
|
||||
the new curl_multi_socket_action() instead of the old curl_multi_socket()
|
||||
*/
|
||||
* the new curl_multi_socket_action() instead of the old curl_multi_socket()
|
||||
*/
|
||||
#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
|
||||
#endif
|
||||
|
||||
@@ -351,10 +351,10 @@ typedef enum {
|
||||
/* This is the argument passed to the socket callback */
|
||||
CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2),
|
||||
|
||||
/* set to 1 to enable pipelining for this multi handle */
|
||||
/* set to 1 to enable pipelining for this multi handle */
|
||||
CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3),
|
||||
|
||||
/* This is the timer callback function pointer */
|
||||
/* This is the timer callback function pointer */
|
||||
CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4),
|
||||
|
||||
/* This is the argument passed to the timer callback */
|
||||
@@ -412,12 +412,12 @@ typedef enum {
|
||||
/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing
|
||||
connections. Connections that are idle will be closed. Ongoing transfers
|
||||
will continue with the connection they have. */
|
||||
#define CURLMNWC_CLEAR_CONNS (1L<<0)
|
||||
#define CURLMNWC_CLEAR_CONNS (1L << 0)
|
||||
|
||||
/* - CURLMNWC_CLEAR_DNS tells libcurl to prevent further reuse of existing
|
||||
connections. Connections that are idle will be closed. Ongoing transfers
|
||||
will continue with the connection they have. */
|
||||
#define CURLMNWC_CLEAR_DNS (1L<<0)
|
||||
#define CURLMNWC_CLEAR_DNS (1L << 0)
|
||||
|
||||
/*
|
||||
* Name: curl_multi_setopt()
|
||||
@@ -429,7 +429,6 @@ typedef enum {
|
||||
CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
CURLMoption option, ...);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_multi_assign()
|
||||
*
|
||||
@@ -454,7 +453,6 @@ CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
*/
|
||||
CURL_EXTERN CURL **curl_multi_get_handles(CURLM *multi_handle);
|
||||
|
||||
|
||||
typedef enum {
|
||||
CURLMINFO_NONE, /* first, never use this */
|
||||
/* The number of easy handles currently managed by the multi handle,
|
||||
|
||||
@@ -44,7 +44,7 @@ typedef enum {
|
||||
|
||||
/* "alias" means it is provided for old programs to remain functional,
|
||||
we prefer another name */
|
||||
#define CURLOT_FLAG_ALIAS (1<<0)
|
||||
#define CURLOT_FLAG_ALIAS (1 << 0)
|
||||
|
||||
/* The CURLOPTTYPE_* id ranges can still be used to figure out what type/size
|
||||
to use for curl_easy_setopt() for the given id */
|
||||
|
||||
+6
-15
@@ -135,21 +135,12 @@
|
||||
# endif
|
||||
|
||||
#elif defined(UNDER_CE)
|
||||
# ifdef __MINGW32CE__
|
||||
# define CURL_TYPEOF_CURL_OFF_T long long
|
||||
# define CURL_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
# include <inttypes.h>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* wraps curl_easy_setopt() with typechecking */
|
||||
/* wraps curl_easy_setopt() with type checking */
|
||||
|
||||
/* To add a new kind of warning, add an
|
||||
* if(curlcheck_sometype_option(_curl_opt))
|
||||
@@ -159,7 +159,7 @@
|
||||
curl_easy_setopt(handle, option, value); \
|
||||
})
|
||||
|
||||
/* wraps curl_easy_getinfo() with typechecking */
|
||||
/* wraps curl_easy_getinfo() with type checking */
|
||||
#define curl_easy_getinfo(handle, info, arg) \
|
||||
__extension__({ \
|
||||
if(__builtin_constant_p(info)) { \
|
||||
@@ -264,7 +264,6 @@
|
||||
*/
|
||||
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
|
||||
|
||||
|
||||
/* the actual warnings, triggered by calling the Wcurl_easy_setopt_err*
|
||||
* functions */
|
||||
|
||||
@@ -590,8 +589,9 @@ CURLWARNING(Wcurl_easy_getinfo_err_curl_off_t,
|
||||
#define curlcheck_off_t_info(info) \
|
||||
(CURLINFO_OFF_T < (info))
|
||||
|
||||
|
||||
/* typecheck helpers -- check whether given expression has requested type */
|
||||
/*
|
||||
* typecheck helpers -- check whether given expression has requested type
|
||||
*/
|
||||
|
||||
/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros,
|
||||
* otherwise define a new macro. Search for __builtin_types_compatible_p
|
||||
@@ -641,7 +641,6 @@ CURLWARNING(Wcurl_easy_getinfo_err_curl_off_t,
|
||||
(curlcheck_NULL(expr) || \
|
||||
__builtin_types_compatible_p(__typeof__(expr), CURL *))
|
||||
|
||||
|
||||
/* evaluates to true if expr is a long (no matter the signedness)
|
||||
* XXX: for now, int is also accepted (and therefore short and char, which
|
||||
* are promoted to int when passed to a variadic function) */
|
||||
|
||||
+22
-22
@@ -81,28 +81,28 @@ typedef enum {
|
||||
CURLUPART_ZONEID /* added in 7.65.0 */
|
||||
} CURLUPart;
|
||||
|
||||
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
|
||||
#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set,
|
||||
if the port number matches the
|
||||
default for the scheme */
|
||||
#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if
|
||||
missing */
|
||||
#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */
|
||||
#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */
|
||||
#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */
|
||||
#define CURLU_URLDECODE (1<<6) /* URL decode on get */
|
||||
#define CURLU_URLENCODE (1<<7) /* URL encode on set */
|
||||
#define CURLU_APPENDQUERY (1<<8) /* append a form style part */
|
||||
#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */
|
||||
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
|
||||
scheme is unknown. */
|
||||
#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
|
||||
#define CURLU_PUNYCODE (1<<12) /* get the hostname in punycode */
|
||||
#define CURLU_PUNY2IDN (1<<13) /* punycode => IDN conversion */
|
||||
#define CURLU_GET_EMPTY (1<<14) /* allow empty queries and fragments
|
||||
when extracting the URL or the
|
||||
components */
|
||||
#define CURLU_NO_GUESS_SCHEME (1<<15) /* for get, do not accept a guess */
|
||||
#define CURLU_DEFAULT_PORT (1 << 0) /* return default port number */
|
||||
#define CURLU_NO_DEFAULT_PORT (1 << 1) /* act as if no port number was set,
|
||||
if the port number matches the
|
||||
default for the scheme */
|
||||
#define CURLU_DEFAULT_SCHEME (1 << 2) /* return default scheme if
|
||||
missing */
|
||||
#define CURLU_NON_SUPPORT_SCHEME (1 << 3) /* allow non-supported scheme */
|
||||
#define CURLU_PATH_AS_IS (1 << 4) /* leave dot sequences */
|
||||
#define CURLU_DISALLOW_USER (1 << 5) /* no user+password allowed */
|
||||
#define CURLU_URLDECODE (1 << 6) /* URL decode on get */
|
||||
#define CURLU_URLENCODE (1 << 7) /* URL encode on set */
|
||||
#define CURLU_APPENDQUERY (1 << 8) /* append a form style part */
|
||||
#define CURLU_GUESS_SCHEME (1 << 9) /* legacy curl-style guessing */
|
||||
#define CURLU_NO_AUTHORITY (1 << 10) /* Allow empty authority when the
|
||||
scheme is unknown. */
|
||||
#define CURLU_ALLOW_SPACE (1 << 11) /* Allow spaces in the URL */
|
||||
#define CURLU_PUNYCODE (1 << 12) /* get the hostname in punycode */
|
||||
#define CURLU_PUNY2IDN (1 << 13) /* punycode => IDN conversion */
|
||||
#define CURLU_GET_EMPTY (1 << 14) /* allow empty queries and fragments
|
||||
when extracting the URL or the
|
||||
components */
|
||||
#define CURLU_NO_GUESS_SCHEME (1 << 15) /* for get, do not accept a guess */
|
||||
|
||||
typedef struct Curl_URL CURLU;
|
||||
|
||||
|
||||
@@ -37,12 +37,12 @@ struct curl_ws_frame {
|
||||
};
|
||||
|
||||
/* flag bits */
|
||||
#define CURLWS_TEXT (1<<0)
|
||||
#define CURLWS_BINARY (1<<1)
|
||||
#define CURLWS_CONT (1<<2)
|
||||
#define CURLWS_CLOSE (1<<3)
|
||||
#define CURLWS_PING (1<<4)
|
||||
#define CURLWS_OFFSET (1<<5)
|
||||
#define CURLWS_TEXT (1 << 0)
|
||||
#define CURLWS_BINARY (1 << 1)
|
||||
#define CURLWS_CONT (1 << 2)
|
||||
#define CURLWS_CLOSE (1 << 3)
|
||||
#define CURLWS_PING (1 << 4)
|
||||
#define CURLWS_OFFSET (1 << 5)
|
||||
|
||||
/*
|
||||
* NAME curl_ws_recv()
|
||||
@@ -57,7 +57,7 @@ CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen,
|
||||
const struct curl_ws_frame **metap);
|
||||
|
||||
/* flags for curl_ws_send() */
|
||||
#define CURLWS_PONG (1<<6)
|
||||
#define CURLWS_PONG (1 << 6)
|
||||
|
||||
/*
|
||||
* NAME curl_ws_send()
|
||||
@@ -86,8 +86,8 @@ CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl,
|
||||
curl_off_t frame_len);
|
||||
|
||||
/* bits for the CURLOPT_WS_OPTIONS bitmask: */
|
||||
#define CURLWS_RAW_MODE (1L<<0)
|
||||
#define CURLWS_NOAUTOPONG (1L<<1)
|
||||
#define CURLWS_RAW_MODE (1L << 0)
|
||||
#define CURLWS_NOAUTOPONG (1L << 1)
|
||||
|
||||
CURL_EXTERN const struct curl_ws_frame *curl_ws_meta(CURL *curl);
|
||||
|
||||
|
||||
+35
-6
@@ -26,7 +26,7 @@ set(LIBCURL_OUTPUT_NAME "${LIB_NAME}" CACHE STRING "Basename of the curl library
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ${CURL_DEBUG_MACROS} "BUILDING_LIBCURL")
|
||||
|
||||
configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
|
||||
configure_file("curl_config-cmake.h.in" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
|
||||
|
||||
# Get CSOURCES, HHEADERS, LIB_RCFILES variables
|
||||
curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
@@ -44,7 +44,7 @@ if(CURL_BUILD_TESTING)
|
||||
# special libcurlu library just for unittests
|
||||
add_library(curlu STATIC EXCLUDE_FROM_ALL ${HHEADERS} ${CSOURCES})
|
||||
target_compile_definitions(curlu PUBLIC "CURL_STATICLIB" "UNITTESTS")
|
||||
target_link_libraries(curlu PRIVATE ${CURL_LIBS})
|
||||
target_link_libraries(curlu PUBLIC ${CURL_LIBS})
|
||||
# There is plenty of parallelism when building the testdeps target.
|
||||
# Override the curlu batch size with the maximum to optimize performance.
|
||||
set_target_properties(curlu PROPERTIES UNITY_BUILD_BATCH_SIZE 0 C_CLANG_TIDY "")
|
||||
@@ -151,8 +151,7 @@ if(BUILD_STATIC_LIBS)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
|
||||
SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB"
|
||||
INTERFACE_LINK_DIRECTORIES "${CURL_LIBDIRS}")
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
|
||||
if(CURL_HIDES_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_OPTIONS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
@@ -174,6 +173,27 @@ if(BUILD_STATIC_LIBS)
|
||||
target_include_directories(${LIB_STATIC} INTERFACE
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
|
||||
|
||||
# CMake before CMP0099 (CMake 3.17 2020-03-20) did not propagate libdirs to
|
||||
# targets. It expected libs to have an absolute filename. As a workaround,
|
||||
# manually apply dependency libdirs, for CMake consumers without this policy.
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17)
|
||||
cmake_policy(GET CMP0099 _has_CMP0099) # https://cmake.org/cmake/help/latest/policy/CMP0099.html
|
||||
endif()
|
||||
if(NOT _has_CMP0099 AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.13 AND CURL_LIBS)
|
||||
set(_curl_libdirs "")
|
||||
foreach(_curl_lib IN LISTS CURL_LIBS)
|
||||
if(TARGET "${_curl_lib}")
|
||||
get_target_property(_curl_libdir "${_curl_lib}" INTERFACE_LINK_DIRECTORIES)
|
||||
if(_curl_libdir)
|
||||
list(APPEND _curl_libdirs "${_curl_libdir}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
if(_curl_libdirs)
|
||||
target_link_directories(${LIB_STATIC} INTERFACE ${_curl_libdirs})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
@@ -304,7 +324,7 @@ add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})
|
||||
add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED})
|
||||
|
||||
if(CURL_ENABLE_EXPORT_TARGET)
|
||||
if(BUILD_STATIC_LIBS)
|
||||
if(NOT CURL_DISABLE_INSTALL AND BUILD_STATIC_LIBS)
|
||||
install(TARGETS ${LIB_STATIC}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
@@ -312,7 +332,7 @@ if(CURL_ENABLE_EXPORT_TARGET)
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(NOT CURL_DISABLE_INSTALL AND BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${LIB_SHARED}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
@@ -326,3 +346,12 @@ if(CURL_ENABLE_EXPORT_TARGET)
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
)
|
||||
endif()
|
||||
|
||||
if(PERL_EXECUTABLE)
|
||||
add_custom_target(curl-optiontable
|
||||
COMMENT "Generating lib/easyoptions.c" VERBATIM USES_TERMINAL
|
||||
COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/optiontable.pl" < "${PROJECT_SOURCE_DIR}/include/curl/curl.h"
|
||||
> "${PROJECT_SOURCE_DIR}/lib/easyoptions.c"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/optiontable.pl" "${PROJECT_SOURCE_DIR}/include/curl/curl.h"
|
||||
)
|
||||
endif()
|
||||
+9
-13
@@ -31,6 +31,7 @@ LIB_CURLX_CFILES = \
|
||||
curlx/inet_pton.c \
|
||||
curlx/multibyte.c \
|
||||
curlx/nonblock.c \
|
||||
curlx/strcopy.c \
|
||||
curlx/strerr.c \
|
||||
curlx/strparse.c \
|
||||
curlx/timediff.c \
|
||||
@@ -50,6 +51,8 @@ LIB_CURLX_HFILES = \
|
||||
curlx/inet_pton.h \
|
||||
curlx/multibyte.h \
|
||||
curlx/nonblock.h \
|
||||
curlx/snprintf.h \
|
||||
curlx/strcopy.h \
|
||||
curlx/strerr.h \
|
||||
curlx/strparse.h \
|
||||
curlx/timediff.h \
|
||||
@@ -85,7 +88,6 @@ LIB_VTLS_CFILES = \
|
||||
vtls/hostcheck.c \
|
||||
vtls/keylog.c \
|
||||
vtls/mbedtls.c \
|
||||
vtls/mbedtls_threadlock.c \
|
||||
vtls/openssl.c \
|
||||
vtls/rustls.c \
|
||||
vtls/schannel.c \
|
||||
@@ -103,7 +105,6 @@ LIB_VTLS_HFILES = \
|
||||
vtls/hostcheck.h \
|
||||
vtls/keylog.h \
|
||||
vtls/mbedtls.h \
|
||||
vtls/mbedtls_threadlock.h \
|
||||
vtls/openssl.h \
|
||||
vtls/rustls.h \
|
||||
vtls/schannel.h \
|
||||
@@ -133,10 +134,10 @@ LIB_VQUIC_HFILES = \
|
||||
LIB_VSSH_CFILES = \
|
||||
vssh/libssh.c \
|
||||
vssh/libssh2.c \
|
||||
vssh/curl_path.c
|
||||
vssh/vssh.c
|
||||
|
||||
LIB_VSSH_HFILES = \
|
||||
vssh/curl_path.h \
|
||||
vssh/vssh.h \
|
||||
vssh/ssh.h
|
||||
|
||||
LIB_CFILES = \
|
||||
@@ -172,6 +173,7 @@ LIB_CFILES = \
|
||||
curl_rtmp.c \
|
||||
curl_sasl.c \
|
||||
curl_sha512_256.c \
|
||||
curl_share.c \
|
||||
curl_sspi.c \
|
||||
curl_threads.c \
|
||||
curl_trc.c \
|
||||
@@ -234,14 +236,13 @@ LIB_CFILES = \
|
||||
progress.c \
|
||||
psl.c \
|
||||
rand.c \
|
||||
rename.c \
|
||||
ratelimit.c \
|
||||
request.c \
|
||||
rtsp.c \
|
||||
select.c \
|
||||
sendf.c \
|
||||
setopt.c \
|
||||
sha256.c \
|
||||
share.c \
|
||||
slist.c \
|
||||
smb.c \
|
||||
smtp.c \
|
||||
@@ -249,7 +250,6 @@ LIB_CFILES = \
|
||||
socks.c \
|
||||
socks_gssapi.c \
|
||||
socks_sspi.c \
|
||||
speedcheck.c \
|
||||
splay.c \
|
||||
strcase.c \
|
||||
strdup.c \
|
||||
@@ -299,8 +299,6 @@ LIB_HFILES = \
|
||||
curl_ldap.h \
|
||||
curl_md4.h \
|
||||
curl_md5.h \
|
||||
curl_mem_undef.h \
|
||||
curl_memory.h \
|
||||
curl_memrchr.h \
|
||||
curl_ntlm_core.h \
|
||||
curl_printf.h \
|
||||
@@ -311,6 +309,7 @@ LIB_HFILES = \
|
||||
curl_setup_once.h \
|
||||
curl_sha256.h \
|
||||
curl_sha512_256.h \
|
||||
curl_share.h \
|
||||
curl_sspi.h \
|
||||
curl_threads.h \
|
||||
curl_trc.h \
|
||||
@@ -351,7 +350,6 @@ LIB_HFILES = \
|
||||
imap.h \
|
||||
llist.h \
|
||||
macos.h \
|
||||
memdebug.h \
|
||||
mime.h \
|
||||
mqtt.h \
|
||||
multihandle.h \
|
||||
@@ -366,7 +364,7 @@ LIB_HFILES = \
|
||||
progress.h \
|
||||
psl.h \
|
||||
rand.h \
|
||||
rename.h \
|
||||
ratelimit.h \
|
||||
request.h \
|
||||
rtsp.h \
|
||||
select.h \
|
||||
@@ -375,7 +373,6 @@ LIB_HFILES = \
|
||||
setup-os400.h \
|
||||
setup-vms.h \
|
||||
setup-win32.h \
|
||||
share.h \
|
||||
sigpipe.h \
|
||||
slist.h \
|
||||
smb.h \
|
||||
@@ -383,7 +380,6 @@ LIB_HFILES = \
|
||||
sockaddr.h \
|
||||
socketpair.h \
|
||||
socks.h \
|
||||
speedcheck.h \
|
||||
splay.h \
|
||||
strcase.h \
|
||||
strdup.h \
|
||||
|
||||
+80
-93
@@ -28,25 +28,17 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "altsvc.h"
|
||||
#include "curl_fopen.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "parsedate.h"
|
||||
#include "sendf.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "rename.h"
|
||||
#include "strdup.h"
|
||||
#include "curl_trc.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_DATELEN 256
|
||||
#define MAX_ALTSVC_HOSTLEN 2048
|
||||
#define MAX_ALTSVC_ALPNLEN 10
|
||||
@@ -68,13 +60,7 @@ const char *Curl_alpnid2str(enum alpnid id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void altsvc_free(struct altsvc *as)
|
||||
{
|
||||
free(as->src.host);
|
||||
free(as->dst.host);
|
||||
free(as);
|
||||
}
|
||||
#define altsvc_free(x) curlx_free(x)
|
||||
|
||||
static struct altsvc *altsvc_createid(const char *srchost,
|
||||
size_t hlen,
|
||||
@@ -85,38 +71,35 @@ static struct altsvc *altsvc_createid(const char *srchost,
|
||||
size_t srcport,
|
||||
size_t dstport)
|
||||
{
|
||||
struct altsvc *as = calloc(1, sizeof(struct altsvc));
|
||||
if(!as)
|
||||
return NULL;
|
||||
DEBUGASSERT(hlen);
|
||||
DEBUGASSERT(dlen);
|
||||
if(!hlen || !dlen)
|
||||
/* bad input */
|
||||
goto error;
|
||||
struct altsvc *as;
|
||||
if((hlen > 2) && srchost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
srchost++;
|
||||
hlen -= 2;
|
||||
}
|
||||
else if(srchost[hlen - 1] == '.') {
|
||||
else if(hlen && (srchost[hlen - 1] == '.')) {
|
||||
/* strip off trailing dot */
|
||||
hlen--;
|
||||
if(!hlen)
|
||||
goto error;
|
||||
}
|
||||
if((dlen > 2) && dsthost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
dsthost++;
|
||||
dlen -= 2;
|
||||
}
|
||||
if(!hlen || !dlen)
|
||||
/* bad input */
|
||||
return NULL;
|
||||
/* struct size plus both strings */
|
||||
as = curlx_calloc(1, sizeof(struct altsvc) + (hlen + 1) + (dlen + 1));
|
||||
if(!as)
|
||||
return NULL;
|
||||
as->src.host = (char *)as + sizeof(struct altsvc);
|
||||
memcpy(as->src.host, srchost, hlen);
|
||||
/* the null terminator is already there */
|
||||
|
||||
as->src.host = Curl_memdup0(srchost, hlen);
|
||||
if(!as->src.host)
|
||||
goto error;
|
||||
|
||||
as->dst.host = Curl_memdup0(dsthost, dlen);
|
||||
if(!as->dst.host)
|
||||
goto error;
|
||||
as->dst.host = (char *)as + sizeof(struct altsvc) + hlen + 1;
|
||||
memcpy(as->dst.host, dsthost, dlen);
|
||||
/* the null terminator is already there */
|
||||
|
||||
as->src.alpnid = srcalpnid;
|
||||
as->dst.alpnid = dstalpnid;
|
||||
@@ -124,9 +107,6 @@ static struct altsvc *altsvc_createid(const char *srchost,
|
||||
as->dst.port = (unsigned short)dstport;
|
||||
|
||||
return as;
|
||||
error:
|
||||
altsvc_free(as);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_create(struct Curl_str *srchost,
|
||||
@@ -136,10 +116,8 @@ static struct altsvc *altsvc_create(struct Curl_str *srchost,
|
||||
size_t srcport,
|
||||
size_t dstport)
|
||||
{
|
||||
enum alpnid dstalpnid =
|
||||
Curl_alpn2alpnid(curlx_str(dstalpn), curlx_strlen(dstalpn));
|
||||
enum alpnid srcalpnid =
|
||||
Curl_alpn2alpnid(curlx_str(srcalpn), curlx_strlen(srcalpn));
|
||||
enum alpnid dstalpnid = Curl_str2alpnid(dstalpn);
|
||||
enum alpnid srcalpnid = Curl_str2alpnid(srcalpn);
|
||||
if(!srcalpnid || !dstalpnid)
|
||||
return NULL;
|
||||
return altsvc_createid(curlx_str(srchost), curlx_strlen(srchost),
|
||||
@@ -201,6 +179,8 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line)
|
||||
as->persist = persist ? 1 : 0;
|
||||
Curl_llist_append(&asi->list, as, &as->node);
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -221,8 +201,8 @@ static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
|
||||
|
||||
/* we need a private copy of the filename so that the altsvc cache file
|
||||
name survives an easy handle reset */
|
||||
free(asi->filename);
|
||||
asi->filename = strdup(file);
|
||||
curlx_free(asi->filename);
|
||||
asi->filename = curlx_strdup(file);
|
||||
if(!asi->filename)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -257,7 +237,7 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
const char *dst6_post = "";
|
||||
const char *src6_pre = "";
|
||||
const char *src6_post = "";
|
||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
||||
CURLcode result = curlx_gmtime(as->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
#ifdef USE_IPV6
|
||||
@@ -301,7 +281,7 @@ static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
*/
|
||||
struct altsvcinfo *Curl_altsvc_init(void)
|
||||
{
|
||||
struct altsvcinfo *asi = calloc(1, sizeof(struct altsvcinfo));
|
||||
struct altsvcinfo *asi = curlx_calloc(1, sizeof(struct altsvcinfo));
|
||||
if(!asi)
|
||||
return NULL;
|
||||
Curl_llist_init(&asi->list, NULL);
|
||||
@@ -352,8 +332,8 @@ void Curl_altsvc_cleanup(struct altsvcinfo **altsvcp)
|
||||
n = Curl_node_next(e);
|
||||
altsvc_free(as);
|
||||
}
|
||||
free(altsvc->filename);
|
||||
free(altsvc);
|
||||
curlx_free(altsvc->filename);
|
||||
curlx_free(altsvc);
|
||||
*altsvcp = NULL; /* clear the pointer */
|
||||
}
|
||||
}
|
||||
@@ -395,13 +375,13 @@ CURLcode Curl_altsvc_save(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
curlx_fclose(out);
|
||||
if(!result && tempstore && Curl_rename(tempstore, file))
|
||||
if(!result && tempstore && curlx_rename(tempstore, file))
|
||||
result = CURLE_WRITE_ERROR;
|
||||
|
||||
if(result && tempstore)
|
||||
unlink(tempstore);
|
||||
}
|
||||
free(tempstore);
|
||||
curlx_free(tempstore);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -479,9 +459,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
unsigned short dstport = srcport; /* the same by default */
|
||||
size_t entries = 0;
|
||||
struct Curl_str alpn;
|
||||
const char *sp;
|
||||
time_t maxage = 24 * 3600; /* default is 24 hours */
|
||||
bool persist = FALSE;
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)data;
|
||||
#endif
|
||||
@@ -506,47 +483,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
|
||||
curlx_str_trimblanks(&alpn);
|
||||
|
||||
/* Handle the optional 'ma' and 'persist' flags once first, as they need to
|
||||
be known for each alternative service. Unknown flags are skipped. */
|
||||
sp = strchr(p, ';');
|
||||
if(sp) {
|
||||
sp++; /* pass the semicolon */
|
||||
for(;;) {
|
||||
struct Curl_str name;
|
||||
struct Curl_str val;
|
||||
const char *vp;
|
||||
curl_off_t num;
|
||||
bool quoted;
|
||||
/* allow some extra whitespaces around name and value */
|
||||
if(curlx_str_until(&sp, &name, 20, '=') ||
|
||||
curlx_str_single(&sp, '=') ||
|
||||
curlx_str_until(&sp, &val, 80, ';'))
|
||||
break;
|
||||
curlx_str_trimblanks(&name);
|
||||
curlx_str_trimblanks(&val);
|
||||
/* the value might be quoted */
|
||||
vp = curlx_str(&val);
|
||||
quoted = (*vp == '\"');
|
||||
if(quoted)
|
||||
vp++;
|
||||
if(!curlx_str_number(&vp, &num, TIME_T_MAX)) {
|
||||
if(curlx_str_casecompare(&name, "ma"))
|
||||
maxage = (time_t)num;
|
||||
else if(curlx_str_casecompare(&name, "persist") && (num == 1))
|
||||
persist = TRUE;
|
||||
}
|
||||
if(quoted && curlx_str_single(&sp, '\"'))
|
||||
break;
|
||||
if(curlx_str_single(&sp, ';'))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if(!curlx_str_single(&p, '=')) {
|
||||
time_t maxage = 24 * 3600; /* default is 24 hours */
|
||||
bool persist = FALSE;
|
||||
/* [protocol]="[host][:port], [protocol]="[host][:port]" */
|
||||
enum alpnid dstalpnid =
|
||||
Curl_alpn2alpnid(curlx_str(&alpn), curlx_strlen(&alpn));
|
||||
enum alpnid dstalpnid = Curl_str2alpnid(&alpn);
|
||||
if(!curlx_str_single(&p, '\"')) {
|
||||
struct Curl_str dsthost;
|
||||
curl_off_t port = 0;
|
||||
@@ -559,7 +501,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* IPv6 host name */
|
||||
/* IPv6 hostname */
|
||||
if(curlx_str_until(&p, &dsthost, MAX_IPADR_LEN, ']') ||
|
||||
curlx_str_single(&p, ']')) {
|
||||
infof(data, "Bad alt-svc IPv6 hostname, ignoring.");
|
||||
@@ -583,6 +525,45 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
if(curlx_str_single(&p, '\"'))
|
||||
break;
|
||||
|
||||
/* Handle the optional 'ma' and 'persist' flags. Unknown flags are
|
||||
skipped. */
|
||||
curlx_str_passblanks(&p);
|
||||
if(!curlx_str_single(&p, ';')) {
|
||||
for(;;) {
|
||||
struct Curl_str name;
|
||||
struct Curl_str val;
|
||||
const char *vp;
|
||||
curl_off_t num;
|
||||
bool quoted;
|
||||
/* allow some extra whitespaces around name and value */
|
||||
if(curlx_str_until(&p, &name, 20, '=') ||
|
||||
curlx_str_single(&p, '=') ||
|
||||
curlx_str_cspn(&p, &val, ",;"))
|
||||
break;
|
||||
curlx_str_trimblanks(&name);
|
||||
curlx_str_trimblanks(&val);
|
||||
/* the value might be quoted */
|
||||
vp = curlx_str(&val);
|
||||
quoted = (*vp == '\"');
|
||||
if(quoted)
|
||||
vp++;
|
||||
if(!curlx_str_number(&vp, &num, TIME_T_MAX)) {
|
||||
if(curlx_str_casecompare(&name, "ma"))
|
||||
maxage = (time_t)num;
|
||||
else if(curlx_str_casecompare(&name, "persist") && (num == 1))
|
||||
persist = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
p = vp; /* point to the byte ending the value */
|
||||
curlx_str_passblanks(&p);
|
||||
if(quoted && curlx_str_single(&p, '\"'))
|
||||
break;
|
||||
curlx_str_passblanks(&p);
|
||||
if(curlx_str_single(&p, ';'))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dstalpnid) {
|
||||
if(!entries++)
|
||||
/* Flush cached alternatives for this source origin, if any - when
|
||||
@@ -608,6 +589,8 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
(int)curlx_strlen(&dsthost), curlx_str(&dsthost),
|
||||
dstport, Curl_alpnid2str(dstalpnid));
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -637,7 +620,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
struct altsvc **dstentry,
|
||||
const int versions) /* one or more bits */
|
||||
const int versions, /* one or more bits */
|
||||
bool *psame_destination)
|
||||
{
|
||||
struct Curl_llist_node *e;
|
||||
struct Curl_llist_node *n;
|
||||
@@ -646,6 +630,7 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
DEBUGASSERT(srchost);
|
||||
DEBUGASSERT(dstentry);
|
||||
|
||||
*psame_destination = FALSE;
|
||||
for(e = Curl_llist_head(&asi->list); e; e = n) {
|
||||
struct altsvc *as = Curl_node_elem(e);
|
||||
n = Curl_node_next(e);
|
||||
@@ -661,6 +646,8 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
(versions & (int)as->dst.alpnid)) {
|
||||
/* match */
|
||||
*dstentry = as;
|
||||
*psame_destination = (srcport == as->dst.port) &&
|
||||
hostcompare(srchost, as->dst.host);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -26,7 +26,6 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "llist.h"
|
||||
|
||||
struct althost {
|
||||
@@ -65,10 +64,11 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
struct altsvc **dstentry,
|
||||
const int versions); /* CURLALTSVC_H* bits */
|
||||
const int versions, /* CURLALTSVC_H* bits */
|
||||
bool *psame_destination);
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_altsvc_save(a,b,c)
|
||||
#define Curl_altsvc_save(a, b, c)
|
||||
#define Curl_altsvc_cleanup(x)
|
||||
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_ALTSVC */
|
||||
#endif /* HEADER_CURL_ALTSVC_H */
|
||||
+10
-19
@@ -21,18 +21,15 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef __AMIGA__
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "hostip.h"
|
||||
#include "amigaos.h"
|
||||
|
||||
#ifdef HAVE_PROTO_BSDSOCKET_H
|
||||
# if defined(__amigaos4__)
|
||||
# ifdef __amigaos4__
|
||||
# include <bsdsocket/socketbasetags.h>
|
||||
# elif !defined(USE_AMISSL)
|
||||
# include <amitcp/socketbasetags.h>
|
||||
@@ -42,10 +39,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef HAVE_PROTO_BSDSOCKET_H
|
||||
|
||||
#ifdef __amigaos4__
|
||||
@@ -120,12 +113,11 @@ void Curl_amiga_cleanup(void)
|
||||
* Because we need to handle the different cases in hostip4.c at runtime,
|
||||
* not at compile-time, based on what was detected in Curl_amiga_init(),
|
||||
* we replace it completely with our own as to not complicate the baseline
|
||||
* code. Assumes malloc/calloc/free are thread safe because Curl_he2ai()
|
||||
* code. Assumes malloc/calloc/free are thread-safe because Curl_he2ai()
|
||||
* allocates memory also.
|
||||
*/
|
||||
|
||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
int port)
|
||||
struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port)
|
||||
{
|
||||
struct Curl_addrinfo *ai = NULL;
|
||||
struct hostent *h;
|
||||
@@ -135,7 +127,7 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
LONG h_errnop = 0;
|
||||
struct hostent *buf;
|
||||
|
||||
buf = calloc(1, CURL_HOSTENT_SIZE);
|
||||
buf = curlx_calloc(1, CURL_HOSTENT_SIZE);
|
||||
if(buf) {
|
||||
h = gethostbyname_r((STRPTR)hostname, buf,
|
||||
(char *)buf + sizeof(struct hostent),
|
||||
@@ -144,12 +136,12 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
if(h) {
|
||||
ai = Curl_he2ai(h, port);
|
||||
}
|
||||
free(buf);
|
||||
curlx_free(buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef CURLRES_THREADED
|
||||
/* gethostbyname() is not thread safe, so we need to reopen bsdsocket
|
||||
#ifdef CURLRES_THREADED
|
||||
/* gethostbyname() is not thread-safe, so we need to reopen bsdsocket
|
||||
* on the thread's context
|
||||
*/
|
||||
struct Library *base = OpenLibrary("bsdsocket.library", 4);
|
||||
@@ -164,13 +156,13 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
}
|
||||
CloseLibrary(base);
|
||||
}
|
||||
#else
|
||||
#else
|
||||
/* not using threaded resolver - safe to use this as-is */
|
||||
h = gethostbyname(hostname);
|
||||
if(h) {
|
||||
ai = Curl_he2ai(h, port);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return ai;
|
||||
@@ -223,8 +215,7 @@ CURLcode Curl_amiga_init(void)
|
||||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG)&errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG)"curl",
|
||||
TAG_DONE)) {
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG)"curl", TAG_DONE)) {
|
||||
CURL_AMIGA_REQUEST("SocketBaseTags ERROR");
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ void Curl_amiga_cleanup(void);
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_amiga_init() CURLE_OK
|
||||
#define Curl_amiga_init() CURLE_OK
|
||||
#define Curl_amiga_cleanup() Curl_nop_stmt
|
||||
|
||||
#endif
|
||||
|
||||
+6
-8
@@ -43,8 +43,7 @@
|
||||
/*
|
||||
* The telnet options represented as strings
|
||||
*/
|
||||
static const char * const telnetoptions[]=
|
||||
{
|
||||
static const char * const telnetoptions[] = {
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD",
|
||||
"NAME", "STATUS", "TIMING MARK", "RCTE",
|
||||
"NAOL", "NAOP", "NAOCRD", "NAOHTS",
|
||||
@@ -79,15 +78,14 @@ static const char * const telnetoptions[]=
|
||||
#define CURL_WILL 251 /* Our side WILL use this option */
|
||||
#define CURL_WONT 252 /* Our side will not use this option */
|
||||
#define CURL_DO 253 /* DO use this option! */
|
||||
#define CURL_DONT 254 /* DON'T use this option! */
|
||||
#define CURL_DONT 254 /* DO NOT use this option! */
|
||||
#define CURL_IAC 255 /* Interpret As Command */
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
/*
|
||||
* Then those numbers represented as strings:
|
||||
*/
|
||||
static const char * const telnetcmds[]=
|
||||
{
|
||||
static const char * const telnetcmds[] = {
|
||||
"EOF", "SUSP", "ABORT", "EOR", "SE",
|
||||
"NOP", "DMARK", "BRK", "IP", "AO",
|
||||
"AYT", "EC", "EL", "GA", "SB",
|
||||
@@ -103,11 +101,11 @@ static const char * const telnetcmds[]=
|
||||
#define CURL_TELQUAL_INFO 2
|
||||
#define CURL_TELQUAL_NAME 3
|
||||
|
||||
#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
|
||||
((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
|
||||
#define CURL_TELCMD_OK(x) (((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
|
||||
((unsigned int)(x) <= CURL_TELCMD_MAXIMUM))
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM]
|
||||
#define CURL_TELCMD(x) telnetcmds[(x) - CURL_TELCMD_MINIMUM]
|
||||
#else
|
||||
#define CURL_TELCMD(x) ""
|
||||
#endif
|
||||
|
||||
+51
-72
@@ -21,7 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
@@ -32,7 +31,6 @@
|
||||
* as defined in asyn.h, nothing else belongs in this file!
|
||||
**********************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
@@ -49,10 +47,8 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "cfilters.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
@@ -88,7 +84,7 @@
|
||||
/* How long we are willing to wait for additional parallel responses after
|
||||
obtaining a "definitive" one. For old c-ares without getaddrinfo.
|
||||
|
||||
This is intended to equal the c-ares default timeout. cURL always uses that
|
||||
This is intended to equal the c-ares default timeout. curl always uses that
|
||||
default value. Unfortunately, c-ares does not expose its default timeout in
|
||||
its API, but it is officially documented as 5 seconds.
|
||||
|
||||
@@ -104,10 +100,6 @@
|
||||
#define HTTPSRR_WORKS
|
||||
#endif
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define CARES_TIMEOUT_PER_ATTEMPT 2000
|
||||
|
||||
static int ares_ver = 0;
|
||||
@@ -144,7 +136,6 @@ void Curl_async_global_cleanup(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void sock_state_cb(void *data, ares_socket_t socket_fd,
|
||||
int readable, int writable)
|
||||
{
|
||||
@@ -185,8 +176,7 @@ static CURLcode async_ares_init(struct Curl_easy *data)
|
||||
status = ares_init_options(&ares->channel, &options, optmask);
|
||||
if(status != ARES_SUCCESS) {
|
||||
ares->channel = NULL;
|
||||
rc = (status == ARES_ENOMEM) ?
|
||||
CURLE_OUT_OF_MEMORY : CURLE_FAILED_INIT;
|
||||
rc = (status == ARES_ENOMEM) ? CURLE_OUT_OF_MEMORY : CURLE_FAILED_INIT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -313,12 +303,13 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
/* Now that we have checked for any last minute results above, see if there
|
||||
are any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
||||
expires. */
|
||||
if(ares->num_pending
|
||||
if(ares->num_pending &&
|
||||
/* This is only set to non-zero if the timer was started. */
|
||||
&& (ares->happy_eyeballs_dns_time.tv_sec
|
||||
|| ares->happy_eyeballs_dns_time.tv_usec)
|
||||
&& (curlx_timediff(curlx_now(), ares->happy_eyeballs_dns_time)
|
||||
>= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
||||
(ares->happy_eyeballs_dns_time.tv_sec ||
|
||||
ares->happy_eyeballs_dns_time.tv_usec) &&
|
||||
(curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&ares->happy_eyeballs_dns_time) >=
|
||||
HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
||||
/* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
|
||||
running. */
|
||||
memset(&ares->happy_eyeballs_dns_time, 0,
|
||||
@@ -343,7 +334,8 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
Curl_dnscache_mk_entry(data, ares->temp_ai,
|
||||
data->state.async.hostname, 0,
|
||||
data->state.async.port, FALSE);
|
||||
ares->temp_ai = NULL; /* temp_ai now owned by entry */
|
||||
if(data->state.async.dns)
|
||||
ares->temp_ai = NULL; /* temp_ai now owned by entry */
|
||||
#ifdef HTTPSRR_WORKS
|
||||
if(data->state.async.dns) {
|
||||
struct Curl_https_rrinfo *lhrr = Curl_httpsrr_dup_move(&ares->hinfo);
|
||||
@@ -394,47 +386,46 @@ CURLcode Curl_async_await(struct Curl_easy *data,
|
||||
{
|
||||
struct async_ares_ctx *ares = &data->state.async.ares;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t timeout;
|
||||
struct curltime now = curlx_now();
|
||||
timediff_t timeout_ms;
|
||||
|
||||
DEBUGASSERT(entry);
|
||||
*entry = NULL; /* clear on entry */
|
||||
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(timeout < 0) {
|
||||
timeout_ms = Curl_timeleft_ms(data, TRUE);
|
||||
if(timeout_ms < 0) {
|
||||
/* already expired! */
|
||||
connclose(data->conn, "Timed out before name resolve started");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
if(!timeout)
|
||||
timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
|
||||
if(!timeout_ms)
|
||||
timeout_ms = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve */
|
||||
|
||||
/* Wait for the name resolve query to complete. */
|
||||
while(!result) {
|
||||
struct timeval *tvp, tv, store;
|
||||
int itimeout;
|
||||
timediff_t timeout_ms;
|
||||
struct timeval *real_timeout, time_buf, max_timeout;
|
||||
int itimeout_ms;
|
||||
timediff_t call_timeout_ms;
|
||||
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
itimeout = (timeout > INT_MAX) ? INT_MAX : (int)timeout;
|
||||
itimeout_ms = (timeout_ms > INT_MAX) ? INT_MAX : (int)timeout_ms;
|
||||
#else
|
||||
itimeout = (int)timeout;
|
||||
itimeout_ms = (int)timeout_ms;
|
||||
#endif
|
||||
|
||||
store.tv_sec = itimeout/1000;
|
||||
store.tv_usec = (itimeout%1000)*1000;
|
||||
max_timeout.tv_sec = itimeout_ms / 1000;
|
||||
max_timeout.tv_usec = (itimeout_ms % 1000) * 1000;
|
||||
|
||||
tvp = ares_timeout(ares->channel, &store, &tv);
|
||||
real_timeout = ares_timeout(ares->channel, &max_timeout, &time_buf);
|
||||
|
||||
/* use the timeout period ares returned to us above if less than one
|
||||
second is left, otherwise just use 1000ms to make sure the progress
|
||||
callback gets called frequent enough */
|
||||
if(!tvp->tv_sec)
|
||||
timeout_ms = (timediff_t)(tvp->tv_usec/1000);
|
||||
if(!real_timeout->tv_sec)
|
||||
call_timeout_ms = (timediff_t)(real_timeout->tv_usec / 1000);
|
||||
else
|
||||
timeout_ms = 1000;
|
||||
call_timeout_ms = 1000;
|
||||
|
||||
if(Curl_ares_perform(ares->channel, timeout_ms) < 0)
|
||||
if(Curl_ares_perform(ares->channel, call_timeout_ms) < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
|
||||
result = Curl_async_is_resolved(data, entry);
|
||||
@@ -444,17 +435,16 @@ CURLcode Curl_async_await(struct Curl_easy *data,
|
||||
if(Curl_pgrsUpdate(data))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else {
|
||||
struct curltime now2 = curlx_now();
|
||||
timediff_t timediff = curlx_timediff(now2, now); /* spent time */
|
||||
if(timediff <= 0)
|
||||
timeout -= 1; /* always deduct at least 1 */
|
||||
else if(timediff > timeout)
|
||||
timeout = -1;
|
||||
struct curltime now = curlx_now(); /* update in loop */
|
||||
timediff_t elapsed_ms = curlx_ptimediff_ms(&now, Curl_pgrs_now(data));
|
||||
if(elapsed_ms <= 0)
|
||||
timeout_ms -= 1; /* always deduct at least 1 */
|
||||
else if(elapsed_ms > timeout_ms)
|
||||
timeout_ms = -1;
|
||||
else
|
||||
timeout -= timediff;
|
||||
now = now2; /* for next loop */
|
||||
timeout_ms -= elapsed_ms;
|
||||
}
|
||||
if(timeout < 0)
|
||||
if(timeout_ms < 0)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -521,7 +511,7 @@ static void async_ares_hostbyname_cb(void *user_data,
|
||||
if(ARES_SUCCESS == status) {
|
||||
ares->ares_status = status; /* one success overrules any error */
|
||||
async_addr_concat(&ares->temp_ai,
|
||||
Curl_he2ai(hostent, data->state.async.port));
|
||||
Curl_he2ai(hostent, data->state.async.port));
|
||||
}
|
||||
else if(ares->ares_status != ARES_SUCCESS) {
|
||||
/* no success so far, remember last error */
|
||||
@@ -566,7 +556,7 @@ static void async_ares_hostbyname_cb(void *user_data,
|
||||
So, now that we have a usable answer (some IPv4 addresses, some IPv6
|
||||
addresses, or "no such domain"), we start a timeout for the remaining
|
||||
pending responses. Even though it is typical that this resolved
|
||||
request came back quickly, that needn't be the case. It might be that
|
||||
request came back quickly, that need not be the case. It might be that
|
||||
this completing request did not get a result from the first DNS
|
||||
server or even the first round of the whole DNS server pool. So it
|
||||
could already be quite some time after we issued the DNS queries in
|
||||
@@ -588,9 +578,8 @@ static void async_ares_hostbyname_cb(void *user_data,
|
||||
timeout to prevent it. After all, we do not even know where in the
|
||||
c-ares retry cycle each request is.
|
||||
*/
|
||||
ares->happy_eyeballs_dns_time = curlx_now();
|
||||
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT,
|
||||
EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||
ares->happy_eyeballs_dns_time = *Curl_pgrs_now(data);
|
||||
Curl_expire(data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +621,7 @@ async_ares_node2addr(struct ares_addrinfo_node *node)
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size);
|
||||
ca = curlx_malloc(sizeof(struct Curl_addrinfo) + ss_size);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
@@ -718,40 +707,31 @@ static void async_ares_rr_done(void *user_data, ares_status_t status,
|
||||
/*
|
||||
* Curl_async_getaddrinfo() - when using ares
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
* successful, the 'hostent' is returned and the fourth argument will point to
|
||||
* memory we need to free after use. That memory *MUST* be freed with
|
||||
* Curl_freeaddrinfo(), nothing else.
|
||||
* Starts a name resolve for the given hostname and port number.
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp)
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version)
|
||||
{
|
||||
struct async_ares_ctx *ares = &data->state.async.ares;
|
||||
#ifdef USE_HTTPSRR
|
||||
char *rrname = NULL;
|
||||
#endif
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
if(async_ares_init_lazy(data))
|
||||
return NULL;
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
data->state.async.done = FALSE; /* not done */
|
||||
data->state.async.dns = NULL; /* clear */
|
||||
data->state.async.port = port;
|
||||
data->state.async.ip_version = ip_version;
|
||||
data->state.async.hostname = strdup(hostname);
|
||||
data->state.async.hostname = curlx_strdup(hostname);
|
||||
if(!data->state.async.hostname)
|
||||
return NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#ifdef USE_HTTPSRR
|
||||
if(port != 443) {
|
||||
rrname = curl_maprintf("_%d_.https.%s", port, hostname);
|
||||
if(!rrname) {
|
||||
free(data->state.async.hostname);
|
||||
return NULL;
|
||||
}
|
||||
if(!rrname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -838,9 +818,8 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
async_ares_rr_done, data, NULL);
|
||||
}
|
||||
#endif
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
|
||||
return NULL; /* no struct yet */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Set what DNS server are is to use. This is called in 2 situations:
|
||||
@@ -892,7 +871,7 @@ static CURLcode async_ares_set_dns_servers(struct Curl_easy *data,
|
||||
result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
break;
|
||||
}
|
||||
#else /* too old c-ares version! */
|
||||
#else /* c-ares version too old! */
|
||||
(void)data;
|
||||
(void)(ares_result);
|
||||
#endif
|
||||
|
||||
+7
-19
@@ -21,7 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
@@ -40,29 +39,21 @@
|
||||
|
||||
#ifdef USE_ARES
|
||||
#include <ares.h>
|
||||
#include <ares_version.h> /* really old c-ares did not include this by
|
||||
itself */
|
||||
#include <ares_version.h> /* really old c-ares did not include it by itself */
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "asyn.h"
|
||||
#include "sendf.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
#include "share.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for builds using asynchronous name resolves
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_ASYNCH
|
||||
|
||||
|
||||
#ifdef USE_ARES
|
||||
|
||||
#if ARES_VERSION < 0x010600
|
||||
@@ -77,8 +68,6 @@
|
||||
*
|
||||
* Returns: sockets-in-use-bitmap
|
||||
*/
|
||||
|
||||
|
||||
CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
struct easy_pollset *ps)
|
||||
@@ -127,8 +116,7 @@ CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
||||
*
|
||||
* return number of sockets it worked on, or -1 on error
|
||||
*/
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms)
|
||||
int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms)
|
||||
{
|
||||
int nfds;
|
||||
int bitmask;
|
||||
@@ -147,11 +135,11 @@ int Curl_ares_perform(ares_channel channel,
|
||||
pfd[i].revents = 0;
|
||||
if(ARES_GETSOCK_READABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLRDNORM|POLLIN;
|
||||
pfd[i].events |= POLLRDNORM | POLLIN;
|
||||
}
|
||||
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLWRNORM|POLLOUT;
|
||||
pfd[i].events |= POLLWRNORM | POLLOUT;
|
||||
}
|
||||
if(pfd[i].events)
|
||||
num++;
|
||||
@@ -175,15 +163,15 @@ int Curl_ares_perform(ares_channel channel,
|
||||
/* move through the descriptors and ask for processing on them */
|
||||
for(i = 0; i < num; i++)
|
||||
ares_process_fd(channel,
|
||||
(pfd[i].revents & (POLLRDNORM|POLLIN)) ?
|
||||
(pfd[i].revents & (POLLRDNORM | POLLIN)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD,
|
||||
(pfd[i].revents & (POLLWRNORM|POLLOUT)) ?
|
||||
(pfd[i].revents & (POLLWRNORM | POLLOUT)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD);
|
||||
}
|
||||
return nfds;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* USE_ARES */
|
||||
|
||||
#endif /* CURLRES_ASYNCH */
|
||||
|
||||
|
||||
+37
-52
@@ -21,15 +21,15 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "socketpair.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for threaded name resolves builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_THREADED
|
||||
|
||||
#include "socketpair.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
@@ -45,24 +45,23 @@
|
||||
#endif
|
||||
|
||||
#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)
|
||||
# include <pthread.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
# define RESOLVER_ENOMEM EAI_MEMORY /* = WSA_NOT_ENOUGH_MEMORY on Windows */
|
||||
#define RESOLVER_ENOMEM EAI_MEMORY /* = WSA_NOT_ENOUGH_MEMORY on Windows */
|
||||
#else
|
||||
# define RESOLVER_ENOMEM SOCKENOMEM
|
||||
#define RESOLVER_ENOMEM SOCKENOMEM
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "cfilters.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "hostip.h"
|
||||
#include "hash.h"
|
||||
#include "share.h"
|
||||
#include "url.h"
|
||||
#include "multiif.h"
|
||||
#include "curl_threads.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
|
||||
#ifdef USE_ARES
|
||||
@@ -72,10 +71,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Curl_async_global_init()
|
||||
@@ -136,7 +131,7 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
|
||||
|
||||
if(destroy) {
|
||||
Curl_mutex_destroy(&addr_ctx->mutx);
|
||||
free(addr_ctx->hostname);
|
||||
curlx_free(addr_ctx->hostname);
|
||||
if(addr_ctx->res)
|
||||
Curl_freeaddrinfo(addr_ctx->res);
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
@@ -145,7 +140,7 @@ static void addr_ctx_unlink(struct async_thrdd_addr_ctx **paddr_ctx,
|
||||
#endif
|
||||
wakeup_close(addr_ctx->sock_pair[0]);
|
||||
#endif
|
||||
free(addr_ctx);
|
||||
curlx_free(addr_ctx);
|
||||
}
|
||||
*paddr_ctx = NULL;
|
||||
}
|
||||
@@ -156,7 +151,7 @@ addr_ctx_create(struct Curl_easy *data,
|
||||
const char *hostname, int port,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct async_thrdd_addr_ctx *addr_ctx = calloc(1, sizeof(*addr_ctx));
|
||||
struct async_thrdd_addr_ctx *addr_ctx = curlx_calloc(1, sizeof(*addr_ctx));
|
||||
if(!addr_ctx)
|
||||
return NULL;
|
||||
|
||||
@@ -186,7 +181,7 @@ addr_ctx_create(struct Curl_easy *data,
|
||||
/* Copying hostname string because original can be destroyed by parent
|
||||
* thread during gethostbyname execution.
|
||||
*/
|
||||
addr_ctx->hostname = strdup(hostname);
|
||||
addr_ctx->hostname = curlx_strdup(hostname);
|
||||
if(!addr_ctx->hostname)
|
||||
goto err_exit;
|
||||
|
||||
@@ -249,7 +244,6 @@ static CURL_THREAD_RETURN_T CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
addr_ctx_unlink(&addr_ctx, NULL);
|
||||
@@ -376,14 +370,17 @@ static CURLcode async_rr_start(struct Curl_easy *data, int port)
|
||||
status = ares_init_options(&thrdd->rr.channel, NULL, 0);
|
||||
if(status != ARES_SUCCESS) {
|
||||
thrdd->rr.channel = NULL;
|
||||
curlx_free(rrname);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#ifdef CURLDEBUG
|
||||
if(getenv("CURL_DNS_SERVER")) {
|
||||
const char *servers = getenv("CURL_DNS_SERVER");
|
||||
status = ares_set_servers_ports_csv(thrdd->rr.channel, servers);
|
||||
if(status)
|
||||
if(status) {
|
||||
curlx_free(rrname);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -432,8 +429,8 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
||||
data->state.async.done = FALSE;
|
||||
data->state.async.port = port;
|
||||
data->state.async.ip_version = ip_version;
|
||||
free(data->state.async.hostname);
|
||||
data->state.async.hostname = strdup(hostname);
|
||||
curlx_free(data->state.async.hostname);
|
||||
data->state.async.hostname = curlx_strdup(hostname);
|
||||
if(!data->state.async.hostname)
|
||||
goto err_exit;
|
||||
|
||||
@@ -444,7 +441,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
||||
|
||||
/* passing addr_ctx to the thread adds a reference */
|
||||
addr_ctx->ref_count = 2;
|
||||
addr_ctx->start = curlx_now();
|
||||
addr_ctx->start = *Curl_pgrs_now(data);
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
addr_ctx->thread_hnd = Curl_thread_create(getaddrinfo_thread, addr_ctx);
|
||||
@@ -470,7 +467,7 @@ static bool async_thrdd_init(struct Curl_easy *data,
|
||||
err_exit:
|
||||
CURL_TRC_DNS(data, "resolve thread failed init: %d", err);
|
||||
async_thrdd_destroy(data);
|
||||
CURL_SETERRNO(err);
|
||||
errno = err;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -487,8 +484,8 @@ static void async_thrdd_shutdown(struct Curl_easy *data)
|
||||
|
||||
Curl_mutex_acquire(&addr_ctx->mutx);
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
if(!addr_ctx->do_abort)
|
||||
Curl_multi_will_close(data, addr_ctx->sock_pair[0]);
|
||||
if(!addr_ctx->do_abort)
|
||||
Curl_multi_will_close(data, addr_ctx->sock_pair[0]);
|
||||
#endif
|
||||
addr_ctx->do_abort = TRUE;
|
||||
done = addr_ctx->thrd_done;
|
||||
@@ -657,8 +654,8 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
else {
|
||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||
/* should be fine even if this converts to 32-bit */
|
||||
timediff_t elapsed = curlx_timediff(curlx_now(),
|
||||
data->progress.t_startsingle);
|
||||
timediff_t elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&data->progress.t_startsingle);
|
||||
if(elapsed < 0)
|
||||
elapsed = 0;
|
||||
|
||||
@@ -666,7 +663,7 @@ CURLcode Curl_async_is_resolved(struct Curl_easy *data,
|
||||
/* Start at 1ms poll interval */
|
||||
thrdd->addr->poll_interval = 1;
|
||||
else if(elapsed >= thrdd->addr->interval_end)
|
||||
/* Back-off exponentially if last interval expired */
|
||||
/* Back-off exponentially if last interval expired */
|
||||
thrdd->addr->poll_interval *= 2;
|
||||
|
||||
if(thrdd->addr->poll_interval > 250)
|
||||
@@ -704,15 +701,16 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
|
||||
|
||||
if(!thrd_done) {
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
/* return read fd to client for polling the DNS resolution status */
|
||||
/* return read fd to client for polling the DNS resolution status */
|
||||
result = Curl_pollset_add_in(data, ps, thrdd->addr->sock_pair[0]);
|
||||
#else
|
||||
timediff_t milli;
|
||||
timediff_t ms = curlx_timediff(curlx_now(), thrdd->addr->start);
|
||||
timediff_t ms =
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data), &thrdd->addr->start);
|
||||
if(ms < 3)
|
||||
milli = 0;
|
||||
else if(ms <= 50)
|
||||
milli = ms/3;
|
||||
milli = ms / 3;
|
||||
else if(ms <= 250)
|
||||
milli = 50;
|
||||
else
|
||||
@@ -727,24 +725,18 @@ CURLcode Curl_async_pollset(struct Curl_easy *data, struct easy_pollset *ps)
|
||||
/*
|
||||
* Curl_async_getaddrinfo() - for platforms without getaddrinfo
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp)
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version)
|
||||
{
|
||||
(void)ip_version;
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if(async_thrdd_init(data, hostname, port, ip_version, NULL)) {
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
return NULL;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
failf(data, "getaddrinfo() thread failed");
|
||||
|
||||
return NULL;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
#else /* !HAVE_GETADDRINFO */
|
||||
@@ -752,15 +744,11 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
/*
|
||||
* Curl_async_getaddrinfo() - for getaddrinfo
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp)
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
int pf = PF_INET;
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
CURL_TRC_DNS(data, "init threaded resolve of %s:%d", hostname, port);
|
||||
#ifdef CURLRES_IPV6
|
||||
@@ -782,14 +770,11 @@ struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
SOCK_STREAM : SOCK_DGRAM;
|
||||
|
||||
/* fire up a new resolver thread! */
|
||||
if(async_thrdd_init(data, hostname, port, ip_version, &hints)) {
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
return NULL;
|
||||
}
|
||||
if(async_thrdd_init(data, hostname, port, ip_version, &hints))
|
||||
return CURLE_OK;
|
||||
|
||||
failf(data, "getaddrinfo() thread failed to start");
|
||||
return NULL;
|
||||
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
+12
-18
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
struct Curl_easy;
|
||||
@@ -118,11 +117,8 @@ CURLcode Curl_async_await(struct Curl_easy *data,
|
||||
* Each resolver backend must of course make sure to return data in the
|
||||
* correct format to comply with this.
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_async_getaddrinfo(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int ip_version,
|
||||
int *waitp);
|
||||
CURLcode Curl_async_getaddrinfo(struct Curl_easy *data, const char *hostname,
|
||||
int port, int ip_version);
|
||||
|
||||
#ifdef USE_ARES
|
||||
/* common functions for c-ares and threaded resolver with HTTPSRR */
|
||||
@@ -132,19 +128,18 @@ CURLcode Curl_ares_pollset(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
struct easy_pollset *ps);
|
||||
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms);
|
||||
int Curl_ares_perform(ares_channel channel, timediff_t timeout_ms);
|
||||
#endif
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
/* async resolving implementation using c-ares alone */
|
||||
struct async_ares_ctx {
|
||||
ares_channel channel;
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
||||
parts */
|
||||
int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */
|
||||
CURLcode result; /* CURLE_OK or error handling response */
|
||||
int ares_status; /* ARES_SUCCESS, ARES_ENOTFOUND, etc. */
|
||||
CURLcode result; /* CURLE_OK or error handling response */
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
#endif
|
||||
@@ -226,11 +221,11 @@ struct doh_probes;
|
||||
#else /* CURLRES_ASYNCH */
|
||||
|
||||
/* convert these functions if an asynch resolver is not used */
|
||||
#define Curl_async_get_impl(x,y) (*(y) = NULL, CURLE_OK)
|
||||
#define Curl_async_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_await(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_global_init() CURLE_OK
|
||||
#define Curl_async_global_cleanup() Curl_nop_stmt
|
||||
#define Curl_async_get_impl(x, y) (*(y) = NULL, CURLE_OK)
|
||||
#define Curl_async_is_resolved(x, y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_await(x, y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_async_global_init() CURLE_OK
|
||||
#define Curl_async_global_cleanup() Curl_nop_stmt
|
||||
|
||||
#endif /* !CURLRES_ASYNCH */
|
||||
|
||||
@@ -270,9 +265,8 @@ void Curl_async_shutdown(struct Curl_easy *data);
|
||||
void Curl_async_destroy(struct Curl_easy *data);
|
||||
#else /* !USE_CURL_ASYNC */
|
||||
#define Curl_async_shutdown(x) Curl_nop_stmt
|
||||
#define Curl_async_destroy(x) Curl_nop_stmt
|
||||
#define Curl_async_destroy(x) Curl_nop_stmt
|
||||
#endif /* USE_CURL_ASYNC */
|
||||
|
||||
|
||||
/********** end of generic resolver interface functions *****************/
|
||||
#endif /* HEADER_CURL_ASYN_H */
|
||||
+22
-27
@@ -21,13 +21,9 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "bufq.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
#include "bufq.h"
|
||||
|
||||
static bool chunk_is_empty(const struct buf_chunk *chunk)
|
||||
{
|
||||
@@ -51,9 +47,9 @@ static void chunk_reset(struct buf_chunk *chunk)
|
||||
}
|
||||
|
||||
static size_t chunk_append(struct buf_chunk *chunk,
|
||||
const unsigned char *buf, size_t len)
|
||||
const uint8_t *buf, size_t len)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->w_offset];
|
||||
uint8_t *p = &chunk->x.data[chunk->w_offset];
|
||||
size_t n = chunk->dlen - chunk->w_offset;
|
||||
DEBUGASSERT(chunk->dlen >= chunk->w_offset);
|
||||
if(n) {
|
||||
@@ -65,9 +61,9 @@ static size_t chunk_append(struct buf_chunk *chunk,
|
||||
}
|
||||
|
||||
static size_t chunk_read(struct buf_chunk *chunk,
|
||||
unsigned char *buf, size_t len)
|
||||
uint8_t *buf, size_t len)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->r_offset];
|
||||
uint8_t *p = &chunk->x.data[chunk->r_offset];
|
||||
size_t n = chunk->w_offset - chunk->r_offset;
|
||||
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
|
||||
if(!n) {
|
||||
@@ -89,7 +85,7 @@ static CURLcode chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
|
||||
Curl_bufq_reader *reader,
|
||||
void *reader_ctx, size_t *pnread)
|
||||
{
|
||||
unsigned char *p = &chunk->x.data[chunk->w_offset];
|
||||
uint8_t *p = &chunk->x.data[chunk->w_offset];
|
||||
size_t n = chunk->dlen - chunk->w_offset; /* free amount */
|
||||
CURLcode result;
|
||||
|
||||
@@ -108,7 +104,7 @@ static CURLcode chunk_slurpn(struct buf_chunk *chunk, size_t max_len,
|
||||
}
|
||||
|
||||
static void chunk_peek(const struct buf_chunk *chunk,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
DEBUGASSERT(chunk->w_offset >= chunk->r_offset);
|
||||
*pbuf = &chunk->x.data[chunk->r_offset];
|
||||
@@ -116,7 +112,7 @@ static void chunk_peek(const struct buf_chunk *chunk,
|
||||
}
|
||||
|
||||
static void chunk_peek_at(const struct buf_chunk *chunk, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
offset += chunk->r_offset;
|
||||
DEBUGASSERT(chunk->w_offset >= offset);
|
||||
@@ -143,11 +139,10 @@ static void chunk_list_free(struct buf_chunk **anchor)
|
||||
while(*anchor) {
|
||||
chunk = *anchor;
|
||||
*anchor = chunk->next;
|
||||
free(chunk);
|
||||
curlx_free(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Curl_bufcp_init(struct bufc_pool *pool,
|
||||
size_t chunk_size, size_t spare_max)
|
||||
{
|
||||
@@ -178,7 +173,7 @@ static CURLcode bufcp_take(struct bufc_pool *pool,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
chunk = calloc(1, sizeof(*chunk) + pool->chunk_size);
|
||||
chunk = curlx_calloc(1, sizeof(*chunk) + pool->chunk_size);
|
||||
if(!chunk) {
|
||||
*pchunk = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -192,7 +187,7 @@ static void bufcp_put(struct bufc_pool *pool,
|
||||
struct buf_chunk *chunk)
|
||||
{
|
||||
if(pool->spare_count >= pool->spare_max) {
|
||||
free(chunk);
|
||||
curlx_free(chunk);
|
||||
}
|
||||
else {
|
||||
chunk_reset(chunk);
|
||||
@@ -311,7 +306,7 @@ static struct buf_chunk *get_spare(struct bufq *q)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chunk = calloc(1, sizeof(*chunk) + q->chunk_size);
|
||||
chunk = curlx_calloc(1, sizeof(*chunk) + q->chunk_size);
|
||||
if(!chunk)
|
||||
return NULL;
|
||||
chunk->dlen = q->chunk_size;
|
||||
@@ -334,11 +329,11 @@ static void prune_head(struct bufq *q)
|
||||
--q->chunk_count;
|
||||
}
|
||||
else if((q->chunk_count > q->max_chunks) ||
|
||||
(q->opts & BUFQ_OPT_NO_SPARES)) {
|
||||
(q->opts & BUFQ_OPT_NO_SPARES)) {
|
||||
/* SOFT_LIMIT allowed us more than max. free spares until
|
||||
* we are at max again. Or free them if we are configured
|
||||
* to not use spares. */
|
||||
free(chunk);
|
||||
curlx_free(chunk);
|
||||
--q->chunk_count;
|
||||
}
|
||||
else {
|
||||
@@ -370,7 +365,7 @@ static struct buf_chunk *get_non_full_tail(struct bufq *q)
|
||||
}
|
||||
|
||||
CURLcode Curl_bufq_write(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct buf_chunk *tail;
|
||||
@@ -400,10 +395,10 @@ CURLcode Curl_bufq_cwrite(struct bufq *q,
|
||||
const char *buf, size_t len,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
return Curl_bufq_write(q, (const unsigned char *)buf, len, pnwritten);
|
||||
return Curl_bufq_write(q, (const uint8_t *)buf, len, pnwritten);
|
||||
}
|
||||
|
||||
CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode Curl_bufq_read(struct bufq *q, uint8_t *buf, size_t len,
|
||||
size_t *pnread)
|
||||
{
|
||||
*pnread = 0;
|
||||
@@ -422,11 +417,11 @@ CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
size_t *pnread)
|
||||
{
|
||||
return Curl_bufq_read(q, (unsigned char *)buf, len, pnread);
|
||||
return Curl_bufq_read(q, (uint8_t *)buf, len, pnread);
|
||||
}
|
||||
|
||||
bool Curl_bufq_peek(struct bufq *q,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
if(q->head && chunk_is_empty(q->head)) {
|
||||
prune_head(q);
|
||||
@@ -441,7 +436,7 @@ bool Curl_bufq_peek(struct bufq *q,
|
||||
}
|
||||
|
||||
bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen)
|
||||
const uint8_t **pbuf, size_t *plen)
|
||||
{
|
||||
struct buf_chunk *c = q->head;
|
||||
size_t clen;
|
||||
@@ -477,7 +472,7 @@ void Curl_bufq_skip(struct bufq *q, size_t amount)
|
||||
CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
||||
void *writer_ctx, size_t *pwritten)
|
||||
{
|
||||
const unsigned char *buf;
|
||||
const uint8_t *buf;
|
||||
size_t blen;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@@ -507,7 +502,7 @@ CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
||||
}
|
||||
|
||||
CURLcode Curl_bufq_write_pass(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
Curl_bufq_writer *writer, void *writer_ctx,
|
||||
size_t *pwritten)
|
||||
{
|
||||
|
||||
+8
-10
@@ -25,8 +25,6 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/**
|
||||
* A chunk of bytes for reading and writing.
|
||||
* The size is fixed a creation with read and write offset
|
||||
@@ -38,7 +36,7 @@ struct buf_chunk {
|
||||
size_t r_offset; /* first unread bytes */
|
||||
size_t w_offset; /* one after last written byte */
|
||||
union {
|
||||
unsigned char data[1]; /* the buffer for `dlen` bytes */
|
||||
uint8_t data[1]; /* the buffer for `dlen` bytes */
|
||||
void *dummy; /* alignment */
|
||||
} x;
|
||||
};
|
||||
@@ -166,7 +164,7 @@ bool Curl_bufq_is_full(const struct bufq *q);
|
||||
* CURLE_AGAIN is returned if the buffer queue is full.
|
||||
*/
|
||||
CURLcode Curl_bufq_write(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
size_t *pnwritten);
|
||||
|
||||
CURLcode Curl_bufq_cwrite(struct bufq *q,
|
||||
@@ -177,7 +175,7 @@ CURLcode Curl_bufq_cwrite(struct bufq *q,
|
||||
* Read buf from the start of the buffer queue. The buf is copied
|
||||
* and the amount of copied bytes is returned.
|
||||
*/
|
||||
CURLcode Curl_bufq_read(struct bufq *q, unsigned char *buf, size_t len,
|
||||
CURLcode Curl_bufq_read(struct bufq *q, uint8_t *buf, size_t len,
|
||||
size_t *pnread);
|
||||
|
||||
CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
@@ -193,10 +191,10 @@ CURLcode Curl_bufq_cread(struct bufq *q, char *buf, size_t len,
|
||||
* is modified, see `Curl_bufq_skip()``
|
||||
*/
|
||||
bool Curl_bufq_peek(struct bufq *q,
|
||||
const unsigned char **pbuf, size_t *plen);
|
||||
const uint8_t **pbuf, size_t *plen);
|
||||
|
||||
bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
const unsigned char **pbuf, size_t *plen);
|
||||
const uint8_t **pbuf, size_t *plen);
|
||||
|
||||
/**
|
||||
* Tell the buffer queue to discard `amount` buf bytes at the head
|
||||
@@ -206,7 +204,7 @@ bool Curl_bufq_peek_at(struct bufq *q, size_t offset,
|
||||
void Curl_bufq_skip(struct bufq *q, size_t amount);
|
||||
|
||||
typedef CURLcode Curl_bufq_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
size_t *pwritten);
|
||||
/**
|
||||
* Passes the chunks in the buffer queue to the writer and returns
|
||||
@@ -221,7 +219,7 @@ CURLcode Curl_bufq_pass(struct bufq *q, Curl_bufq_writer *writer,
|
||||
void *writer_ctx, size_t *pwritten);
|
||||
|
||||
typedef CURLcode Curl_bufq_reader(void *reader_ctx,
|
||||
unsigned char *buf, size_t len,
|
||||
uint8_t *buf, size_t len,
|
||||
size_t *pnread);
|
||||
|
||||
/**
|
||||
@@ -253,7 +251,7 @@ CURLcode Curl_bufq_sipn(struct bufq *q, size_t max_len,
|
||||
* amount buffered, chunk size, etc.
|
||||
*/
|
||||
CURLcode Curl_bufq_write_pass(struct bufq *q,
|
||||
const unsigned char *buf, size_t len,
|
||||
const uint8_t *buf, size_t len,
|
||||
Curl_bufq_writer *writer, void *writer_ctx,
|
||||
size_t *pwritten);
|
||||
|
||||
|
||||
+16
-7
@@ -21,15 +21,12 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
#include "bufref.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define SIGNATURE 0x5c48e9b2 /* Random pattern. */
|
||||
#endif
|
||||
@@ -79,7 +76,7 @@ void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
||||
DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH);
|
||||
|
||||
Curl_bufref_free(br);
|
||||
br->ptr = (const unsigned char *) ptr;
|
||||
br->ptr = (const unsigned char *)ptr;
|
||||
br->len = len;
|
||||
br->dtor = dtor;
|
||||
}
|
||||
@@ -87,7 +84,7 @@ void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
||||
/*
|
||||
* Get a pointer to the referenced buffer.
|
||||
*/
|
||||
const unsigned char *Curl_bufref_ptr(const struct bufref *br)
|
||||
const unsigned char *Curl_bufref_uptr(const struct bufref *br)
|
||||
{
|
||||
DEBUGASSERT(br);
|
||||
DEBUGASSERT(br->signature == SIGNATURE);
|
||||
@@ -96,6 +93,18 @@ const unsigned char *Curl_bufref_ptr(const struct bufref *br)
|
||||
return br->ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a pointer to the referenced string.
|
||||
*/
|
||||
const char *Curl_bufref_ptr(const struct bufref *br)
|
||||
{
|
||||
DEBUGASSERT(br);
|
||||
DEBUGASSERT(br->signature == SIGNATURE);
|
||||
DEBUGASSERT(br->ptr || !br->len);
|
||||
|
||||
return (const char *)br->ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the length of the referenced buffer data.
|
||||
*/
|
||||
@@ -108,7 +117,7 @@ size_t Curl_bufref_len(const struct bufref *br)
|
||||
return br->len;
|
||||
}
|
||||
|
||||
CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len)
|
||||
CURLcode Curl_bufref_memdup0(struct bufref *br, const void *ptr, size_t len)
|
||||
{
|
||||
unsigned char *cpy = NULL;
|
||||
|
||||
|
||||
+6
-3
@@ -36,13 +36,16 @@ struct bufref {
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void Curl_bufref_init(struct bufref *br);
|
||||
void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len,
|
||||
void (*dtor)(void *));
|
||||
const unsigned char *Curl_bufref_ptr(const struct bufref *br);
|
||||
const char *Curl_bufref_ptr(const struct bufref *br);
|
||||
const unsigned char *Curl_bufref_uptr(const struct bufref *br);
|
||||
size_t Curl_bufref_len(const struct bufref *br);
|
||||
CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len);
|
||||
CURLcode Curl_bufref_memdup0(struct bufref *br, const void *ptr, size_t len);
|
||||
void Curl_bufref_free(struct bufref *br);
|
||||
|
||||
/* return a strdup() version of the buffer */
|
||||
#define Curl_bufref_dup(x) curlx_strdup(Curl_bufref_ptr(x))
|
||||
|
||||
#endif
|
||||
+140
-114
@@ -21,12 +21,10 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "curlx/dynbuf.h"
|
||||
#include "sendf.h"
|
||||
@@ -41,23 +39,17 @@
|
||||
#include "connect.h"
|
||||
#include "curl_trc.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "transfer.h"
|
||||
#include "multiif.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
H1_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H1_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
|
||||
H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H1_TUNNEL_ESTABLISHED,
|
||||
H1_TUNNEL_FAILED
|
||||
H1_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H1_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
|
||||
H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H1_TUNNEL_ESTABLISHED,
|
||||
H1_TUNNEL_FAILED
|
||||
} h1_tunnel_state;
|
||||
|
||||
/* struct for HTTP CONNECT tunneling */
|
||||
@@ -76,9 +68,10 @@ struct h1_tunnel_state {
|
||||
h1_tunnel_state tunnel_state;
|
||||
BIT(chunked_encoding);
|
||||
BIT(close_connection);
|
||||
BIT(maybe_folded);
|
||||
BIT(leading_unfold);
|
||||
};
|
||||
|
||||
|
||||
static bool tunnel_is_established(struct h1_tunnel_state *ts)
|
||||
{
|
||||
return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED);
|
||||
@@ -102,6 +95,8 @@ static CURLcode tunnel_reinit(struct Curl_cfilter *cf,
|
||||
ts->keepon = KEEPON_CONNECT;
|
||||
ts->cl = 0;
|
||||
ts->close_connection = FALSE;
|
||||
ts->maybe_folded = FALSE;
|
||||
ts->leading_unfold = FALSE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -116,7 +111,7 @@ static CURLcode tunnel_init(struct Curl_cfilter *cf,
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
ts = calloc(1, sizeof(*ts));
|
||||
ts = curlx_calloc(1, sizeof(*ts));
|
||||
if(!ts)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -126,8 +121,7 @@ static CURLcode tunnel_init(struct Curl_cfilter *cf,
|
||||
curlx_dyn_init(&ts->request_data, DYN_HTTP_REQUEST);
|
||||
Curl_httpchunk_init(data, &ts->ch, TRUE);
|
||||
|
||||
*pts = ts;
|
||||
connkeep(cf->conn, "HTTP proxy CONNECT");
|
||||
*pts = ts;
|
||||
return tunnel_reinit(cf, data, ts);
|
||||
}
|
||||
|
||||
@@ -175,7 +169,7 @@ static void h1_tunnel_go_state(struct Curl_cfilter *cf,
|
||||
curlx_dyn_reset(&ts->rcvbuf);
|
||||
curlx_dyn_reset(&ts->request_data);
|
||||
/* restore the protocol pointer */
|
||||
data->info.httpcode = 0; /* clear it as it might've been used for the
|
||||
data->info.httpcode = 0; /* clear it as it might have been used for the
|
||||
proxy */
|
||||
/* If a proxy-authorization header was used for the proxy, then we should
|
||||
make sure that it is not accidentally used for the document request
|
||||
@@ -195,7 +189,7 @@ static void tunnel_free(struct Curl_cfilter *cf,
|
||||
curlx_dyn_free(&ts->rcvbuf);
|
||||
curlx_dyn_free(&ts->request_data);
|
||||
Curl_httpchunk_free(data, &ts->ch);
|
||||
free(ts);
|
||||
curlx_free(ts);
|
||||
cf->ctx = NULL;
|
||||
}
|
||||
}
|
||||
@@ -214,9 +208,9 @@ static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
||||
int http_minor;
|
||||
CURLcode result;
|
||||
|
||||
/* This only happens if we have looped here due to authentication
|
||||
reasons, and we do not really use the newly cloned URL here
|
||||
then. Just free() it. */
|
||||
/* This only happens if we have looped here due to authentication
|
||||
reasons, and we do not really use the newly cloned URL here
|
||||
then. Just free it. */
|
||||
Curl_safefree(data->req.newurl);
|
||||
|
||||
result = Curl_http_proxy_create_CONNECT(&req, cf, data, 1);
|
||||
@@ -247,7 +241,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf,
|
||||
struct h1_tunnel_state *ts,
|
||||
bool *done)
|
||||
{
|
||||
char *buf = curlx_dyn_ptr(&ts->request_data);
|
||||
uint8_t *buf = curlx_dyn_uptr(&ts->request_data);
|
||||
size_t request_len = curlx_dyn_len(&ts->request_data);
|
||||
size_t blen = request_len;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -268,7 +262,7 @@ static CURLcode send_CONNECT(struct Curl_cfilter *cf,
|
||||
|
||||
DEBUGASSERT(blen >= nwritten);
|
||||
ts->nsent += nwritten;
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, buf, (size_t)nwritten);
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)buf, nwritten);
|
||||
|
||||
out:
|
||||
if(result)
|
||||
@@ -286,10 +280,8 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
||||
struct SingleRequest *k = &data->req;
|
||||
(void)cf;
|
||||
|
||||
if((checkprefix("WWW-Authenticate:", header) &&
|
||||
(401 == k->httpcode)) ||
|
||||
(checkprefix("Proxy-authenticate:", header) &&
|
||||
(407 == k->httpcode))) {
|
||||
if((checkprefix("WWW-Authenticate:", header) && (401 == k->httpcode)) ||
|
||||
(checkprefix("Proxy-authenticate:", header) && (407 == k->httpcode))) {
|
||||
|
||||
bool proxy = (k->httpcode == 407);
|
||||
char *auth = Curl_copy_header_value(header);
|
||||
@@ -299,13 +291,13 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
||||
CURL_TRC_CF(data, cf, "CONNECT: fwd auth header '%s'", header);
|
||||
result = Curl_http_input_auth(data, proxy, auth);
|
||||
|
||||
free(auth);
|
||||
curlx_free(auth);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else if(checkprefix("Content-Length:", header)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
if(k->httpcode / 100 == 2) {
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
@@ -324,7 +316,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
||||
STRCONST("Connection:"), STRCONST("close")))
|
||||
ts->close_connection = TRUE;
|
||||
else if(checkprefix("Transfer-Encoding:", header)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
if(k->httpcode / 100 == 2) {
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
@@ -350,22 +342,88 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
||||
ISDIGIT(header[9]) && ISDIGIT(header[10]) && ISDIGIT(header[11]) &&
|
||||
!ISDIGIT(header[12])) {
|
||||
/* store the HTTP code from the proxy */
|
||||
data->info.httpproxycode = k->httpcode = (header[9] - '0') * 100 +
|
||||
data->info.httpproxycode = k->httpcode = (header[9] - '0') * 100 +
|
||||
(header[10] - '0') * 10 + (header[11] - '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode single_header(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *linep = curlx_dyn_ptr(&ts->rcvbuf);
|
||||
size_t line_len = curlx_dyn_len(&ts->rcvbuf); /* bytes in this line */
|
||||
struct SingleRequest *k = &data->req;
|
||||
int writetype;
|
||||
ts->headerlines++;
|
||||
|
||||
/* output debug if that is requested */
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, linep, line_len);
|
||||
|
||||
/* send the header to the callback */
|
||||
writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT |
|
||||
(ts->headerlines == 1 ? CLIENTWRITE_STATUS : 0);
|
||||
result = Curl_client_write(data, writetype, linep, line_len);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_bump_headersize(data, line_len, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Newlines are CRLF, so the CR is ignored as the line is not
|
||||
really terminated until the LF comes. Treat a following CR
|
||||
as end-of-headers as well.*/
|
||||
|
||||
if(ISNEWLINE(linep[0])) {
|
||||
/* end of response-headers from the proxy */
|
||||
|
||||
if((407 == k->httpcode) && !data->state.authproblem) {
|
||||
/* If we get a 407 response code with content length
|
||||
when we have no auth problem, we must ignore the
|
||||
whole response-body */
|
||||
ts->keepon = KEEPON_IGNORE;
|
||||
|
||||
if(ts->cl) {
|
||||
infof(data, "Ignore %" FMT_OFF_T " bytes of response-body", ts->cl);
|
||||
}
|
||||
else if(ts->chunked_encoding) {
|
||||
infof(data, "Ignore chunked response-body");
|
||||
}
|
||||
else {
|
||||
/* without content-length or chunked encoding, we
|
||||
cannot keep the connection alive since the close is
|
||||
the end signal so we bail out at once instead */
|
||||
CURL_TRC_CF(data, cf, "CONNECT: no content-length or chunked");
|
||||
ts->keepon = KEEPON_DONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ts->keepon = KEEPON_DONE;
|
||||
}
|
||||
|
||||
DEBUGASSERT(ts->keepon == KEEPON_IGNORE ||
|
||||
ts->keepon == KEEPON_DONE);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = on_resp_header(cf, data, ts, linep);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
curlx_dyn_reset(&ts->rcvbuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts,
|
||||
bool *done)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SingleRequest *k = &data->req;
|
||||
char *linep;
|
||||
size_t line_len;
|
||||
int error, writetype;
|
||||
int error;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
@@ -384,8 +442,8 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||
/* socket buffer drained, return */
|
||||
return CURLE_OK;
|
||||
|
||||
if(Curl_pgrsUpdate(data))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
if(!result)
|
||||
result = Curl_pgrsUpdate(data);
|
||||
|
||||
if(result) {
|
||||
ts->keepon = KEEPON_DONE;
|
||||
@@ -439,6 +497,31 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ts->maybe_folded) {
|
||||
if(ISBLANK(byte)) {
|
||||
Curl_http_to_fold(&ts->rcvbuf);
|
||||
ts->leading_unfold = TRUE;
|
||||
}
|
||||
else {
|
||||
result = single_header(cf, data, ts);
|
||||
if(result)
|
||||
return result;
|
||||
/* now handle the new byte */
|
||||
}
|
||||
ts->maybe_folded = FALSE;
|
||||
}
|
||||
|
||||
if(ts->leading_unfold) {
|
||||
if(ISBLANK(byte))
|
||||
/* skip a bit brother */
|
||||
continue;
|
||||
/* non-blank, insert a space then continue the unfolding */
|
||||
if(curlx_dyn_addn(&ts->rcvbuf, " ", 1)) {
|
||||
failf(data, "CONNECT response too large");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
ts->leading_unfold = FALSE;
|
||||
}
|
||||
if(curlx_dyn_addn(&ts->rcvbuf, &byte, 1)) {
|
||||
failf(data, "CONNECT response too large");
|
||||
return CURLE_RECV_ERROR;
|
||||
@@ -447,73 +530,25 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||
/* if this is not the end of a header line then continue */
|
||||
if(byte != 0x0a)
|
||||
continue;
|
||||
|
||||
ts->headerlines++;
|
||||
linep = curlx_dyn_ptr(&ts->rcvbuf);
|
||||
line_len = curlx_dyn_len(&ts->rcvbuf); /* amount of bytes in this line */
|
||||
|
||||
/* output debug if that is requested */
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, linep, line_len);
|
||||
|
||||
/* send the header to the callback */
|
||||
writetype = CLIENTWRITE_HEADER | CLIENTWRITE_CONNECT |
|
||||
(ts->headerlines == 1 ? CLIENTWRITE_STATUS : 0);
|
||||
result = Curl_client_write(data, writetype, linep, line_len);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_bump_headersize(data, line_len, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Newlines are CRLF, so the CR is ignored as the line is not
|
||||
really terminated until the LF comes. Treat a following CR
|
||||
as end-of-headers as well.*/
|
||||
|
||||
if(('\r' == linep[0]) ||
|
||||
('\n' == linep[0])) {
|
||||
/* end of response-headers from the proxy */
|
||||
|
||||
if((407 == k->httpcode) && !data->state.authproblem) {
|
||||
/* If we get a 407 response code with content length
|
||||
when we have no auth problem, we must ignore the
|
||||
whole response-body */
|
||||
ts->keepon = KEEPON_IGNORE;
|
||||
|
||||
if(ts->cl) {
|
||||
infof(data, "Ignore %" FMT_OFF_T " bytes of response-body", ts->cl);
|
||||
}
|
||||
else if(ts->chunked_encoding) {
|
||||
infof(data, "Ignore chunked response-body");
|
||||
}
|
||||
else {
|
||||
/* without content-length or chunked encoding, we
|
||||
cannot keep the connection alive since the close is
|
||||
the end signal so we bail out at once instead */
|
||||
CURL_TRC_CF(data, cf, "CONNECT: no content-length or chunked");
|
||||
ts->keepon = KEEPON_DONE;
|
||||
}
|
||||
else {
|
||||
char *linep = curlx_dyn_ptr(&ts->rcvbuf);
|
||||
size_t hlen = curlx_dyn_len(&ts->rcvbuf);
|
||||
if(hlen && ISNEWLINE(linep[0])) {
|
||||
/* end of headers */
|
||||
result = single_header(cf, data, ts);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
ts->keepon = KEEPON_DONE;
|
||||
}
|
||||
|
||||
DEBUGASSERT(ts->keepon == KEEPON_IGNORE
|
||||
|| ts->keepon == KEEPON_DONE);
|
||||
continue;
|
||||
else
|
||||
ts->maybe_folded = TRUE;
|
||||
}
|
||||
|
||||
result = on_resp_header(cf, data, ts, linep);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
curlx_dyn_reset(&ts->rcvbuf);
|
||||
} /* while there is buffer left and loop is requested */
|
||||
|
||||
if(error)
|
||||
result = CURLE_RECV_ERROR;
|
||||
*done = (ts->keepon == KEEPON_DONE);
|
||||
if(!result && *done && data->info.httpproxycode/100 != 2) {
|
||||
if(!result && *done && data->info.httpproxycode / 100 != 2) {
|
||||
/* Deal with the possibly already received authenticate
|
||||
headers. 'newurl' is set to a new URL if we must loop. */
|
||||
result = Curl_http_auth_act(data);
|
||||
@@ -535,10 +570,8 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
||||
return CURLE_RECV_ERROR; /* Need a cfilter close and new bootstrap */
|
||||
|
||||
do {
|
||||
timediff_t check;
|
||||
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
if(Curl_timeleft_ms(data, TRUE) < 0) {
|
||||
failf(data, "Proxy CONNECT aborted due to timeout");
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
goto out;
|
||||
@@ -567,10 +600,8 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
||||
/* read what is there */
|
||||
CURL_TRC_CF(data, cf, "CONNECT receive");
|
||||
result = recv_CONNECT_resp(cf, data, ts, &done);
|
||||
if(Curl_pgrsUpdate(data)) {
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
goto out;
|
||||
}
|
||||
if(!result)
|
||||
result = Curl_pgrsUpdate(data);
|
||||
/* error or not complete yet. return for more multi-multi */
|
||||
if(result || !done)
|
||||
goto out;
|
||||
@@ -595,7 +626,6 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
||||
CURL_TRC_CF(data, cf, "CONNECT need to close+open");
|
||||
infof(data, "Connect me again please");
|
||||
Curl_conn_cf_close(cf, data);
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
result = Curl_conn_cf_connect(cf->next, data, &done);
|
||||
goto out;
|
||||
}
|
||||
@@ -613,11 +643,9 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
||||
} while(data->req.newurl);
|
||||
|
||||
DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE);
|
||||
if(data->info.httpproxycode/100 != 2) {
|
||||
if(data->info.httpproxycode / 100 != 2) {
|
||||
/* a non-2xx response and we have no next URL to try. */
|
||||
Curl_safefree(data->req.newurl);
|
||||
/* failure, close this connection to avoid reuse */
|
||||
streamclose(conn, "proxy CONNECT failure");
|
||||
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
|
||||
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
@@ -673,8 +701,7 @@ out:
|
||||
/* The real request will follow the CONNECT, reset request partially */
|
||||
Curl_req_soft_reset(&data->req, data);
|
||||
Curl_client_reset(data);
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsReset(data);
|
||||
|
||||
tunnel_free(cf, data);
|
||||
}
|
||||
@@ -729,10 +756,9 @@ static void cf_h1_proxy_close(struct Curl_cfilter *cf,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Curl_cftype Curl_cft_h1_proxy = {
|
||||
"H1-PROXY",
|
||||
CF_TYPE_IP_CONNECT|CF_TYPE_PROXY,
|
||||
CF_TYPE_IP_CONNECT | CF_TYPE_PROXY,
|
||||
0,
|
||||
cf_h1_proxy_destroy,
|
||||
cf_h1_proxy_connect,
|
||||
@@ -761,4 +787,4 @@ CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf_at,
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY && ! CURL_DISABLE_HTTP */
|
||||
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
|
||||
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
@@ -33,7 +32,6 @@ CURLcode Curl_cf_h1_proxy_insert_after(struct Curl_cfilter *cf,
|
||||
|
||||
extern struct Curl_cftype Curl_cft_h1_proxy;
|
||||
|
||||
|
||||
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
|
||||
|
||||
#endif /* HEADER_CURL_H1_PROXY_H */
|
||||
+112
-129
@@ -21,13 +21,13 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY) && \
|
||||
defined(USE_NGHTTP2)
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "bufq.h"
|
||||
#include "curlx/dynbuf.h"
|
||||
#include "dynhds.h"
|
||||
#include "http1.h"
|
||||
#include "http2.h"
|
||||
#include "http_proxy.h"
|
||||
#include "multiif.h"
|
||||
@@ -44,16 +43,12 @@
|
||||
#include "select.h"
|
||||
#include "cf-h2-proxy.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define PROXY_H2_CHUNK_SIZE (16*1024)
|
||||
#define PROXY_H2_CHUNK_SIZE (16 * 1024)
|
||||
|
||||
#define PROXY_HTTP2_HUGE_WINDOW_SIZE (100 * 1024 * 1024)
|
||||
#define H2_TUNNEL_WINDOW_SIZE (10 * 1024 * 1024)
|
||||
|
||||
#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
|
||||
#define PROXY_H2_NW_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
|
||||
#define PROXY_H2_NW_SEND_CHUNKS 1
|
||||
|
||||
#define H2_TUNNEL_RECV_CHUNKS (H2_TUNNEL_WINDOW_SIZE / PROXY_H2_CHUNK_SIZE)
|
||||
@@ -61,11 +56,11 @@
|
||||
|
||||
|
||||
typedef enum {
|
||||
H2_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H2_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H2_TUNNEL_ESTABLISHED,
|
||||
H2_TUNNEL_FAILED
|
||||
H2_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||
H2_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||
H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||
H2_TUNNEL_ESTABLISHED,
|
||||
H2_TUNNEL_FAILED
|
||||
} h2_tunnel_state;
|
||||
|
||||
struct tunnel_stream {
|
||||
@@ -87,7 +82,6 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
|
||||
const char *hostname;
|
||||
int port;
|
||||
bool ipv6_ip;
|
||||
CURLcode result;
|
||||
|
||||
ts->state = H2_TUNNEL_INIT;
|
||||
ts->stream_id = -1;
|
||||
@@ -95,13 +89,11 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
|
||||
BUFQ_OPT_SOFT_LIMIT);
|
||||
Curl_bufq_init(&ts->sendbuf, PROXY_H2_CHUNK_SIZE, H2_TUNNEL_SEND_CHUNKS);
|
||||
|
||||
result = Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
|
||||
if(result)
|
||||
return result;
|
||||
Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
|
||||
|
||||
ts->authority = /* host:port with IPv6 support */
|
||||
curl_maprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
/* host:port with IPv6 support */
|
||||
ts->authority = curl_maprintf("%s%s%s:%d", ipv6_ip ? "[" : "", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
if(!ts->authority)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -190,8 +182,7 @@ struct cf_h2_proxy_ctx {
|
||||
|
||||
/* How to access `call_data` from a cf_h2 filter */
|
||||
#undef CF_CTX_CALL_DATA
|
||||
#define CF_CTX_CALL_DATA(cf) \
|
||||
((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
|
||||
#define CF_CTX_CALL_DATA(cf) ((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
|
||||
|
||||
static void cf_h2_proxy_ctx_clear(struct cf_h2_proxy_ctx *ctx)
|
||||
{
|
||||
@@ -211,7 +202,7 @@ static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx)
|
||||
{
|
||||
if(ctx) {
|
||||
cf_h2_proxy_ctx_clear(ctx);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +218,7 @@ static void drain_tunnel(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
static CURLcode proxy_h2_nw_out_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
const uint8_t *buf, size_t buflen,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct Curl_cfilter *cf = writer_ctx;
|
||||
@@ -235,7 +226,7 @@ static CURLcode proxy_h2_nw_out_writer(void *writer_ctx,
|
||||
if(cf) {
|
||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||
CURLcode result;
|
||||
result = Curl_conn_cf_send(cf->next, data, (const char *)buf, buflen,
|
||||
result = Curl_conn_cf_send(cf->next, data, buf, buflen,
|
||||
FALSE, pnwritten);
|
||||
CURL_TRC_CF(data, cf, "[0] nw_out_writer(len=%zu) -> %d, %zu",
|
||||
buflen, result, *pnwritten);
|
||||
@@ -249,8 +240,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};
|
||||
nghttp2_mem mem = { NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
|
||||
Curl_nghttp2_calloc, Curl_nghttp2_realloc };
|
||||
|
||||
int rc = nghttp2_option_new(&o);
|
||||
if(rc)
|
||||
@@ -314,7 +305,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
||||
|
||||
rc = nghttp2_session_callbacks_new(&cbs);
|
||||
if(rc) {
|
||||
failf(data, "Couldn't initialize nghttp2 callbacks");
|
||||
failf(data, "Could not initialize nghttp2 callbacks");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -334,7 +325,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
||||
/* The nghttp2 session is not yet setup, do it */
|
||||
rc = proxy_h2_client_new(cf, cbs);
|
||||
if(rc) {
|
||||
failf(data, "Couldn't initialize nghttp2");
|
||||
failf(data, "Could not initialize nghttp2");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -365,7 +356,6 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* all set, traffic will be send on connect */
|
||||
result = CURLE_OK;
|
||||
|
||||
@@ -412,32 +402,30 @@ static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
|
||||
* This function returns 0 if it succeeds, or -1 and error code will
|
||||
* be assigned to *err.
|
||||
*/
|
||||
static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
CURLcode *err)
|
||||
static CURLcode proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
const unsigned char *buf;
|
||||
size_t blen;
|
||||
size_t blen, nread;
|
||||
ssize_t rv;
|
||||
|
||||
while(Curl_bufq_peek(&ctx->inbufq, &buf, &blen)) {
|
||||
|
||||
rv = nghttp2_session_mem_recv(ctx->h2, (const uint8_t *)buf, blen);
|
||||
CURL_TRC_CF(data, cf, "[0] %zu bytes to nghttp2 -> %zd", blen, rv);
|
||||
if(rv < 0) {
|
||||
if(!curlx_sztouz(rv, &nread)) {
|
||||
failf(data,
|
||||
"process_pending_input: nghttp2_session_mem_recv() returned "
|
||||
"%zd:%s", rv, nghttp2_strerror((int)rv));
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
else if(!rv) {
|
||||
else if(!nread) {
|
||||
/* nghttp2 does not want to process more, but has no error. This
|
||||
* probably cannot happen, but be safe. */
|
||||
break;
|
||||
}
|
||||
Curl_bufq_skip(&ctx->inbufq, (size_t)rv);
|
||||
Curl_bufq_skip(&ctx->inbufq, nread);
|
||||
if(Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
CURL_TRC_CF(data, cf, "[0] all data in connection buffer processed");
|
||||
break;
|
||||
@@ -447,8 +435,7 @@ static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||
"in connection buffer", Curl_bufq_len(&ctx->inbufq));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
||||
@@ -458,18 +445,19 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t nread;
|
||||
|
||||
/* Process network input buffer fist */
|
||||
/* Process network input buffer first */
|
||||
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
CURL_TRC_CF(data, cf, "[0] process %zu bytes in connection buffer",
|
||||
Curl_bufq_len(&ctx->inbufq));
|
||||
if(proxy_h2_process_pending_input(cf, data, &result) < 0)
|
||||
result = proxy_h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Receive data from the "lower" filters, e.g. network until
|
||||
* it is time to stop or we have enough data for this stream */
|
||||
while(!ctx->conn_closed && /* not closed the connection */
|
||||
!ctx->tunnel.closed && /* nor the tunnel */
|
||||
while(!ctx->conn_closed && /* not closed the connection */
|
||||
!ctx->tunnel.closed && /* nor the tunnel */
|
||||
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
|
||||
!Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
|
||||
|
||||
@@ -488,14 +476,11 @@ static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
||||
break;
|
||||
}
|
||||
|
||||
if(proxy_h2_process_pending_input(cf, data, &result))
|
||||
result = proxy_h2_process_pending_input(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(ctx->conn_closed && Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||
connclose(cf->conn, "GOAWAY received");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -554,70 +539,70 @@ static int proxy_h2_fr_print(const nghttp2_frame *frame,
|
||||
char *buffer, size_t blen)
|
||||
{
|
||||
switch(frame->hd.type) {
|
||||
case NGHTTP2_DATA: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[DATA, len=%d, eos=%d, padlen=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
|
||||
(int)frame->data.padlen);
|
||||
case NGHTTP2_DATA: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[DATA, len=%d, eos=%d, padlen=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM),
|
||||
(int)frame->data.padlen);
|
||||
}
|
||||
case NGHTTP2_HEADERS: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
|
||||
}
|
||||
case NGHTTP2_PRIORITY: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PRIORITY, len=%d, flags=%d]",
|
||||
(int)frame->hd.length, frame->hd.flags);
|
||||
}
|
||||
case NGHTTP2_RST_STREAM: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
|
||||
(int)frame->hd.length, frame->hd.flags,
|
||||
frame->rst_stream.error_code);
|
||||
}
|
||||
case NGHTTP2_SETTINGS: {
|
||||
if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
|
||||
return curl_msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
|
||||
}
|
||||
case NGHTTP2_HEADERS: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[HEADERS, len=%d, hend=%d, eos=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS),
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM));
|
||||
}
|
||||
case NGHTTP2_PRIORITY: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PRIORITY, len=%d, flags=%d]",
|
||||
(int)frame->hd.length, frame->hd.flags);
|
||||
}
|
||||
case NGHTTP2_RST_STREAM: {
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[RST_STREAM, len=%d, flags=%d, error=%u]",
|
||||
(int)frame->hd.length, frame->hd.flags,
|
||||
frame->rst_stream.error_code);
|
||||
}
|
||||
case NGHTTP2_SETTINGS: {
|
||||
if(frame->hd.flags & NGHTTP2_FLAG_ACK) {
|
||||
return curl_msnprintf(buffer, blen, "FRAME[SETTINGS, ack=1]");
|
||||
}
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
|
||||
}
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
|
||||
case NGHTTP2_PING:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PING, len=%d, ack=%d]",
|
||||
(int)frame->hd.length,
|
||||
frame->hd.flags & NGHTTP2_FLAG_ACK);
|
||||
case NGHTTP2_GOAWAY: {
|
||||
char scratch[128];
|
||||
size_t s_len = CURL_ARRAYSIZE(scratch);
|
||||
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 curl_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 curl_msnprintf(buffer, blen,
|
||||
"FRAME[WINDOW_UPDATE, incr=%d]",
|
||||
frame->window_update.window_size_increment);
|
||||
}
|
||||
default:
|
||||
return curl_msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
|
||||
frame->hd.type, (int)frame->hd.length,
|
||||
frame->hd.flags);
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[SETTINGS, len=%d]", (int)frame->hd.length);
|
||||
}
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PUSH_PROMISE, len=%d, hend=%d]",
|
||||
(int)frame->hd.length,
|
||||
!!(frame->hd.flags & NGHTTP2_FLAG_END_HEADERS));
|
||||
case NGHTTP2_PING:
|
||||
return curl_msnprintf(buffer, blen,
|
||||
"FRAME[PING, len=%d, ack=%d]",
|
||||
(int)frame->hd.length,
|
||||
frame->hd.flags & NGHTTP2_FLAG_ACK);
|
||||
case NGHTTP2_GOAWAY: {
|
||||
char scratch[128];
|
||||
size_t s_len = CURL_ARRAYSIZE(scratch);
|
||||
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 curl_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 curl_msnprintf(buffer, blen,
|
||||
"FRAME[WINDOW_UPDATE, incr=%d]",
|
||||
frame->window_update.window_size_increment);
|
||||
}
|
||||
default:
|
||||
return curl_msnprintf(buffer, blen, "FRAME[%d, len=%d, flags=%d]",
|
||||
frame->hd.type, (int)frame->hd.length,
|
||||
frame->hd.flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +618,7 @@ static int proxy_h2_on_frame_send(nghttp2_session *session,
|
||||
if(data && Curl_trc_cf_is_verbose(cf, data)) {
|
||||
char buffer[256];
|
||||
int len;
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1);
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer) - 1);
|
||||
buffer[len] = 0;
|
||||
CURL_TRC_CF(data, cf, "[%d] -> %s", frame->hd.stream_id, buffer);
|
||||
}
|
||||
@@ -656,9 +641,9 @@ static int proxy_h2_on_frame_recv(nghttp2_session *session,
|
||||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
char buffer[256];
|
||||
int len;
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer)-1);
|
||||
len = proxy_h2_fr_print(frame, buffer, sizeof(buffer) - 1);
|
||||
buffer[len] = 0;
|
||||
CURL_TRC_CF(data, cf, "[%d] <- %s",frame->hd.stream_id, buffer);
|
||||
CURL_TRC_CF(data, cf, "[%d] <- %s", frame->hd.stream_id, buffer);
|
||||
}
|
||||
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
@@ -851,7 +836,7 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
|
||||
#endif
|
||||
}
|
||||
/* tunnel.recbuf has soft limit, any success MUST add all data */
|
||||
DEBUGASSERT((size_t)nwritten == len);
|
||||
DEBUGASSERT(nwritten == len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -927,7 +912,7 @@ static CURLcode proxy_h2_submit(int32_t *pstream_id,
|
||||
result = CURLE_OK;
|
||||
|
||||
out:
|
||||
free(nva);
|
||||
curlx_free(nva);
|
||||
Curl_dynhds_free(&h2_headers);
|
||||
*pstream_id = stream_id;
|
||||
return result;
|
||||
@@ -974,7 +959,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
|
||||
(void)cf;
|
||||
|
||||
DEBUGASSERT(ts->resp);
|
||||
if(ts->resp->status/100 == 2) {
|
||||
if(ts->resp->status / 100 == 2) {
|
||||
infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
|
||||
h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data);
|
||||
return CURLE_OK;
|
||||
@@ -1077,7 +1062,6 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct cf_call_data save;
|
||||
timediff_t check;
|
||||
struct tunnel_stream *ts = &ctx->tunnel;
|
||||
|
||||
if(cf->connected) {
|
||||
@@ -1102,8 +1086,7 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
|
||||
}
|
||||
DEBUGASSERT(ts->authority);
|
||||
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
if(Curl_timeleft_ms(data, TRUE) < 0) {
|
||||
failf(data, "Proxy CONNECT aborted due to timeout");
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
goto out;
|
||||
@@ -1234,7 +1217,7 @@ static CURLcode cf_h2_proxy_adjust_pollset(struct Curl_cfilter *cf,
|
||||
c_exhaust = !nghttp2_session_get_remote_window_size(ctx->h2);
|
||||
s_exhaust = ctx->tunnel.stream_id >= 0 &&
|
||||
!nghttp2_session_get_stream_remote_window_size(
|
||||
ctx->h2, ctx->tunnel.stream_id);
|
||||
ctx->h2, ctx->tunnel.stream_id);
|
||||
want_recv = (want_recv || c_exhaust || s_exhaust);
|
||||
want_send = (!s_exhaust && want_send) ||
|
||||
(!c_exhaust && nghttp2_session_want_write(ctx->h2)) ||
|
||||
@@ -1271,7 +1254,7 @@ static CURLcode h2_handle_tunnel_close(struct Curl_cfilter *cf,
|
||||
if(ctx->tunnel.error == NGHTTP2_REFUSED_STREAM) {
|
||||
CURL_TRC_CF(data, cf, "[%d] REFUSED_STREAM, try again on a new "
|
||||
"connection", ctx->tunnel.stream_id);
|
||||
connclose(cf->conn, "REFUSED_STREAM"); /* do not use this anymore */
|
||||
failf(data, "proxy server refused HTTP/2 stream");
|
||||
return CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
|
||||
}
|
||||
else if(ctx->tunnel.error != NGHTTP2_NO_ERROR) {
|
||||
@@ -1366,7 +1349,7 @@ out:
|
||||
|
||||
static CURLcode cf_h2_proxy_send(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||
@@ -1428,7 +1411,7 @@ out:
|
||||
"h2 windows %d-%d (stream-conn), buffers %zu-%zu (stream-conn)",
|
||||
ctx->tunnel.stream_id, len, result, *pnwritten,
|
||||
nghttp2_session_get_stream_remote_window_size(
|
||||
ctx->h2, ctx->tunnel.stream_id),
|
||||
ctx->h2, ctx->tunnel.stream_id),
|
||||
nghttp2_session_get_remote_window_size(ctx->h2),
|
||||
Curl_bufq_len(&ctx->tunnel.sendbuf),
|
||||
Curl_bufq_len(&ctx->outbufq));
|
||||
@@ -1489,7 +1472,7 @@ static bool proxy_h2_connisalive(struct Curl_cfilter *cf,
|
||||
*input_pending = FALSE;
|
||||
result = Curl_cf_recv_bufq(cf->next, data, &ctx->inbufq, 0, &nread);
|
||||
if(!result) {
|
||||
if(proxy_h2_process_pending_input(cf, data, &result) < 0)
|
||||
if(proxy_h2_process_pending_input(cf, data))
|
||||
/* immediate error, considered dead */
|
||||
alive = FALSE;
|
||||
else {
|
||||
@@ -1580,7 +1563,7 @@ static CURLcode cf_h2_proxy_cntrl(struct Curl_cfilter *cf,
|
||||
|
||||
struct Curl_cftype Curl_cft_h2_proxy = {
|
||||
"H2-PROXY",
|
||||
CF_TYPE_IP_CONNECT|CF_TYPE_PROXY,
|
||||
CF_TYPE_IP_CONNECT | CF_TYPE_PROXY,
|
||||
CURL_LOG_LVL_NONE,
|
||||
cf_h2_proxy_destroy,
|
||||
cf_h2_proxy_connect,
|
||||
@@ -1604,7 +1587,7 @@ CURLcode Curl_cf_h2_proxy_insert_after(struct Curl_cfilter *cf,
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NGHTTP2) && !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
+7
-14
@@ -21,28 +21,21 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "cfilters.h"
|
||||
#include "cf-haproxy.h"
|
||||
#include "curl_trc.h"
|
||||
#include "multiif.h"
|
||||
#include "select.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
HAPROXY_INIT, /* init/default/no tunnel state */
|
||||
HAPROXY_SEND, /* data_out being sent */
|
||||
HAPROXY_DONE /* all work done */
|
||||
HAPROXY_INIT, /* init/default/no tunnel state */
|
||||
HAPROXY_SEND, /* data_out being sent */
|
||||
HAPROXY_DONE /* all work done */
|
||||
} haproxy_state;
|
||||
|
||||
struct cf_haproxy_ctx {
|
||||
@@ -61,11 +54,11 @@ static void cf_haproxy_ctx_free(struct cf_haproxy_ctx *ctx)
|
||||
{
|
||||
if(ctx) {
|
||||
curlx_dyn_free(&ctx->data_out);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter*cf,
|
||||
static CURLcode cf_haproxy_date_out_set(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_haproxy_ctx *ctx = cf->ctx;
|
||||
@@ -133,7 +126,7 @@ static CURLcode cf_haproxy_connect(struct Curl_cfilter *cf,
|
||||
if(len > 0) {
|
||||
size_t nwritten;
|
||||
result = Curl_conn_cf_send(cf->next, data,
|
||||
curlx_dyn_ptr(&ctx->data_out), len, FALSE,
|
||||
curlx_dyn_uptr(&ctx->data_out), len, FALSE,
|
||||
&nwritten);
|
||||
if(result) {
|
||||
if(result != CURLE_AGAIN)
|
||||
@@ -217,7 +210,7 @@ static CURLcode cf_haproxy_create(struct Curl_cfilter **pcf,
|
||||
CURLcode result;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
|
||||
+1
-1
@@ -23,8 +23,8 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|
||||
+50
-30
@@ -21,13 +21,11 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "curl_trc.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
@@ -35,13 +33,10 @@
|
||||
#include "multiif.h"
|
||||
#include "cf-https-connect.h"
|
||||
#include "http2.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef enum {
|
||||
CF_HC_INIT,
|
||||
CF_HC_CONNECT,
|
||||
@@ -55,7 +50,7 @@ struct cf_hc_baller {
|
||||
CURLcode result;
|
||||
struct curltime started;
|
||||
int reply_ms;
|
||||
unsigned char transport;
|
||||
uint8_t transport;
|
||||
enum alpnid alpn_id;
|
||||
BIT(shutdown);
|
||||
};
|
||||
@@ -124,7 +119,7 @@ struct cf_hc_ctx {
|
||||
|
||||
static void cf_hc_baller_assign(struct cf_hc_baller *b,
|
||||
enum alpnid alpn_id,
|
||||
unsigned char def_transport)
|
||||
uint8_t def_transport)
|
||||
{
|
||||
b->alpn_id = alpn_id;
|
||||
b->transport = def_transport;
|
||||
@@ -148,12 +143,12 @@ static void cf_hc_baller_assign(struct cf_hc_baller *b,
|
||||
static void cf_hc_baller_init(struct cf_hc_baller *b,
|
||||
struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct Curl_cfilter *save = cf->next;
|
||||
|
||||
cf->next = NULL;
|
||||
b->started = curlx_now();
|
||||
b->started = *Curl_pgrs_now(data);
|
||||
switch(b->alpn_id) {
|
||||
case ALPN_h3:
|
||||
transport = TRNSPRT_QUIC;
|
||||
@@ -215,12 +210,13 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
|
||||
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)curlx_timediff(curlx_now(),
|
||||
winner->started), reply_ms);
|
||||
winner->name,
|
||||
(int)curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&winner->started), reply_ms);
|
||||
else
|
||||
CURL_TRC_CF(data, cf, "deferred handshake %s: %dms",
|
||||
winner->name, (int)curlx_timediff(curlx_now(),
|
||||
winner->started));
|
||||
winner->name, (int)curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&winner->started));
|
||||
|
||||
/* install the winning filter below this one. */
|
||||
cf->next = winner->cf;
|
||||
@@ -247,7 +243,6 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static bool time_to_start_next(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
size_t idx, struct curltime now)
|
||||
@@ -269,7 +264,7 @@ static bool time_to_start_next(struct Curl_cfilter *cf,
|
||||
ctx->ballers[idx].name);
|
||||
return TRUE;
|
||||
}
|
||||
elapsed_ms = curlx_timediff(now, ctx->started);
|
||||
elapsed_ms = curlx_ptimediff_ms(&now, &ctx->started);
|
||||
if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
|
||||
CURL_TRC_CF(data, cf, "hard timeout of %" FMT_TIMEDIFF_T "ms reached, "
|
||||
"starting %s",
|
||||
@@ -297,7 +292,6 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
||||
bool *done)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct curltime now;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i, failed_ballers;
|
||||
|
||||
@@ -307,14 +301,13 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
*done = FALSE;
|
||||
now = curlx_now();
|
||||
switch(ctx->state) {
|
||||
case CF_HC_INIT:
|
||||
DEBUGASSERT(!cf->next);
|
||||
for(i = 0; i < ctx->baller_count; i++)
|
||||
DEBUGASSERT(!ctx->ballers[i].cf);
|
||||
CURL_TRC_CF(data, cf, "connect, init");
|
||||
ctx->started = now;
|
||||
ctx->started = *Curl_pgrs_now(data);
|
||||
cf_hc_baller_init(&ctx->ballers[0], cf, data, ctx->ballers[0].transport);
|
||||
if(ctx->baller_count > 1) {
|
||||
Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
|
||||
@@ -333,7 +326,7 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
||||
}
|
||||
}
|
||||
|
||||
if(time_to_start_next(cf, data, 1, now)) {
|
||||
if(time_to_start_next(cf, data, 1, *Curl_pgrs_now(data))) {
|
||||
cf_hc_baller_init(&ctx->ballers[1], cf, data, ctx->ballers[1].transport);
|
||||
}
|
||||
|
||||
@@ -474,7 +467,7 @@ static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
|
||||
struct Curl_cfilter *cfb = ctx->ballers[i].cf;
|
||||
memset(&t, 0, sizeof(t));
|
||||
if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
|
||||
if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0)
|
||||
if((t.tv_sec || t.tv_usec) && curlx_ptimediff_us(&t, &tmax) > 0)
|
||||
tmax = t;
|
||||
}
|
||||
}
|
||||
@@ -580,27 +573,29 @@ struct Curl_cftype Curl_cft_http_connect = {
|
||||
static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
enum alpnid *alpnids, size_t alpn_count,
|
||||
unsigned char def_transport)
|
||||
uint8_t def_transport)
|
||||
{
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
struct cf_hc_ctx *ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i;
|
||||
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUGASSERT(alpnids);
|
||||
DEBUGASSERT(alpn_count);
|
||||
DEBUGASSERT(alpn_count <= CURL_ARRAYSIZE(ctx->ballers));
|
||||
if(!alpn_count || (alpn_count > CURL_ARRAYSIZE(ctx->ballers))) {
|
||||
failf(data, "https-connect filter create with unsupported %zu ALPN ids",
|
||||
alpn_count);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
result = CURLE_FAILED_INIT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for(i = 0; i < alpn_count; ++i)
|
||||
cf_hc_baller_assign(&ctx->ballers[i], alpnids[i], def_transport);
|
||||
for(; i < CURL_ARRAYSIZE(ctx->ballers); ++i)
|
||||
@@ -615,7 +610,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
|
||||
|
||||
out:
|
||||
*pcf = result ? NULL : cf;
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -623,7 +618,7 @@ static CURLcode cf_http_connect_add(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
enum alpnid *alpn_ids, size_t alpn_count,
|
||||
unsigned char def_transport)
|
||||
uint8_t def_transport)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -712,6 +707,31 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add preferred HTTP version ALPN first */
|
||||
if(data->state.http_neg.preferred &&
|
||||
(alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
|
||||
(data->state.http_neg.preferred & data->state.http_neg.allowed)) {
|
||||
enum alpnid alpn_pref = ALPN_none;
|
||||
switch(data->state.http_neg.preferred) {
|
||||
case CURL_HTTP_V3x:
|
||||
if(!Curl_conn_may_http3(data, conn, conn->transport_wanted))
|
||||
alpn_pref = ALPN_h3;
|
||||
break;
|
||||
case CURL_HTTP_V2x:
|
||||
alpn_pref = ALPN_h2;
|
||||
break;
|
||||
case CURL_HTTP_V1x:
|
||||
alpn_pref = ALPN_h1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(alpn_pref &&
|
||||
!cf_https_alpns_contain(alpn_pref, alpn_ids, alpn_count)) {
|
||||
alpn_ids[alpn_count++] = alpn_pref;
|
||||
}
|
||||
}
|
||||
|
||||
if((alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
|
||||
(data->state.http_neg.wanted & CURL_HTTP_V3x) &&
|
||||
!cf_https_alpns_contain(ALPN_h3, alpn_ids, alpn_count)) {
|
||||
|
||||
@@ -44,6 +44,5 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP */
|
||||
#endif /* HEADER_CURL_CF_HTTP_H */
|
||||
+79
-88
@@ -21,15 +21,11 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h> /* for sockaddr_un */
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_TCP_H
|
||||
#include <linux/tcp.h>
|
||||
#elif defined(HAVE_NETINET_TCP_H)
|
||||
@@ -60,13 +56,9 @@
|
||||
#include "select.h"
|
||||
#include "vquic/vquic.h" /* for quic cfilters */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
struct transport_provider {
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
cf_ip_connect_create *cf_create;
|
||||
};
|
||||
|
||||
@@ -87,7 +79,7 @@ struct transport_provider transport_providers[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static cf_ip_connect_create *get_cf_create(int transport)
|
||||
static cf_ip_connect_create *get_cf_create(uint8_t transport)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) {
|
||||
@@ -99,7 +91,7 @@ static cf_ip_connect_create *get_cf_create(int transport)
|
||||
|
||||
#ifdef UNITTESTS
|
||||
/* used by unit2600.c */
|
||||
void Curl_debug_set_transport_provider(int transport,
|
||||
void Curl_debug_set_transport_provider(uint8_t transport,
|
||||
cf_ip_connect_create *cf_create)
|
||||
{
|
||||
size_t i;
|
||||
@@ -112,7 +104,6 @@ void Curl_debug_set_transport_provider(int transport,
|
||||
}
|
||||
#endif /* UNITTESTS */
|
||||
|
||||
|
||||
struct cf_ai_iter {
|
||||
const struct Curl_addrinfo *head;
|
||||
const struct Curl_addrinfo *last;
|
||||
@@ -172,7 +163,7 @@ struct cf_ip_attempt {
|
||||
struct curltime started; /* start of current attempt */
|
||||
CURLcode result;
|
||||
int ai_family;
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
int error;
|
||||
BIT(connected); /* cf has connected */
|
||||
BIT(shutdown); /* cf has shutdown */
|
||||
@@ -186,7 +177,7 @@ static void cf_ip_attempt_free(struct cf_ip_attempt *a,
|
||||
if(a) {
|
||||
if(a->cf)
|
||||
Curl_conn_cf_discard_chain(&a->cf, data);
|
||||
free(a);
|
||||
curlx_free(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +186,7 @@ static CURLcode cf_ip_attempt_new(struct cf_ip_attempt **pa,
|
||||
struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *addr,
|
||||
int ai_family,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
cf_ip_connect_create *cf_create)
|
||||
{
|
||||
struct Curl_cfilter *wcf;
|
||||
@@ -203,7 +194,7 @@ static CURLcode cf_ip_attempt_new(struct cf_ip_attempt **pa,
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*pa = NULL;
|
||||
a = calloc(1, sizeof(*a));
|
||||
a = curlx_calloc(1, sizeof(*a));
|
||||
if(!a)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -237,7 +228,7 @@ static CURLcode cf_ip_attempt_connect(struct cf_ip_attempt *a,
|
||||
bool *connected)
|
||||
{
|
||||
*connected = a->connected;
|
||||
if(!a->result && !*connected) {
|
||||
if(!a->result && !*connected) {
|
||||
/* evaluate again */
|
||||
a->result = Curl_conn_cf_connect(a->cf, data, connected);
|
||||
|
||||
@@ -264,7 +255,7 @@ struct cf_ip_ballers {
|
||||
struct curltime last_attempt_started;
|
||||
timediff_t attempt_delay_ms;
|
||||
int last_attempt_ai_family;
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
};
|
||||
|
||||
static CURLcode cf_ip_attempt_restart(struct cf_ip_attempt *a,
|
||||
@@ -315,7 +306,7 @@ static void cf_ip_ballers_clear(struct Curl_cfilter *cf,
|
||||
static CURLcode cf_ip_ballers_init(struct cf_ip_ballers *bs, int ip_version,
|
||||
const struct Curl_addrinfo *addr_list,
|
||||
cf_ip_connect_create *cf_create,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
timediff_t attempt_delay_ms)
|
||||
{
|
||||
memset(bs, 0, sizeof(*bs));
|
||||
@@ -358,7 +349,6 @@ static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs,
|
||||
CURLcode result = CURLE_OK;
|
||||
struct cf_ip_attempt *a = NULL, **panchor;
|
||||
bool do_more;
|
||||
struct curltime now;
|
||||
timediff_t next_expire_ms;
|
||||
int i, inconclusive, ongoing;
|
||||
|
||||
@@ -366,7 +356,6 @@ static CURLcode cf_ip_ballers_run(struct cf_ip_ballers *bs,
|
||||
return CURLE_OK;
|
||||
|
||||
evaluate:
|
||||
now = curlx_now();
|
||||
ongoing = inconclusive = 0;
|
||||
|
||||
/* check if a running baller connects now */
|
||||
@@ -403,7 +392,7 @@ evaluate:
|
||||
/* no attempt connected yet, start another one? */
|
||||
if(!ongoing) {
|
||||
if(!bs->started.tv_sec && !bs->started.tv_usec)
|
||||
bs->started = now;
|
||||
bs->started = *Curl_pgrs_now(data);
|
||||
do_more = TRUE;
|
||||
}
|
||||
else {
|
||||
@@ -413,8 +402,8 @@ evaluate:
|
||||
more_possible = cf_ai_iter_has_more(&bs->ipv6_iter);
|
||||
#endif
|
||||
do_more = more_possible &&
|
||||
(curlx_timediff(now, bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms);
|
||||
(curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started) >=
|
||||
bs->attempt_delay_ms);
|
||||
if(do_more)
|
||||
CURL_TRC_CF(data, cf, "happy eyeballs timeout expired, "
|
||||
"start next attempt");
|
||||
@@ -427,9 +416,9 @@ evaluate:
|
||||
int ai_family = 0;
|
||||
#ifdef USE_IPV6
|
||||
if((bs->last_attempt_ai_family == AF_INET) ||
|
||||
!cf_ai_iter_has_more(&bs->addr_iter)) {
|
||||
addr = cf_ai_iter_next(&bs->ipv6_iter);
|
||||
ai_family = bs->ipv6_iter.ai_family;
|
||||
!cf_ai_iter_has_more(&bs->addr_iter)) {
|
||||
addr = cf_ai_iter_next(&bs->ipv6_iter);
|
||||
ai_family = bs->ipv6_iter.ai_family;
|
||||
}
|
||||
#endif
|
||||
if(!addr) {
|
||||
@@ -452,7 +441,7 @@ evaluate:
|
||||
while(*panchor)
|
||||
panchor = &((*panchor)->next);
|
||||
*panchor = a;
|
||||
bs->last_attempt_started = now;
|
||||
bs->last_attempt_started = *Curl_pgrs_now(data);
|
||||
bs->last_attempt_ai_family = ai_family;
|
||||
/* and run everything again */
|
||||
goto evaluate;
|
||||
@@ -460,7 +449,8 @@ evaluate:
|
||||
else if(inconclusive) {
|
||||
/* tried all addresses, no success but some where inconclusive.
|
||||
* Let's restart the inconclusive ones. */
|
||||
timediff_t since_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
timediff_t since_ms =
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started);
|
||||
timediff_t delay_ms = bs->attempt_delay_ms - since_ms;
|
||||
if(delay_ms <= 0) {
|
||||
CURL_TRC_CF(data, cf, "all attempts inconclusive, restarting one");
|
||||
@@ -473,7 +463,7 @@ evaluate:
|
||||
CURL_TRC_CF(data, cf, "restarted baller %d -> %d", i, result);
|
||||
if(result) /* serious failure */
|
||||
goto out;
|
||||
bs->last_attempt_started = now;
|
||||
bs->last_attempt_started = *Curl_pgrs_now(data);
|
||||
goto evaluate;
|
||||
}
|
||||
DEBUGASSERT(0); /* should not come here */
|
||||
@@ -505,10 +495,11 @@ out:
|
||||
bool more_possible;
|
||||
|
||||
/* when do we need to be called again? */
|
||||
next_expire_ms = Curl_timeleft(data, &now, TRUE);
|
||||
next_expire_ms = Curl_timeleft_ms(data, TRUE);
|
||||
if(next_expire_ms <= 0) {
|
||||
failf(data, "Connection timeout after %" FMT_OFF_T " ms",
|
||||
curlx_timediff(now, data->progress.t_startsingle));
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&data->progress.t_startsingle));
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -519,14 +510,15 @@ out:
|
||||
#endif
|
||||
if(more_possible) {
|
||||
timediff_t expire_ms, elapsed_ms;
|
||||
elapsed_ms = curlx_timediff(now, bs->last_attempt_started);
|
||||
elapsed_ms =
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data), &bs->last_attempt_started);
|
||||
expire_ms = CURLMAX(bs->attempt_delay_ms - elapsed_ms, 0);
|
||||
next_expire_ms = CURLMIN(next_expire_ms, expire_ms);
|
||||
if(next_expire_ms <= 0) {
|
||||
CURL_TRC_CF(data, cf, "HAPPY_EYBALLS timeout due, re-evaluate");
|
||||
CURL_TRC_CF(data, cf, "HAPPY_EYEBALLS timeout due, re-evaluate");
|
||||
goto evaluate;
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "next HAPPY_EYBALLS timeout in %" FMT_TIMEDIFF_T
|
||||
CURL_TRC_CF(data, cf, "next HAPPY_EYEBALLS timeout in %" FMT_TIMEDIFF_T
|
||||
"ms", next_expire_ms);
|
||||
Curl_expire(data, next_expire_ms, EXPIRE_HAPPY_EYEBALLS);
|
||||
}
|
||||
@@ -595,7 +587,7 @@ static struct curltime cf_ip_ballers_max_time(struct cf_ip_ballers *bs,
|
||||
for(a = bs->running; a; a = a->next) {
|
||||
memset(&t, 0, sizeof(t));
|
||||
if(!a->cf->cft->query(a->cf, data, query, NULL, &t)) {
|
||||
if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0)
|
||||
if((t.tv_sec || t.tv_usec) && curlx_ptimediff_us(&t, &tmax) > 0)
|
||||
tmax = t;
|
||||
}
|
||||
}
|
||||
@@ -618,7 +610,6 @@ static int cf_ip_ballers_min_reply_ms(struct cf_ip_ballers *bs,
|
||||
return reply_ms;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {
|
||||
SCFST_INIT,
|
||||
SCFST_WAITING,
|
||||
@@ -626,14 +617,13 @@ typedef enum {
|
||||
} cf_connect_state;
|
||||
|
||||
struct cf_ip_happy_ctx {
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
cf_ip_connect_create *cf_create;
|
||||
cf_connect_state state;
|
||||
struct cf_ip_ballers ballers;
|
||||
struct curltime started;
|
||||
};
|
||||
|
||||
|
||||
static CURLcode is_connected(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
bool *connected)
|
||||
@@ -682,7 +672,8 @@ static CURLcode is_connected(struct Curl_cfilter *cf,
|
||||
proxy_name ? "via " : "",
|
||||
proxy_name ? proxy_name : "",
|
||||
proxy_name ? " " : "",
|
||||
curlx_timediff(curlx_now(), data->progress.t_startsingle),
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&data->progress.t_startsingle),
|
||||
curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
@@ -707,14 +698,14 @@ static CURLcode start_connect(struct Curl_cfilter *cf,
|
||||
if(!dns)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(Curl_timeleft(data, NULL, TRUE) < 0) {
|
||||
if(Curl_timeleft_ms(data, TRUE) < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
failf(data, "Connection time-out");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
CURL_TRC_CF(data, cf, "init ip ballers for transport %d", ctx->transport);
|
||||
ctx->started = curlx_now();
|
||||
CURL_TRC_CF(data, cf, "init ip ballers for transport %u", ctx->transport);
|
||||
ctx->started = *Curl_pgrs_now(data);
|
||||
return cf_ip_ballers_init(&ctx->ballers, cf->conn->ip_version,
|
||||
dns->addr, ctx->cf_create, ctx->transport,
|
||||
data->set.happy_eyeballs_timeout);
|
||||
@@ -778,50 +769,50 @@ static CURLcode cf_ip_happy_connect(struct Curl_cfilter *cf,
|
||||
*done = FALSE;
|
||||
|
||||
switch(ctx->state) {
|
||||
case SCFST_INIT:
|
||||
DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data));
|
||||
DEBUGASSERT(!cf->connected);
|
||||
result = start_connect(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
ctx->state = SCFST_WAITING;
|
||||
FALLTHROUGH();
|
||||
case SCFST_WAITING:
|
||||
result = is_connected(cf, data, done);
|
||||
if(!result && *done) {
|
||||
DEBUGASSERT(ctx->ballers.winner);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf->connected);
|
||||
/* we have a winner. Install and activate it.
|
||||
* close/free all others. */
|
||||
ctx->state = SCFST_DONE;
|
||||
cf->connected = TRUE;
|
||||
cf->next = ctx->ballers.winner->cf;
|
||||
ctx->ballers.winner->cf = NULL;
|
||||
cf_ip_happy_ctx_clear(cf, data);
|
||||
Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS);
|
||||
case SCFST_INIT:
|
||||
DEBUGASSERT(CURL_SOCKET_BAD == Curl_conn_cf_get_socket(cf, data));
|
||||
DEBUGASSERT(!cf->connected);
|
||||
result = start_connect(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
ctx->state = SCFST_WAITING;
|
||||
FALLTHROUGH();
|
||||
case SCFST_WAITING:
|
||||
result = is_connected(cf, data, done);
|
||||
if(!result && *done) {
|
||||
DEBUGASSERT(ctx->ballers.winner);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf);
|
||||
DEBUGASSERT(ctx->ballers.winner->cf->connected);
|
||||
/* we have a winner. Install and activate it.
|
||||
* close/free all others. */
|
||||
ctx->state = SCFST_DONE;
|
||||
cf->connected = TRUE;
|
||||
cf->next = ctx->ballers.winner->cf;
|
||||
ctx->ballers.winner->cf = NULL;
|
||||
cf_ip_happy_ctx_clear(cf, data);
|
||||
Curl_expire_done(data, EXPIRE_HAPPY_EYEBALLS);
|
||||
|
||||
if(cf->conn->handler->protocol & PROTO_FAMILY_SSH)
|
||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */
|
||||
if(cf->conn->handler->protocol & PROTO_FAMILY_SSH)
|
||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we are connected already */
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) {
|
||||
const char *host;
|
||||
int port;
|
||||
Curl_conn_get_current_host(data, cf->sockindex, &host, &port);
|
||||
CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u",
|
||||
host, ipquad.remote_ip, ipquad.remote_port);
|
||||
}
|
||||
if(Curl_trc_cf_is_verbose(cf, data)) {
|
||||
struct ip_quadruple ipquad;
|
||||
bool is_ipv6;
|
||||
if(!Curl_conn_cf_get_ip_info(cf->next, data, &is_ipv6, &ipquad)) {
|
||||
const char *host;
|
||||
int port;
|
||||
Curl_conn_get_current_host(data, cf->sockindex, &host, &port);
|
||||
CURL_TRC_CF(data, cf, "Connected to %s (%s) port %u",
|
||||
host, ipquad.remote_ip, ipquad.remote_port);
|
||||
}
|
||||
#endif
|
||||
data->info.numconnects++; /* to track the # of connections made */
|
||||
}
|
||||
break;
|
||||
case SCFST_DONE:
|
||||
*done = TRUE;
|
||||
break;
|
||||
#endif
|
||||
data->info.numconnects++; /* to track the # of connections made */
|
||||
}
|
||||
break;
|
||||
case SCFST_DONE:
|
||||
*done = TRUE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -933,7 +924,7 @@ static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
cf_ip_connect_create *cf_create,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct cf_ip_happy_ctx *ctx = NULL;
|
||||
CURLcode result;
|
||||
@@ -941,7 +932,7 @@ static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf,
|
||||
(void)data;
|
||||
(void)conn;
|
||||
*pcf = NULL;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
@@ -954,14 +945,14 @@ static CURLcode cf_ip_happy_create(struct Curl_cfilter **pcf,
|
||||
out:
|
||||
if(result) {
|
||||
Curl_safefree(*pcf);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
cf_ip_connect_create *cf_create;
|
||||
struct Curl_cfilter *cf;
|
||||
@@ -971,7 +962,7 @@ CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at,
|
||||
DEBUGASSERT(cf_at);
|
||||
cf_create = get_cf_create(transport);
|
||||
if(!cf_create) {
|
||||
CURL_TRC_CF(data, cf_at, "unsupported transport type %d", transport);
|
||||
CURL_TRC_CF(data, cf_at, "unsupported transport type %u", transport);
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
result = cf_ip_happy_create(&cf, data, cf_at->conn, cf_create, transport);
|
||||
|
||||
+3
-6
@@ -25,9 +25,6 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curlx/nonblock.h" /* for curlx_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
|
||||
/**
|
||||
* Create a cfilter for making an "ip" connection to the
|
||||
* given address, using parameters from `conn`. The "ip" connection
|
||||
@@ -43,16 +40,16 @@ typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
CURLcode cf_ip_happy_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
extern struct Curl_cftype Curl_cft_ip_happy;
|
||||
|
||||
#ifdef UNITTESTS
|
||||
void Curl_debug_set_transport_provider(int transport,
|
||||
void Curl_debug_set_transport_provider(uint8_t transport,
|
||||
cf_ip_connect_create *cf_create);
|
||||
#endif
|
||||
|
||||
|
||||
+268
-277
@@ -21,15 +21,11 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h> /* <netinet/tcp.h> may need it */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h> /* for sockaddr_un */
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_TCP_H
|
||||
#include <linux/tcp.h>
|
||||
#elif defined(HAVE_NETINET_TCP_H)
|
||||
@@ -60,61 +56,41 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "bufq.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "if2ip.h"
|
||||
#include "cfilters.h"
|
||||
#include "cf-socket.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
#include "multiif.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "progress.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "rand.h"
|
||||
#include "share.h"
|
||||
#include "strdup.h"
|
||||
#include "system_win32.h"
|
||||
#include "curlx/nonblock.h"
|
||||
#include "curlx/version_win32.h"
|
||||
#include "curlx/strerr.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
#if defined(USE_IPV6) && defined(IPV6_V6ONLY) && defined(_WIN32)
|
||||
/* It makes support for IPv4-mapped IPv6 addresses.
|
||||
* Linux kernel, NetBSD, FreeBSD and Darwin: default is off;
|
||||
* Windows Vista and later: default is on;
|
||||
* DragonFly BSD: acts like off, and dummy setting;
|
||||
* OpenBSD and earlier Windows: unsupported.
|
||||
* Linux: controlled by /proc/sys/net/ipv6/bindv6only.
|
||||
*/
|
||||
static void set_ipv6_v6only(curl_socket_t sockfd, int on)
|
||||
{
|
||||
(void)setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on));
|
||||
}
|
||||
#else
|
||||
#define set_ipv6_v6only(x,y)
|
||||
#endif
|
||||
|
||||
static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
|
||||
static void tcpnodelay(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
#if defined(TCP_NODELAY) && defined(CURL_TCP_NODELAY_SUPPORTED)
|
||||
curl_socklen_t onoff = (curl_socklen_t) 1;
|
||||
curl_socklen_t onoff = (curl_socklen_t)1;
|
||||
int level = IPPROTO_TCP;
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
if(setsockopt(sockfd, level, TCP_NODELAY,
|
||||
(void *)&onoff, sizeof(onoff)) < 0)
|
||||
infof(data, "Could not set TCP_NODELAY: %s",
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
CURL_TRC_CF(data, cf, "Could not set TCP_NODELAY: %s",
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#else
|
||||
(void)cf;
|
||||
(void)data;
|
||||
(void)sockfd;
|
||||
#endif
|
||||
@@ -125,31 +101,28 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd)
|
||||
sending data to a dead peer (instead of relying on the 4th argument to send
|
||||
being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
|
||||
systems? */
|
||||
static void nosigpipe(struct Curl_easy *data,
|
||||
static void nosigpipe(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
int onoff = 1;
|
||||
(void)data;
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE,
|
||||
(void *)&onoff, sizeof(onoff)) < 0) {
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
char buffer[STRERROR_LEN];
|
||||
infof(data, "Could not set SO_NOSIGPIPE: %s",
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
CURL_TRC_CF(data, cf, "Could not set SO_NOSIGPIPE: %s",
|
||||
curlx_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
#else
|
||||
(void)cf;
|
||||
(void)data;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define nosigpipe(x,y) Curl_nop_stmt
|
||||
#define nosigpipe(x, y, z) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#if defined(USE_WINSOCK) && \
|
||||
defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT)
|
||||
/* Win 10, v 1709 (10.0.16299) and later can use SetSockOpt TCP_KEEP____
|
||||
* so should use seconds */
|
||||
#define CURL_WINSOCK_KEEP_SSO
|
||||
#define KEEPALIVE_FACTOR(x)
|
||||
#elif defined(USE_WINSOCK) || \
|
||||
#if defined(USE_WINSOCK) || \
|
||||
(defined(__sun) && !defined(TCP_KEEPIDLE)) || \
|
||||
(defined(__DragonFly__) && __DragonFly_version < 500702) || \
|
||||
(defined(_WIN32) && !defined(TCP_KEEPIDLE))
|
||||
@@ -160,82 +133,91 @@ static void nosigpipe(struct Curl_easy *data,
|
||||
#define KEEPALIVE_FACTOR(x)
|
||||
#endif
|
||||
|
||||
/* Offered by mingw-w64 and MS SDK. Latter only when targeting Win7+. */
|
||||
#if defined(USE_WINSOCK) && !defined(SIO_KEEPALIVE_VALS)
|
||||
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
|
||||
|
||||
struct tcp_keepalive {
|
||||
u_long onoff;
|
||||
u_long keepalivetime;
|
||||
u_long keepaliveinterval;
|
||||
};
|
||||
#endif
|
||||
|
||||
static void
|
||||
tcpkeepalive(struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
static void tcpkeepalive(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
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,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set SO_KEEPALIVE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set SO_KEEPALIVE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
else {
|
||||
#ifdef SIO_KEEPALIVE_VALS /* Windows */
|
||||
/* Windows 10, version 1709 (10.0.16299) and later versions */
|
||||
#ifdef CURL_WINSOCK_KEEP_SSO
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
|
||||
(const char *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPIDLE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
}
|
||||
optval = curlx_sltosi(data->set.tcp_keepintvl);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
|
||||
(const char *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPINTVL on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
}
|
||||
optval = curlx_sltosi(data->set.tcp_keepcnt);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT,
|
||||
(const char *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPCNT on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
}
|
||||
#else /* Windows < 10.0.16299 */
|
||||
struct tcp_keepalive vals;
|
||||
DWORD dummy;
|
||||
vals.onoff = 1;
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
vals.keepalivetime = (u_long)optval;
|
||||
optval = curlx_sltosi(data->set.tcp_keepintvl);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
vals.keepaliveinterval = (u_long)optval;
|
||||
if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
|
||||
NULL, 0, &dummy, NULL, NULL) != 0) {
|
||||
infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#ifdef USE_WINSOCK
|
||||
/* Windows 10, version 1709 (10.0.16299) and later versions can use
|
||||
setsockopt() TCP_KEEP*. Older versions return with failure. */
|
||||
if(curlx_verify_windows_version(10, 0, 16299, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
CURL_TRC_CF(data, cf, "Set TCP_KEEP* on fd=%" FMT_SOCKET_T, sockfd);
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
/* Offered by mingw-w64 v12+. MS SDK 6.0A+. */
|
||||
#ifndef TCP_KEEPALIVE
|
||||
#define TCP_KEEPALIVE 3
|
||||
#endif
|
||||
#else /* !Windows */
|
||||
/* Offered by mingw-w64 v12+. MS SDK ~10+/~VS2017+. */
|
||||
#ifndef TCP_KEEPCNT
|
||||
#define TCP_KEEPCNT 16
|
||||
#endif
|
||||
#ifndef TCP_KEEPIDLE
|
||||
#define TCP_KEEPIDLE TCP_KEEPALIVE
|
||||
#endif
|
||||
#ifndef TCP_KEEPINTVL
|
||||
#define TCP_KEEPINTVL 17
|
||||
#endif
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
|
||||
(const char *)&optval, sizeof(optval)) < 0) {
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPIDLE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
optval = curlx_sltosi(data->set.tcp_keepintvl);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
|
||||
(const char *)&optval, sizeof(optval)) < 0) {
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPINTVL on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
optval = curlx_sltosi(data->set.tcp_keepcnt);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT,
|
||||
(const char *)&optval, sizeof(optval)) < 0) {
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPCNT on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Offered by mingw-w64 and MS SDK. Latter only when targeting Win7+. */
|
||||
#ifndef SIO_KEEPALIVE_VALS
|
||||
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR, 4)
|
||||
struct tcp_keepalive {
|
||||
u_long onoff;
|
||||
u_long keepalivetime;
|
||||
u_long keepaliveinterval;
|
||||
};
|
||||
#endif
|
||||
struct tcp_keepalive vals;
|
||||
DWORD dummy;
|
||||
vals.onoff = 1;
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
vals.keepalivetime = (u_long)optval;
|
||||
optval = curlx_sltosi(data->set.tcp_keepintvl);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
vals.keepaliveinterval = (u_long)optval;
|
||||
if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID)&vals, sizeof(vals),
|
||||
NULL, 0, &dummy, NULL, NULL) != 0) {
|
||||
CURL_TRC_CF(data, cf, "Failed to set SIO_KEEPALIVE_VALS on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
}
|
||||
#else /* !USE_WINSOCK */
|
||||
#ifdef TCP_KEEPIDLE
|
||||
optval = curlx_sltosi(data->set.tcp_keepidle);
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPIDLE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPIDLE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#elif defined(TCP_KEEPALIVE)
|
||||
/* macOS style */
|
||||
@@ -243,9 +225,8 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPALIVE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPALIVE on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#elif defined(TCP_KEEPALIVE_THRESHOLD)
|
||||
/* Solaris <11.4 style */
|
||||
@@ -253,9 +234,8 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPALIVE_THRESHOLD on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPALIVE_THRESHOLD on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPINTVL
|
||||
@@ -263,9 +243,8 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPINTVL on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d",
|
||||
sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPINTVL on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#elif defined(TCP_KEEPALIVE_ABORT_THRESHOLD)
|
||||
/* Solaris <11.4 style */
|
||||
@@ -284,19 +263,19 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
KEEPALIVE_FACTOR(optval);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPALIVE_ABORT_THRESHOLD on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPALIVE_ABORT_THRESHOLD"
|
||||
" on fd %" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#endif
|
||||
#ifdef TCP_KEEPCNT
|
||||
optval = curlx_sltosi(data->set.tcp_keepcnt);
|
||||
if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT,
|
||||
(void *)&optval, sizeof(optval)) < 0) {
|
||||
infof(data, "Failed to set TCP_KEEPCNT on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
CURL_TRC_CF(data, cf, "Failed to set TCP_KEEPCNT on fd "
|
||||
"%" FMT_SOCKET_T ": errno %d", sockfd, SOCKERRNO);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* USE_WINSOCK */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,7 +285,7 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
*/
|
||||
static CURLcode sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
/*
|
||||
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
||||
@@ -349,15 +328,15 @@ static CURLcode socket_open(struct Curl_easy *data,
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->conn);
|
||||
if(data->set.fopensocket) {
|
||||
/*
|
||||
* If the opensocket callback is set, all the destination address
|
||||
* information is passed to the callback. Depending on this information the
|
||||
* callback may opt to abort the connection, this is indicated returning
|
||||
* CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
|
||||
* the callback returns a valid socket the destination address information
|
||||
* might have been changed and this 'new' address will actually be used
|
||||
* here to connect.
|
||||
*/
|
||||
/*
|
||||
* If the opensocket callback is set, all the destination address
|
||||
* information is passed to the callback. Depending on this information the
|
||||
* callback may opt to abort the connection, this is indicated returning
|
||||
* CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
|
||||
* the callback returns a valid socket the destination address information
|
||||
* might have been changed and this 'new' address will actually be used
|
||||
* here to connect.
|
||||
*/
|
||||
Curl_set_in_callback(data, TRUE);
|
||||
*sockfd = data->set.fopensocket(data->set.opensocket_client,
|
||||
CURLSOCKTYPE_IPCXN,
|
||||
@@ -367,6 +346,8 @@ static CURLcode socket_open(struct Curl_easy *data,
|
||||
else {
|
||||
/* opensocket callback not set, so simply create the socket now */
|
||||
*sockfd = CURL_SOCKET(addr->family, addr->socktype, addr->protocol);
|
||||
if((*sockfd == CURL_SOCKET_BAD) && (SOCKERRNO == SOCKENOMEM))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(*sockfd == CURL_SOCKET_BAD) {
|
||||
@@ -407,7 +388,7 @@ static CURLcode socket_open(struct Curl_easy *data,
|
||||
CURLcode Curl_socket_open(struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
curl_socket_t *sockfd)
|
||||
{
|
||||
struct Curl_sockaddr_ex dummy;
|
||||
@@ -558,7 +539,7 @@ CURLcode Curl_parse_interface(const char *input,
|
||||
++host_part;
|
||||
*host = Curl_memdup0(host_part, len - (host_part - input));
|
||||
if(!*host) {
|
||||
free(*iface);
|
||||
curlx_free(*iface);
|
||||
*iface = NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -607,7 +588,7 @@ 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) )
|
||||
else if(iface && (strlen(iface) >= 255))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
|
||||
@@ -647,33 +628,33 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
/* Discover IP from input device, then bind to it */
|
||||
if2ip_result = Curl_if2ip(af,
|
||||
#ifdef USE_IPV6
|
||||
scope, conn->scope_id,
|
||||
scope, conn->scope_id,
|
||||
#endif
|
||||
iface, myhost, sizeof(myhost));
|
||||
iface, myhost, sizeof(myhost));
|
||||
}
|
||||
switch(if2ip_result) {
|
||||
case IF2IP_NOT_FOUND:
|
||||
if(iface_input && !host_input) {
|
||||
/* Do not fall back to treating it as a hostname */
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "Couldn't bind to interface '%s' with errno %d: %s",
|
||||
iface, error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
break;
|
||||
case IF2IP_AF_NOT_SUPPORTED:
|
||||
/* Signal the caller to try another address family if available */
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
case IF2IP_FOUND:
|
||||
/*
|
||||
* We now have the numerical IP address in the 'myhost' buffer
|
||||
*/
|
||||
host = myhost;
|
||||
infof(data, "Local Interface %s is ip %s using address family %i",
|
||||
iface, host, af);
|
||||
done = 1;
|
||||
break;
|
||||
case IF2IP_NOT_FOUND:
|
||||
if(iface_input && !host_input) {
|
||||
/* Do not fall back to treating it as a hostname */
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "Could not bind to interface '%s' with errno %d: %s",
|
||||
iface, error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
break;
|
||||
case IF2IP_AF_NOT_SUPPORTED:
|
||||
/* Signal the caller to try another address family if available */
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
case IF2IP_FOUND:
|
||||
/*
|
||||
* We now have the numerical IP address in the 'myhost' buffer
|
||||
*/
|
||||
host = myhost;
|
||||
infof(data, "Local Interface %s is ip %s using address family %i",
|
||||
iface, host, af);
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
if(!iface_input || host_input) {
|
||||
/*
|
||||
@@ -735,7 +716,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
present, is known to be numeric */
|
||||
curl_off_t scope_id;
|
||||
if(curlx_str_number((const char **)CURL_UNCONST(&scope_ptr),
|
||||
&scope_id, UINT_MAX))
|
||||
&scope_id, UINT_MAX))
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
si6->sin6_scope_id = (unsigned int)scope_id;
|
||||
}
|
||||
@@ -761,7 +742,7 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.errorbuf = FALSE;
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "Couldn't bind to '%s' with errno %d: %s", host,
|
||||
failf(data, "Could not bind to '%s' with errno %d: %s", host,
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
@@ -846,24 +827,11 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
||||
*
|
||||
* Someone got to verify this on Win-NT 4.0, 2000."
|
||||
*/
|
||||
|
||||
#ifdef UNDER_CE
|
||||
Sleep(0);
|
||||
#else
|
||||
SleepEx(0, FALSE);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
|
||||
err = SOCKERRNO;
|
||||
#ifdef UNDER_CE
|
||||
/* Old Windows CE versions do not support SO_ERROR */
|
||||
if(WSAENOPROTOOPT == err) {
|
||||
SET_SOCKERRNO(0);
|
||||
err = 0;
|
||||
}
|
||||
#endif
|
||||
#if defined(EBADIOCTL) && defined(__minix)
|
||||
/* Minix 3.1.x does not support getsockopt on UDP sockets */
|
||||
if(EBADIOCTL == err) {
|
||||
@@ -925,7 +893,7 @@ static CURLcode socket_connect_result(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
struct cf_socket_ctx {
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
struct Curl_sockaddr_ex addr; /* address to connect to */
|
||||
curl_socket_t sock; /* current attempt socket */
|
||||
struct ip_quadruple ip; /* The IP quadruple 2x(addr+port) */
|
||||
@@ -941,7 +909,7 @@ struct cf_socket_ctx {
|
||||
int wblock_percent; /* percent of writes doing EAGAIN */
|
||||
int wpartial_percent; /* percent of bytes written in send */
|
||||
int rblock_percent; /* percent of reads doing EAGAIN */
|
||||
size_t recv_max; /* max enforced read size */
|
||||
size_t recv_max; /* max enforced read size */
|
||||
#endif
|
||||
BIT(got_first_byte); /* if first byte was received */
|
||||
BIT(listening); /* socket is listening */
|
||||
@@ -952,7 +920,7 @@ struct cf_socket_ctx {
|
||||
|
||||
static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
@@ -1042,7 +1010,7 @@ static void cf_socket_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
|
||||
cf_socket_close(cf, data);
|
||||
CURL_TRC_CF(data, cf, "destroy");
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
cf->ctx = NULL;
|
||||
}
|
||||
|
||||
@@ -1051,7 +1019,7 @@ static void set_local_ip(struct Curl_cfilter *cf,
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
ctx->ip.local_ip[0] = 0;
|
||||
ctx->ip.local_port = -1;
|
||||
ctx->ip.local_port = 0;
|
||||
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
if((ctx->sock != CURL_SOCKET_BAD) &&
|
||||
@@ -1063,12 +1031,12 @@ static void set_local_ip(struct Curl_cfilter *cf,
|
||||
curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
|
||||
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
|
||||
if(getsockname(ctx->sock, (struct sockaddr *)&ssloc, &slen)) {
|
||||
int error = SOCKERRNO;
|
||||
infof(data, "getsockname() failed with errno %d: %s",
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
}
|
||||
else if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
|
||||
else if(!Curl_addr2string((struct sockaddr *)&ssloc, slen,
|
||||
ctx->ip.local_ip, &ctx->ip.local_port)) {
|
||||
infof(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, curlx_strerror(errno, buffer, sizeof(buffer)));
|
||||
@@ -1085,6 +1053,7 @@ 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 */
|
||||
ctx->ip.transport = ctx->transport;
|
||||
if(!Curl_addr2string(&ctx->addr.curl_sa_addr,
|
||||
(curl_socklen_t)ctx->addr.addrlen,
|
||||
ctx->ip.remote_ip, &ctx->ip.remote_port)) {
|
||||
@@ -1110,7 +1079,7 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
||||
|
||||
(void)data;
|
||||
DEBUGASSERT(ctx->sock == CURL_SOCKET_BAD);
|
||||
ctx->started_at = curlx_now();
|
||||
ctx->started_at = *Curl_pgrs_now(data);
|
||||
#ifdef SOCK_NONBLOCK
|
||||
/* Do not tuck SOCK_NONBLOCK into socktype when opensocket callback is set
|
||||
* because we would not know how socketype is about to be used in the
|
||||
@@ -1134,7 +1103,18 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
||||
|
||||
#ifdef USE_IPV6
|
||||
if(ctx->addr.family == AF_INET6) {
|
||||
set_ipv6_v6only(ctx->sock, 0);
|
||||
#ifdef USE_WINSOCK
|
||||
/* Turn on support for IPv4-mapped IPv6 addresses.
|
||||
* Linux kernel, NetBSD, FreeBSD, Darwin, lwIP: default is off;
|
||||
* Windows Vista and later: default is on;
|
||||
* DragonFly BSD: acts like off, and dummy setting;
|
||||
* OpenBSD and earlier Windows: unsupported.
|
||||
* Linux: controlled by /proc/sys/net/ipv6/bindv6only.
|
||||
*/
|
||||
int on = 0;
|
||||
(void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
(void *)&on, sizeof(on));
|
||||
#endif
|
||||
infof(data, " Trying [%s]:%d...", ctx->ip.remote_ip, ctx->ip.remote_port);
|
||||
}
|
||||
else
|
||||
@@ -1142,22 +1122,22 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
||||
infof(data, " Trying %s:%d...", ctx->ip.remote_ip, ctx->ip.remote_port);
|
||||
|
||||
#ifdef USE_IPV6
|
||||
is_tcp = (ctx->addr.family == AF_INET
|
||||
|| ctx->addr.family == AF_INET6) &&
|
||||
is_tcp = (ctx->addr.family == AF_INET ||
|
||||
ctx->addr.family == AF_INET6) &&
|
||||
ctx->addr.socktype == SOCK_STREAM;
|
||||
#else
|
||||
is_tcp = (ctx->addr.family == AF_INET) &&
|
||||
ctx->addr.socktype == SOCK_STREAM;
|
||||
#endif
|
||||
if(is_tcp && data->set.tcp_nodelay)
|
||||
tcpnodelay(data, ctx->sock);
|
||||
tcpnodelay(cf, data, ctx->sock);
|
||||
|
||||
nosigpipe(data, ctx->sock);
|
||||
nosigpipe(cf, data, ctx->sock);
|
||||
|
||||
Curl_sndbuf_init(ctx->sock);
|
||||
|
||||
if(is_tcp && data->set.tcp_keepalive)
|
||||
tcpkeepalive(data, ctx->sock);
|
||||
tcpkeepalive(cf, data, ctx->sock);
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
/* activate callback for setting socket options */
|
||||
@@ -1226,7 +1206,7 @@ out:
|
||||
}
|
||||
else if(isconnected) {
|
||||
set_local_ip(cf, data);
|
||||
ctx->connected_at = curlx_now();
|
||||
ctx->connected_at = *Curl_pgrs_now(data);
|
||||
cf->connected = TRUE;
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "cf_socket_open() -> %d, fd=%" FMT_SOCKET_T,
|
||||
@@ -1271,8 +1251,8 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
|
||||
if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
|
||||
(void *)&optval, sizeof(optval)) < 0)
|
||||
infof(data, "Failed to enable TCP Fast Open on fd %" FMT_SOCKET_T,
|
||||
ctx->sock);
|
||||
CURL_TRC_CF(data, cf, "Failed to enable TCP Fast Open on fd %"
|
||||
FMT_SOCKET_T, ctx->sock);
|
||||
|
||||
rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
|
||||
#elif defined(MSG_FASTOPEN) /* old Linux */
|
||||
@@ -1339,14 +1319,13 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
|
||||
rc = SOCKET_WRITABLE(ctx->sock, 0);
|
||||
|
||||
if(rc == 0) { /* no connection yet */
|
||||
CURL_TRC_CF(data, cf, "not connected yet on fd=%" FMT_SOCKET_T,
|
||||
ctx->sock);
|
||||
CURL_TRC_CF(data, cf, "not connected yet on fd=%" FMT_SOCKET_T, ctx->sock);
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if(rc == CURL_CSELECT_OUT || cf->conn->bits.tcp_fastopen) {
|
||||
if(verifyconnect(ctx->sock, &ctx->error)) {
|
||||
/* we are connected with TCP, awesome! */
|
||||
ctx->connected_at = curlx_now();
|
||||
ctx->connected_at = *Curl_pgrs_now(data);
|
||||
set_local_ip(cf, data);
|
||||
*done = TRUE;
|
||||
cf->connected = TRUE;
|
||||
@@ -1422,33 +1401,34 @@ static CURLcode cf_socket_adjust_pollset(struct Curl_cfilter *cf,
|
||||
#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
|
||||
#endif
|
||||
|
||||
static void win_update_sndbuf_size(struct cf_socket_ctx *ctx)
|
||||
static void win_update_sndbuf_size(struct Curl_easy *data,
|
||||
struct cf_socket_ctx *ctx)
|
||||
{
|
||||
ULONG ideal;
|
||||
DWORD ideallen;
|
||||
struct curltime n = curlx_now();
|
||||
|
||||
if(curlx_timediff(n, ctx->last_sndbuf_query_at) > 1000) {
|
||||
if(curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&ctx->last_sndbuf_query_at) > 1000) {
|
||||
if(!WSAIoctl(ctx->sock, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
|
||||
&ideal, sizeof(ideal), &ideallen, 0, 0) &&
|
||||
&ideal, sizeof(ideal), &ideallen, 0, 0) &&
|
||||
ideal != ctx->sndbuf_size &&
|
||||
!setsockopt(ctx->sock, SOL_SOCKET, SO_SNDBUF,
|
||||
(const char *)&ideal, sizeof(ideal))) {
|
||||
ctx->sndbuf_size = ideal;
|
||||
}
|
||||
ctx->last_sndbuf_query_at = n;
|
||||
ctx->last_sndbuf_query_at = *Curl_pgrs_now(data);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_WINSOCK */
|
||||
|
||||
static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
curl_socket_t fdsave;
|
||||
ssize_t nwritten;
|
||||
ssize_t rv;
|
||||
size_t orig_len = len;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@@ -1462,7 +1442,7 @@ static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
if(ctx->wblock_percent > 0) {
|
||||
unsigned char c = 0;
|
||||
Curl_rand_bytes(data, FALSE, &c, 1);
|
||||
if(c >= ((100-ctx->wblock_percent)*256/100)) {
|
||||
if(c >= ((100 - ctx->wblock_percent) * 256 / 100)) {
|
||||
CURL_TRC_CF(data, cf, "send(len=%zu) SIMULATE EWOULDBLOCK", orig_len);
|
||||
cf->conn->sock[cf->sockindex] = fdsave;
|
||||
return CURLE_AGAIN;
|
||||
@@ -1479,15 +1459,15 @@ static CURLcode 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,
|
||||
&ctx->addr.curl_sa_addr, ctx->addr.addrlen);
|
||||
rv = sendto(ctx->sock, buf, len, MSG_FASTOPEN,
|
||||
&ctx->addr.curl_sa_addr, ctx->addr.addrlen);
|
||||
cf->conn->bits.tcp_fastopen = FALSE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
nwritten = swrite(ctx->sock, buf, len);
|
||||
rv = swrite(ctx->sock, buf, len);
|
||||
|
||||
if(nwritten < 0) {
|
||||
if(!curlx_sztouz(rv, pnwritten)) {
|
||||
int sockerr = SOCKERRNO;
|
||||
|
||||
if(
|
||||
@@ -1514,12 +1494,10 @@ static CURLcode cf_socket_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
result = CURLE_SEND_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
*pnwritten = (size_t)nwritten;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
if(!result)
|
||||
win_update_sndbuf_size(ctx);
|
||||
win_update_sndbuf_size(data, ctx);
|
||||
#endif
|
||||
|
||||
CURL_TRC_CF(data, cf, "send(len=%zu) -> %d, %zu",
|
||||
@@ -1533,7 +1511,7 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
ssize_t nread;
|
||||
ssize_t rv;
|
||||
|
||||
*pnread = 0;
|
||||
#ifdef DEBUGBUILD
|
||||
@@ -1541,7 +1519,7 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
if(cf->cft != &Curl_cft_udp && ctx->rblock_percent > 0) {
|
||||
unsigned char c = 0;
|
||||
Curl_rand(data, &c, 1);
|
||||
if(c >= ((100-ctx->rblock_percent)*256/100)) {
|
||||
if(c >= ((100 - ctx->rblock_percent) * 256 / 100)) {
|
||||
CURL_TRC_CF(data, cf, "recv(len=%zu) SIMULATE EWOULDBLOCK", len);
|
||||
return CURLE_AGAIN;
|
||||
}
|
||||
@@ -1554,9 +1532,9 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
}
|
||||
#endif
|
||||
|
||||
nread = sread(ctx->sock, buf, len);
|
||||
rv = sread(ctx->sock, buf, len);
|
||||
|
||||
if(nread < 0) {
|
||||
if(!curlx_sztouz(rv, pnread)) {
|
||||
int sockerr = SOCKERRNO;
|
||||
|
||||
if(
|
||||
@@ -1582,12 +1560,10 @@ static CURLcode cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
*pnread = (size_t)nread;
|
||||
|
||||
CURL_TRC_CF(data, cf, "recv(len=%zu) -> %d, %zu", len, result, *pnread);
|
||||
if(!result && !ctx->got_first_byte) {
|
||||
ctx->first_byte_at = curlx_now();
|
||||
ctx->first_byte_at = *Curl_pgrs_now(data);
|
||||
ctx->got_first_byte = TRUE;
|
||||
}
|
||||
return result;
|
||||
@@ -1657,7 +1633,7 @@ static bool cf_socket_conn_is_alive(struct Curl_cfilter *cf,
|
||||
|
||||
/* Check with 0 timeout if there are any events pending on the socket */
|
||||
pfd[0].fd = ctx->sock;
|
||||
pfd[0].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
|
||||
pfd[0].events = POLLRDNORM | POLLIN | POLLRDBAND | POLLPRI;
|
||||
pfd[0].revents = 0;
|
||||
|
||||
r = Curl_poll(pfd, 1, 0);
|
||||
@@ -1669,7 +1645,7 @@ static bool cf_socket_conn_is_alive(struct Curl_cfilter *cf,
|
||||
CURL_TRC_CF(data, cf, "is_alive: poll timeout, assume alive");
|
||||
return TRUE;
|
||||
}
|
||||
else if(pfd[0].revents & (POLLERR|POLLHUP|POLLPRI|POLLNVAL)) {
|
||||
else if(pfd[0].revents & (POLLERR | POLLHUP | POLLPRI | POLLNVAL)) {
|
||||
CURL_TRC_CF(data, cf, "is_alive: err/hup/etc events, assume dead");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1701,7 +1677,8 @@ static CURLcode cf_socket_query(struct Curl_cfilter *cf,
|
||||
return CURLE_OK;
|
||||
case CF_QUERY_CONNECT_REPLY_MS:
|
||||
if(ctx->got_first_byte) {
|
||||
timediff_t ms = curlx_timediff(ctx->first_byte_at, ctx->started_at);
|
||||
timediff_t ms = curlx_ptimediff_ms(&ctx->first_byte_at,
|
||||
&ctx->started_at);
|
||||
*pres1 = (ms < INT_MAX) ? (int)ms : INT_MAX;
|
||||
}
|
||||
else
|
||||
@@ -1763,7 +1740,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = NULL;
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
@@ -1777,7 +1754,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
@@ -1799,14 +1776,49 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static void linux_quic_mtu(struct cf_socket_ctx *ctx)
|
||||
{
|
||||
int val;
|
||||
switch(ctx->addr.family) {
|
||||
#ifdef IP_MTU_DISCOVER
|
||||
case AF_INET:
|
||||
val = IP_PMTUDISC_DO;
|
||||
(void)setsockopt(ctx->sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
|
||||
sizeof(val));
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPV6_MTU_DISCOVER
|
||||
case AF_INET6:
|
||||
val = IPV6_PMTUDISC_DO;
|
||||
(void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
|
||||
sizeof(val));
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define linux_quic_mtu(x)
|
||||
#endif
|
||||
|
||||
#if defined(UDP_GRO) && \
|
||||
(defined(HAVE_SENDMMSG) || defined(HAVE_SENDMSG)) && \
|
||||
((defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || defined(USE_QUICHE))
|
||||
static void linux_quic_gro(struct cf_socket_ctx *ctx)
|
||||
{
|
||||
int one = 1;
|
||||
(void)setsockopt(ctx->sock, IPPROTO_UDP, UDP_GRO, &one,
|
||||
(socklen_t)sizeof(one));
|
||||
}
|
||||
#else
|
||||
#define linux_quic_gro(x)
|
||||
#endif
|
||||
|
||||
static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
int rc;
|
||||
int one = 1;
|
||||
|
||||
(void)one;
|
||||
|
||||
/* QUIC needs a connected socket, nonblocking */
|
||||
DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
|
||||
@@ -1831,33 +1843,8 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
|
||||
* non-blocking socket created by cf_socket_open() to it. Thus, we
|
||||
* do not need to call curlx_nonblock() in cf_udp_setup_quic() anymore.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
switch(ctx->addr.family) {
|
||||
#ifdef IP_MTU_DISCOVER
|
||||
case AF_INET: {
|
||||
int val = IP_PMTUDISC_DO;
|
||||
(void)setsockopt(ctx->sock, IPPROTO_IP, IP_MTU_DISCOVER, &val,
|
||||
sizeof(val));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef IPV6_MTU_DISCOVER
|
||||
case AF_INET6: {
|
||||
int val = IPV6_PMTUDISC_DO;
|
||||
(void)setsockopt(ctx->sock, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val,
|
||||
sizeof(val));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(UDP_GRO) && \
|
||||
(defined(HAVE_SENDMMSG) || defined(HAVE_SENDMSG)) && \
|
||||
((defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || defined(USE_QUICHE))
|
||||
(void)setsockopt(ctx->sock, IPPROTO_UDP, UDP_GRO, &one,
|
||||
(socklen_t)sizeof(one));
|
||||
#endif
|
||||
#endif
|
||||
linux_quic_mtu(ctx);
|
||||
linux_quic_gro(ctx);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1919,7 +1906,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = NULL;
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
@@ -1928,7 +1915,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
|
||||
(void)data;
|
||||
(void)conn;
|
||||
DEBUGASSERT(transport == TRNSPRT_UDP || transport == TRNSPRT_QUIC);
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
@@ -1973,7 +1960,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
uint8_t transport)
|
||||
{
|
||||
struct cf_socket_ctx *ctx = NULL;
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
@@ -1982,7 +1969,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
|
||||
(void)data;
|
||||
(void)conn;
|
||||
DEBUGASSERT(transport == TRNSPRT_UNIX);
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
@@ -2009,24 +1996,22 @@ static timediff_t cf_tcp_accept_timeleft(struct Curl_cfilter *cf,
|
||||
{
|
||||
struct cf_socket_ctx *ctx = cf->ctx;
|
||||
timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
|
||||
timediff_t other;
|
||||
struct curltime now;
|
||||
timediff_t other_ms;
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
if(data->set.accepttimeout > 0)
|
||||
timeout_ms = data->set.accepttimeout;
|
||||
#endif
|
||||
|
||||
now = curlx_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
|
||||
other_ms = Curl_timeleft_ms(data, FALSE);
|
||||
if(other_ms && (other_ms < timeout_ms))
|
||||
/* note that this also works fine for when other_ms happens to be negative
|
||||
due to it already having elapsed */
|
||||
timeout_ms = other;
|
||||
timeout_ms = other_ms;
|
||||
else {
|
||||
/* subtract elapsed time */
|
||||
timeout_ms -= curlx_timediff(now, ctx->started_at);
|
||||
timeout_ms -= curlx_ptimediff_ms(Curl_pgrs_now(data), &ctx->started_at);
|
||||
if(!timeout_ms)
|
||||
/* avoid returning 0 as that means no timeout! */
|
||||
timeout_ms = -1;
|
||||
@@ -2047,13 +2032,13 @@ static void cf_tcp_set_accepted_remote_ip(struct Curl_cfilter *cf,
|
||||
ctx->ip.remote_port = 0;
|
||||
plen = sizeof(ssrem);
|
||||
memset(&ssrem, 0, plen);
|
||||
if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
|
||||
if(getpeername(ctx->sock, (struct sockaddr *)&ssrem, &plen)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getpeername() failed with errno %d: %s",
|
||||
error, curlx_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
|
||||
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, curlx_strerror(errno, buffer, sizeof(buffer)));
|
||||
@@ -2077,7 +2062,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
#else
|
||||
struct sockaddr_in add;
|
||||
#endif
|
||||
curl_socklen_t size = (curl_socklen_t) sizeof(add);
|
||||
curl_socklen_t size = (curl_socklen_t)sizeof(add);
|
||||
curl_socket_t s_accepted = CURL_SOCKET_BAD;
|
||||
timediff_t timeout_ms;
|
||||
int socketstate = 0;
|
||||
@@ -2100,8 +2085,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
|
||||
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);
|
||||
socketstate = SOCKET_READABLE(ctx->sock, 0);
|
||||
CURL_TRC_CF(data, cf, "socket_check -> %x", socketstate);
|
||||
switch(socketstate) {
|
||||
case -1: /* error */
|
||||
@@ -2123,10 +2107,10 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
|
||||
size = sizeof(add);
|
||||
#ifdef HAVE_ACCEPT4
|
||||
s_accepted = CURL_ACCEPT4(ctx->sock, (struct sockaddr *) &add, &size,
|
||||
s_accepted = CURL_ACCEPT4(ctx->sock, (struct sockaddr *)&add, &size,
|
||||
SOCK_NONBLOCK | SOCK_CLOEXEC);
|
||||
#else
|
||||
s_accepted = CURL_ACCEPT(ctx->sock, (struct sockaddr *) &add, &size);
|
||||
s_accepted = CURL_ACCEPT(ctx->sock, (struct sockaddr *)&add, &size);
|
||||
#endif
|
||||
|
||||
if(CURL_SOCKET_BAD == s_accepted) {
|
||||
@@ -2134,15 +2118,22 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
#if !defined(HAVE_ACCEPT4) && defined(HAVE_FCNTL)
|
||||
if((fcntl(s_accepted, F_SETFD, FD_CLOEXEC) < 0) ||
|
||||
(curlx_nonblock(s_accepted, TRUE) < 0)) {
|
||||
failf(data, "fcntl set CLOEXEC/NONBLOCK: %s",
|
||||
#ifndef HAVE_ACCEPT4
|
||||
#ifdef HAVE_FCNTL
|
||||
if(fcntl(s_accepted, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
failf(data, "fcntl set CLOEXEC: %s",
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
Curl_socket_close(data, cf->conn, s_accepted);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_FCNTL */
|
||||
if(curlx_nonblock(s_accepted, TRUE) < 0) {
|
||||
failf(data, "set socket NONBLOCK: %s",
|
||||
curlx_strerror(SOCKERRNO, errbuf, sizeof(errbuf)));
|
||||
Curl_socket_close(data, cf->conn, s_accepted);
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
}
|
||||
#endif /* !HAVE_ACCEPT4 */
|
||||
infof(data, "Connection accepted from server");
|
||||
|
||||
/* Replace any filter on SECONDARY with one listening on this socket */
|
||||
@@ -2155,7 +2146,7 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
||||
cf_tcp_set_accepted_remote_ip(cf, data);
|
||||
set_local_ip(cf, data);
|
||||
ctx->active = TRUE;
|
||||
ctx->connected_at = curlx_now();
|
||||
ctx->connected_at = *Curl_pgrs_now(data);
|
||||
cf->connected = TRUE;
|
||||
CURL_TRC_CF(data, cf, "accepted_set(sock=%" FMT_SOCKET_T
|
||||
", remote=%s port=%d)",
|
||||
@@ -2207,7 +2198,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
|
||||
Curl_conn_cf_discard_all(data, conn, sockindex);
|
||||
DEBUGASSERT(conn->sock[sockindex] == CURL_SOCKET_BAD);
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
@@ -2221,7 +2212,7 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
|
||||
goto out;
|
||||
Curl_conn_cf_add(data, conn, sockindex, cf);
|
||||
|
||||
ctx->started_at = curlx_now();
|
||||
ctx->started_at = *Curl_pgrs_now(data);
|
||||
conn->sock[sockindex] = ctx->sock;
|
||||
set_local_ip(cf, data);
|
||||
CURL_TRC_CF(data, cf, "set filter for listen socket fd=%" FMT_SOCKET_T
|
||||
|
||||
+7
-8
@@ -25,8 +25,7 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curlx/nonblock.h" /* for curlx_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
|
||||
struct Curl_addrinfo;
|
||||
struct Curl_cfilter;
|
||||
@@ -52,12 +51,12 @@ struct Curl_sockaddr_ex {
|
||||
struct Curl_sockaddr_storage buf;
|
||||
} addr;
|
||||
};
|
||||
#define curl_sa_addr addr.sa
|
||||
#define curl_sa_addr addr.sa
|
||||
#define curl_sa_addrbuf addr.buf
|
||||
|
||||
/*
|
||||
* Parse interface option, and return the interface name and the host part.
|
||||
*/
|
||||
*/
|
||||
CURLcode Curl_parse_interface(const char *input,
|
||||
char **dev, char **iface, char **host);
|
||||
|
||||
@@ -71,7 +70,7 @@ CURLcode Curl_parse_interface(const char *input,
|
||||
CURLcode Curl_socket_open(struct Curl_easy *data,
|
||||
const struct Curl_addrinfo *ai,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
curl_socket_t *sockfd);
|
||||
|
||||
int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
|
||||
@@ -103,7 +102,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that opens a UDP socket to the given address
|
||||
@@ -116,7 +115,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that opens a UNIX socket to the given address
|
||||
@@ -129,7 +128,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
uint8_t transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that keeps a listening socket.
|
||||
|
||||
+31
-55
@@ -21,7 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
@@ -29,18 +28,11 @@
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
#include "url.h"
|
||||
#include "sendf.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "multiif.h"
|
||||
#include "curl_trc.h"
|
||||
#include "progress.h"
|
||||
#include "select.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static void cf_cntrl_update_info(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
@@ -63,8 +55,8 @@ CURLcode Curl_cf_def_shutdown(struct Curl_cfilter *cf,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void conn_report_connect_stats(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
static void conn_report_connect_stats(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
@@ -85,7 +77,7 @@ bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
if(cf->next)
|
||||
@@ -143,7 +135,7 @@ void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
|
||||
*/
|
||||
cf->next = NULL;
|
||||
cf->cft->destroy(cf, data);
|
||||
free(cf);
|
||||
curlx_free(cf);
|
||||
cf = cfn;
|
||||
}
|
||||
}
|
||||
@@ -173,7 +165,6 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t timeout_ms;
|
||||
struct curltime now;
|
||||
|
||||
DEBUGASSERT(data->conn);
|
||||
|
||||
@@ -191,14 +182,13 @@ CURLcode Curl_conn_shutdown(struct Curl_easy *data, int sockindex, bool *done)
|
||||
}
|
||||
|
||||
*done = FALSE;
|
||||
now = curlx_now();
|
||||
if(!Curl_shutdown_started(data, sockindex)) {
|
||||
CURL_TRC_M(data, "shutdown start on%s connection",
|
||||
sockindex ? " secondary" : "");
|
||||
Curl_shutdown_start(data, sockindex, 0, &now);
|
||||
Curl_shutdown_start(data, sockindex, 0);
|
||||
}
|
||||
else {
|
||||
timeout_ms = Curl_shutdown_timeleft(data->conn, sockindex, &now);
|
||||
timeout_ms = Curl_shutdown_timeleft(data, data->conn, sockindex);
|
||||
if(timeout_ms < 0) {
|
||||
/* info message, since this might be regarded as acceptable */
|
||||
infof(data, "shutdown timeout");
|
||||
@@ -246,7 +236,7 @@ CURLcode Curl_cf_recv(struct Curl_easy *data, int num, char *buf,
|
||||
}
|
||||
|
||||
CURLcode Curl_cf_send(struct Curl_easy *data, int num,
|
||||
const void *mem, size_t len, bool eos,
|
||||
const uint8_t *mem, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
@@ -296,12 +286,11 @@ CURLcode Curl_cf_recv_bufq(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
static CURLcode cf_bufq_writer(void *writer_ctx,
|
||||
const unsigned char *buf, size_t buflen,
|
||||
const uint8_t *buf, size_t buflen,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
struct cf_io_ctx *io = writer_ctx;
|
||||
return Curl_conn_cf_send(io->cf, io->data, (const char *)buf,
|
||||
buflen, FALSE, pnwritten);
|
||||
return Curl_conn_cf_send(io->cf, io->data, buf, buflen, FALSE, pnwritten);
|
||||
}
|
||||
|
||||
CURLcode Curl_cf_send_bufq(struct Curl_cfilter *cf,
|
||||
@@ -333,7 +322,7 @@ CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
DEBUGASSERT(cft);
|
||||
cf = calloc(1, sizeof(*cf));
|
||||
cf = curlx_calloc(1, sizeof(*cf));
|
||||
if(!cf)
|
||||
goto out;
|
||||
|
||||
@@ -422,7 +411,7 @@ void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten)
|
||||
{
|
||||
if(cf)
|
||||
@@ -508,17 +497,16 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
||||
* persist information at the connection. E.g. cf-socket sets the
|
||||
* socket and ip related information. */
|
||||
cf_cntrl_update_info(data, data->conn);
|
||||
conn_report_connect_stats(data, data->conn);
|
||||
data->conn->keepalive = curlx_now();
|
||||
conn_report_connect_stats(cf, data);
|
||||
data->conn->keepalive = *Curl_pgrs_now(data);
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
result = cf_verboseconnect(data, cf);
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
else if(result) {
|
||||
CURL_TRC_CF(data, cf, "Curl_conn_connect(), filter returned %d",
|
||||
result);
|
||||
conn_report_connect_stats(data, data->conn);
|
||||
CURL_TRC_CF(data, cf, "Curl_conn_connect(), filter returned %d", result);
|
||||
conn_report_connect_stats(cf, data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -526,7 +514,7 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
|
||||
goto out;
|
||||
else {
|
||||
/* check allowed time left */
|
||||
const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
const timediff_t timeout_ms = Curl_timeleft_ms(data, TRUE);
|
||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||
int rc;
|
||||
|
||||
@@ -583,7 +571,11 @@ bool Curl_conn_is_connected(struct connectdata *conn, int sockindex)
|
||||
if(!CONN_SOCK_IDX_VALID(sockindex))
|
||||
return FALSE;
|
||||
cf = conn->cfilter[sockindex];
|
||||
return cf && cf->connected;
|
||||
if(cf)
|
||||
return cf->connected;
|
||||
else if(conn->handler->flags & PROTOPT_NONETWORK)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
|
||||
@@ -658,7 +650,7 @@ bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
|
||||
for(; cf; cf = cf->next) {
|
||||
if(cf->cft->flags & CF_TYPE_MULTIPLEX)
|
||||
return TRUE;
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_SSL))
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -696,7 +688,7 @@ unsigned char Curl_conn_http_version(struct Curl_easy *data,
|
||||
v = (unsigned char)value;
|
||||
break;
|
||||
}
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_SSL))
|
||||
break;
|
||||
}
|
||||
return (unsigned char)(result ? 0 : v);
|
||||
@@ -808,9 +800,9 @@ void Curl_conn_get_current_host(struct Curl_easy *data, int sockindex,
|
||||
cf = CONN_SOCK_IDX_VALID(sockindex) ? data->conn->cfilter[sockindex] : NULL;
|
||||
/* Find the "lowest" tunneling proxy filter that has not connected yet. */
|
||||
while(cf && !cf->connected) {
|
||||
if((cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_PROXY)) ==
|
||||
(CF_TYPE_IP_CONNECT|CF_TYPE_PROXY))
|
||||
cf_proxy = cf;
|
||||
if((cf->cft->flags & (CF_TYPE_IP_CONNECT | CF_TYPE_PROXY)) ==
|
||||
(CF_TYPE_IP_CONNECT | CF_TYPE_PROXY))
|
||||
cf_proxy = cf;
|
||||
cf = cf->next;
|
||||
}
|
||||
/* cf_proxy (!= NULL) is not connected yet. It is talking
|
||||
@@ -931,19 +923,6 @@ Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex)
|
||||
return cf ? cf_get_remote_addr(cf, data) : NULL;
|
||||
}
|
||||
|
||||
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn && CONN_SOCK_IDX_VALID(sockindex)) {
|
||||
struct Curl_cfilter *cf = conn->cfilter[sockindex];
|
||||
if(cf)
|
||||
(void)Curl_conn_cf_cntrl(cf, data, TRUE,
|
||||
CF_CTRL_FORGET_SOCKET, 0, NULL);
|
||||
fake_sclose(conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode cf_cntrl_all(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
bool ignore_result,
|
||||
@@ -963,8 +942,7 @@ static CURLcode cf_cntrl_all(struct connectdata *conn,
|
||||
|
||||
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
|
||||
{
|
||||
return cf_cntrl_all(data->conn, data, FALSE,
|
||||
CF_CTRL_DATA_SETUP, 0, NULL);
|
||||
return cf_cntrl_all(data->conn, data, FALSE, CF_CTRL_DATA_SETUP, 0, NULL);
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex)
|
||||
@@ -1008,10 +986,9 @@ static void cf_cntrl_update_info(struct Curl_easy *data,
|
||||
/**
|
||||
* Update connection statistics
|
||||
*/
|
||||
static void conn_report_connect_stats(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
static void conn_report_connect_stats(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
|
||||
if(cf) {
|
||||
struct curltime connected;
|
||||
struct curltime appconnected;
|
||||
@@ -1119,8 +1096,7 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
#ifdef DEBUGBUILD
|
||||
if(write_len) {
|
||||
/* Allow debug builds to override this logic to force short sends
|
||||
*/
|
||||
/* Allow debug builds to override this logic to force short sends */
|
||||
const char *p = getenv("CURL_SMALLSENDS");
|
||||
if(p) {
|
||||
curl_off_t altsize;
|
||||
|
||||
+30
-35
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curlx/timediff.h"
|
||||
|
||||
struct bufq;
|
||||
@@ -89,7 +88,7 @@ typedef bool Curl_cft_data_pending(struct Curl_cfilter *cf,
|
||||
|
||||
typedef CURLcode Curl_cft_send(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data, /* transfer */
|
||||
const void *buf, /* data to write */
|
||||
const uint8_t *buf, /* data to write */
|
||||
size_t len, /* amount to write */
|
||||
bool eos, /* last chunk */
|
||||
size_t *pnwritten); /* how much sent */
|
||||
@@ -116,16 +115,16 @@ typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
|
||||
* "ignored" meaning return values are ignored and the event is distributed
|
||||
* to all filters in the chain. Overall result is always CURLE_OK.
|
||||
*/
|
||||
/* data event arg1 arg2 return */
|
||||
#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
|
||||
/* unused now 5 */
|
||||
#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
|
||||
#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
|
||||
#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
|
||||
/* data event arg1 arg2 return */
|
||||
#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
|
||||
/* unused now 5 */
|
||||
#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
|
||||
#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
|
||||
#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
|
||||
/* update conn info at connection and data */
|
||||
#define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */
|
||||
#define CF_CTRL_FORGET_SOCKET (256+1) /* 0 NULL ignored */
|
||||
#define CF_CTRL_FLUSH (256+2) /* 0 NULL first fail */
|
||||
#define CF_CTRL_CONN_INFO_UPDATE (256 + 0) /* 0 NULL ignored */
|
||||
#define CF_CTRL_FORGET_SOCKET (256 + 1) /* 0 NULL ignored */
|
||||
#define CF_CTRL_FLUSH (256 + 2) /* 0 NULL first fail */
|
||||
|
||||
/**
|
||||
* Handle event/control for the filter.
|
||||
@@ -135,7 +134,6 @@ typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2);
|
||||
|
||||
|
||||
/**
|
||||
* Queries to ask via a `Curl_cft_query *query` method on a cfilter chain.
|
||||
* - MAX_CONCURRENT: the maximum number of parallel transfers the filter
|
||||
@@ -210,21 +208,21 @@ typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
|
||||
|
||||
/* A connection filter type, e.g. specific implementation. */
|
||||
struct Curl_cftype {
|
||||
const char *name; /* name of the filter type */
|
||||
int flags; /* flags of filter type */
|
||||
int log_level; /* log level for such filters */
|
||||
Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
|
||||
Curl_cft_connect *do_connect; /* establish connection */
|
||||
Curl_cft_close *do_close; /* close conn */
|
||||
Curl_cft_shutdown *do_shutdown; /* shutdown conn */
|
||||
const char *name; /* name of the filter type */
|
||||
int flags; /* flags of filter type */
|
||||
int log_level; /* log level for such filters */
|
||||
Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
|
||||
Curl_cft_connect *do_connect; /* establish connection */
|
||||
Curl_cft_close *do_close; /* close conn */
|
||||
Curl_cft_shutdown *do_shutdown; /* shutdown conn */
|
||||
Curl_cft_adjust_pollset *adjust_pollset; /* adjust transfer poll set */
|
||||
Curl_cft_data_pending *has_data_pending;/* conn has data pending */
|
||||
Curl_cft_send *do_send; /* send data */
|
||||
Curl_cft_recv *do_recv; /* receive data */
|
||||
Curl_cft_cntrl *cntrl; /* events/control */
|
||||
Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */
|
||||
Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */
|
||||
Curl_cft_query *query; /* query filter chain */
|
||||
Curl_cft_data_pending *has_data_pending; /* conn has data pending */
|
||||
Curl_cft_send *do_send; /* send data */
|
||||
Curl_cft_recv *do_recv; /* receive data */
|
||||
Curl_cft_cntrl *cntrl; /* events/control */
|
||||
Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */
|
||||
Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */
|
||||
Curl_cft_query *query; /* query filter chain */
|
||||
};
|
||||
|
||||
/* A connection filter instance, e.g. registered at a connection */
|
||||
@@ -250,7 +248,7 @@ CURLcode Curl_cf_def_adjust_pollset(struct Curl_cfilter *cf,
|
||||
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
|
||||
const struct Curl_easy *data);
|
||||
CURLcode Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten);
|
||||
CURLcode Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
char *buf, size_t len, size_t *pnread);
|
||||
@@ -317,13 +315,12 @@ void Curl_conn_cf_discard_all(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
|
||||
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
bool *done);
|
||||
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
|
||||
CURLcode Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten);
|
||||
CURLcode Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
char *buf, size_t len, size_t *pnread);
|
||||
@@ -426,7 +423,7 @@ const char *Curl_conn_get_alpn_negotiated(struct Curl_easy *data,
|
||||
|
||||
/**
|
||||
* Close the filter chain at `sockindex` for connection `data->conn`.
|
||||
* Filters remain in place and may be connected again afterwards.
|
||||
* Filters remain in place and may be connected again afterwards.
|
||||
*/
|
||||
void Curl_conn_close(struct Curl_easy *data, int sockindex);
|
||||
|
||||
@@ -508,7 +505,7 @@ CURLcode Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
* in `*pnwritten` or on error.
|
||||
*/
|
||||
CURLcode Curl_cf_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, bool eos,
|
||||
const uint8_t *buf, size_t len, bool eos,
|
||||
size_t *pnwritten);
|
||||
|
||||
/**
|
||||
@@ -622,7 +619,6 @@ CURLcode Curl_conn_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t blen, bool eos,
|
||||
size_t *pnwritten);
|
||||
|
||||
|
||||
/**
|
||||
* Types and macros used to keep the current easy handle in filter calls,
|
||||
* allowing for nested invocations. See #10336.
|
||||
@@ -654,7 +650,7 @@ struct cf_call_data {
|
||||
* a member in the cfilter's `ctx`.
|
||||
*
|
||||
* #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
|
||||
@@ -688,7 +684,6 @@ struct cf_call_data {
|
||||
|
||||
#endif /* !DEBUGBUILD */
|
||||
|
||||
#define CF_DATA_CURRENT(cf) \
|
||||
((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
|
||||
#define CF_DATA_CURRENT(cf) ((cf) ? (CF_CTX_CALL_DATA(cf).data) : NULL)
|
||||
|
||||
#endif /* HEADER_CURL_CFILTERS_H */
|
||||
+52
-62
@@ -22,39 +22,28 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "multi_ev.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "cshutdn.h"
|
||||
#include "conncache.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "share.h"
|
||||
#include "curl_share.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "uint-table.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
#define CPOOL_IS_LOCKED(c) ((c) && (c)->locked)
|
||||
|
||||
#define CPOOL_LOCK(c,d) \
|
||||
#define CPOOL_LOCK(c, d) \
|
||||
do { \
|
||||
if((c)) { \
|
||||
if(c) { \
|
||||
if(CURL_SHARE_KEEP_CONNECT((c)->share)) \
|
||||
Curl_share_lock((d), CURL_LOCK_DATA_CONNECT, \
|
||||
CURL_LOCK_ACCESS_SINGLE); \
|
||||
@@ -63,9 +52,9 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define CPOOL_UNLOCK(c,d) \
|
||||
#define CPOOL_UNLOCK(c,d) \
|
||||
do { \
|
||||
if((c)) { \
|
||||
if(c) { \
|
||||
DEBUGASSERT((c)->locked); \
|
||||
(c)->locked = FALSE; \
|
||||
if(CURL_SHARE_KEEP_CONNECT((c)->share)) \
|
||||
@@ -73,7 +62,6 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* A list of connections to the same destination. */
|
||||
struct cpool_bundle {
|
||||
struct Curl_llist conns; /* connections in the bundle */
|
||||
@@ -81,7 +69,6 @@ struct cpool_bundle {
|
||||
char dest[1]; /* destination of bundle, allocated to keep dest_len bytes */
|
||||
};
|
||||
|
||||
|
||||
static void cpool_discard_conn(struct cpool *cpool,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
@@ -92,7 +79,7 @@ static struct cpool_bundle *cpool_bundle_create(const char *dest)
|
||||
struct cpool_bundle *bundle;
|
||||
size_t dest_len = strlen(dest) + 1;
|
||||
|
||||
bundle = calloc(1, sizeof(*bundle) + dest_len - 1);
|
||||
bundle = curlx_calloc(1, sizeof(*bundle) + dest_len - 1);
|
||||
if(!bundle)
|
||||
return NULL;
|
||||
Curl_llist_init(&bundle->conns, NULL);
|
||||
@@ -104,7 +91,7 @@ static struct cpool_bundle *cpool_bundle_create(const char *dest)
|
||||
static void cpool_bundle_destroy(struct cpool_bundle *bundle)
|
||||
{
|
||||
DEBUGASSERT(!Curl_llist_count(&bundle->conns));
|
||||
free(bundle);
|
||||
curlx_free(bundle);
|
||||
}
|
||||
|
||||
/* Add a connection to a bundle */
|
||||
@@ -165,7 +152,6 @@ static struct connectdata *cpool_get_first(struct cpool *cpool)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct cpool_bundle *cpool_find_bundle(struct cpool *cpool,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
@@ -173,7 +159,6 @@ static struct cpool_bundle *cpool_find_bundle(struct cpool *cpool,
|
||||
conn->destination, strlen(conn->destination) + 1);
|
||||
}
|
||||
|
||||
|
||||
static void cpool_remove_bundle(struct cpool *cpool,
|
||||
struct cpool_bundle *bundle)
|
||||
{
|
||||
@@ -182,7 +167,6 @@ static void cpool_remove_bundle(struct cpool *cpool,
|
||||
Curl_hash_delete(&cpool->dest2bundle, bundle->dest, bundle->dest_len);
|
||||
}
|
||||
|
||||
|
||||
static void cpool_remove_conn(struct cpool *cpool,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
@@ -220,7 +204,6 @@ void Curl_cpool_destroy(struct cpool *cpool)
|
||||
while(conn) {
|
||||
cpool_remove_conn(cpool, conn);
|
||||
sigpipe_apply(cpool->idata, &pipe_st);
|
||||
connclose(conn, "kill all");
|
||||
cpool_discard_conn(cpool, cpool->idata, conn, FALSE);
|
||||
conn = cpool_get_first(cpool);
|
||||
}
|
||||
@@ -265,8 +248,8 @@ void Curl_cpool_xfer_init(struct Curl_easy *data)
|
||||
}
|
||||
}
|
||||
|
||||
static struct cpool_bundle *
|
||||
cpool_add_bundle(struct cpool *cpool, struct connectdata *conn)
|
||||
static struct cpool_bundle *cpool_add_bundle(struct cpool *cpool,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct cpool_bundle *bundle;
|
||||
|
||||
@@ -283,23 +266,22 @@ cpool_add_bundle(struct cpool *cpool, struct connectdata *conn)
|
||||
}
|
||||
|
||||
static struct connectdata *
|
||||
cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle)
|
||||
cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle,
|
||||
const struct curltime *pnow)
|
||||
{
|
||||
struct Curl_llist_node *curr;
|
||||
timediff_t highscore = -1;
|
||||
timediff_t score;
|
||||
struct curltime now;
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct connectdata *conn;
|
||||
|
||||
now = curlx_now();
|
||||
curr = Curl_llist_head(&bundle->conns);
|
||||
while(curr) {
|
||||
conn = Curl_node_elem(curr);
|
||||
|
||||
if(!CONN_INUSE(conn)) {
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = curlx_timediff(now, conn->lastused);
|
||||
score = curlx_ptimediff_ms(pnow, &conn->lastused);
|
||||
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
@@ -311,18 +293,17 @@ cpool_bundle_get_oldest_idle(struct cpool_bundle *bundle)
|
||||
return oldest_idle;
|
||||
}
|
||||
|
||||
static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
||||
static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool,
|
||||
const struct curltime *pnow)
|
||||
{
|
||||
struct Curl_hash_iterator iter;
|
||||
struct Curl_llist_node *curr;
|
||||
struct Curl_hash_element *he;
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
struct cpool_bundle *bundle;
|
||||
struct curltime now;
|
||||
timediff_t highscore = -1;
|
||||
timediff_t score;
|
||||
|
||||
now = curlx_now();
|
||||
Curl_hash_start_iterate(&cpool->dest2bundle, &iter);
|
||||
|
||||
for(he = Curl_hash_next_element(&iter); he;
|
||||
@@ -336,7 +317,7 @@ static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
||||
if(CONN_INUSE(conn) || conn->bits.close || conn->connect_only)
|
||||
continue;
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = curlx_timediff(now, conn->lastused);
|
||||
score = curlx_ptimediff_ms(pnow, &conn->lastused);
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
oldest_idle = conn;
|
||||
@@ -346,7 +327,6 @@ static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool)
|
||||
return oldest_idle;
|
||||
}
|
||||
|
||||
|
||||
int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
@@ -375,7 +355,7 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
bundle = cpool_find_bundle(cpool, conn);
|
||||
live = bundle ? Curl_llist_count(&bundle->conns) : 0;
|
||||
shutdowns = Curl_cshutdn_dest_count(data, conn->destination);
|
||||
while((live + shutdowns) >= dest_limit) {
|
||||
while((live + shutdowns) >= dest_limit) {
|
||||
if(shutdowns) {
|
||||
/* close one connection in shutdown right away, if we can */
|
||||
if(!Curl_cshutdn_close_oldest(data, conn->destination))
|
||||
@@ -387,14 +367,15 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
/* The bundle is full. Extract the oldest connection that may
|
||||
* be removed now, if there is one. */
|
||||
oldest_idle = cpool_bundle_get_oldest_idle(bundle);
|
||||
oldest_idle = cpool_bundle_get_oldest_idle(bundle,
|
||||
Curl_pgrs_now(data));
|
||||
if(!oldest_idle)
|
||||
break;
|
||||
/* disconnect the old conn and continue */
|
||||
CURL_TRC_M(data, "Discarding connection #%"
|
||||
FMT_OFF_T " from %zu to reach destination "
|
||||
"limit of %zu", oldest_idle->connection_id,
|
||||
Curl_llist_count(&bundle->conns), dest_limit);
|
||||
CURL_TRC_M(data, "Discarding connection #%" FMT_OFF_T
|
||||
" from %zu to reach destination limit of %zu",
|
||||
oldest_idle->connection_id,
|
||||
Curl_llist_count(&bundle->conns), dest_limit);
|
||||
Curl_conn_terminate(cpool->idata, oldest_idle, FALSE);
|
||||
|
||||
/* in case the bundle was destroyed in disconnect, look it up again */
|
||||
@@ -418,7 +399,8 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
else {
|
||||
struct connectdata *oldest_idle = cpool_get_oldest_idle(cpool);
|
||||
struct connectdata *oldest_idle =
|
||||
cpool_get_oldest_idle(cpool, Curl_pgrs_now(data));
|
||||
if(!oldest_idle)
|
||||
break;
|
||||
/* disconnect the old conn and continue */
|
||||
@@ -536,6 +518,9 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
bool kept = TRUE;
|
||||
|
||||
if(!data)
|
||||
return kept;
|
||||
|
||||
if(!data->multi->maxconnects) {
|
||||
unsigned int running = Curl_multi_xfers_running(data->multi);
|
||||
maxconnects = (running <= UINT_MAX / 4) ? running * 4 : UINT_MAX;
|
||||
@@ -544,7 +529,7 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
||||
maxconnects = data->multi->maxconnects;
|
||||
}
|
||||
|
||||
conn->lastused = curlx_now(); /* it was used up until now */
|
||||
conn->lastused = *Curl_pgrs_now(data); /* it was used up until now */
|
||||
if(cpool && maxconnects) {
|
||||
/* may be called form a callback already under lock */
|
||||
bool do_lock = !CPOOL_IS_LOCKED(cpool);
|
||||
@@ -554,7 +539,7 @@ bool Curl_cpool_conn_now_idle(struct Curl_easy *data,
|
||||
infof(data, "Connection pool is full, closing the oldest of %zu/%u",
|
||||
cpool->num_conn, maxconnects);
|
||||
|
||||
oldest_idle = cpool_get_oldest_idle(cpool);
|
||||
oldest_idle = cpool_get_oldest_idle(cpool, Curl_pgrs_now(data));
|
||||
kept = (oldest_idle != conn);
|
||||
if(oldest_idle) {
|
||||
Curl_conn_terminate(data, oldest_idle, FALSE);
|
||||
@@ -626,7 +611,7 @@ static void cpool_discard_conn(struct cpool *cpool,
|
||||
if(CONN_INUSE(conn) && !aborted) {
|
||||
CURL_TRC_M(data, "[CPOOL] not discarding #%" FMT_OFF_T
|
||||
" still in use by %u transfers", conn->connection_id,
|
||||
CONN_ATTACHED(conn));
|
||||
conn->attached_xfers);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -670,7 +655,7 @@ void Curl_conn_terminate(struct Curl_easy *data,
|
||||
* are other users of it */
|
||||
if(CONN_INUSE(conn) && !aborted) {
|
||||
DEBUGASSERT(0); /* does this ever happen? */
|
||||
DEBUGF(infof(data, "Curl_disconnect when inuse: %u", CONN_ATTACHED(conn)));
|
||||
DEBUGF(infof(data, "conn terminate when inuse: %u", conn->attached_xfers));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -706,18 +691,24 @@ void Curl_conn_terminate(struct Curl_easy *data,
|
||||
CPOOL_UNLOCK(cpool, data);
|
||||
}
|
||||
|
||||
|
||||
struct cpool_reaper_ctx {
|
||||
struct curltime now;
|
||||
size_t checked;
|
||||
size_t reaped;
|
||||
};
|
||||
|
||||
static int cpool_reap_dead_cb(struct Curl_easy *data,
|
||||
struct connectdata *conn, void *param)
|
||||
{
|
||||
struct cpool_reaper_ctx *rctx = param;
|
||||
if((!CONN_INUSE(conn) && conn->bits.no_reuse) ||
|
||||
Curl_conn_seems_dead(conn, data, &rctx->now)) {
|
||||
struct cpool_reaper_ctx *reaper = param;
|
||||
bool terminate = !CONN_INUSE(conn) && conn->bits.no_reuse;
|
||||
|
||||
if(!terminate) {
|
||||
reaper->checked++;
|
||||
terminate = Curl_conn_seems_dead(conn, data);
|
||||
}
|
||||
if(terminate) {
|
||||
/* stop the iteration here, pass back the connection that was pruned */
|
||||
reaper->reaped++;
|
||||
Curl_conn_terminate(data, conn, FALSE);
|
||||
return 1;
|
||||
}
|
||||
@@ -734,20 +725,20 @@ static int cpool_reap_dead_cb(struct Curl_easy *data,
|
||||
void Curl_cpool_prune_dead(struct Curl_easy *data)
|
||||
{
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
struct cpool_reaper_ctx rctx;
|
||||
struct cpool_reaper_ctx reaper;
|
||||
timediff_t elapsed;
|
||||
|
||||
if(!cpool)
|
||||
return;
|
||||
|
||||
rctx.now = curlx_now();
|
||||
memset(&reaper, 0, sizeof(reaper));
|
||||
CPOOL_LOCK(cpool, data);
|
||||
elapsed = curlx_timediff(rctx.now, cpool->last_cleanup);
|
||||
elapsed = curlx_ptimediff_ms(Curl_pgrs_now(data), &cpool->last_cleanup);
|
||||
|
||||
if(elapsed >= 1000L) {
|
||||
while(cpool_foreach(data, cpool, &rctx, cpool_reap_dead_cb))
|
||||
while(cpool_foreach(data, cpool, &reaper, cpool_reap_dead_cb))
|
||||
;
|
||||
cpool->last_cleanup = rctx.now;
|
||||
cpool->last_cleanup = *Curl_pgrs_now(data);
|
||||
}
|
||||
CPOOL_UNLOCK(cpool, data);
|
||||
}
|
||||
@@ -756,21 +747,20 @@ static int conn_upkeep(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
void *param)
|
||||
{
|
||||
struct curltime *now = param;
|
||||
Curl_conn_upkeep(data, conn, now);
|
||||
(void)param;
|
||||
Curl_conn_upkeep(data, conn);
|
||||
return 0; /* continue iteration */
|
||||
}
|
||||
|
||||
CURLcode Curl_cpool_upkeep(void *data)
|
||||
CURLcode Curl_cpool_upkeep(struct Curl_easy *data)
|
||||
{
|
||||
struct cpool *cpool = cpool_get_instance(data);
|
||||
struct curltime now = curlx_now();
|
||||
|
||||
if(!cpool)
|
||||
return CURLE_OK;
|
||||
|
||||
CPOOL_LOCK(cpool, data);
|
||||
cpool_foreach(data, cpool, &now, conn_upkeep);
|
||||
cpool_foreach(data, cpool, NULL, conn_upkeep);
|
||||
CPOOL_UNLOCK(cpool, data);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
+2
-5
@@ -24,8 +24,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
struct connectdata;
|
||||
@@ -49,7 +47,7 @@ void Curl_conn_terminate(struct Curl_easy *data,
|
||||
bool aborted);
|
||||
|
||||
struct cpool {
|
||||
/* the pooled connections, bundled per destination */
|
||||
/* the pooled connections, bundled per destination */
|
||||
struct Curl_hash dest2bundle;
|
||||
size_t num_conn;
|
||||
curl_off_t next_connection_id;
|
||||
@@ -139,7 +137,7 @@ void Curl_cpool_prune_dead(struct Curl_easy *data);
|
||||
/**
|
||||
* Perform upkeep actions on connections in the transfer's pool.
|
||||
*/
|
||||
CURLcode Curl_cpool_upkeep(void *data);
|
||||
CURLcode Curl_cpool_upkeep(struct Curl_easy *data);
|
||||
|
||||
typedef void Curl_cpool_conn_do_cb(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
@@ -166,5 +164,4 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
|
||||
/* Close all unused connections, prevent reuse of existing ones. */
|
||||
void Curl_cpool_nw_changed(struct Curl_easy *data);
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_CONNCACHE_H */
|
||||
+89
-113
@@ -21,7 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
@@ -51,8 +50,7 @@
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "if2ip.h"
|
||||
#include "curl_trc.h"
|
||||
#include "strerror.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
@@ -60,63 +58,59 @@
|
||||
#include "cf-https-connect.h"
|
||||
#include "cf-ip-happy.h"
|
||||
#include "cf-socket.h"
|
||||
#include "select.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
#include "multiif.h"
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "curlx/inet_ntop.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/strparse.h"
|
||||
#include "vtls/vtls.h" /* for vtsl cfilters */
|
||||
#include "progress.h"
|
||||
#include "curlx/warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "share.h"
|
||||
#include "http_proxy.h"
|
||||
#include "socks.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_ALTSVC) || defined(USE_HTTPSRR)
|
||||
|
||||
enum alpnid Curl_alpn2alpnid(const char *name, size_t len)
|
||||
enum alpnid Curl_alpn2alpnid(const unsigned char *name, size_t len)
|
||||
{
|
||||
if(len == 2) {
|
||||
if(curl_strnequal(name, "h1", 2))
|
||||
if(!memcmp(name, "h1", 2))
|
||||
return ALPN_h1;
|
||||
if(curl_strnequal(name, "h2", 2))
|
||||
if(!memcmp(name, "h2", 2))
|
||||
return ALPN_h2;
|
||||
if(curl_strnequal(name, "h3", 2))
|
||||
if(!memcmp(name, "h3", 2))
|
||||
return ALPN_h3;
|
||||
}
|
||||
else if(len == 8) {
|
||||
if(curl_strnequal(name, "http/1.1", 8))
|
||||
if(!memcmp(name, "http/1.1", 8))
|
||||
return ALPN_h1;
|
||||
}
|
||||
return ALPN_none; /* unknown, probably rubbish input */
|
||||
}
|
||||
|
||||
enum alpnid Curl_str2alpnid(const struct Curl_str *cstr)
|
||||
{
|
||||
return Curl_alpn2alpnid((const unsigned char *)curlx_str(cstr),
|
||||
curlx_strlen(cstr));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
||||
* Curl_timeleft_ms() returns the amount of milliseconds left allowed for the
|
||||
* transfer/connection. If the value is 0, there is no timeout (ie there is
|
||||
* infinite time left). If the value is negative, the timeout time has already
|
||||
* elapsed.
|
||||
* @param data the transfer to check on
|
||||
* @param nowp timestamp to use for calculation, NULL to use curlx_now()
|
||||
* @param duringconnect TRUE iff connect timeout is also taken into account.
|
||||
* @unittest: 1303
|
||||
*/
|
||||
timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct curltime *nowp,
|
||||
bool duringconnect)
|
||||
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
|
||||
const struct curltime *pnow,
|
||||
bool duringconnect)
|
||||
{
|
||||
timediff_t timeleft_ms = 0;
|
||||
timediff_t ctimeleft_ms = 0;
|
||||
struct curltime now;
|
||||
timediff_t ctimeout_ms;
|
||||
|
||||
/* The duration of a connect and the total transfer are calculated from two
|
||||
different time-stamps. It can end up with the total timeout being reached
|
||||
@@ -126,90 +120,76 @@ timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
if((!data->set.timeout || data->set.connect_only) && !duringconnect)
|
||||
return 0; /* no timeout in place or checked, return "no limit" */
|
||||
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
|
||||
if(data->set.timeout) {
|
||||
timeleft_ms = data->set.timeout -
|
||||
curlx_timediff(*nowp, data->progress.t_startop);
|
||||
curlx_ptimediff_ms(pnow, &data->progress.t_startop);
|
||||
if(!timeleft_ms)
|
||||
timeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!duringconnect)
|
||||
return timeleft_ms; /* no connect check, this is it */
|
||||
}
|
||||
|
||||
if(duringconnect) {
|
||||
timediff_t ctimeout_ms = (data->set.connecttimeout > 0) ?
|
||||
data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
|
||||
ctimeleft_ms = ctimeout_ms -
|
||||
curlx_timediff(*nowp, data->progress.t_startsingle);
|
||||
if(!ctimeleft_ms)
|
||||
ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!timeleft_ms)
|
||||
return ctimeleft_ms; /* no general timeout, this is it */
|
||||
}
|
||||
if(!duringconnect)
|
||||
return timeleft_ms; /* no connect check, this is it */
|
||||
ctimeout_ms = (data->set.connecttimeout > 0) ?
|
||||
data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT;
|
||||
ctimeleft_ms = ctimeout_ms -
|
||||
curlx_ptimediff_ms(pnow, &data->progress.t_startsingle);
|
||||
if(!ctimeleft_ms)
|
||||
ctimeleft_ms = -1; /* 0 is "no limit", fake 1 ms expiry */
|
||||
if(!timeleft_ms)
|
||||
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;
|
||||
}
|
||||
|
||||
timediff_t Curl_timeleft_ms(struct Curl_easy *data,
|
||||
bool duringconnect)
|
||||
{
|
||||
return Curl_timeleft_now_ms(data, Curl_pgrs_now(data), duringconnect);
|
||||
}
|
||||
|
||||
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
int timeout_ms, struct curltime *nowp)
|
||||
int timeout_ms)
|
||||
{
|
||||
struct curltime now;
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
conn->shutdown.start[sockindex] = *nowp;
|
||||
conn->shutdown.start[sockindex] = *Curl_pgrs_now(data);
|
||||
conn->shutdown.timeout_ms = (timeout_ms > 0) ?
|
||||
(timediff_t)timeout_ms :
|
||||
((data->set.shutdowntimeout > 0) ?
|
||||
data->set.shutdowntimeout : DEFAULT_SHUTDOWN_TIMEOUT_MS);
|
||||
/* Set a timer, unless we operate on the admin handle */
|
||||
if(data->mid)
|
||||
Curl_expire_ex(data, nowp, conn->shutdown.timeout_ms,
|
||||
EXPIRE_SHUTDOWN);
|
||||
Curl_expire_ex(data, conn->shutdown.timeout_ms, EXPIRE_SHUTDOWN);
|
||||
}
|
||||
|
||||
timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
struct curltime *nowp)
|
||||
timediff_t Curl_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct curltime now;
|
||||
timediff_t left_ms;
|
||||
|
||||
if(!conn->shutdown.start[sockindex].tv_sec ||
|
||||
(conn->shutdown.timeout_ms <= 0))
|
||||
return 0; /* not started or no limits */
|
||||
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
left_ms = conn->shutdown.timeout_ms -
|
||||
curlx_timediff(*nowp, conn->shutdown.start[sockindex]);
|
||||
curlx_ptimediff_ms(Curl_pgrs_now(data),
|
||||
&conn->shutdown.start[sockindex]);
|
||||
return left_ms ? left_ms : -1;
|
||||
}
|
||||
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
|
||||
struct curltime *nowp)
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
timediff_t left_ms = 0, ms;
|
||||
struct curltime now;
|
||||
int i;
|
||||
|
||||
for(i = 0; conn->shutdown.timeout_ms && (i < 2); ++i) {
|
||||
if(!conn->shutdown.start[i].tv_sec)
|
||||
continue;
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
ms = Curl_shutdown_timeleft(conn, i, nowp);
|
||||
ms = Curl_shutdown_timeleft(data, conn, i);
|
||||
if(ms && (!left_ms || ms < left_ms))
|
||||
left_ms = ms;
|
||||
}
|
||||
@@ -231,56 +211,53 @@ bool Curl_shutdown_started(struct Curl_easy *data, int sockindex)
|
||||
/* retrieves ip address and port from a sockaddr structure. note it calls
|
||||
curlx_inet_ntop which sets errno on fail, not SOCKERRNO. */
|
||||
bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
||||
char *addr, int *port)
|
||||
char *addr, uint16_t *port)
|
||||
{
|
||||
struct sockaddr_in *si = NULL;
|
||||
#ifdef USE_IPV6
|
||||
struct sockaddr_in6 *si6 = NULL;
|
||||
#endif
|
||||
#if (defined(HAVE_SYS_UN_H) || defined(WIN32_SOCKADDR_UN)) && defined(AF_UNIX)
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
struct sockaddr_un *su = NULL;
|
||||
#else
|
||||
(void)salen;
|
||||
#endif
|
||||
|
||||
switch(sa->sa_family) {
|
||||
case AF_INET:
|
||||
si = (struct sockaddr_in *)(void *) sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) {
|
||||
unsigned short us_port = ntohs(si->sin_port);
|
||||
*port = us_port;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_IPV6
|
||||
case AF_INET6:
|
||||
si6 = (struct sockaddr_in6 *)(void *) sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr,
|
||||
MAX_IPADR_LEN)) {
|
||||
unsigned short us_port = ntohs(si6->sin6_port);
|
||||
*port = us_port;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (defined(HAVE_SYS_UN_H) || defined(WIN32_SOCKADDR_UN)) && defined(AF_UNIX)
|
||||
case AF_UNIX:
|
||||
if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) {
|
||||
su = (struct sockaddr_un*)sa;
|
||||
curl_msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
}
|
||||
else
|
||||
addr[0] = 0; /* socket with no name */
|
||||
*port = 0;
|
||||
case AF_INET:
|
||||
si = (struct sockaddr_in *)(void *)sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si->sin_addr, addr, MAX_IPADR_LEN)) {
|
||||
*port = ntohs(si->sin_port);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#ifdef USE_IPV6
|
||||
case AF_INET6:
|
||||
si6 = (struct sockaddr_in6 *)(void *)sa;
|
||||
if(curlx_inet_ntop(sa->sa_family, &si6->sin6_addr, addr, MAX_IPADR_LEN)) {
|
||||
*port = ntohs(si6->sin6_port);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
case AF_UNIX:
|
||||
if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) {
|
||||
su = (struct sockaddr_un *)sa;
|
||||
curl_msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
}
|
||||
else
|
||||
addr[0] = 0; /* socket with no name */
|
||||
*port = 0;
|
||||
return TRUE;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addr[0] = '\0';
|
||||
*port = 0;
|
||||
CURL_SETERRNO(SOCKEAFNOSUPPORT);
|
||||
errno = SOCKEAFNOSUPPORT;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -337,7 +314,7 @@ void Curl_conncontrol(struct connectdata *conn,
|
||||
#endif
|
||||
is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET);
|
||||
closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !is_multiplex);
|
||||
((ctrl == CONNCTRL_STREAM) && !is_multiplex);
|
||||
if((ctrl == CONNCTRL_STREAM) && is_multiplex)
|
||||
; /* stream signal on multiplex conn never affects close state */
|
||||
else if((bit)closeit != conn->bits.close) {
|
||||
@@ -359,7 +336,7 @@ typedef enum {
|
||||
struct cf_setup_ctx {
|
||||
cf_setup_state state;
|
||||
int ssl_mode;
|
||||
int transport;
|
||||
uint8_t transport;
|
||||
};
|
||||
|
||||
static CURLcode cf_setup_connect(struct Curl_cfilter *cf,
|
||||
@@ -408,8 +385,8 @@ connect_sub_chain:
|
||||
|
||||
if(ctx->state < CF_SETUP_CNNCT_HTTP_PROXY && cf->conn->bits.httpproxy) {
|
||||
#ifdef USE_SSL
|
||||
if(IS_HTTPS_PROXY(cf->conn->http_proxy.proxytype)
|
||||
&& !Curl_conn_is_ssl(cf->conn, cf->sockindex)) {
|
||||
if(IS_HTTPS_PROXY(cf->conn->http_proxy.proxytype) &&
|
||||
!Curl_conn_is_ssl(cf->conn, cf->sockindex)) {
|
||||
result = Curl_cf_ssl_proxy_insert_after(cf, data);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -449,9 +426,9 @@ connect_sub_chain:
|
||||
|
||||
if(ctx->state < CF_SETUP_CNNCT_SSL) {
|
||||
#ifdef USE_SSL
|
||||
if((ctx->ssl_mode == CURL_CF_SSL_ENABLE
|
||||
|| (ctx->ssl_mode != CURL_CF_SSL_DISABLE
|
||||
&& cf->conn->handler->flags & PROTOPT_SSL)) /* we want SSL */
|
||||
if((ctx->ssl_mode == CURL_CF_SSL_ENABLE ||
|
||||
(ctx->ssl_mode != CURL_CF_SSL_DISABLE &&
|
||||
cf->conn->handler->flags & PROTOPT_SSL)) /* we want SSL */
|
||||
&& !Curl_conn_is_ssl(cf->conn, cf->sockindex)) { /* it is missing */
|
||||
result = Curl_cf_ssl_insert_after(cf, data);
|
||||
if(result)
|
||||
@@ -493,7 +470,6 @@ static void cf_setup_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
Curl_safefree(ctx);
|
||||
}
|
||||
|
||||
|
||||
struct Curl_cftype Curl_cft_setup = {
|
||||
"SETUP",
|
||||
0,
|
||||
@@ -514,7 +490,7 @@ struct Curl_cftype Curl_cft_setup = {
|
||||
|
||||
static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode)
|
||||
{
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
@@ -522,7 +498,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
@@ -539,7 +515,7 @@ static CURLcode cf_setup_create(struct Curl_cfilter **pcf,
|
||||
out:
|
||||
*pcf = result ? NULL : cf;
|
||||
if(ctx) {
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -547,7 +523,7 @@ out:
|
||||
static CURLcode cf_setup_add(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
@@ -564,7 +540,7 @@ out:
|
||||
|
||||
CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
|
||||
+22
-19
@@ -25,37 +25,40 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curlx/nonblock.h" /* for curlx_nonblock() */
|
||||
#include "sockaddr.h"
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
struct Curl_dns_entry;
|
||||
struct ip_quadruple;
|
||||
struct Curl_str;
|
||||
|
||||
enum alpnid Curl_alpn2alpnid(const char *name, size_t len);
|
||||
enum alpnid Curl_alpn2alpnid(const unsigned char *name, size_t len);
|
||||
enum alpnid Curl_str2alpnid(const struct Curl_str *str);
|
||||
|
||||
/* generic function that returns how much time there is left to run, according
|
||||
to the timeouts set */
|
||||
timediff_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct curltime *nowp,
|
||||
bool duringconnect);
|
||||
timediff_t Curl_timeleft_ms(struct Curl_easy *data,
|
||||
bool duringconnect);
|
||||
timediff_t Curl_timeleft_now_ms(struct Curl_easy *data,
|
||||
const struct curltime *pnow,
|
||||
bool duringconnect);
|
||||
|
||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||
|
||||
#define DEFAULT_SHUTDOWN_TIMEOUT_MS (2 * 1000)
|
||||
|
||||
void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
int timeout_ms, struct curltime *nowp);
|
||||
int timeout_ms);
|
||||
|
||||
/* return how much time there is left to shutdown the connection at
|
||||
* sockindex. Returns 0 if there is no limit or shutdown has not started. */
|
||||
timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
struct curltime *nowp);
|
||||
timediff_t Curl_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex);
|
||||
|
||||
/* return how much time there is left to shutdown the connection.
|
||||
* Returns 0 if there is no limit or shutdown has not started. */
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
|
||||
struct curltime *nowp);
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
void Curl_shutdown_clear(struct Curl_easy *data, int sockindex);
|
||||
|
||||
@@ -72,7 +75,7 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
||||
struct connectdata **connp);
|
||||
|
||||
bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
|
||||
char *addr, int *port);
|
||||
char *addr, uint16_t *port);
|
||||
|
||||
/*
|
||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
||||
@@ -98,18 +101,18 @@ void Curl_conncontrol(struct connectdata *conn,
|
||||
);
|
||||
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
||||
#define streamclose(x, y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
||||
#define connclose(x, y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
||||
#define connkeep(x, y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
||||
#else /* if !DEBUGBUILD || CURL_DISABLE_VERBOSE_STRINGS */
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
||||
#define streamclose(x, y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
||||
#define connclose(x, y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
||||
#define connkeep(x, y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
||||
#endif
|
||||
|
||||
CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at,
|
||||
struct Curl_easy *data,
|
||||
int transport,
|
||||
uint8_t transport,
|
||||
int ssl_mode);
|
||||
|
||||
/**
|
||||
|
||||
+54
-91
@@ -21,12 +21,10 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include <stddef.h>
|
||||
#include "curlx/dynbuf.h"
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
@@ -49,13 +47,9 @@
|
||||
#endif
|
||||
|
||||
#include "sendf.h"
|
||||
#include "http.h"
|
||||
#include "curl_trc.h"
|
||||
#include "content_encoding.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define CONTENT_ENCODING_DEFAULT "identity"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
@@ -90,24 +84,20 @@ struct zlib_writer {
|
||||
z_stream z; /* State structure for zlib. */
|
||||
};
|
||||
|
||||
|
||||
static voidpf
|
||||
zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
|
||||
static voidpf zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
|
||||
{
|
||||
(void)opaque;
|
||||
/* not a typo, keep it calloc() */
|
||||
return (voidpf) calloc(items, size);
|
||||
/* not a typo, keep it curlx_calloc() */
|
||||
return (voidpf)curlx_calloc(items, size);
|
||||
}
|
||||
|
||||
static void
|
||||
zfree_cb(voidpf opaque, voidpf ptr)
|
||||
static void zfree_cb(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
(void)opaque;
|
||||
free(ptr);
|
||||
curlx_free(ptr);
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
process_zlib_error(struct Curl_easy *data, z_stream *z)
|
||||
static CURLcode process_zlib_error(struct Curl_easy *data, z_stream *z)
|
||||
{
|
||||
if(z->msg)
|
||||
failf(data, "Error while processing content unencoding: %s",
|
||||
@@ -119,9 +109,8 @@ process_zlib_error(struct Curl_easy *data, z_stream *z)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
exit_zlib(struct Curl_easy *data,
|
||||
z_stream *z, zlibInitState *zlib_init, CURLcode result)
|
||||
static CURLcode exit_zlib(struct Curl_easy *data, z_stream *z,
|
||||
zlibInitState *zlib_init, CURLcode result)
|
||||
{
|
||||
if(*zlib_init != ZLIB_UNINIT) {
|
||||
if(inflateEnd(z) != Z_OK && result == CURLE_OK)
|
||||
@@ -132,8 +121,7 @@ exit_zlib(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode process_trailer(struct Curl_easy *data,
|
||||
struct zlib_writer *zp)
|
||||
static CURLcode process_trailer(struct Curl_easy *data, struct zlib_writer *zp)
|
||||
{
|
||||
z_stream *z = &zp->z;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -160,7 +148,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
zlibInitState started)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
uInt nread = z->avail_in;
|
||||
z_const Bytef *orig_in = z->next_in;
|
||||
@@ -180,7 +168,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
done = TRUE;
|
||||
|
||||
/* (re)set buffer for decompressed output for every iteration */
|
||||
z->next_out = (Bytef *) zp->buffer;
|
||||
z->next_out = (Bytef *)zp->buffer;
|
||||
z->avail_out = DECOMPRESS_BUFFER_SIZE;
|
||||
|
||||
status = inflate(z, Z_BLOCK);
|
||||
@@ -241,17 +229,16 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Deflate handler. */
|
||||
static CURLcode deflate_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
z->zalloc = (alloc_func)zalloc_cb;
|
||||
z->zfree = (free_func)zfree_cb;
|
||||
|
||||
if(inflateInit(z) != Z_OK)
|
||||
return process_zlib_error(data, z);
|
||||
@@ -263,7 +250,7 @@ static CURLcode deflate_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
@@ -283,7 +270,7 @@ static CURLcode deflate_do_write(struct Curl_easy *data,
|
||||
static void deflate_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
exit_zlib(data, z, &zp->zlib_init, CURLE_OK);
|
||||
@@ -298,17 +285,19 @@ static const struct Curl_cwtype deflate_encoding = {
|
||||
sizeof(struct zlib_writer)
|
||||
};
|
||||
|
||||
/*
|
||||
* Gzip handler.
|
||||
*/
|
||||
|
||||
/* Gzip handler. */
|
||||
static CURLcode gzip_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
z->zalloc = (alloc_func)zalloc_cb;
|
||||
z->zfree = (free_func)zfree_cb;
|
||||
|
||||
if(inflateInit2(z, MAX_WBITS + 32) != Z_OK)
|
||||
return process_zlib_error(data, z);
|
||||
@@ -321,7 +310,7 @@ static CURLcode gzip_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
@@ -342,7 +331,7 @@ static CURLcode gzip_do_write(struct Curl_easy *data,
|
||||
static void gzip_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
struct zlib_writer *zp = (struct zlib_writer *)writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
|
||||
exit_zlib(data, z, &zp->zlib_init, CURLE_OK);
|
||||
@@ -384,12 +373,10 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
||||
case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:
|
||||
case BROTLI_DECODER_ERROR_FORMAT_PADDING_1:
|
||||
case BROTLI_DECODER_ERROR_FORMAT_PADDING_2:
|
||||
#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY
|
||||
#ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY /* brotli v1.1.0+ */
|
||||
case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY:
|
||||
#endif
|
||||
#ifdef BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET
|
||||
case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:
|
||||
#endif
|
||||
case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:
|
||||
@@ -408,7 +395,7 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
||||
static CURLcode brotli_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
struct brotli_writer *bp = (struct brotli_writer *)writer;
|
||||
(void)data;
|
||||
|
||||
bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
|
||||
@@ -419,8 +406,8 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
const uint8_t *src = (const uint8_t *) buf;
|
||||
struct brotli_writer *bp = (struct brotli_writer *)writer;
|
||||
const uint8_t *src = (const uint8_t *)buf;
|
||||
uint8_t *dst;
|
||||
size_t dstleft;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -434,7 +421,7 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
||||
|
||||
while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) &&
|
||||
result == CURLE_OK) {
|
||||
dst = (uint8_t *) bp->buffer;
|
||||
dst = (uint8_t *)bp->buffer;
|
||||
dstleft = DECOMPRESS_BUFFER_SIZE;
|
||||
r = BrotliDecoderDecompressStream(bp->br,
|
||||
&nbytes, &src, &dstleft, &dst, NULL);
|
||||
@@ -463,7 +450,7 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
||||
static void brotli_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
struct brotli_writer *bp = (struct brotli_writer *)writer;
|
||||
(void)data;
|
||||
|
||||
if(bp->br) {
|
||||
@@ -507,7 +494,7 @@ static void Curl_zstd_free(void *opaque, void *address)
|
||||
static CURLcode zstd_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
struct zstd_writer *zp = (struct zstd_writer *)writer;
|
||||
|
||||
(void)data;
|
||||
|
||||
@@ -529,7 +516,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
struct zstd_writer *zp = (struct zstd_writer *)writer;
|
||||
ZSTD_inBuffer in;
|
||||
ZSTD_outBuffer out;
|
||||
size_t errorCode;
|
||||
@@ -566,7 +553,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
||||
static void zstd_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
struct zstd_writer *zp = (struct zstd_writer *)writer;
|
||||
(void)data;
|
||||
|
||||
if(zp->zds) {
|
||||
@@ -619,41 +606,27 @@ static const struct Curl_cwtype * const transfer_unencoders[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Provide a list of comma-separated names of supported encodings.
|
||||
*/
|
||||
void Curl_all_content_encodings(char *buf, size_t blen)
|
||||
/* Return the list of comma-separated names of supported encodings.
|
||||
*/
|
||||
char *Curl_get_content_encodings(void)
|
||||
{
|
||||
size_t len = 0;
|
||||
struct dynbuf enc;
|
||||
const struct Curl_cwtype * const *cep;
|
||||
const struct Curl_cwtype *ce;
|
||||
CURLcode result = CURLE_OK;
|
||||
curlx_dyn_init(&enc, 255);
|
||||
|
||||
DEBUGASSERT(buf);
|
||||
DEBUGASSERT(blen);
|
||||
buf[0] = 0;
|
||||
|
||||
for(cep = general_unencoders; *cep; cep++) {
|
||||
ce = *cep;
|
||||
if(!curl_strequal(ce->name, CONTENT_ENCODING_DEFAULT))
|
||||
len += strlen(ce->name) + 2;
|
||||
}
|
||||
|
||||
if(!len) {
|
||||
if(blen >= sizeof(CONTENT_ENCODING_DEFAULT))
|
||||
strcpy(buf, CONTENT_ENCODING_DEFAULT);
|
||||
}
|
||||
else if(blen > len) {
|
||||
char *p = buf;
|
||||
for(cep = general_unencoders; *cep; cep++) {
|
||||
ce = *cep;
|
||||
if(!curl_strequal(ce->name, CONTENT_ENCODING_DEFAULT)) {
|
||||
strcpy(p, ce->name);
|
||||
p += strlen(p);
|
||||
*p++ = ',';
|
||||
*p++ = ' ';
|
||||
}
|
||||
for(cep = general_unencoders; *cep && !result; cep++) {
|
||||
const struct Curl_cwtype *ce = *cep;
|
||||
if(!curl_strequal(ce->name, CONTENT_ENCODING_DEFAULT)) {
|
||||
if(curlx_dyn_len(&enc))
|
||||
result = curlx_dyn_addn(&enc, ", ", 2);
|
||||
if(!result)
|
||||
result = curlx_dyn_add(&enc, ce->name);
|
||||
}
|
||||
p[-2] = '\0';
|
||||
}
|
||||
if(!result)
|
||||
return curlx_dyn_ptr(&enc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Deferred error dummy writer. */
|
||||
@@ -675,12 +648,7 @@ static CURLcode error_do_write(struct Curl_easy *data,
|
||||
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
|
||||
else {
|
||||
char all[256];
|
||||
(void)Curl_all_content_encodings(all, sizeof(all));
|
||||
failf(data, "Unrecognized content encoding type. "
|
||||
"libcurl understands %s content encodings.", all);
|
||||
}
|
||||
failf(data, "Unrecognized content encoding type");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
@@ -847,14 +815,9 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
void Curl_all_content_encodings(char *buf, size_t blen)
|
||||
char *Curl_get_content_encodings(void)
|
||||
{
|
||||
DEBUGASSERT(buf);
|
||||
DEBUGASSERT(blen);
|
||||
if(blen < sizeof(CONTENT_ENCODING_DEFAULT))
|
||||
buf[0] = 0;
|
||||
else
|
||||
strcpy(buf, CONTENT_ENCODING_DEFAULT);
|
||||
return curlx_strdup(CONTENT_ENCODING_DEFAULT);
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
struct Curl_cwriter;
|
||||
|
||||
void Curl_all_content_encodings(char *buf, size_t blen);
|
||||
/* returns an allocated string or NULL */
|
||||
char *Curl_get_content_encodings(void);
|
||||
|
||||
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
||||
const char *enclist, int is_transfer);
|
||||
|
||||
+434
-487
@@ -21,54 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/***
|
||||
|
||||
|
||||
RECEIVING COOKIE INFORMATION
|
||||
============================
|
||||
|
||||
Curl_cookie_init()
|
||||
|
||||
Inits a cookie struct to store data in a local file. This is always
|
||||
called before any cookies are set.
|
||||
|
||||
Curl_cookie_add()
|
||||
|
||||
Adds a cookie to the in-memory cookie jar.
|
||||
|
||||
|
||||
SENDING COOKIE INFORMATION
|
||||
==========================
|
||||
|
||||
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
|
||||
boolean informs the cookie if a secure connection is achieved or
|
||||
not.
|
||||
|
||||
It shall only return cookies that have not expired.
|
||||
|
||||
Example set of cookies:
|
||||
|
||||
Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
|
||||
Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
|
||||
domain=.fidelity.com; path=/ftgw; secure
|
||||
Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
|
||||
domain=.fidelity.com; path=/; secure
|
||||
Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
|
||||
domain=.fidelity.com; path=/; secure
|
||||
Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
|
||||
domain=.fidelity.com; path=/; secure
|
||||
Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
|
||||
domain=.fidelity.com; path=/; secure
|
||||
Set-cookie:
|
||||
Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday,
|
||||
13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
|
||||
****/
|
||||
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
@@ -76,27 +28,21 @@ Example set of cookies:
|
||||
#include "urldata.h"
|
||||
#include "cookie.h"
|
||||
#include "psl.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "slist.h"
|
||||
#include "share.h"
|
||||
#include "curl_share.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_fopen.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "parsedate.h"
|
||||
#include "rename.h"
|
||||
#include "strdup.h"
|
||||
#include "llist.h"
|
||||
#include "bufref.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static void strstore(char **str, const char *newstr, size_t len);
|
||||
|
||||
/* number of seconds in 400 days */
|
||||
#define COOKIES_MAXAGE (400*24*3600)
|
||||
#define COOKIES_MAXAGE (400 * 24 * 3600)
|
||||
|
||||
/* Make sure cookies never expire further away in time than 400 days into the
|
||||
future. (from RFC6265bis draft-19)
|
||||
@@ -110,19 +56,19 @@ static void cap_expires(time_t now, struct Cookie *co)
|
||||
timediff_t cap = now + COOKIES_MAXAGE;
|
||||
if(co->expires > cap) {
|
||||
cap += 30;
|
||||
co->expires = (cap/60)*60;
|
||||
co->expires = (cap / 60) * 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void freecookie(struct Cookie *co)
|
||||
static void freecookie(struct Cookie *co, bool maintoo)
|
||||
{
|
||||
free(co->domain);
|
||||
free(co->path);
|
||||
free(co->spath);
|
||||
free(co->name);
|
||||
free(co->value);
|
||||
free(co);
|
||||
curlx_free(co->domain);
|
||||
curlx_free(co->path);
|
||||
curlx_free(co->name);
|
||||
curlx_free(co->value);
|
||||
if(maintoo)
|
||||
curlx_free(co);
|
||||
}
|
||||
|
||||
static bool cookie_tailmatch(const char *cookie_domain,
|
||||
@@ -135,7 +81,7 @@ static bool cookie_tailmatch(const char *cookie_domain,
|
||||
return FALSE;
|
||||
|
||||
if(!curl_strnequal(cookie_domain,
|
||||
hostname + hostname_len-cookie_domain_len,
|
||||
hostname + hostname_len - cookie_domain_len,
|
||||
cookie_domain_len))
|
||||
return FALSE;
|
||||
|
||||
@@ -278,22 +224,21 @@ static size_t cookiehash(const char * const domain)
|
||||
/*
|
||||
* cookie path sanitize
|
||||
*/
|
||||
static char *sanitize_cookie_path(const char *cookie_path)
|
||||
static char *sanitize_cookie_path(const char *cookie_path, size_t len)
|
||||
{
|
||||
size_t len = strlen(cookie_path);
|
||||
|
||||
/* some sites send path attribute within '"'. */
|
||||
if(cookie_path[0] == '\"') {
|
||||
if(len && (cookie_path[0] == '\"')) {
|
||||
cookie_path++;
|
||||
len--;
|
||||
|
||||
if(len && (cookie_path[len - 1] == '\"'))
|
||||
len--;
|
||||
}
|
||||
if(len && (cookie_path[len - 1] == '\"'))
|
||||
len--;
|
||||
|
||||
/* RFC6265 5.2.4 The Path Attribute */
|
||||
if(cookie_path[0] != '/')
|
||||
if(!len || (cookie_path[0] != '/'))
|
||||
/* Let cookie-path be the default-path. */
|
||||
return strdup("/");
|
||||
return curlx_strdup("/");
|
||||
|
||||
/* remove trailing slash when path is non-empty */
|
||||
/* convert /hoge/ to /hoge */
|
||||
@@ -303,34 +248,6 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
||||
return Curl_memdup0(cookie_path, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
||||
*
|
||||
* NOTE: OOM or cookie parsing failures are ignored.
|
||||
*/
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data)
|
||||
{
|
||||
struct curl_slist *list = data->state.cookielist;
|
||||
if(list) {
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
while(list) {
|
||||
struct CookieInfo *ci =
|
||||
Curl_cookie_init(data, list->data, data->cookies,
|
||||
data->set.cookiesession);
|
||||
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 = ci;
|
||||
list = list->next;
|
||||
}
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* strstore
|
||||
*
|
||||
@@ -340,15 +257,17 @@ void Curl_cookie_loadfiles(struct Curl_easy *data)
|
||||
* parsing in a last-wins scenario. The caller is responsible for checking
|
||||
* for OOM errors.
|
||||
*/
|
||||
static void strstore(char **str, const char *newstr, size_t len)
|
||||
static CURLcode strstore(char **str, const char *newstr, size_t len)
|
||||
{
|
||||
DEBUGASSERT(str);
|
||||
free(*str);
|
||||
if(!len) {
|
||||
len++;
|
||||
newstr = "";
|
||||
}
|
||||
*str = Curl_memdup0(newstr, len);
|
||||
if(!*str)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -390,7 +309,7 @@ static void remove_expired(struct CookieInfo *ci)
|
||||
if(co->expires) {
|
||||
if(co->expires < now) {
|
||||
Curl_node_remove(n);
|
||||
freecookie(co);
|
||||
freecookie(co, TRUE);
|
||||
ci->numcookies--;
|
||||
}
|
||||
else if(co->expires < ci->next_expiration)
|
||||
@@ -433,37 +352,19 @@ static bool bad_domain(const char *domain, size_t len)
|
||||
fine. The prime reason for filtering out control bytes is that some HTTP
|
||||
servers return 400 for requests that contain such.
|
||||
*/
|
||||
static bool invalid_octets(const char *ptr)
|
||||
static bool invalid_octets(const char *ptr, size_t len)
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *)ptr;
|
||||
/* Reject all bytes \x01 - \x1f (*except* \x09, TAB) + \x7f */
|
||||
while(*p) {
|
||||
while(len && *p) {
|
||||
if(((*p != 9) && (*p < 0x20)) || (*p == 0x7f))
|
||||
return TRUE;
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#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 */
|
||||
#ifdef USE_LIBPSL
|
||||
#define CERR_PSL 14 /* a public suffix */
|
||||
#endif
|
||||
#define CERR_LIVE_WINS 15
|
||||
|
||||
/* The maximum length we accept a date string for the 'expire' keyword. The
|
||||
standard date formats are within the 30 bytes range. This adds an extra
|
||||
margin just to make sure it realistically works with what is used out
|
||||
@@ -471,10 +372,64 @@ static bool invalid_octets(const char *ptr)
|
||||
*/
|
||||
#define MAX_DATE_LENGTH 80
|
||||
|
||||
static int
|
||||
#define COOKIE_NAME 0
|
||||
#define COOKIE_VALUE 1
|
||||
#define COOKIE_DOMAIN 2
|
||||
#define COOKIE_PATH 3
|
||||
|
||||
#define COOKIE_PIECES 4 /* the list above */
|
||||
|
||||
static CURLcode storecookie(struct Cookie *co, struct Curl_str *cp,
|
||||
const char *path, const char *domain)
|
||||
{
|
||||
CURLcode result;
|
||||
result = strstore(&co->name, curlx_str(&cp[COOKIE_NAME]),
|
||||
curlx_strlen(&cp[COOKIE_NAME]));
|
||||
if(!result)
|
||||
result = strstore(&co->value, curlx_str(&cp[COOKIE_VALUE]),
|
||||
curlx_strlen(&cp[COOKIE_VALUE]));
|
||||
if(!result) {
|
||||
size_t plen = 0;
|
||||
if(curlx_strlen(&cp[COOKIE_PATH])) {
|
||||
path = curlx_str(&cp[COOKIE_PATH]);
|
||||
plen = curlx_strlen(&cp[COOKIE_PATH]);
|
||||
}
|
||||
else if(path) {
|
||||
/* No path was given in the header line, set the default */
|
||||
const char *endslash = strrchr(path, '/');
|
||||
if(endslash)
|
||||
plen = (endslash - path + 1); /* include end slash */
|
||||
else
|
||||
plen = strlen(path);
|
||||
}
|
||||
|
||||
if(path) {
|
||||
co->path = sanitize_cookie_path(path, plen);
|
||||
if(!co->path)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
if(!result) {
|
||||
if(curlx_strlen(&cp[COOKIE_DOMAIN]))
|
||||
result = strstore(&co->domain, curlx_str(&cp[COOKIE_DOMAIN]),
|
||||
curlx_strlen(&cp[COOKIE_DOMAIN]));
|
||||
else if(domain) {
|
||||
/* no domain was given in the header line, set the default */
|
||||
co->domain = curlx_strdup(domain);
|
||||
if(!co->domain)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* this function return errors on OOM etc, not on plain cookie format
|
||||
problems */
|
||||
static CURLcode
|
||||
parse_cookie_header(struct Curl_easy *data,
|
||||
struct Cookie *co,
|
||||
struct CookieInfo *ci,
|
||||
bool *okay, /* if the cookie was fine */
|
||||
const char *ptr,
|
||||
const char *domain, /* default domain */
|
||||
const char *path, /* full path used when this cookie is
|
||||
@@ -484,121 +439,97 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
origin */
|
||||
{
|
||||
/* This line was read off an HTTP-header */
|
||||
time_t now;
|
||||
time_t now = 0;
|
||||
size_t linelength = strlen(ptr);
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_str cookie[COOKIE_PIECES];
|
||||
*okay = FALSE;
|
||||
if(linelength > MAX_COOKIE_LINE)
|
||||
/* discard overly long lines at once */
|
||||
return CERR_TOO_LONG;
|
||||
return CURLE_OK;
|
||||
|
||||
now = time(NULL);
|
||||
/* memset instead of initializer because gcc 4.8.1 is silly */
|
||||
memset(cookie, 0, sizeof(cookie));
|
||||
do {
|
||||
struct Curl_str name;
|
||||
struct Curl_str val;
|
||||
|
||||
/* we have a <name>=<value> pair or a stand-alone word here */
|
||||
if(!curlx_str_cspn(&ptr, &name, ";\t\r\n=")) {
|
||||
bool done = FALSE;
|
||||
bool sep = FALSE;
|
||||
curlx_str_trimblanks(&name);
|
||||
|
||||
if(!curlx_str_single(&ptr, '=')) {
|
||||
sep = TRUE; /* a '=' was used */
|
||||
if(!curlx_str_cspn(&ptr, &val, ";\r\n")) {
|
||||
if(!curlx_str_cspn(&ptr, &val, ";\r\n"))
|
||||
curlx_str_trimblanks(&val);
|
||||
|
||||
/* Reject cookies with a TAB inside the value */
|
||||
if(memchr(curlx_str(&val), '\t', curlx_strlen(&val))) {
|
||||
infof(data, "cookie contains TAB, dropping");
|
||||
return CERR_TAB;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
curlx_str_init(&val);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(curlx_strlen(&name) >= (MAX_NAME-1) ||
|
||||
curlx_strlen(&val) >= (MAX_NAME-1) ||
|
||||
((curlx_strlen(&name) + curlx_strlen(&val)) > MAX_NAME)) {
|
||||
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes",
|
||||
curlx_strlen(&name), curlx_strlen(&val));
|
||||
return CERR_TOO_BIG;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(!strncmp("__Secure-", curlx_str(&name), 9))
|
||||
co->prefix_secure = TRUE;
|
||||
else if(!strncmp("__Host-", curlx_str(&name), 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, curlx_str(&name), curlx_strlen(&name));
|
||||
strstore(&co->value, curlx_str(&val), curlx_strlen(&val));
|
||||
done = TRUE;
|
||||
if(!co->name || !co->value)
|
||||
return CERR_NO_NAME_VALUE;
|
||||
|
||||
if(invalid_octets(co->value) || invalid_octets(co->name)) {
|
||||
if(!curlx_strlen(&cookie[COOKIE_NAME])) {
|
||||
/* The first name/value pair is the actual cookie name */
|
||||
if(!sep ||
|
||||
/* Bad name/value pair. */
|
||||
invalid_octets(curlx_str(&name), curlx_strlen(&name)) ||
|
||||
invalid_octets(curlx_str(&val), curlx_strlen(&val)) ||
|
||||
!curlx_strlen(&name)) {
|
||||
infof(data, "invalid octets in name/value, cookie dropped");
|
||||
return CERR_INVALID_OCTET;
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
else if(!curlx_strlen(&val)) {
|
||||
|
||||
/*
|
||||
* this was a "<name>=" with no content, and we must allow
|
||||
* 'secure' and 'httponly' specified this weirdly
|
||||
* Check for too long individual name or contents, or too long
|
||||
* combination of name + contents. Chrome and Firefox support 4095 or
|
||||
* 4096 bytes combo
|
||||
*/
|
||||
done = TRUE;
|
||||
if(curlx_strlen(&name) >= (MAX_NAME - 1) ||
|
||||
curlx_strlen(&val) >= (MAX_NAME - 1) ||
|
||||
((curlx_strlen(&name) + curlx_strlen(&val)) > MAX_NAME)) {
|
||||
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes",
|
||||
curlx_strlen(&name), curlx_strlen(&val));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Reject cookies with a TAB inside the value */
|
||||
if(curlx_strlen(&val) &&
|
||||
memchr(curlx_str(&val), '\t', curlx_strlen(&val))) {
|
||||
infof(data, "cookie contains TAB, dropping");
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Check if we have a reserved prefix set. */
|
||||
if(!strncmp("__Secure-", curlx_str(&name), 9))
|
||||
co->prefix_secure = TRUE;
|
||||
else if(!strncmp("__Host-", curlx_str(&name), 7))
|
||||
co->prefix_host = TRUE;
|
||||
|
||||
cookie[COOKIE_NAME] = name;
|
||||
cookie[COOKIE_VALUE] = val;
|
||||
}
|
||||
else if(!sep) {
|
||||
/*
|
||||
* this is a "<name>" with no content
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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(curlx_str_casecompare(&name, "secure")) {
|
||||
if(secure || !ci->running) {
|
||||
if(secure || !ci->running)
|
||||
co->secure = TRUE;
|
||||
}
|
||||
else {
|
||||
return CERR_BAD_SECURE;
|
||||
infof(data, "skipped cookie because not 'secure'");
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
else if(curlx_str_casecompare(&name, "httponly"))
|
||||
co->httponly = TRUE;
|
||||
else if(sep)
|
||||
/* there was a '=' so we are not done parsing this field */
|
||||
done = FALSE;
|
||||
}
|
||||
if(done)
|
||||
;
|
||||
else if(curlx_str_casecompare(&name, "path")) {
|
||||
strstore(&co->path, curlx_str(&val), curlx_strlen(&val));
|
||||
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;
|
||||
cookie[COOKIE_PATH] = val;
|
||||
}
|
||||
else if(curlx_str_casecompare(&name, "domain") && curlx_strlen(&val)) {
|
||||
bool is_ip;
|
||||
@@ -623,16 +554,13 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
|
||||
is_ip = Curl_host_is_ipnum(domain ? domain : curlx_str(&val));
|
||||
|
||||
if(!domain
|
||||
|| (is_ip && !strncmp(curlx_str(&val), domain,
|
||||
curlx_strlen(&val)) &&
|
||||
(curlx_strlen(&val) == strlen(domain)))
|
||||
|| (!is_ip && cookie_tailmatch(curlx_str(&val),
|
||||
if(!domain ||
|
||||
(is_ip &&
|
||||
!strncmp(curlx_str(&val), domain, curlx_strlen(&val)) &&
|
||||
(curlx_strlen(&val) == strlen(domain))) ||
|
||||
(!is_ip && cookie_tailmatch(curlx_str(&val),
|
||||
curlx_strlen(&val), domain))) {
|
||||
strstore(&co->domain, curlx_str(&val), curlx_strlen(&val));
|
||||
if(!co->domain)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
|
||||
cookie[COOKIE_DOMAIN] = val;
|
||||
if(!is_ip)
|
||||
co->tailmatch = TRUE; /* we always do that if the domain name was
|
||||
given */
|
||||
@@ -644,12 +572,9 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
*/
|
||||
infof(data, "skipped cookie with bad tailmatch domain: %s",
|
||||
curlx_str(&val));
|
||||
return CERR_NO_TAILMATCH;
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
else if(curlx_str_casecompare(&name, "version")) {
|
||||
/* just ignore */
|
||||
}
|
||||
else if(curlx_str_casecompare(&name, "max-age") && curlx_strlen(&val)) {
|
||||
/*
|
||||
* Defined in RFC2109:
|
||||
@@ -665,6 +590,8 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
if(*maxage == '\"')
|
||||
maxage++;
|
||||
rc = curlx_str_number(&maxage, &co->expires, CURL_OFF_T_MAX);
|
||||
if(!now)
|
||||
now = time(NULL);
|
||||
switch(rc) {
|
||||
case STRE_OVERFLOW:
|
||||
/* overflow, used max value */
|
||||
@@ -686,79 +613,47 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
}
|
||||
cap_expires(now, co);
|
||||
}
|
||||
else if(curlx_str_casecompare(&name, "expires") && curlx_strlen(&val)) {
|
||||
if(!co->expires && (curlx_strlen(&val) < MAX_DATE_LENGTH)) {
|
||||
/*
|
||||
* Let max-age have priority.
|
||||
*
|
||||
* If the date cannot get parsed for whatever reason, the cookie
|
||||
* will be treated as a session cookie
|
||||
*/
|
||||
char dbuf[MAX_DATE_LENGTH + 1];
|
||||
time_t date = 0;
|
||||
memcpy(dbuf, curlx_str(&val), curlx_strlen(&val));
|
||||
dbuf[curlx_strlen(&val)] = 0;
|
||||
if(!Curl_getdate_capped(dbuf, &date)) {
|
||||
if(!date)
|
||||
date++;
|
||||
co->expires = (curl_off_t)date;
|
||||
}
|
||||
else
|
||||
co->expires = 0;
|
||||
cap_expires(now, co);
|
||||
else if(curlx_str_casecompare(&name, "expires") && curlx_strlen(&val) &&
|
||||
!co->expires && (curlx_strlen(&val) < MAX_DATE_LENGTH)) {
|
||||
/*
|
||||
* Let max-age have priority.
|
||||
*
|
||||
* If the date cannot get parsed for whatever reason, the cookie
|
||||
* will be treated as a session cookie
|
||||
*/
|
||||
char dbuf[MAX_DATE_LENGTH + 1];
|
||||
time_t date = 0;
|
||||
memcpy(dbuf, curlx_str(&val), curlx_strlen(&val));
|
||||
dbuf[curlx_strlen(&val)] = 0;
|
||||
if(!Curl_getdate_capped(dbuf, &date)) {
|
||||
if(!date)
|
||||
date++;
|
||||
co->expires = (curl_off_t)date;
|
||||
}
|
||||
else
|
||||
co->expires = 0;
|
||||
if(!now)
|
||||
now = time(NULL);
|
||||
cap_expires(now, co);
|
||||
}
|
||||
|
||||
/*
|
||||
* Else, this is the second (or more) name we do not know about!
|
||||
*/
|
||||
}
|
||||
} while(!curlx_str_single(&ptr, ';'));
|
||||
|
||||
if(curlx_str_single(&ptr, ';'))
|
||||
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(curlx_strlen(&cookie[COOKIE_NAME])) {
|
||||
/* the header was fine, now store the data */
|
||||
result = storecookie(co, &cookie[0], path, domain);
|
||||
if(!result)
|
||||
*okay = TRUE;
|
||||
}
|
||||
|
||||
if(!co->path && path) {
|
||||
/*
|
||||
* No path was given in the header line, set the default.
|
||||
*/
|
||||
const char *endslash = strrchr(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 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;
|
||||
|
||||
return CERR_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_netscape(struct Cookie *co,
|
||||
struct CookieInfo *ci,
|
||||
const char *lineptr,
|
||||
bool secure) /* TRUE if connection is over secure
|
||||
origin */
|
||||
static CURLcode parse_netscape(struct Cookie *co,
|
||||
struct CookieInfo *ci,
|
||||
bool *okay,
|
||||
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
|
||||
@@ -767,6 +662,7 @@ parse_netscape(struct Cookie *co,
|
||||
const char *ptr, *next;
|
||||
int fields;
|
||||
size_t len;
|
||||
*okay = FALSE;
|
||||
|
||||
/*
|
||||
* In 2008, Internet Explorer introduced HTTP-only cookies to prevent XSS
|
||||
@@ -779,9 +675,9 @@ parse_netscape(struct Cookie *co,
|
||||
co->httponly = TRUE;
|
||||
}
|
||||
|
||||
if(lineptr[0]=='#')
|
||||
if(lineptr[0] == '#')
|
||||
/* do not even try the comments */
|
||||
return CERR_COMMENT;
|
||||
return CURLE_OK;
|
||||
|
||||
/*
|
||||
* Now loop through the fields and init the struct we already have
|
||||
@@ -794,13 +690,13 @@ parse_netscape(struct Cookie *co,
|
||||
next = (ptr[len] == '\t' ? &ptr[len + 1] : NULL);
|
||||
switch(fields) {
|
||||
case 0:
|
||||
if(ptr[0]=='.') { /* skip preceding dots */
|
||||
if(ptr[0] == '.') { /* skip preceding dots */
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
co->domain = Curl_memdup0(ptr, len);
|
||||
if(!co->domain)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
@@ -814,23 +710,17 @@ parse_netscape(struct Cookie *co,
|
||||
/* The file format allows the path field to remain not filled in */
|
||||
if(strncmp("TRUE", ptr, len) && strncmp("FALSE", ptr, len)) {
|
||||
/* only if the path does not look like a boolean option! */
|
||||
co->path = Curl_memdup0(ptr, len);
|
||||
co->path = sanitize_cookie_path(ptr, len);
|
||||
if(!co->path)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
else {
|
||||
co->spath = sanitize_cookie_path(co->path);
|
||||
if(!co->spath)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
}
|
||||
return CURLE_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;
|
||||
else {
|
||||
/* this does not look like a path, make one up! */
|
||||
co->path = curlx_strdup("/");
|
||||
if(!co->path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
fields++; /* add a field and fall down to secure */
|
||||
FALLTHROUGH();
|
||||
case 3:
|
||||
@@ -839,17 +729,17 @@ parse_netscape(struct Cookie *co,
|
||||
if(secure || ci->running)
|
||||
co->secure = TRUE;
|
||||
else
|
||||
return CERR_BAD_SECURE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(curlx_str_number(&ptr, &co->expires, CURL_OFF_T_MAX))
|
||||
return CERR_RANGE;
|
||||
return CURLE_OK;
|
||||
break;
|
||||
case 5:
|
||||
co->name = Curl_memdup0(ptr, len);
|
||||
if(!co->name)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
else {
|
||||
/* For Netscape file format cookies we check prefix on the name */
|
||||
if(curl_strnequal("__Secure-", co->name, 9))
|
||||
@@ -861,30 +751,30 @@ parse_netscape(struct Cookie *co,
|
||||
case 6:
|
||||
co->value = Curl_memdup0(ptr, len);
|
||||
if(!co->value)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fields == 6) {
|
||||
/* we got a cookie with blank contents, fix it */
|
||||
co->value = strdup("");
|
||||
co->value = curlx_strdup("");
|
||||
if(!co->value)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
fields++;
|
||||
}
|
||||
|
||||
if(fields != 7)
|
||||
/* we did not find the sufficient number of fields */
|
||||
return CERR_FIELDS;
|
||||
return CURLE_OK;
|
||||
|
||||
return CERR_OK;
|
||||
*okay = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
is_public_suffix(struct Curl_easy *data,
|
||||
struct Cookie *co,
|
||||
const char *domain)
|
||||
static bool is_public_suffix(struct Curl_easy *data,
|
||||
struct Cookie *co,
|
||||
const char *domain)
|
||||
{
|
||||
#ifdef USE_LIBPSL
|
||||
/*
|
||||
@@ -916,7 +806,7 @@ is_public_suffix(struct Curl_easy *data,
|
||||
if(!acceptable) {
|
||||
infof(data, "cookie '%s' dropped, domain '%s' must not "
|
||||
"set cookies for '%s'", co->name, domain, co->domain);
|
||||
return CERR_PSL;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -926,15 +816,15 @@ is_public_suffix(struct Curl_easy *data,
|
||||
DEBUGF(infof(data, "NO PSL to check set-cookie '%s' for domain=%s in %s",
|
||||
co->name, co->domain, domain));
|
||||
#endif
|
||||
return CERR_OK;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
replace_existing(struct Curl_easy *data,
|
||||
struct Cookie *co,
|
||||
struct CookieInfo *ci,
|
||||
bool secure,
|
||||
bool *replacep)
|
||||
/* returns TRUE when replaced */
|
||||
static bool 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;
|
||||
@@ -955,7 +845,7 @@ replace_existing(struct Curl_easy *data,
|
||||
matching_domains = TRUE;
|
||||
|
||||
if(matching_domains && /* the domains were identical */
|
||||
clist->spath && co->spath && /* both have paths */
|
||||
clist->path && co->path && /* both have paths */
|
||||
clist->secure && !co->secure && !secure) {
|
||||
size_t cllen;
|
||||
const char *sep = NULL;
|
||||
@@ -967,18 +857,18 @@ replace_existing(struct Curl_easy *data,
|
||||
* "/loginhelper" is ok.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(clist->spath[0]);
|
||||
if(clist->spath[0])
|
||||
sep = strchr(clist->spath + 1, '/');
|
||||
DEBUGASSERT(clist->path[0]);
|
||||
if(clist->path[0])
|
||||
sep = strchr(clist->path + 1, '/');
|
||||
if(sep)
|
||||
cllen = sep - clist->spath;
|
||||
cllen = sep - clist->path;
|
||||
else
|
||||
cllen = strlen(clist->spath);
|
||||
cllen = strlen(clist->path);
|
||||
|
||||
if(curl_strnequal(clist->spath, co->spath, cllen)) {
|
||||
if(curl_strnequal(clist->path, co->path, cllen)) {
|
||||
infof(data, "cookie '%s' for domain '%s' dropped, would "
|
||||
"overlay an existing cookie", co->name, co->domain);
|
||||
return CERR_BAD_SECURE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -988,7 +878,7 @@ replace_existing(struct Curl_easy *data,
|
||||
|
||||
if(clist->domain && co->domain) {
|
||||
if(curl_strequal(clist->domain, co->domain) &&
|
||||
(clist->tailmatch == co->tailmatch))
|
||||
(clist->tailmatch == co->tailmatch))
|
||||
/* The domains are identical */
|
||||
replace_old = TRUE;
|
||||
}
|
||||
@@ -998,10 +888,10 @@ replace_existing(struct Curl_easy *data,
|
||||
if(replace_old) {
|
||||
/* the domains were identical */
|
||||
|
||||
if(clist->spath && co->spath &&
|
||||
!curl_strequal(clist->spath, co->spath))
|
||||
if(clist->path && co->path &&
|
||||
!curl_strequal(clist->path, co->path))
|
||||
replace_old = FALSE;
|
||||
else if(!clist->spath != !co->spath)
|
||||
else if(!clist->path != !co->path)
|
||||
replace_old = FALSE;
|
||||
}
|
||||
|
||||
@@ -1012,7 +902,7 @@ replace_existing(struct Curl_easy *data,
|
||||
* was read from a file and thus is not "live". "live" cookies are
|
||||
* preferred so the new cookie is freed.
|
||||
*/
|
||||
return CERR_LIVE_WINS;
|
||||
return FALSE;
|
||||
}
|
||||
if(replace_old)
|
||||
replace_n = n;
|
||||
@@ -1028,10 +918,10 @@ replace_existing(struct Curl_easy *data,
|
||||
Curl_node_remove(replace_n);
|
||||
|
||||
/* free the old cookie */
|
||||
freecookie(repl);
|
||||
freecookie(repl, TRUE);
|
||||
}
|
||||
*replacep = replace_old;
|
||||
return CERR_OK;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1041,10 +931,8 @@ replace_existing(struct Curl_easy *data,
|
||||
* 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 *
|
||||
CURLcode
|
||||
Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *ci,
|
||||
bool httpheader, /* TRUE if HTTP header-style line */
|
||||
@@ -1056,27 +944,28 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
unless set */
|
||||
bool secure) /* TRUE if connection is over secure origin */
|
||||
{
|
||||
struct Cookie comem;
|
||||
struct Cookie *co;
|
||||
size_t myhash;
|
||||
int rc;
|
||||
CURLcode result;
|
||||
bool replaces = FALSE;
|
||||
bool okay;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(MAX_SET_COOKIE_AMOUNT <= 255); /* counter is an unsigned char */
|
||||
if(data->req.setcookies >= MAX_SET_COOKIE_AMOUNT)
|
||||
return NULL;
|
||||
return CURLE_OK; /* silently ignore */
|
||||
|
||||
/* 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 */
|
||||
co = &comem;
|
||||
memset(co, 0, sizeof(comem));
|
||||
|
||||
if(httpheader)
|
||||
rc = parse_cookie_header(data, co, ci, lineptr, domain, path, secure);
|
||||
result = parse_cookie_header(data, co, ci, &okay,
|
||||
lineptr, domain, path, secure);
|
||||
else
|
||||
rc = parse_netscape(co, ci, lineptr, secure);
|
||||
result = parse_netscape(co, ci, &okay, lineptr, secure);
|
||||
|
||||
if(rc)
|
||||
if(result || !okay)
|
||||
goto fail;
|
||||
|
||||
if(co->prefix_secure && !co->secure)
|
||||
@@ -1088,7 +977,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
* 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)
|
||||
if(co->secure && co->path && !strcmp(co->path, "/") && !co->tailmatch)
|
||||
;
|
||||
else
|
||||
goto fail;
|
||||
@@ -1115,9 +1004,17 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if(is_public_suffix(data, co, domain))
|
||||
goto fail;
|
||||
|
||||
if(replace_existing(data, co, ci, secure, &replaces))
|
||||
if(!replace_existing(data, co, ci, secure, &replaces))
|
||||
goto fail;
|
||||
|
||||
/* clone the stack struct into heap */
|
||||
co = Curl_memdup(&comem, sizeof(comem));
|
||||
if(!co) {
|
||||
co = &comem;
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto fail; /* bail out if we are this low on memory */
|
||||
}
|
||||
|
||||
/* add this cookie to the list */
|
||||
myhash = cookiehash(co->domain);
|
||||
Curl_llist_append(&ci->cookielist[myhash], co, &co->node);
|
||||
@@ -1126,7 +1023,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
/* 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,
|
||||
replaces ? "Replaced":"Added", co->name, co->value,
|
||||
replaces ? "Replaced" : "Added", co->name, co->value,
|
||||
co->domain, co->path, co->expires);
|
||||
|
||||
if(!replaces)
|
||||
@@ -1142,13 +1039,12 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if(httpheader)
|
||||
data->req.setcookies++;
|
||||
|
||||
return co;
|
||||
return result;
|
||||
fail:
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
freecookie(co, FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_cookie_init()
|
||||
*
|
||||
@@ -1161,91 +1057,129 @@ fail:
|
||||
* Note that 'data' might be called as NULL pointer. If data is NULL, 'file'
|
||||
* will be ignored.
|
||||
*
|
||||
* Returns NULL on out of memory. Invalid cookies are ignored.
|
||||
* Returns NULL on out of memory.
|
||||
*/
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *file,
|
||||
struct CookieInfo *ci,
|
||||
bool newsession)
|
||||
struct CookieInfo *Curl_cookie_init(void)
|
||||
{
|
||||
FILE *handle = NULL;
|
||||
int i;
|
||||
struct CookieInfo *ci = curlx_calloc(1, sizeof(struct CookieInfo));
|
||||
if(!ci)
|
||||
return NULL;
|
||||
|
||||
if(!ci) {
|
||||
int i;
|
||||
|
||||
/* we did not get a struct, create one */
|
||||
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.
|
||||
*/
|
||||
ci->next_expiration = CURL_OFF_T_MAX;
|
||||
}
|
||||
ci->newsession = newsession; /* new session? */
|
||||
|
||||
if(data) {
|
||||
FILE *fp = NULL;
|
||||
if(file && *file) {
|
||||
if(!strcmp(file, "-"))
|
||||
fp = stdin;
|
||||
else {
|
||||
fp = curlx_fopen(file, "rb");
|
||||
if(!fp)
|
||||
infof(data, "WARNING: failed to open cookie file \"%s\"", file);
|
||||
else
|
||||
handle = fp;
|
||||
}
|
||||
}
|
||||
|
||||
ci->running = FALSE; /* this is not running, this is init */
|
||||
if(fp) {
|
||||
struct dynbuf buf;
|
||||
bool eof = FALSE;
|
||||
CURLcode result;
|
||||
curlx_dyn_init(&buf, MAX_COOKIE_LINE);
|
||||
do {
|
||||
result = Curl_get_line(&buf, fp, &eof);
|
||||
if(!result) {
|
||||
const char *lineptr = curlx_dyn_ptr(&buf);
|
||||
bool headerline = FALSE;
|
||||
if(checkprefix("Set-Cookie:", lineptr)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr += 11;
|
||||
headerline = TRUE;
|
||||
curlx_str_passblanks(&lineptr);
|
||||
}
|
||||
|
||||
(void)Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL,
|
||||
NULL, TRUE);
|
||||
/* File reading cookie failures are not propagated back to the
|
||||
caller because there is no way to do that */
|
||||
}
|
||||
} while(!result && !eof);
|
||||
curlx_dyn_free(&buf); /* free the line buffer */
|
||||
|
||||
/*
|
||||
* Remove expired cookies from the hash. We must make sure to run this
|
||||
* after reading the file, and not on every cookie.
|
||||
*/
|
||||
remove_expired(ci);
|
||||
|
||||
if(handle)
|
||||
curlx_fclose(handle);
|
||||
}
|
||||
data->state.cookie_engine = TRUE;
|
||||
}
|
||||
ci->running = TRUE; /* now, we are running */
|
||||
/* 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.
|
||||
*/
|
||||
ci->next_expiration = CURL_OFF_T_MAX;
|
||||
|
||||
return ci;
|
||||
}
|
||||
|
||||
/*
|
||||
* cookie_load()
|
||||
*
|
||||
* Reads cookies from a local file. This is always called before any cookies
|
||||
* are set. If file is "-" then STDIN is read.
|
||||
*
|
||||
* If 'newsession' is TRUE, discard all "session cookies" on read from file.
|
||||
*
|
||||
*/
|
||||
static CURLcode cookie_load(struct Curl_easy *data, const char *file,
|
||||
struct CookieInfo *ci, bool newsession)
|
||||
{
|
||||
FILE *handle = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
FILE *fp = NULL;
|
||||
DEBUGASSERT(ci);
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(file);
|
||||
|
||||
ci->newsession = newsession; /* new session? */
|
||||
ci->running = FALSE; /* this is not running, this is init */
|
||||
|
||||
if(file && *file) {
|
||||
if(!strcmp(file, "-"))
|
||||
fp = stdin;
|
||||
else {
|
||||
fp = curlx_fopen(file, "rb");
|
||||
if(!fp)
|
||||
infof(data, "WARNING: failed to open cookie file \"%s\"", file);
|
||||
else
|
||||
handle = fp;
|
||||
}
|
||||
}
|
||||
|
||||
if(fp) {
|
||||
struct dynbuf buf;
|
||||
bool eof = FALSE;
|
||||
curlx_dyn_init(&buf, MAX_COOKIE_LINE);
|
||||
do {
|
||||
result = Curl_get_line(&buf, fp, &eof);
|
||||
if(!result) {
|
||||
const char *lineptr = curlx_dyn_ptr(&buf);
|
||||
bool headerline = FALSE;
|
||||
if(checkprefix("Set-Cookie:", lineptr)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr += 11;
|
||||
headerline = TRUE;
|
||||
curlx_str_passblanks(&lineptr);
|
||||
}
|
||||
|
||||
result = Curl_cookie_add(data, ci, headerline, TRUE, lineptr, NULL,
|
||||
NULL, TRUE);
|
||||
/* File reading cookie failures are not propagated back to the
|
||||
caller because there is no way to do that */
|
||||
}
|
||||
} while(!result && !eof);
|
||||
curlx_dyn_free(&buf); /* free the line buffer */
|
||||
|
||||
/*
|
||||
* Remove expired cookies from the hash. We must make sure to run this
|
||||
* after reading the file, and not on every cookie.
|
||||
*/
|
||||
remove_expired(ci);
|
||||
|
||||
if(handle)
|
||||
curlx_fclose(handle);
|
||||
}
|
||||
data->state.cookie_engine = TRUE;
|
||||
ci->running = TRUE; /* now, we are running */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
||||
*/
|
||||
CURLcode Curl_cookie_loadfiles(struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct curl_slist *list = data->state.cookielist;
|
||||
if(list) {
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
if(!data->cookies)
|
||||
data->cookies = Curl_cookie_init();
|
||||
if(!data->cookies)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else {
|
||||
data->state.cookie_engine = TRUE;
|
||||
while(list) {
|
||||
result = cookie_load(data, list->data, data->cookies,
|
||||
data->set.cookiesession);
|
||||
if(result)
|
||||
break;
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* cookie_sort
|
||||
*
|
||||
@@ -1300,7 +1234,7 @@ static int cookie_sort_ct(const void *p1, const void *p2)
|
||||
|
||||
bool Curl_secure_context(struct connectdata *conn, const char *host)
|
||||
{
|
||||
return conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) ||
|
||||
return conn->handler->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS) ||
|
||||
curl_strequal("localhost", host) ||
|
||||
!strcmp(host, "127.0.0.1") ||
|
||||
!strcmp(host, "::1");
|
||||
@@ -1315,12 +1249,13 @@ bool Curl_secure_context(struct connectdata *conn, const char *host)
|
||||
*
|
||||
* It shall only return cookies that have not expired.
|
||||
*
|
||||
* Returns 0 when there is a list returned. Otherwise non-zero.
|
||||
* 'okay' is TRUE when there is a list returned.
|
||||
*/
|
||||
int Curl_cookie_getlist(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const char *host,
|
||||
struct Curl_llist *list)
|
||||
CURLcode Curl_cookie_getlist(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *okay,
|
||||
const char *host,
|
||||
struct Curl_llist *list)
|
||||
{
|
||||
size_t matches = 0;
|
||||
const bool is_ip = Curl_host_is_ipnum(host);
|
||||
@@ -1329,17 +1264,18 @@ int Curl_cookie_getlist(struct Curl_easy *data,
|
||||
const bool secure = Curl_secure_context(conn, host);
|
||||
struct CookieInfo *ci = data->cookies;
|
||||
const char *path = data->state.up.path;
|
||||
CURLcode result = CURLE_OK;
|
||||
*okay = FALSE;
|
||||
|
||||
Curl_llist_init(list, NULL);
|
||||
|
||||
if(!ci || !Curl_llist_count(&ci->cookielist[myhash]))
|
||||
return 1; /* no cookie struct or no cookies in the struct */
|
||||
return CURLE_OK; /* no cookie struct or no cookies in the struct */
|
||||
|
||||
/* at first, remove expired cookies */
|
||||
remove_expired(ci);
|
||||
|
||||
for(n = Curl_llist_head(&ci->cookielist[myhash]);
|
||||
n; n = Curl_node_next(n)) {
|
||||
for(n = Curl_llist_head(&ci->cookielist[myhash]); n; n = Curl_node_next(n)) {
|
||||
struct Cookie *co = Curl_node_elem(n);
|
||||
|
||||
/* if the cookie requires we are secure we must only continue if we are! */
|
||||
@@ -1349,7 +1285,7 @@ int Curl_cookie_getlist(struct Curl_easy *data,
|
||||
if(!co->domain ||
|
||||
(co->tailmatch && !is_ip &&
|
||||
cookie_tailmatch(co->domain, strlen(co->domain), host)) ||
|
||||
((!co->tailmatch || is_ip) && curl_strequal(host, co->domain)) ) {
|
||||
((!co->tailmatch || is_ip) && curl_strequal(host, co->domain))) {
|
||||
/*
|
||||
* the right part of the host matches the domain stuff in the
|
||||
* cookie data
|
||||
@@ -1359,7 +1295,7 @@ int Curl_cookie_getlist(struct Curl_easy *data,
|
||||
* now check the left part of the path with the cookies path
|
||||
* requirement
|
||||
*/
|
||||
if(!co->spath || pathmatch(co->spath, path) ) {
|
||||
if(!co->path || pathmatch(co->path, path)) {
|
||||
|
||||
/*
|
||||
* This is a match and we add it to the return-linked-list
|
||||
@@ -1386,9 +1322,11 @@ int Curl_cookie_getlist(struct Curl_easy *data,
|
||||
size_t i;
|
||||
|
||||
/* alloc an array and store all cookie pointers */
|
||||
array = malloc(sizeof(struct Cookie *) * matches);
|
||||
if(!array)
|
||||
array = curlx_malloc(sizeof(struct Cookie *) * matches);
|
||||
if(!array) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
n = Curl_llist_head(list);
|
||||
|
||||
@@ -1404,15 +1342,16 @@ int Curl_cookie_getlist(struct Curl_easy *data,
|
||||
for(i = 0; i < matches; i++)
|
||||
Curl_llist_append(list, array[i], &array[i]->getnode);
|
||||
|
||||
free(array); /* remove the temporary data again */
|
||||
curlx_free(array); /* remove the temporary data again */
|
||||
}
|
||||
|
||||
return 0; /* success */
|
||||
*okay = TRUE;
|
||||
return CURLE_OK; /* success */
|
||||
|
||||
fail:
|
||||
/* failure, clear up the allocated chain and return NULL */
|
||||
Curl_llist_destroy(list, NULL);
|
||||
return 2; /* error */
|
||||
return result; /* error */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1430,7 +1369,7 @@ void Curl_cookie_clearall(struct CookieInfo *ci)
|
||||
struct Cookie *c = Curl_node_elem(n);
|
||||
struct Curl_llist_node *e = Curl_node_next(n);
|
||||
Curl_node_remove(n);
|
||||
freecookie(c);
|
||||
freecookie(c, TRUE);
|
||||
n = e;
|
||||
}
|
||||
}
|
||||
@@ -1459,7 +1398,7 @@ void Curl_cookie_clearsess(struct CookieInfo *ci)
|
||||
e = Curl_node_next(n); /* in case the node is removed, get it early */
|
||||
if(!curr->expires) {
|
||||
Curl_node_remove(n);
|
||||
freecookie(curr);
|
||||
freecookie(curr, TRUE);
|
||||
ci->numcookies--;
|
||||
}
|
||||
}
|
||||
@@ -1475,7 +1414,7 @@ void Curl_cookie_cleanup(struct CookieInfo *ci)
|
||||
{
|
||||
if(ci) {
|
||||
Curl_cookie_clearall(ci);
|
||||
free(ci); /* free the base struct as well */
|
||||
curlx_free(ci); /* free the base struct as well */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1489,14 +1428,14 @@ void Curl_cookie_cleanup(struct CookieInfo *ci)
|
||||
static char *get_netscape_format(const struct Cookie *co)
|
||||
{
|
||||
return curl_maprintf(
|
||||
"%s" /* httponly preamble */
|
||||
"%s%s\t" /* domain */
|
||||
"%s\t" /* tailmatch */
|
||||
"%s\t" /* path */
|
||||
"%s\t" /* secure */
|
||||
"%" FMT_OFF_T "\t" /* expires */
|
||||
"%s\t" /* name */
|
||||
"%s", /* value */
|
||||
"%s" /* httponly preamble */
|
||||
"%s%s\t" /* domain */
|
||||
"%s\t" /* tailmatch */
|
||||
"%s\t" /* path */
|
||||
"%s\t" /* secure */
|
||||
"%" FMT_OFF_T "\t" /* expires */
|
||||
"%s\t" /* name */
|
||||
"%s", /* value */
|
||||
co->httponly ? "#HttpOnly_" : "",
|
||||
/*
|
||||
* Make sure all domains are prefixed with a dot if they allow
|
||||
@@ -1558,7 +1497,7 @@ static CURLcode cookie_output(struct Curl_easy *data,
|
||||
struct Cookie **array;
|
||||
struct Curl_llist_node *n;
|
||||
|
||||
array = calloc(1, sizeof(struct Cookie *) * ci->numcookies);
|
||||
array = curlx_calloc(1, sizeof(struct Cookie *) * ci->numcookies);
|
||||
if(!array) {
|
||||
error = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
@@ -1566,8 +1505,7 @@ 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(n = Curl_llist_head(&ci->cookielist[i]); n;
|
||||
n = Curl_node_next(n)) {
|
||||
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;
|
||||
@@ -1580,21 +1518,21 @@ static CURLcode cookie_output(struct Curl_easy *data,
|
||||
for(i = 0; i < nvalid; i++) {
|
||||
char *format_ptr = get_netscape_format(array[i]);
|
||||
if(!format_ptr) {
|
||||
free(array);
|
||||
curlx_free(array);
|
||||
error = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
curl_mfprintf(out, "%s\n", format_ptr);
|
||||
free(format_ptr);
|
||||
curlx_free(format_ptr);
|
||||
}
|
||||
|
||||
free(array);
|
||||
curlx_free(array);
|
||||
}
|
||||
|
||||
if(!use_stdout) {
|
||||
curlx_fclose(out);
|
||||
out = NULL;
|
||||
if(tempstore && Curl_rename(tempstore, filename)) {
|
||||
if(tempstore && curlx_rename(tempstore, filename)) {
|
||||
error = CURLE_WRITE_ERROR;
|
||||
goto error;
|
||||
}
|
||||
@@ -1605,7 +1543,7 @@ static CURLcode cookie_output(struct Curl_easy *data,
|
||||
* no need to inspect the error, any error case should have jumped into the
|
||||
* error block below.
|
||||
*/
|
||||
free(tempstore);
|
||||
curlx_free(tempstore);
|
||||
return CURLE_OK;
|
||||
|
||||
error:
|
||||
@@ -1613,7 +1551,7 @@ error:
|
||||
curlx_fclose(out);
|
||||
if(tempstore) {
|
||||
unlink(tempstore);
|
||||
free(tempstore);
|
||||
curlx_free(tempstore);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
@@ -1645,7 +1583,7 @@ static struct curl_slist *cookie_list(struct Curl_easy *data)
|
||||
}
|
||||
beg = Curl_slist_append_nodup(list, line);
|
||||
if(!beg) {
|
||||
free(line);
|
||||
curlx_free(line);
|
||||
curl_slist_free_all(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1667,26 +1605,35 @@ struct curl_slist *Curl_cookie_list(struct Curl_easy *data)
|
||||
|
||||
void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
|
||||
{
|
||||
CURLcode res;
|
||||
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
/* only save the cookie file if a transfer was started (data->state.url is
|
||||
/* only save the cookie file if a transfer was started (cookies->running is
|
||||
set), as otherwise the cookies were not completely initialized and there
|
||||
might be cookie files that weren't loaded so saving the file is the wrong
|
||||
thing. */
|
||||
if(data->set.str[STRING_COOKIEJAR] && data->state.url) {
|
||||
/* if we have a destination file for all the cookies to get dumped to */
|
||||
res = cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]);
|
||||
if(res)
|
||||
infof(data, "WARNING: failed to save cookies in %s: %s",
|
||||
data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res));
|
||||
}
|
||||
might be cookie files that were not loaded so saving the file is the
|
||||
wrong thing. */
|
||||
if(data->cookies) {
|
||||
if(data->set.str[STRING_COOKIEJAR] && data->cookies->running) {
|
||||
/* if we have a destination file for all the cookies to get dumped to */
|
||||
CURLcode result = cookie_output(data, data->cookies,
|
||||
data->set.str[STRING_COOKIEJAR]);
|
||||
if(result)
|
||||
infof(data, "WARNING: failed to save cookies in %s: %s",
|
||||
data->set.str[STRING_COOKIEJAR], curl_easy_strerror(result));
|
||||
}
|
||||
|
||||
if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
|
||||
Curl_cookie_cleanup(data->cookies);
|
||||
data->cookies = NULL;
|
||||
if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
|
||||
Curl_cookie_cleanup(data->cookies);
|
||||
data->cookies = NULL;
|
||||
}
|
||||
}
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
|
||||
void Curl_cookie_run(struct Curl_easy *data)
|
||||
{
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
if(data->cookies)
|
||||
data->cookies->running = TRUE;
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
|
||||
+33
-35
@@ -25,34 +25,31 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "llist.h"
|
||||
|
||||
struct Cookie {
|
||||
struct Curl_llist_node node; /* for the main cookie list */
|
||||
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> */
|
||||
unsigned 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 */
|
||||
char *name; /* <this> = value */
|
||||
char *value; /* name = <this> */
|
||||
char *path; /* canonical path */
|
||||
char *domain; /* domain = <this> */
|
||||
curl_off_t expires; /* expires = <this> */
|
||||
unsigned 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 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 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Available cookie prefixes, as defined in
|
||||
* draft-ietf-httpbis-rfc6265bis-02
|
||||
*/
|
||||
#define COOKIE_PREFIX__SECURE (1<<0)
|
||||
#define COOKIE_PREFIX__HOST (1<<1)
|
||||
#define COOKIE_PREFIX__SECURE (1 << 0)
|
||||
#define COOKIE_PREFIX__HOST (1 << 1)
|
||||
|
||||
#define COOKIE_HASH_SIZE 63
|
||||
|
||||
@@ -60,9 +57,9 @@ struct CookieInfo {
|
||||
/* 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 */
|
||||
unsigned int numcookies; /* number of cookies in the "jar" */
|
||||
unsigned int lastct; /* last creation-time used in the jar */
|
||||
BIT(running); /* state info, for cookie adding information */
|
||||
unsigned int numcookies; /* number of cookies in the "jar" */
|
||||
unsigned int lastct; /* last creation-time used in the jar */
|
||||
BIT(running); /* state info, for cookie adding information */
|
||||
BIT(newsession); /* new session, discard session cookies on load */
|
||||
};
|
||||
|
||||
@@ -113,30 +110,31 @@ struct connectdata;
|
||||
*/
|
||||
|
||||
bool Curl_secure_context(struct connectdata *conn, const char *host);
|
||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *c, bool header,
|
||||
bool noexpiry, const char *lineptr,
|
||||
const char *domain, const char *path,
|
||||
bool secure);
|
||||
int Curl_cookie_getlist(struct Curl_easy *data, struct connectdata *conn,
|
||||
const char *host, struct Curl_llist *list);
|
||||
CURLcode Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *c, bool header,
|
||||
bool noexpiry, const char *lineptr,
|
||||
const char *domain, const char *path,
|
||||
bool secure) WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_cookie_getlist(struct Curl_easy *data, struct connectdata *conn,
|
||||
bool *okay, const char *host,
|
||||
struct Curl_llist *list) WARN_UNUSED_RESULT;
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
||||
#define Curl_cookie_list(x) NULL
|
||||
#define Curl_cookie_loadfiles(x) Curl_nop_stmt
|
||||
#define Curl_cookie_init(x,y,z,w) NULL
|
||||
#define Curl_cookie_loadfiles(x) CURLE_OK
|
||||
#define Curl_cookie_init() NULL
|
||||
#define Curl_cookie_run(x) Curl_nop_stmt
|
||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x,y) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x, y) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_flush_cookies(struct Curl_easy *data, bool cleanup);
|
||||
void Curl_cookie_cleanup(struct CookieInfo *c);
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *file, struct CookieInfo *inc,
|
||||
bool newsession);
|
||||
struct CookieInfo *Curl_cookie_init(void);
|
||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data);
|
||||
CURLcode Curl_cookie_loadfiles(struct Curl_easy *data) WARN_UNUSED_RESULT;
|
||||
void Curl_cookie_run(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_COOKIE_H */
|
||||
+20
-45
@@ -22,30 +22,21 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "cfilters.h"
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "multi_ev.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "cshutdn.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "curlx/strparse.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
static void cshutdn_run_conn_handler(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
@@ -123,7 +114,6 @@ void Curl_cshutdn_run_once(struct Curl_easy *data,
|
||||
Curl_detach_connection(data);
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_terminate(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool do_shutdown)
|
||||
@@ -231,15 +221,12 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void cshutdn_perform(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_llist_node *e = Curl_llist_head(&cshutdn->list);
|
||||
struct Curl_llist_node *enext;
|
||||
struct connectdata *conn;
|
||||
struct curltime *nowp = NULL;
|
||||
struct curltime now;
|
||||
timediff_t next_expire_ms = 0, ms;
|
||||
bool done;
|
||||
|
||||
@@ -259,11 +246,7 @@ static void cshutdn_perform(struct cshutdn *cshutdn,
|
||||
else {
|
||||
/* idata has one timer list, but maybe more than one connection.
|
||||
* Set EXPIRE_SHUTDOWN to the smallest time left for all. */
|
||||
if(!nowp) {
|
||||
now = curlx_now();
|
||||
nowp = &now;
|
||||
}
|
||||
ms = Curl_conn_shutdown_timeleft(conn, nowp);
|
||||
ms = Curl_conn_shutdown_timeleft(data, conn);
|
||||
if(ms && ms < next_expire_ms)
|
||||
next_expire_ms = ms;
|
||||
}
|
||||
@@ -271,15 +254,14 @@ static void cshutdn_perform(struct cshutdn *cshutdn,
|
||||
}
|
||||
|
||||
if(next_expire_ms)
|
||||
Curl_expire_ex(data, nowp, next_expire_ms, EXPIRE_SHUTDOWN);
|
||||
Curl_expire_ex(data, next_expire_ms, EXPIRE_SHUTDOWN);
|
||||
}
|
||||
|
||||
|
||||
static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
int timeout_ms)
|
||||
{
|
||||
struct curltime started = curlx_now();
|
||||
struct curltime started = *Curl_pgrs_now(data);
|
||||
struct Curl_llist_node *e;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
@@ -291,7 +273,7 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
|
||||
while(Curl_llist_head(&cshutdn->list)) {
|
||||
timediff_t timespent;
|
||||
timediff_t spent_ms;
|
||||
int remain_ms;
|
||||
|
||||
cshutdn_perform(cshutdn, data);
|
||||
@@ -302,14 +284,14 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
||||
}
|
||||
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
timespent = curlx_timediff(curlx_now(), started);
|
||||
if(timespent >= (timediff_t)timeout_ms) {
|
||||
spent_ms = curlx_ptimediff_ms(Curl_pgrs_now(data), &started);
|
||||
if(spent_ms >= (timediff_t)timeout_ms) {
|
||||
CURL_TRC_M(data, "[SHUTDOWN] shutdown finished, %s",
|
||||
(timeout_ms > 0) ? "timeout" : "best effort done");
|
||||
(timeout_ms > 0) ? "timeout" : "best effort done");
|
||||
break;
|
||||
}
|
||||
|
||||
remain_ms = timeout_ms - (int)timespent;
|
||||
remain_ms = timeout_ms - (int)spent_ms;
|
||||
if(cshutdn_wait(cshutdn, data, remain_ms)) {
|
||||
CURL_TRC_M(data, "[SHUTDOWN] shutdown finished, aborted");
|
||||
break;
|
||||
@@ -329,7 +311,6 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn,
|
||||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
|
||||
|
||||
int Curl_cshutdn_init(struct cshutdn *cshutdn,
|
||||
struct Curl_multi *multi)
|
||||
{
|
||||
@@ -340,7 +321,6 @@ int Curl_cshutdn_init(struct cshutdn *cshutdn,
|
||||
return 0; /* good */
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_destroy(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
@@ -392,7 +372,6 @@ size_t Curl_cshutdn_dest_count(struct Curl_easy *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
@@ -408,14 +387,12 @@ static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn,
|
||||
return mresult;
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_add(struct cshutdn *cshutdn,
|
||||
struct connectdata *conn,
|
||||
size_t conns_in_pool)
|
||||
{
|
||||
struct Curl_easy *data = cshutdn->multi->admin;
|
||||
size_t max_total = (cshutdn->multi->max_total_connections > 0) ?
|
||||
(size_t)cshutdn->multi->max_total_connections : 0;
|
||||
size_t max_total = cshutdn->multi->max_total_connections;
|
||||
|
||||
/* Add the connection to our shutdown list for non-blocking shutdown
|
||||
* during multi processing. */
|
||||
@@ -441,7 +418,6 @@ void Curl_cshutdn_add(struct cshutdn *cshutdn,
|
||||
conn->connection_id, Curl_llist_count(&cshutdn->list));
|
||||
}
|
||||
|
||||
|
||||
static void cshutdn_multi_socket(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t s)
|
||||
@@ -466,7 +442,6 @@ static void cshutdn_multi_socket(struct cshutdn *cshutdn,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Curl_cshutdn_perform(struct cshutdn *cshutdn,
|
||||
struct Curl_easy *data,
|
||||
curl_socket_t s)
|
||||
@@ -488,8 +463,7 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn,
|
||||
struct easy_pollset ps;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) {
|
||||
unsigned int i;
|
||||
struct connectdata *conn = Curl_node_elem(e);
|
||||
CURLcode result;
|
||||
@@ -503,20 +477,23 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn,
|
||||
continue;
|
||||
|
||||
for(i = 0; i < ps.n; i++) {
|
||||
curl_socket_t sock = ps.sockets[i];
|
||||
if(!FDSET_SOCK(sock))
|
||||
continue;
|
||||
#ifdef __DJGPP__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warith-conversion"
|
||||
#endif
|
||||
if(ps.actions[i] & CURL_POLL_IN)
|
||||
FD_SET(ps.sockets[i], read_fd_set);
|
||||
FD_SET(sock, read_fd_set);
|
||||
if(ps.actions[i] & CURL_POLL_OUT)
|
||||
FD_SET(ps.sockets[i], write_fd_set);
|
||||
FD_SET(sock, write_fd_set);
|
||||
#ifdef __DJGPP__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
if((ps.actions[i] & (CURL_POLL_OUT | CURL_POLL_IN)) &&
|
||||
((int)ps.sockets[i] > *maxfd))
|
||||
*maxfd = (int)ps.sockets[i];
|
||||
((int)sock > *maxfd))
|
||||
*maxfd = (int)sock;
|
||||
}
|
||||
}
|
||||
Curl_pollset_cleanup(&ps);
|
||||
@@ -537,8 +514,7 @@ unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn,
|
||||
CURLcode result;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) {
|
||||
conn = Curl_node_elem(e);
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
@@ -565,8 +541,7 @@ CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn,
|
||||
struct connectdata *conn;
|
||||
|
||||
Curl_pollset_init(&ps);
|
||||
for(e = Curl_llist_head(&cshutdn->list); e;
|
||||
e = Curl_node_next(e)) {
|
||||
for(e = Curl_llist_head(&cshutdn->list); e; e = Curl_node_next(e)) {
|
||||
conn = Curl_node_elem(e);
|
||||
Curl_pollset_reset(&ps);
|
||||
Curl_attach_connection(data, conn);
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curlx/timeval.h"
|
||||
|
||||
struct connectdata;
|
||||
struct Curl_easy;
|
||||
struct curl_pollfds;
|
||||
|
||||
+55
-59
@@ -21,11 +21,8 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
@@ -47,16 +44,11 @@
|
||||
# include <inet.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stddef.h> /* for offsetof() */
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "fake_addrinfo.h"
|
||||
#include "curlx/inet_pton.h"
|
||||
#include "curlx/warnless.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_freeaddrinfo()
|
||||
@@ -68,26 +60,24 @@
|
||||
*/
|
||||
|
||||
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
|
||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
||||
defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
|
||||
/* workaround icc 9.1 optimizer issue */
|
||||
# define vqualifier volatile
|
||||
#else
|
||||
# define vqualifier
|
||||
#endif
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
||||
void Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
||||
{
|
||||
struct Curl_addrinfo *vqualifier canext;
|
||||
struct Curl_addrinfo *ca;
|
||||
|
||||
for(ca = cahead; ca; ca = canext) {
|
||||
canext = ca->ai_next;
|
||||
free(ca);
|
||||
curlx_free(ca);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
/*
|
||||
* Curl_getaddrinfo_ex()
|
||||
@@ -102,12 +92,10 @@ Curl_freeaddrinfo(struct Curl_addrinfo *cahead)
|
||||
* There should be no single call to system's getaddrinfo() in the
|
||||
* whole library, any such call should be 'routed' through this one.
|
||||
*/
|
||||
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct Curl_addrinfo **result)
|
||||
int Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct Curl_addrinfo **result)
|
||||
{
|
||||
const struct addrinfo *ai;
|
||||
struct addrinfo *aihead;
|
||||
@@ -146,7 +134,7 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
ca = malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
ca = curlx_malloc(sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
@@ -180,7 +168,6 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
if(calast)
|
||||
calast->ai_next = ca;
|
||||
calast = ca;
|
||||
|
||||
}
|
||||
|
||||
/* destroy the addrinfo list */
|
||||
@@ -212,7 +199,6 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
}
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
|
||||
/*
|
||||
* Curl_he2ai()
|
||||
*
|
||||
@@ -252,10 +238,8 @@ 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)
|
||||
struct Curl_addrinfo *Curl_he2ai(const struct hostent *he, int port)
|
||||
{
|
||||
struct Curl_addrinfo *ai;
|
||||
struct Curl_addrinfo *prevai = NULL;
|
||||
@@ -285,7 +269,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
|
||||
/* allocate memory to hold the struct, the address and the name */
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + ss_size + namelen);
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
@@ -347,16 +331,15 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_ip2addr()
|
||||
* ip2addr()
|
||||
*
|
||||
* This function takes an Internet address, in binary form, as input parameter
|
||||
* along with its address family and the string version of the address, and it
|
||||
* returns a Curl_addrinfo chain filled in correctly with information for the
|
||||
* given address/host
|
||||
*/
|
||||
|
||||
struct Curl_addrinfo *
|
||||
Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
static CURLcode ip2addr(struct Curl_addrinfo **addrp, int af,
|
||||
const void *inaddr, const char *hostname, int port)
|
||||
{
|
||||
struct Curl_addrinfo *ai;
|
||||
size_t addrsize;
|
||||
@@ -369,6 +352,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
DEBUGASSERT(inaddr && hostname);
|
||||
|
||||
namelen = strlen(hostname) + 1;
|
||||
*addrp = NULL;
|
||||
|
||||
if(af == AF_INET)
|
||||
addrsize = sizeof(struct sockaddr_in);
|
||||
@@ -377,12 +361,12 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
addrsize = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
/* allocate memory to hold the struct, the address and the name */
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen);
|
||||
ai = curlx_calloc(1, sizeof(struct Curl_addrinfo) + addrsize + namelen);
|
||||
if(!ai)
|
||||
return NULL;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
/* put the address after the struct */
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
/* then put the name after the address */
|
||||
@@ -412,29 +396,46 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ai;
|
||||
*addrp = ai;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an IPv4 or IPv6 dotted string address, this converts it to a proper
|
||||
* allocated Curl_addrinfo struct and returns it.
|
||||
*/
|
||||
struct Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
CURLcode Curl_str2addr(const char *address, int port,
|
||||
struct Curl_addrinfo **addrp)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(curlx_inet_pton(AF_INET, address, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, address, port);
|
||||
return ip2addr(addrp, AF_INET, &in, address, port);
|
||||
#ifdef USE_IPV6
|
||||
{
|
||||
struct in6_addr in6;
|
||||
if(curlx_inet_pton(AF_INET6, address, &in6) > 0)
|
||||
/* This is a dotted IPv6 address ::1-style */
|
||||
return Curl_ip2addr(AF_INET6, &in6, address, port);
|
||||
return ip2addr(addrp, AF_INET6, &in6, address, port);
|
||||
}
|
||||
#endif
|
||||
return NULL; /* bad input format */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT; /* bad input format */
|
||||
}
|
||||
|
||||
bool Curl_is_ipaddr(const char *address)
|
||||
{
|
||||
struct in_addr in;
|
||||
if(curlx_inet_pton(AF_INET, address, &in) > 0)
|
||||
return TRUE;
|
||||
#ifdef USE_IPV6
|
||||
{
|
||||
struct in6_addr in6;
|
||||
if(curlx_inet_pton(AF_INET6, address, &in6) > 0)
|
||||
/* This is a dotted IPv6 address ::1-style */
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
@@ -452,18 +453,19 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
|
||||
ai = curlx_calloc(1,
|
||||
sizeof(struct Curl_addrinfo) + sizeof(struct sockaddr_un));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
ai->ai_addr = (void *)((char *)ai + sizeof(struct Curl_addrinfo));
|
||||
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un = (void *)ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
|
||||
/* sun_path must be able to store the null-terminated path */
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai);
|
||||
curlx_free(ai);
|
||||
*longpath = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
@@ -492,10 +494,8 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I did not want to include in memdebug.c
|
||||
*/
|
||||
|
||||
void
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
void curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
{
|
||||
curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n",
|
||||
source, line, (void *)freethis);
|
||||
@@ -517,7 +517,6 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
}
|
||||
#endif /* CURLDEBUG && HAVE_FREEADDRINFO */
|
||||
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
/*
|
||||
* curl_dbg_getaddrinfo()
|
||||
@@ -526,13 +525,11 @@ curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
* require a bunch of structs I did not want to include in memdebug.c
|
||||
*/
|
||||
|
||||
int
|
||||
curl_dbg_getaddrinfo(const char *hostname,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source)
|
||||
int curl_dbg_getaddrinfo(const char *hostname,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source)
|
||||
{
|
||||
#ifdef USE_LWIPSOCK
|
||||
int res = lwip_getaddrinfo(hostname, service, hints, result);
|
||||
@@ -550,11 +547,10 @@ curl_dbg_getaddrinfo(const char *hostname,
|
||||
#endif
|
||||
if(res == 0)
|
||||
/* success */
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, (void *)*result);
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n", source, line,
|
||||
(void *)*result);
|
||||
else
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n",
|
||||
source, line);
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n", source, line);
|
||||
return res;
|
||||
}
|
||||
#endif /* CURLDEBUG && HAVE_GETADDRINFO */
|
||||
|
||||
+16
-22
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
@@ -60,26 +59,21 @@ struct Curl_addrinfo {
|
||||
struct Curl_addrinfo *ai_next;
|
||||
};
|
||||
|
||||
void
|
||||
Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
|
||||
void Curl_freeaddrinfo(struct Curl_addrinfo *cahead);
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
int
|
||||
Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct Curl_addrinfo **result);
|
||||
int Curl_getaddrinfo_ex(const char *nodename,
|
||||
const char *servname,
|
||||
const struct addrinfo *hints,
|
||||
struct Curl_addrinfo **result);
|
||||
#endif
|
||||
|
||||
#if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETADDRINFO_THREADSAFE))
|
||||
struct Curl_addrinfo *
|
||||
Curl_he2ai(const struct hostent *he, int port);
|
||||
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);
|
||||
|
||||
struct Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
bool Curl_is_ipaddr(const char *address);
|
||||
CURLcode Curl_str2addr(const char *dotted, int port, struct Curl_addrinfo **);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
@@ -87,23 +81,23 @@ struct Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath,
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
void
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source);
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
void curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line,
|
||||
const char *source);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
int
|
||||
curl_dbg_getaddrinfo(const char *hostname, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **result,
|
||||
int line, const char *source);
|
||||
int curl_dbg_getaddrinfo(const char *hostname, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result, int line,
|
||||
const char *source);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#ifdef USE_RESOLVE_ON_IPS
|
||||
void Curl_addrinfo_set_port(struct Curl_addrinfo *addrinfo, int port);
|
||||
#else
|
||||
#define Curl_addrinfo_set_port(x,y)
|
||||
#define Curl_addrinfo_set_port(x, y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
/* disabled WebSocket */
|
||||
#cmakedefine CURL_DISABLE_WEBSOCKETS 1
|
||||
|
||||
/* disables use of socketpair for curl_multi_poll */
|
||||
/* disables use of socketpair for curl_multi_poll() */
|
||||
#cmakedefine CURL_DISABLE_SOCKETPAIR 1
|
||||
|
||||
/* disables TELNET */
|
||||
@@ -160,6 +160,9 @@
|
||||
/* disables TFTP */
|
||||
#cmakedefine CURL_DISABLE_TFTP 1
|
||||
|
||||
/* disables curl_easy_setopt()/curl_easy_getinfo() type checking */
|
||||
#cmakedefine CURL_DISABLE_TYPECHECK 1
|
||||
|
||||
/* disables verbose strings */
|
||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
||||
|
||||
@@ -388,6 +391,9 @@
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#cmakedefine HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have a working localtime_r function. */
|
||||
#cmakedefine HAVE_LOCALTIME_R 1
|
||||
|
||||
/* Define to 1 if the compiler supports the 'long long' data type. */
|
||||
#cmakedefine HAVE_LONGLONG 1
|
||||
|
||||
@@ -727,6 +733,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* Define to 1 if you have the <uv.h> header file. */
|
||||
#cmakedefine HAVE_UV_H 1
|
||||
|
||||
/* if libbacktrace is in use */
|
||||
#cmakedefine USE_BACKTRACE 1
|
||||
|
||||
/* Define to 1 if you do not want the OpenSSL configuration to be loaded
|
||||
automatically */
|
||||
#cmakedefine CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG 1
|
||||
@@ -755,9 +764,6 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS 1
|
||||
|
||||
/* Define to 1 if you are building a Windows target with large file support. */
|
||||
#cmakedefine USE_WIN32_LARGE_FILES 1
|
||||
|
||||
/* to enable SSPI support */
|
||||
#cmakedefine USE_WINDOWS_SSPI 1
|
||||
|
||||
+4
-4
@@ -25,17 +25,17 @@
|
||||
***************************************************************************/
|
||||
|
||||
#define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f'))
|
||||
#define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F'))
|
||||
#define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F'))
|
||||
|
||||
#define ISLOWCNTRL(x) ((unsigned char)(x) <= 0x1f)
|
||||
#define IS7F(x) ((x) == 0x7f)
|
||||
#define IS7F(x) ((x) == 0x7f)
|
||||
|
||||
#define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d))
|
||||
|
||||
#define ISPRINT(x) (ISLOWPRINT(x) || (((x) >= ' ') && ((x) <= 0x7e)))
|
||||
#define ISGRAPH(x) (ISLOWPRINT(x) || (((x) > ' ') && ((x) <= 0x7e)))
|
||||
#define ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x))
|
||||
#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
|
||||
#define ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x))
|
||||
#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
|
||||
#define ISXDIGIT(x) (ISDIGIT(x) || ISLOWHEXALHA(x) || ISUPHEXALHA(x))
|
||||
#define ISODIGIT(x) (((x) >= '0') && ((x) <= '7'))
|
||||
#define ISALNUM(x) (ISDIGIT(x) || ISLOWER(x) || ISUPPER(x))
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_endian.h"
|
||||
|
||||
+6
-11
@@ -21,16 +21,11 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_fnmatch.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifndef HAVE_FNMATCH
|
||||
|
||||
@@ -243,7 +238,7 @@ static int setcharset(const unsigned char **p, unsigned char *charset)
|
||||
case CURLFNM_SCHS_RIGHTBRLEFTBR:
|
||||
if(c == ']')
|
||||
return SETCHARSET_OK;
|
||||
state = CURLFNM_SCHS_DEFAULT;
|
||||
state = CURLFNM_SCHS_DEFAULT;
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
break;
|
||||
@@ -361,7 +356,8 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||
return loop((const unsigned char *)pattern,
|
||||
(const unsigned char *)string, 2);
|
||||
}
|
||||
#else
|
||||
#else /* HAVE_FNMATCH */
|
||||
|
||||
#include <fnmatch.h>
|
||||
/*
|
||||
* @unittest: 1307
|
||||
@@ -384,7 +380,6 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
#endif /* !HAVE_FNMATCH */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* if FTP is disabled */
|
||||
#endif /* !CURL_DISABLE_FTP */
|
||||
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#define CURL_FNMATCH_MATCH 0
|
||||
#define CURL_FNMATCH_NOMATCH 1
|
||||
#define CURL_FNMATCH_FAIL 2
|
||||
|
||||
+16
-21
@@ -21,7 +21,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
|
||||
@@ -31,10 +30,6 @@
|
||||
#include "rand.h"
|
||||
#include "curl_fopen.h"
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
The dirslash() function breaks a null-terminated pathname string into
|
||||
directory and filename components then returns the directory component up
|
||||
@@ -66,10 +61,10 @@ static char *dirslash(const char *path)
|
||||
n = strlen(path);
|
||||
if(n) {
|
||||
/* find the rightmost path separator, if any */
|
||||
while(n && !IS_SEP(path[n-1]))
|
||||
while(n && !IS_SEP(path[n - 1]))
|
||||
--n;
|
||||
/* skip over all the path separators, if any */
|
||||
while(n && IS_SEP(path[n-1]))
|
||||
while(n && IS_SEP(path[n - 1]))
|
||||
--n;
|
||||
}
|
||||
if(curlx_dyn_addn(&out, path, n))
|
||||
@@ -93,25 +88,22 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
CURLcode result = CURLE_WRITE_ERROR;
|
||||
unsigned char randbuf[41];
|
||||
char *tempstore = NULL;
|
||||
#ifndef _WIN32
|
||||
struct_stat sb;
|
||||
#endif
|
||||
int fd = -1;
|
||||
char *dir = NULL;
|
||||
*tempname = NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
*fh = curlx_fopen(filename, FOPEN_WRITETEXT);
|
||||
if(!*fh)
|
||||
goto fail;
|
||||
if(
|
||||
#ifdef UNDER_CE
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
stat(filename, &sb) == -1
|
||||
#else
|
||||
fstat(fileno(*fh), &sb) == -1
|
||||
#endif
|
||||
|| !S_ISREG(sb.st_mode)) {
|
||||
if(fstat(fileno(*fh), &sb) == -1 || !S_ISREG(sb.st_mode)) {
|
||||
return CURLE_OK;
|
||||
}
|
||||
curlx_fclose(*fh);
|
||||
#endif
|
||||
*fh = NULL;
|
||||
|
||||
result = Curl_rand_alnum(data, randbuf, sizeof(randbuf));
|
||||
@@ -123,7 +115,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
/* The temp filename should not end up too long for the target file
|
||||
system */
|
||||
tempstore = curl_maprintf("%s%s.tmp", dir, randbuf);
|
||||
free(dir);
|
||||
curlx_free(dir);
|
||||
}
|
||||
|
||||
if(!tempstore) {
|
||||
@@ -132,13 +124,16 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
}
|
||||
|
||||
result = CURLE_WRITE_ERROR;
|
||||
#if (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
#ifdef _WIN32
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
S_IREAD | S_IWRITE);
|
||||
#elif (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
(defined(__i386__) || defined(__arm__))
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
(mode_t)(0600 | sb.st_mode));
|
||||
(mode_t)(S_IRUSR | S_IWUSR | sb.st_mode));
|
||||
#else
|
||||
fd = curlx_open(tempstore, O_WRONLY | O_CREAT | O_EXCL,
|
||||
0600 | sb.st_mode);
|
||||
S_IRUSR | S_IWUSR | sb.st_mode);
|
||||
#endif
|
||||
if(fd == -1)
|
||||
goto fail;
|
||||
@@ -156,8 +151,8 @@ fail:
|
||||
unlink(tempstore);
|
||||
}
|
||||
|
||||
free(tempstore);
|
||||
curlx_free(tempstore);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* ! disabled */
|
||||
#endif /* !disabled */
|
||||
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curlx/fopen.h"
|
||||
|
||||
CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
|
||||
|
||||
+2
-7
@@ -21,19 +21,14 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
|
||||
!defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC)
|
||||
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#define appendnl(b) \
|
||||
curlx_dyn_addn(buf, "\n", 1)
|
||||
#define appendnl(b) curlx_dyn_addn(buf, "\n", 1)
|
||||
|
||||
/*
|
||||
* Curl_get_line() returns only complete whole lines that end with newline.
|
||||
@@ -60,7 +55,7 @@ CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof)
|
||||
/* now check the full line */
|
||||
rlen = curlx_dyn_len(buf);
|
||||
b = curlx_dyn_ptr(buf);
|
||||
if(rlen && (b[rlen-1] == '\n'))
|
||||
if(rlen && (b[rlen - 1] == '\n'))
|
||||
/* LF at end of the line */
|
||||
return CURLE_OK; /* all good */
|
||||
if(*eof)
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curlx/dynbuf.h"
|
||||
|
||||
/* Curl_get_line() returns complete lines that end with a newline. */
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_gethostname.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
/*
|
||||
* Curl_gethostname() is a wrapper around gethostname() which allows
|
||||
@@ -60,9 +60,9 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
const char *force_hostname = getenv("CURL_GETHOSTNAME");
|
||||
if(force_hostname) {
|
||||
if(strlen(force_hostname) < (size_t)namelen)
|
||||
strcpy(name, force_hostname);
|
||||
curlx_strcopy(name, namelen, force_hostname, strlen(force_hostname));
|
||||
else
|
||||
return 1; /* can't do it */
|
||||
return 1; /* cannot do it */
|
||||
err = 0;
|
||||
}
|
||||
else {
|
||||
@@ -93,5 +93,4 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
+17
-22
@@ -21,20 +21,18 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_trc.h"
|
||||
#include "curlx/strcopy.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
||||
/* To avoid memdebug macro replacement, wrap the name in parentheses to call
|
||||
the original version. It is freed via the GSS API gss_release_buffer(). */
|
||||
#define Curl_gss_alloc (malloc)
|
||||
#define Curl_gss_free (free)
|
||||
#define Curl_gss_alloc malloc /* freed via the GSS API gss_release_buffer() */
|
||||
#define Curl_gss_free free /* pair of the above */
|
||||
#define CURL_GSS_STUB
|
||||
/* For correctness this would be required for all platforms, not only Windows,
|
||||
but, as of v1.22.1, MIT Kerberos uses a special allocator only for Windows,
|
||||
@@ -51,10 +49,6 @@
|
||||
#endif
|
||||
#endif /* DEBUGBUILD */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CURL_ALIGN8 __attribute__((aligned(8)))
|
||||
#else
|
||||
@@ -160,7 +154,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
}
|
||||
|
||||
/* Server response, either D (RA==) or C (Qw==) */
|
||||
if(((char *) input_token->value)[0] == 'D') {
|
||||
if(((char *)input_token->value)[0] == 'D') {
|
||||
/* Done */
|
||||
switch(ctx->sent) {
|
||||
case STUB_GSS_KRB5:
|
||||
@@ -176,7 +170,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
}
|
||||
}
|
||||
|
||||
if(((char *) input_token->value)[0] != 'C') {
|
||||
if(((char *)input_token->value)[0] != 'C') {
|
||||
/* We only support Done or Continue */
|
||||
*min = STUB_GSS_SERVER_ERR;
|
||||
return GSS_S_FAILURE;
|
||||
@@ -208,7 +202,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
ctx = curlx_calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
@@ -225,18 +219,18 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
else if(ctx->have_ntlm)
|
||||
ctx->sent = STUB_GSS_NTLM1;
|
||||
else {
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MECH;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
strcpy(ctx->creds, creds);
|
||||
curlx_strcopy(ctx->creds, sizeof(ctx->creds), creds, strlen(creds));
|
||||
ctx->flags = req_flags;
|
||||
}
|
||||
|
||||
token = Curl_gss_alloc(length);
|
||||
if(!token) {
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
@@ -250,14 +244,14 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
&target_desc, &name_type);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if(strlen(creds) + target_desc.length + 5 >= sizeof(ctx->creds)) {
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
@@ -273,7 +267,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
|
||||
if(used >= length) {
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
curlx_free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
@@ -308,7 +302,7 @@ stub_gss_delete_sec_context(OM_uint32 *min,
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
free(*context);
|
||||
curlx_free(*context);
|
||||
*context = NULL;
|
||||
*min = 0;
|
||||
|
||||
@@ -392,7 +386,8 @@ OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
||||
|
||||
#define GSS_LOG_BUFFER_LEN 1024
|
||||
static size_t display_gss_error(OM_uint32 status, int type,
|
||||
char *buf, size_t len) {
|
||||
char *buf, size_t len)
|
||||
{
|
||||
OM_uint32 maj_stat;
|
||||
OM_uint32 min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
@@ -433,7 +428,7 @@ static size_t display_gss_error(OM_uint32 status, int type,
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor)
|
||||
{
|
||||
char buf[GSS_LOG_BUFFER_LEN];
|
||||
char buf[GSS_LOG_BUFFER_LEN] = "";
|
||||
size_t len = 0;
|
||||
|
||||
if(major != GSS_S_FAILURE)
|
||||
|
||||
+1
-6
@@ -23,16 +23,11 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#ifdef GSS_C_CHANNEL_BOUND_FLAG /* MIT Kerberos 1.19+, missing from GNU GSS */
|
||||
#define CURL_GSSAPI_HAS_CHANNEL_BINDING
|
||||
#endif
|
||||
|
||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
!defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \
|
||||
defined(USE_LIBSSH2) || defined(USE_SSL)
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define HMAC_MD5_LENGTH 16
|
||||
|
||||
typedef CURLcode (*HMAC_hinit)(void *context);
|
||||
@@ -48,7 +46,6 @@ struct HMAC_params {
|
||||
unsigned int resultlen; /* Result length (bytes). */
|
||||
};
|
||||
|
||||
|
||||
/* HMAC computation context. */
|
||||
struct HMAC_context {
|
||||
const struct HMAC_params *hash; /* Hash function definition. */
|
||||
@@ -56,7 +53,6 @@ struct HMAC_context {
|
||||
void *hashctxt2; /* Hash function context 2. */
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes. */
|
||||
struct HMAC_context *Curl_HMAC_init(const struct HMAC_params *hashparams,
|
||||
const unsigned char *key,
|
||||
|
||||
+4
-3
@@ -26,11 +26,12 @@
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
extern const struct Curl_handler Curl_handler_ldap;
|
||||
|
||||
#if !defined(CURL_DISABLE_LDAPS) && \
|
||||
((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
|
||||
(!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
|
||||
#if !defined(CURL_DISABLE_LDAPS) && \
|
||||
((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
|
||||
(!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
|
||||
extern const struct Curl_handler Curl_handler_ldaps;
|
||||
#endif
|
||||
|
||||
void Curl_ldap_version(char *buf, size_t bufsz);
|
||||
#endif
|
||||
#endif /* HEADER_CURL_LDAP_H */
|
||||
@@ -23,9 +23,7 @@
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef USE_CURL_NTLM_CORE
|
||||
|
||||
|
||||
Loaded 100 of 387 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user