mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-23 07:28:51 -06:00
curl 2025-02-05 (34cf9d54)
Code extracted from:
https://github.com/curl/curl.git
at commit 34cf9d54a46598c44938aa7598820484d7af7133 (curl-8_12_0).
This commit is contained in:
@@ -29,11 +29,13 @@ 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)
|
||||
set(CURL_HIDDEN_SYMBOLS OFF)
|
||||
endif()
|
||||
|
||||
set(CURL_HIDES_PRIVATE_SYMBOLS FALSE)
|
||||
unset(CURL_EXTERN_SYMBOL)
|
||||
unset(CURL_CFLAG_SYMBOLS_HIDE)
|
||||
set(CURL_EXTERN_SYMBOL "")
|
||||
set(CURL_CFLAG_SYMBOLS_HIDE "")
|
||||
|
||||
if(CURL_HIDDEN_SYMBOLS)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
|
||||
|
||||
@@ -50,7 +50,6 @@ int main(void)
|
||||
int flags = 0;
|
||||
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
|
||||
return 1;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -147,24 +146,21 @@ int main(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FILE_OFFSET_BITS
|
||||
#ifdef _FILE_OFFSET_BITS
|
||||
#undef _FILE_OFFSET_BITS
|
||||
#endif
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#include <sys/types.h>
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
We cannot simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
/* Check that off_t can represent 2**63 - 1 correctly.
|
||||
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))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
int main(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET
|
||||
/* includes start */
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
@@ -180,10 +176,7 @@ int main(void)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET_CAMEL
|
||||
/* includes start */
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
#include <proto/bsdsocket.h>
|
||||
int main(void)
|
||||
{
|
||||
/* IoctlSocket source code */
|
||||
@@ -195,9 +188,9 @@ int main(void)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
|
||||
/* includes start */
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#include <proto/bsdsocket.h>
|
||||
#ifdef HAVE_SYS_IOCTL_H
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
int main(void)
|
||||
{
|
||||
@@ -211,7 +204,6 @@ int main(void)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOCTLSOCKET_FIONBIO
|
||||
/* includes start */
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
@@ -227,7 +219,6 @@ int main(void)
|
||||
|
||||
#ifdef HAVE_IOCTL_FIONBIO
|
||||
/* headers for FIONBIO test */
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
@@ -255,7 +246,6 @@ int main(void)
|
||||
|
||||
#ifdef HAVE_IOCTL_SIOCGIFADDR
|
||||
/* headers for FIONBIO test */
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
@@ -283,18 +273,15 @@ int main(void)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
|
||||
/* includes start */
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
/* includes end */
|
||||
int main(void)
|
||||
{
|
||||
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
|
||||
@@ -372,7 +359,6 @@ int main(void)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATOMIC
|
||||
/* includes start */
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
@@ -382,8 +368,6 @@ int main(void)
|
||||
#ifdef HAVE_STDATOMIC_H
|
||||
# include <stdatomic.h>
|
||||
#endif
|
||||
/* includes end */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
_Atomic int i = 1;
|
||||
@@ -393,14 +377,12 @@ int main(void)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WIN32_WINNT
|
||||
/* includes start */
|
||||
#ifdef _WIN32
|
||||
# ifndef NOGDI
|
||||
# define NOGDI
|
||||
# define NOGDI
|
||||
# endif
|
||||
# include <windows.h>
|
||||
#endif
|
||||
/* includes end */
|
||||
|
||||
#define enquote(x) #x
|
||||
#define expand(x) enquote(x)
|
||||
@@ -411,3 +393,20 @@ int main(void)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MINGW64_VERSION
|
||||
#ifdef __MINGW32__
|
||||
# include <_mingw.h>
|
||||
#endif
|
||||
|
||||
#define enquote(x) #x
|
||||
#define expand(x) enquote(x)
|
||||
#pragma message("MINGW64_VERSION=" \
|
||||
expand(__MINGW64_VERSION_MAJOR) "." \
|
||||
expand(__MINGW64_VERSION_MINOR))
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -34,47 +34,47 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
set(BROTLI_PC_REQUIRES "libbrotlidec")
|
||||
|
||||
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(PC_BROTLI "libbrotlidec")
|
||||
pkg_check_modules(BROTLI "libbrotlicommon")
|
||||
pkg_check_modules(BROTLIDEC ${BROTLI_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(BROTLI_INCLUDE_DIR "brotli/decode.h"
|
||||
HINTS
|
||||
${PC_BROTLI_INCLUDEDIR}
|
||||
${PC_BROTLI_INCLUDE_DIRS}
|
||||
)
|
||||
if(BROTLI_FOUND AND BROTLIDEC_FOUND)
|
||||
list(APPEND BROTLIDEC_LIBRARIES ${BROTLI_LIBRARIES}) # order is significant: brotlidec then brotlicommon
|
||||
list(REVERSE BROTLIDEC_LIBRARIES)
|
||||
list(REMOVE_DUPLICATES BROTLIDEC_LIBRARIES)
|
||||
list(REVERSE BROTLIDEC_LIBRARIES)
|
||||
set(BROTLI_LIBRARIES ${BROTLIDEC_LIBRARIES})
|
||||
string(REPLACE ";" " " BROTLI_CFLAGS "${BROTLI_CFLAGS}")
|
||||
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")
|
||||
find_library(BROTLIDEC_LIBRARY NAMES "brotlidec")
|
||||
|
||||
find_library(BROTLICOMMON_LIBRARY NAMES "brotlicommon"
|
||||
HINTS
|
||||
${PC_BROTLI_LIBDIR}
|
||||
${PC_BROTLI_LIBRARY_DIRS}
|
||||
)
|
||||
find_library(BROTLIDEC_LIBRARY NAMES "brotlidec"
|
||||
HINTS
|
||||
${PC_BROTLI_LIBDIR}
|
||||
${PC_BROTLI_LIBRARY_DIRS}
|
||||
)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Brotli
|
||||
REQUIRED_VARS
|
||||
BROTLI_INCLUDE_DIR
|
||||
BROTLIDEC_LIBRARY
|
||||
BROTLICOMMON_LIBRARY
|
||||
)
|
||||
|
||||
if(PC_BROTLI_VERSION)
|
||||
set(BROTLI_VERSION ${PC_BROTLI_VERSION})
|
||||
if(BROTLI_FOUND)
|
||||
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()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Brotli
|
||||
REQUIRED_VARS
|
||||
BROTLI_INCLUDE_DIR
|
||||
BROTLIDEC_LIBRARY
|
||||
BROTLICOMMON_LIBRARY
|
||||
VERSION_VAR
|
||||
BROTLI_VERSION
|
||||
)
|
||||
|
||||
if(BROTLI_FOUND)
|
||||
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)
|
||||
|
||||
@@ -33,58 +33,64 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
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(PC_CARES "libcares")
|
||||
pkg_check_modules(CARES ${CARES_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(CARES_INCLUDE_DIR NAMES "ares.h"
|
||||
HINTS
|
||||
${PC_CARES_INCLUDEDIR}
|
||||
${PC_CARES_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(CARES_LIBRARY NAMES ${CARES_NAMES} "cares"
|
||||
HINTS
|
||||
${PC_CARES_LIBDIR}
|
||||
${PC_CARES_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_CARES_VERSION)
|
||||
set(CARES_VERSION ${PC_CARES_VERSION})
|
||||
elseif(CARES_INCLUDE_DIR AND EXISTS "${CARES_INCLUDE_DIR}/ares_version.h")
|
||||
set(_version_regex1 "#[\t ]*define[\t ]+ARES_VERSION_MAJOR[\t ]+([0-9]+).*")
|
||||
set(_version_regex2 "#[\t ]*define[\t ]+ARES_VERSION_MINOR[\t ]+([0-9]+).*")
|
||||
set(_version_regex3 "#[\t ]*define[\t ]+ARES_VERSION_PATCH[\t ]+([0-9]+).*")
|
||||
file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str1 REGEX "${_version_regex1}")
|
||||
file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str2 REGEX "${_version_regex2}")
|
||||
file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str3 REGEX "${_version_regex3}")
|
||||
string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
|
||||
string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
|
||||
string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
|
||||
set(CARES_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
|
||||
unset(_version_regex1)
|
||||
unset(_version_regex2)
|
||||
unset(_version_regex3)
|
||||
unset(_version_str1)
|
||||
unset(_version_str2)
|
||||
unset(_version_str3)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Cares
|
||||
REQUIRED_VARS
|
||||
CARES_INCLUDE_DIR
|
||||
CARES_LIBRARY
|
||||
VERSION_VAR
|
||||
CARES_VERSION
|
||||
)
|
||||
|
||||
if(CARES_FOUND)
|
||||
set(CARES_INCLUDE_DIRS ${CARES_INCLUDE_DIR})
|
||||
set(CARES_LIBRARIES ${CARES_LIBRARY})
|
||||
string(REPLACE ";" " " CARES_CFLAGS "${CARES_CFLAGS}")
|
||||
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")
|
||||
|
||||
unset(CARES_VERSION CACHE)
|
||||
if(CARES_INCLUDE_DIR AND EXISTS "${CARES_INCLUDE_DIR}/ares_version.h")
|
||||
set(_version_regex1 "#[\t ]*define[\t ]+ARES_VERSION_MAJOR[\t ]+([0-9]+).*")
|
||||
set(_version_regex2 "#[\t ]*define[\t ]+ARES_VERSION_MINOR[\t ]+([0-9]+).*")
|
||||
set(_version_regex3 "#[\t ]*define[\t ]+ARES_VERSION_PATCH[\t ]+([0-9]+).*")
|
||||
file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str1 REGEX "${_version_regex1}")
|
||||
file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str2 REGEX "${_version_regex2}")
|
||||
file(STRINGS "${CARES_INCLUDE_DIR}/ares_version.h" _version_str3 REGEX "${_version_regex3}")
|
||||
string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
|
||||
string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
|
||||
string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
|
||||
set(CARES_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
|
||||
unset(_version_regex1)
|
||||
unset(_version_regex2)
|
||||
unset(_version_regex3)
|
||||
unset(_version_str1)
|
||||
unset(_version_str2)
|
||||
unset(_version_str3)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Cares
|
||||
REQUIRED_VARS
|
||||
CARES_INCLUDE_DIR
|
||||
CARES_LIBRARY
|
||||
VERSION_VAR
|
||||
CARES_VERSION
|
||||
)
|
||||
|
||||
if(CARES_FOUND)
|
||||
set(CARES_INCLUDE_DIRS ${CARES_INCLUDE_DIR})
|
||||
set(CARES_LIBRARIES ${CARES_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(CARES_INCLUDE_DIR CARES_LIBRARY)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(CARES_INCLUDE_DIR CARES_LIBRARY)
|
||||
if(CARES_FOUND AND WIN32)
|
||||
list(APPEND CARES_LIBRARIES "iphlpapi") # for if_indextoname and others
|
||||
endif()
|
||||
|
||||
@@ -99,7 +99,7 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
|
||||
foreach(_flag IN LISTS _GSS_CFLAGS)
|
||||
if(_flag MATCHES "^-I.*")
|
||||
if(_flag MATCHES "^-I")
|
||||
string(REGEX REPLACE "^-I" "" _val "${_flag}")
|
||||
list(APPEND _GSS_INCLUDE_DIRS "${_val}")
|
||||
else()
|
||||
@@ -123,10 +123,10 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}")
|
||||
|
||||
foreach(_flag IN LISTS _gss_lib_flags)
|
||||
if(_flag MATCHES "^-l.*")
|
||||
if(_flag MATCHES "^-l")
|
||||
string(REGEX REPLACE "^-l" "" _val "${_flag}")
|
||||
list(APPEND _GSS_LIBRARIES "${_val}")
|
||||
elseif(_flag MATCHES "^-L.*")
|
||||
elseif(_flag MATCHES "^-L")
|
||||
string(REGEX REPLACE "^-L" "" _val "${_flag}")
|
||||
list(APPEND _GSS_LIBRARY_DIRS "${_val}")
|
||||
endif()
|
||||
@@ -156,7 +156,7 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
if(_gss_configure_failed)
|
||||
set(GSS_FLAVOUR "Heimdal") # most probably, should not really matter
|
||||
else()
|
||||
if(_gss_vendor MATCHES ".*H|heimdal.*")
|
||||
if(_gss_vendor MATCHES "H|heimdal")
|
||||
set(GSS_FLAVOUR "Heimdal")
|
||||
else()
|
||||
set(GSS_FLAVOUR "MIT")
|
||||
@@ -175,7 +175,7 @@ if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional appr
|
||||
|
||||
if(_GSS_INCLUDE_DIRS) # jay, we have found something
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}")
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}")
|
||||
check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers)
|
||||
|
||||
if(_gss_have_mit_headers)
|
||||
|
||||
111
CMake/FindLDAP.cmake
Normal file
111
CMake/FindLDAP.cmake
Normal file
@@ -0,0 +1,111 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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 ldap library
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LDAP_INCLUDE_DIR`: The ldap include directory.
|
||||
# - `LDAP_LIBRARY`: Path to `ldap` library.
|
||||
# - `LDAP_LBER_LIBRARY`: Path to `lber` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
# - `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.
|
||||
|
||||
set(LDAP_PC_REQUIRES "ldap")
|
||||
|
||||
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_LBER "lber")
|
||||
endif()
|
||||
|
||||
if(LDAP_FOUND AND LDAP_LBER_FOUND)
|
||||
list(APPEND LDAP_LIBRARIES ${LDAP_LBER_LIBRARIES})
|
||||
list(REVERSE LDAP_LIBRARIES)
|
||||
list(REMOVE_DUPLICATES LDAP_LIBRARIES)
|
||||
list(REVERSE LDAP_LIBRARIES)
|
||||
string(REPLACE ";" " " LDAP_CFLAGS "${LDAP_CFLAGS}")
|
||||
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
|
||||
|
||||
# On Apple the SDK LDAP gets picked up from
|
||||
# 'MacOSX.sdk/System/Library/Frameworks/LDAP.framework/Headers', which contains
|
||||
# ldap.h and lber.h both being stubs to include <ldap.h> and <lber.h>.
|
||||
# This causes an infinite inclusion loop in compile. Also do this for libraries
|
||||
# to avoid picking up the 'ldap.framework' with a full path.
|
||||
set(_save_cmake_system_framework_path ${CMAKE_SYSTEM_FRAMEWORK_PATH})
|
||||
set(CMAKE_SYSTEM_FRAMEWORK_PATH "")
|
||||
find_path(LDAP_INCLUDE_DIR NAMES "ldap.h")
|
||||
find_library(LDAP_LIBRARY NAMES "ldap")
|
||||
find_library(LDAP_LBER_LIBRARY NAMES "lber")
|
||||
set(CMAKE_SYSTEM_FRAMEWORK_PATH ${_save_cmake_system_framework_path})
|
||||
|
||||
unset(LDAP_VERSION CACHE)
|
||||
if(LDAP_INCLUDE_DIR AND EXISTS "${LDAP_INCLUDE_DIR}/ldap_features.h")
|
||||
set(_version_regex1 "#[\t ]*define[\t ]+LDAP_VENDOR_VERSION_MAJOR[\t ]+([0-9]+).*")
|
||||
set(_version_regex2 "#[\t ]*define[\t ]+LDAP_VENDOR_VERSION_MINOR[\t ]+([0-9]+).*")
|
||||
set(_version_regex3 "#[\t ]*define[\t ]+LDAP_VENDOR_VERSION_PATCH[\t ]+([0-9]+).*")
|
||||
file(STRINGS "${LDAP_INCLUDE_DIR}/ldap_features.h" _version_str1 REGEX "${_version_regex1}")
|
||||
file(STRINGS "${LDAP_INCLUDE_DIR}/ldap_features.h" _version_str2 REGEX "${_version_regex2}")
|
||||
file(STRINGS "${LDAP_INCLUDE_DIR}/ldap_features.h" _version_str3 REGEX "${_version_regex3}")
|
||||
string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
|
||||
string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
|
||||
string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
|
||||
set(LDAP_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
|
||||
unset(_version_regex1)
|
||||
unset(_version_regex2)
|
||||
unset(_version_regex3)
|
||||
unset(_version_str1)
|
||||
unset(_version_str2)
|
||||
unset(_version_str3)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LDAP
|
||||
REQUIRED_VARS
|
||||
LDAP_INCLUDE_DIR
|
||||
LDAP_LIBRARY
|
||||
LDAP_LBER_LIBRARY
|
||||
VERSION_VAR
|
||||
LDAP_VERSION
|
||||
)
|
||||
|
||||
if(LDAP_FOUND)
|
||||
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()
|
||||
@@ -34,14 +34,17 @@
|
||||
# - `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.
|
||||
|
||||
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")
|
||||
pkg_check_modules(LIBGSASL ${LIBGSASL_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(LIBGSASL_FOUND)
|
||||
|
||||
@@ -34,14 +34,17 @@
|
||||
# - `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.
|
||||
|
||||
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")
|
||||
pkg_check_modules(LIBIDN2 ${LIBIDN2_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(LIBIDN2_FOUND)
|
||||
|
||||
@@ -33,48 +33,50 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
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(PC_LIBPSL "libpsl")
|
||||
pkg_check_modules(LIBPSL ${LIBPSL_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(LIBPSL_INCLUDE_DIR NAMES "libpsl.h"
|
||||
HINTS
|
||||
${PC_LIBPSL_INCLUDEDIR}
|
||||
${PC_LIBPSL_INCLUDE_DIRS}
|
||||
)
|
||||
if(LIBPSL_FOUND AND LIBPSL_INCLUDE_DIRS)
|
||||
string(REPLACE ";" " " LIBPSL_CFLAGS "${LIBPSL_CFLAGS}")
|
||||
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")
|
||||
|
||||
find_library(LIBPSL_LIBRARY NAMES "psl" "libpsl"
|
||||
HINTS
|
||||
${PC_LIBPSL_LIBDIR}
|
||||
${PC_LIBPSL_LIBRARY_DIRS}
|
||||
)
|
||||
unset(LIBPSL_VERSION CACHE)
|
||||
if(LIBPSL_INCLUDE_DIR AND EXISTS "${LIBPSL_INCLUDE_DIR}/libpsl.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+PSL_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(LIBPSL_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
if(PC_LIBPSL_VERSION)
|
||||
set(LIBPSL_VERSION ${PC_LIBPSL_VERSION})
|
||||
elseif(LIBPSL_INCLUDE_DIR AND EXISTS "${LIBPSL_INCLUDE_DIR}/libpsl.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+PSL_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${LIBPSL_INCLUDE_DIR}/libpsl.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(LIBPSL_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libpsl
|
||||
REQUIRED_VARS
|
||||
LIBPSL_INCLUDE_DIR
|
||||
LIBPSL_LIBRARY
|
||||
VERSION_VAR
|
||||
LIBPSL_VERSION
|
||||
)
|
||||
|
||||
if(LIBPSL_FOUND)
|
||||
set(LIBPSL_INCLUDE_DIRS ${LIBPSL_INCLUDE_DIR})
|
||||
set(LIBPSL_LIBRARIES ${LIBPSL_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libpsl
|
||||
REQUIRED_VARS
|
||||
LIBPSL_INCLUDE_DIR
|
||||
LIBPSL_LIBRARY
|
||||
VERSION_VAR
|
||||
LIBPSL_VERSION
|
||||
)
|
||||
|
||||
if(LIBPSL_FOUND)
|
||||
set(LIBPSL_INCLUDE_DIRS ${LIBPSL_INCLUDE_DIR})
|
||||
set(LIBPSL_LIBRARIES ${LIBPSL_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBPSL_INCLUDE_DIR LIBPSL_LIBRARY)
|
||||
|
||||
102
CMake/FindLibrtmp.cmake
Normal file
102
CMake/FindLibrtmp.cmake
Normal file
@@ -0,0 +1,102 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# 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 librtmp library
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# - `LIBRTMP_INCLUDE_DIR`: The librtmp include directory.
|
||||
# - `LIBRTMP_LIBRARY`: Path to `librtmp` library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
# - `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.
|
||||
|
||||
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})
|
||||
endif()
|
||||
|
||||
if(LIBRTMP_FOUND AND LIBRTMP_INCLUDE_DIRS)
|
||||
string(REPLACE ";" " " LIBRTMP_CFLAGS "${LIBRTMP_CFLAGS}")
|
||||
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")
|
||||
|
||||
unset(LIBRTMP_VERSION CACHE)
|
||||
if(LIBRTMP_INCLUDE_DIR AND EXISTS "${LIBRTMP_INCLUDE_DIR}/librtmp/rtmp.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+RTMP_LIB_VERSION[\t ]+0x([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F]).*")
|
||||
file(STRINGS "${LIBRTMP_INCLUDE_DIR}/librtmp/rtmp.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str1 "${_version_str}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\2" _version_str2 "${_version_str}")
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
# No support for hex version numbers, just strip leading zeroes
|
||||
string(REGEX REPLACE "^0" "" _version_str1 "${_version_str1}")
|
||||
string(REGEX REPLACE "^0" "" _version_str2 "${_version_str2}")
|
||||
else()
|
||||
math(EXPR _version_str1 "0x${_version_str1}" OUTPUT_FORMAT DECIMAL)
|
||||
math(EXPR _version_str2 "0x${_version_str2}" OUTPUT_FORMAT DECIMAL)
|
||||
endif()
|
||||
set(LIBRTMP_VERSION "${_version_str1}.${_version_str2}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str1)
|
||||
unset(_version_str2)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Librtmp
|
||||
REQUIRED_VARS
|
||||
LIBRTMP_INCLUDE_DIR
|
||||
LIBRTMP_LIBRARY
|
||||
VERSION_VAR
|
||||
LIBRTMP_VERSION
|
||||
)
|
||||
|
||||
if(LIBRTMP_FOUND)
|
||||
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)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBRTMP_FOUND AND WIN32)
|
||||
list(APPEND LIBRTMP_LIBRARIES "winmm")
|
||||
endif()
|
||||
@@ -25,23 +25,26 @@
|
||||
#
|
||||
# Input variables:
|
||||
#
|
||||
# LIBSSH_INCLUDE_DIR The libssh include directory.
|
||||
# LIBSSH_LIBRARY Path to libssh library.
|
||||
# - `LIBSSH_INCLUDE_DIR`: The libssh include directory.
|
||||
# - `LIBSSH_LIBRARY`: Path to libssh library.
|
||||
#
|
||||
# Result variables:
|
||||
#
|
||||
# LIBSSH_FOUND System has libssh.
|
||||
# LIBSSH_INCLUDE_DIRS The libssh include directories.
|
||||
# LIBSSH_LIBRARIES The libssh library names.
|
||||
# LIBSSH_LIBRARY_DIRS The libssh library directories.
|
||||
# LIBSSH_CFLAGS Required compiler flags.
|
||||
# LIBSSH_VERSION Version of libssh.
|
||||
# - `LIBSSH_FOUND`: System has libssh.
|
||||
# - `LIBSSH_INCLUDE_DIRS`: The libssh include directories.
|
||||
# - `LIBSSH_LIBRARIES`: The libssh library names.
|
||||
# - `LIBSSH_LIBRARY_DIRS`: The libssh library directories.
|
||||
# - `LIBSSH_PC_REQUIRES`: The libssh pkg-config packages.
|
||||
# - `LIBSSH_CFLAGS`: Required compiler flags.
|
||||
# - `LIBSSH_VERSION`: Version of 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")
|
||||
pkg_check_modules(LIBSSH ${LIBSSH_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(LIBSSH_FOUND)
|
||||
|
||||
@@ -33,48 +33,50 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
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(PC_LIBSSH2 "libssh2")
|
||||
pkg_check_modules(LIBSSH2 ${LIBSSH2_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(LIBSSH2_INCLUDE_DIR NAMES "libssh2.h"
|
||||
HINTS
|
||||
${PC_LIBSSH2_INCLUDEDIR}
|
||||
${PC_LIBSSH2_INCLUDE_DIRS}
|
||||
)
|
||||
if(LIBSSH2_FOUND AND LIBSSH2_INCLUDE_DIRS)
|
||||
string(REPLACE ";" " " LIBSSH2_CFLAGS "${LIBSSH2_CFLAGS}")
|
||||
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")
|
||||
|
||||
find_library(LIBSSH2_LIBRARY NAMES "ssh2" "libssh2"
|
||||
HINTS
|
||||
${PC_LIBSSH2_LIBDIR}
|
||||
${PC_LIBSSH2_LIBRARY_DIRS}
|
||||
)
|
||||
unset(LIBSSH2_VERSION CACHE)
|
||||
if(LIBSSH2_INCLUDE_DIR AND EXISTS "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+LIBSSH2_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(LIBSSH2_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
if(PC_LIBSSH2_VERSION)
|
||||
set(LIBSSH2_VERSION ${PC_LIBSSH2_VERSION})
|
||||
elseif(LIBSSH2_INCLUDE_DIR AND EXISTS "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+LIBSSH2_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(LIBSSH2_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libssh2
|
||||
REQUIRED_VARS
|
||||
LIBSSH2_INCLUDE_DIR
|
||||
LIBSSH2_LIBRARY
|
||||
VERSION_VAR
|
||||
LIBSSH2_VERSION
|
||||
)
|
||||
|
||||
if(LIBSSH2_FOUND)
|
||||
set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR})
|
||||
set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libssh2
|
||||
REQUIRED_VARS
|
||||
LIBSSH2_INCLUDE_DIR
|
||||
LIBSSH2_LIBRARY
|
||||
VERSION_VAR
|
||||
LIBSSH2_VERSION
|
||||
)
|
||||
|
||||
if(LIBSSH2_FOUND)
|
||||
set(LIBSSH2_INCLUDE_DIRS ${LIBSSH2_INCLUDE_DIR})
|
||||
set(LIBSSH2_LIBRARIES ${LIBSSH2_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY)
|
||||
|
||||
@@ -34,14 +34,17 @@
|
||||
# - `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.
|
||||
|
||||
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")
|
||||
pkg_check_modules(LIBUV ${LIBUV_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(LIBUV_FOUND)
|
||||
|
||||
@@ -38,18 +38,21 @@
|
||||
# - `MSH3_CFLAGS`: Required compiler flags.
|
||||
# - `MSH3_VERSION`: Version of msh3.
|
||||
|
||||
set(MSH3_PC_REQUIRES "libmsh3")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED MSH3_INCLUDE_DIR AND
|
||||
NOT DEFINED MSH3_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(MSH3 "libmsh3")
|
||||
pkg_check_modules(MSH3 ${MSH3_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(MSH3_FOUND)
|
||||
set(MSH3_PC_REQUIRES "libmsh3")
|
||||
string(REPLACE ";" " " MSH3_CFLAGS "${MSH3_CFLAGS}")
|
||||
message(STATUS "Found MSH3 (via pkg-config): ${MSH3_INCLUDE_DIRS} (found version \"${MSH3_VERSION}\")")
|
||||
else()
|
||||
set(MSH3_PC_REQUIRES "") # Depend on pkg-config only when found via pkg-config
|
||||
|
||||
find_path(MSH3_INCLUDE_DIR NAMES "msh3.h")
|
||||
find_library(MSH3_LIBRARY NAMES "msh3")
|
||||
|
||||
|
||||
@@ -46,24 +46,29 @@ if(DEFINED MBEDTLS_INCLUDE_DIRS AND NOT DEFINED MBEDTLS_INCLUDE_DIR)
|
||||
unset(MBEDTLS_INCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
set(MBEDTLS_PC_REQUIRES "mbedtls")
|
||||
|
||||
if(CURL_USE_PKGCONFIG AND
|
||||
NOT DEFINED MBEDTLS_INCLUDE_DIR AND
|
||||
NOT DEFINED MBEDTLS_LIBRARY AND
|
||||
NOT DEFINED MBEDX509_LIBRARY AND
|
||||
NOT DEFINED MBEDCRYPTO_LIBRARY)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(MBEDTLS "mbedtls")
|
||||
pkg_check_modules(MBEDTLS ${MBEDTLS_PC_REQUIRES})
|
||||
pkg_check_modules(MBEDX509 "mbedx509")
|
||||
pkg_check_modules(MBEDCRYPTO "mbedcrypto")
|
||||
endif()
|
||||
|
||||
if(MBEDTLS_FOUND AND MBEDX509_FOUND AND MBEDCRYPTO_FOUND)
|
||||
list(APPEND MBEDTLS_LIBRARIES ${MBEDX509_LIBRARIES} ${MBEDCRYPTO_LIBRARIES})
|
||||
list(REVERSE MBEDTLS_LIBRARIES)
|
||||
list(REMOVE_DUPLICATES MBEDTLS_LIBRARIES)
|
||||
set(MBEDTLS_PC_REQUIRES "mbedtls")
|
||||
list(REVERSE MBEDTLS_LIBRARIES)
|
||||
string(REPLACE ";" " " MBEDTLS_CFLAGS "${MBEDTLS_CFLAGS}")
|
||||
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
|
||||
|
||||
find_path(MBEDTLS_INCLUDE_DIR NAMES "mbedtls/ssl.h")
|
||||
find_library(MBEDTLS_LIBRARY NAMES "mbedtls" "libmbedtls")
|
||||
find_library(MBEDX509_LIBRARY NAMES "mbedx509" "libmbedx509")
|
||||
|
||||
@@ -33,48 +33,50 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
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(PC_NGHTTP2 "libnghttp2")
|
||||
pkg_check_modules(NGHTTP2 ${NGHTTP2_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(NGHTTP2_INCLUDE_DIR NAMES "nghttp2/nghttp2.h"
|
||||
HINTS
|
||||
${PC_NGHTTP2_INCLUDEDIR}
|
||||
${PC_NGHTTP2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(NGHTTP2_LIBRARY NAMES "nghttp2" "nghttp2_static"
|
||||
HINTS
|
||||
${PC_NGHTTP2_LIBDIR}
|
||||
${PC_NGHTTP2_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_NGHTTP2_VERSION)
|
||||
set(NGHTTP2_VERSION ${PC_NGHTTP2_VERSION})
|
||||
elseif(NGHTTP2_INCLUDE_DIR AND EXISTS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2ver.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+NGHTTP2_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2ver.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(NGHTTP2_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGHTTP2
|
||||
REQUIRED_VARS
|
||||
NGHTTP2_INCLUDE_DIR
|
||||
NGHTTP2_LIBRARY
|
||||
VERSION_VAR
|
||||
NGHTTP2_VERSION
|
||||
)
|
||||
|
||||
if(NGHTTP2_FOUND)
|
||||
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
|
||||
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
|
||||
endif()
|
||||
string(REPLACE ";" " " NGHTTP2_CFLAGS "${NGHTTP2_CFLAGS}")
|
||||
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")
|
||||
|
||||
mark_as_advanced(NGHTTP2_INCLUDE_DIR NGHTTP2_LIBRARY)
|
||||
unset(NGHTTP2_VERSION CACHE)
|
||||
if(NGHTTP2_INCLUDE_DIR AND EXISTS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2ver.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+NGHTTP2_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${NGHTTP2_INCLUDE_DIR}/nghttp2/nghttp2ver.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(NGHTTP2_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGHTTP2
|
||||
REQUIRED_VARS
|
||||
NGHTTP2_INCLUDE_DIR
|
||||
NGHTTP2_LIBRARY
|
||||
VERSION_VAR
|
||||
NGHTTP2_VERSION
|
||||
)
|
||||
|
||||
if(NGHTTP2_FOUND)
|
||||
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
|
||||
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGHTTP2_INCLUDE_DIR NGHTTP2_LIBRARY)
|
||||
endif()
|
||||
|
||||
@@ -33,48 +33,50 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
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(PC_NGHTTP3 "libnghttp3")
|
||||
pkg_check_modules(NGHTTP3 ${NGHTTP3_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(NGHTTP3_INCLUDE_DIR NAMES "nghttp3/nghttp3.h"
|
||||
HINTS
|
||||
${PC_NGHTTP3_INCLUDEDIR}
|
||||
${PC_NGHTTP3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(NGHTTP3_LIBRARY NAMES "nghttp3"
|
||||
HINTS
|
||||
${PC_NGHTTP3_LIBDIR}
|
||||
${PC_NGHTTP3_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_NGHTTP3_VERSION)
|
||||
set(NGHTTP3_VERSION ${PC_NGHTTP3_VERSION})
|
||||
elseif(NGHTTP3_INCLUDE_DIR AND EXISTS "${NGHTTP3_INCLUDE_DIR}/nghttp3/version.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+NGHTTP3_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${NGHTTP3_INCLUDE_DIR}/nghttp3/version.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(NGHTTP3_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGHTTP3
|
||||
REQUIRED_VARS
|
||||
NGHTTP3_INCLUDE_DIR
|
||||
NGHTTP3_LIBRARY
|
||||
VERSION_VAR
|
||||
NGHTTP3_VERSION
|
||||
)
|
||||
|
||||
if(NGHTTP3_FOUND)
|
||||
set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
|
||||
set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY})
|
||||
endif()
|
||||
string(REPLACE ";" " " NGHTTP3_CFLAGS "${NGHTTP3_CFLAGS}")
|
||||
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")
|
||||
|
||||
mark_as_advanced(NGHTTP3_INCLUDE_DIR NGHTTP3_LIBRARY)
|
||||
unset(NGHTTP3_VERSION CACHE)
|
||||
if(NGHTTP3_INCLUDE_DIR AND EXISTS "${NGHTTP3_INCLUDE_DIR}/nghttp3/version.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+NGHTTP3_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${NGHTTP3_INCLUDE_DIR}/nghttp3/version.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(NGHTTP3_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGHTTP3
|
||||
REQUIRED_VARS
|
||||
NGHTTP3_INCLUDE_DIR
|
||||
NGHTTP3_LIBRARY
|
||||
VERSION_VAR
|
||||
NGHTTP3_VERSION
|
||||
)
|
||||
|
||||
if(NGHTTP3_FOUND)
|
||||
set(NGHTTP3_INCLUDE_DIRS ${NGHTTP3_INCLUDE_DIR})
|
||||
set(NGHTTP3_LIBRARIES ${NGHTTP3_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGHTTP3_INCLUDE_DIR NGHTTP3_LIBRARY)
|
||||
endif()
|
||||
|
||||
@@ -41,36 +41,11 @@
|
||||
# - `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.
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_NGTCP2 "libngtcp2")
|
||||
endif()
|
||||
|
||||
find_path(NGTCP2_INCLUDE_DIR NAMES "ngtcp2/ngtcp2.h"
|
||||
HINTS
|
||||
${PC_NGTCP2_INCLUDEDIR}
|
||||
${PC_NGTCP2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(NGTCP2_LIBRARY NAMES "ngtcp2"
|
||||
HINTS
|
||||
${PC_NGTCP2_LIBDIR}
|
||||
${PC_NGTCP2_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_NGTCP2_VERSION)
|
||||
set(NGTCP2_VERSION ${PC_NGTCP2_VERSION})
|
||||
elseif(NGTCP2_INCLUDE_DIR AND EXISTS "${NGTCP2_INCLUDE_DIR}/ngtcp2/version.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+NGTCP2_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${NGTCP2_INCLUDE_DIR}/ngtcp2/version.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(NGTCP2_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
if(NGTCP2_FIND_COMPONENTS)
|
||||
set(_ngtcp2_crypto_backend "")
|
||||
foreach(_component IN LISTS NGTCP2_FIND_COMPONENTS)
|
||||
@@ -83,40 +58,73 @@ if(NGTCP2_FIND_COMPONENTS)
|
||||
endforeach()
|
||||
|
||||
if(_ngtcp2_crypto_backend)
|
||||
string(TOLOWER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library)
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
pkg_check_modules(PC_${_crypto_library} "lib${_crypto_library}")
|
||||
endif()
|
||||
|
||||
get_filename_component(_ngtcp2_library_dir "${NGTCP2_LIBRARY}" DIRECTORY)
|
||||
find_library(${_crypto_library}_LIBRARY NAMES ${_crypto_library}
|
||||
HINTS
|
||||
${_ngtcp2_library_dir}
|
||||
${PC_${_crypto_library}_LIBDIR}
|
||||
${PC_${_crypto_library}_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(${_crypto_library}_LIBRARY)
|
||||
set(NGTCP2_${_ngtcp2_crypto_backend}_FOUND TRUE)
|
||||
set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library}_LIBRARY})
|
||||
endif()
|
||||
string(TOLOWER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library_lower)
|
||||
string(TOUPPER "ngtcp2_crypto_${_ngtcp2_crypto_backend}" _crypto_library_upper)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGTCP2
|
||||
REQUIRED_VARS
|
||||
NGTCP2_INCLUDE_DIR
|
||||
NGTCP2_LIBRARY
|
||||
VERSION_VAR
|
||||
NGTCP2_VERSION
|
||||
HANDLE_COMPONENTS
|
||||
)
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
set(NGTCP2_INCLUDE_DIRS ${NGTCP2_INCLUDE_DIR})
|
||||
set(NGTCP2_LIBRARIES ${NGTCP2_LIBRARY} ${NGTCP2_CRYPTO_LIBRARY})
|
||||
set(NGTCP2_PC_REQUIRES "libngtcp2")
|
||||
if(_ngtcp2_crypto_backend)
|
||||
set(NGTCP2_CRYPTO_PC_REQUIRES "lib${_crypto_library_lower}")
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NGTCP2_INCLUDE_DIR NGTCP2_LIBRARY NGTCP2_CRYPTO_LIBRARY)
|
||||
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})
|
||||
if(_ngtcp2_crypto_backend)
|
||||
pkg_check_modules("${_crypto_library_upper}" ${NGTCP2_CRYPTO_PC_REQUIRES})
|
||||
else()
|
||||
set("${_crypto_library_upper}_FOUND" TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND NGTCP2_PC_REQUIRES ${NGTCP2_CRYPTO_PC_REQUIRES})
|
||||
|
||||
if(NGTCP2_FOUND AND "${${_crypto_library_upper}_FOUND}")
|
||||
list(APPEND NGTCP2_LIBRARIES "${${_crypto_library_upper}_LIBRARIES}")
|
||||
list(REMOVE_DUPLICATES NGTCP2_LIBRARIES)
|
||||
string(REPLACE ";" " " NGTCP2_CFLAGS "${NGTCP2_CFLAGS}")
|
||||
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")
|
||||
|
||||
unset(NGTCP2_VERSION CACHE)
|
||||
if(NGTCP2_INCLUDE_DIR AND EXISTS "${NGTCP2_INCLUDE_DIR}/ngtcp2/version.h")
|
||||
set(_version_regex "#[\t ]*define[\t ]+NGTCP2_VERSION[\t ]+\"([^\"]*)\"")
|
||||
file(STRINGS "${NGTCP2_INCLUDE_DIR}/ngtcp2/version.h" _version_str REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
|
||||
set(NGTCP2_VERSION "${_version_str}")
|
||||
unset(_version_regex)
|
||||
unset(_version_str)
|
||||
endif()
|
||||
|
||||
if(_ngtcp2_crypto_backend)
|
||||
get_filename_component(_ngtcp2_library_dir "${NGTCP2_LIBRARY}" DIRECTORY)
|
||||
find_library(${_crypto_library_upper}_LIBRARY NAMES ${_crypto_library_lower} HINTS ${_ngtcp2_library_dir})
|
||||
|
||||
if(${_crypto_library_upper}_LIBRARY)
|
||||
set(NGTCP2_${_ngtcp2_crypto_backend}_FOUND TRUE)
|
||||
set(NGTCP2_CRYPTO_LIBRARY ${${_crypto_library_upper}_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NGTCP2
|
||||
REQUIRED_VARS
|
||||
NGTCP2_INCLUDE_DIR
|
||||
NGTCP2_LIBRARY
|
||||
VERSION_VAR
|
||||
NGTCP2_VERSION
|
||||
HANDLE_COMPONENTS
|
||||
)
|
||||
|
||||
if(NGTCP2_FOUND)
|
||||
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)
|
||||
endif()
|
||||
|
||||
@@ -34,14 +34,17 @@
|
||||
# - `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.
|
||||
|
||||
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")
|
||||
pkg_check_modules(NETTLE ${NETTLE_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(NETTLE_FOUND)
|
||||
|
||||
@@ -34,14 +34,17 @@
|
||||
# - `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.
|
||||
|
||||
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")
|
||||
pkg_check_modules(QUICHE ${QUICHE_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(QUICHE_FOUND)
|
||||
|
||||
@@ -38,18 +38,21 @@
|
||||
# - `RUSTLS_CFLAGS`: Required compiler flags.
|
||||
# - `RUSTLS_VERSION`: Version of 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")
|
||||
pkg_check_modules(RUSTLS ${RUSTLS_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(RUSTLS_FOUND)
|
||||
set(RUSTLS_PC_REQUIRES "rustls")
|
||||
string(REPLACE ";" " " RUSTLS_CFLAGS "${RUSTLS_CFLAGS}")
|
||||
message(STATUS "Found Rustls (via pkg-config): ${RUSTLS_INCLUDE_DIRS} (found version \"${RUSTLS_VERSION}\")")
|
||||
else()
|
||||
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")
|
||||
|
||||
@@ -68,36 +71,38 @@ else()
|
||||
mark_as_advanced(RUSTLS_INCLUDE_DIR RUSTLS_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
find_library(SECURITY_FRAMEWORK "Security")
|
||||
mark_as_advanced(SECURITY_FRAMEWORK)
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
list(APPEND RUSTLS_LIBRARIES "-framework Security")
|
||||
if(RUSTLS_FOUND)
|
||||
if(APPLE)
|
||||
find_library(SECURITY_FRAMEWORK NAMES "Security")
|
||||
mark_as_advanced(SECURITY_FRAMEWORK)
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
list(APPEND RUSTLS_LIBRARIES "-framework Security")
|
||||
|
||||
find_library(FOUNDATION_FRAMEWORK "Foundation")
|
||||
mark_as_advanced(FOUNDATION_FRAMEWORK)
|
||||
if(NOT FOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "Foundation framework not found")
|
||||
endif()
|
||||
list(APPEND RUSTLS_LIBRARIES "-framework Foundation")
|
||||
elseif(NOT WIN32)
|
||||
find_library(_pthread_library "pthread")
|
||||
if(_pthread_library)
|
||||
list(APPEND RUSTLS_LIBRARIES "pthread")
|
||||
endif()
|
||||
mark_as_advanced(_pthread_library)
|
||||
find_library(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")
|
||||
elseif(NOT WIN32)
|
||||
find_library(PTHREAD_LIBRARY NAMES "pthread")
|
||||
if(PTHREAD_LIBRARY)
|
||||
list(APPEND RUSTLS_LIBRARIES ${PTHREAD_LIBRARY})
|
||||
endif()
|
||||
mark_as_advanced(PTHREAD_LIBRARY)
|
||||
|
||||
find_library(_dl_library "dl")
|
||||
if(_dl_library)
|
||||
list(APPEND RUSTLS_LIBRARIES "dl")
|
||||
endif()
|
||||
mark_as_advanced(_dl_library)
|
||||
find_library(DL_LIBRARY NAMES "dl")
|
||||
if(DL_LIBRARY)
|
||||
list(APPEND RUSTLS_LIBRARIES ${DL_LIBRARY})
|
||||
endif()
|
||||
mark_as_advanced(DL_LIBRARY)
|
||||
|
||||
find_library(_math_library "m")
|
||||
if(_math_library)
|
||||
list(APPEND RUSTLS_LIBRARIES "m")
|
||||
find_library(MATH_LIBRARY NAMES "m")
|
||||
if(MATH_LIBRARY)
|
||||
list(APPEND RUSTLS_LIBRARIES ${MATH_LIBRARY})
|
||||
endif()
|
||||
mark_as_advanced(MATH_LIBRARY)
|
||||
endif()
|
||||
mark_as_advanced(_math_library)
|
||||
endif()
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
# - `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.
|
||||
|
||||
@@ -46,11 +47,13 @@ if(DEFINED WolfSSL_LIBRARY AND NOT DEFINED WOLFSSL_LIBRARY)
|
||||
set(WOLFSSL_LIBRARY "${WolfSSL_LIBRARY}")
|
||||
endif()
|
||||
|
||||
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")
|
||||
pkg_check_modules(WOLFSSL ${WOLFSSL_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
if(WOLFSSL_FOUND)
|
||||
@@ -87,10 +90,10 @@ else()
|
||||
mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
find_library(_math_library "m")
|
||||
if(_math_library)
|
||||
list(APPEND WOLFSSL_LIBRARIES "m") # for log and pow
|
||||
if(WOLFSSL_FOUND AND NOT WIN32)
|
||||
find_library(MATH_LIBRARY NAMES "m")
|
||||
if(MATH_LIBRARY)
|
||||
list(APPEND WOLFSSL_LIBRARIES ${MATH_LIBRARY}) # for log and pow
|
||||
endif()
|
||||
mark_as_advanced(_math_library)
|
||||
mark_as_advanced(MATH_LIBRARY)
|
||||
endif()
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
# - `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.
|
||||
|
||||
if(DEFINED Zstd_INCLUDE_DIR AND NOT DEFINED ZSTD_INCLUDE_DIR)
|
||||
@@ -44,56 +47,55 @@ if(DEFINED Zstd_LIBRARY AND NOT DEFINED ZSTD_LIBRARY)
|
||||
set(ZSTD_LIBRARY "${Zstd_LIBRARY}")
|
||||
endif()
|
||||
|
||||
if(CURL_USE_PKGCONFIG)
|
||||
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(PC_ZSTD "libzstd")
|
||||
pkg_check_modules(ZSTD ${ZSTD_PC_REQUIRES})
|
||||
endif()
|
||||
|
||||
find_path(ZSTD_INCLUDE_DIR NAMES "zstd.h"
|
||||
HINTS
|
||||
${PC_ZSTD_INCLUDEDIR}
|
||||
${PC_ZSTD_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(ZSTD_LIBRARY NAMES "zstd"
|
||||
HINTS
|
||||
${PC_ZSTD_LIBDIR}
|
||||
${PC_ZSTD_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(PC_ZSTD_VERSION)
|
||||
set(ZSTD_VERSION ${PC_ZSTD_VERSION})
|
||||
elseif(ZSTD_INCLUDE_DIR AND EXISTS "${ZSTD_INCLUDE_DIR}/zstd.h")
|
||||
set(_version_regex1 "#[\t ]*define[ \t]+ZSTD_VERSION_MAJOR[ \t]+([0-9]+).*")
|
||||
set(_version_regex2 "#[\t ]*define[ \t]+ZSTD_VERSION_MINOR[ \t]+([0-9]+).*")
|
||||
set(_version_regex3 "#[\t ]*define[ \t]+ZSTD_VERSION_RELEASE[ \t]+([0-9]+).*")
|
||||
file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str1 REGEX "${_version_regex1}")
|
||||
file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str2 REGEX "${_version_regex2}")
|
||||
file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str3 REGEX "${_version_regex3}")
|
||||
string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
|
||||
string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
|
||||
string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
|
||||
set(ZSTD_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
|
||||
unset(_version_regex1)
|
||||
unset(_version_regex2)
|
||||
unset(_version_regex3)
|
||||
unset(_version_str1)
|
||||
unset(_version_str2)
|
||||
unset(_version_str3)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Zstd
|
||||
REQUIRED_VARS
|
||||
ZSTD_INCLUDE_DIR
|
||||
ZSTD_LIBRARY
|
||||
VERSION_VAR
|
||||
ZSTD_VERSION
|
||||
)
|
||||
|
||||
if(ZSTD_FOUND)
|
||||
set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR})
|
||||
set(ZSTD_LIBRARIES ${ZSTD_LIBRARY})
|
||||
endif()
|
||||
string(REPLACE ";" " " ZSTD_CFLAGS "${ZSTD_CFLAGS}")
|
||||
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")
|
||||
|
||||
mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY)
|
||||
unset(ZSTD_VERSION CACHE)
|
||||
if(ZSTD_INCLUDE_DIR AND EXISTS "${ZSTD_INCLUDE_DIR}/zstd.h")
|
||||
set(_version_regex1 "#[\t ]*define[ \t]+ZSTD_VERSION_MAJOR[ \t]+([0-9]+).*")
|
||||
set(_version_regex2 "#[\t ]*define[ \t]+ZSTD_VERSION_MINOR[ \t]+([0-9]+).*")
|
||||
set(_version_regex3 "#[\t ]*define[ \t]+ZSTD_VERSION_RELEASE[ \t]+([0-9]+).*")
|
||||
file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str1 REGEX "${_version_regex1}")
|
||||
file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str2 REGEX "${_version_regex2}")
|
||||
file(STRINGS "${ZSTD_INCLUDE_DIR}/zstd.h" _version_str3 REGEX "${_version_regex3}")
|
||||
string(REGEX REPLACE "${_version_regex1}" "\\1" _version_str1 "${_version_str1}")
|
||||
string(REGEX REPLACE "${_version_regex2}" "\\1" _version_str2 "${_version_str2}")
|
||||
string(REGEX REPLACE "${_version_regex3}" "\\1" _version_str3 "${_version_str3}")
|
||||
set(ZSTD_VERSION "${_version_str1}.${_version_str2}.${_version_str3}")
|
||||
unset(_version_regex1)
|
||||
unset(_version_regex2)
|
||||
unset(_version_regex3)
|
||||
unset(_version_str1)
|
||||
unset(_version_str2)
|
||||
unset(_version_str3)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Zstd
|
||||
REQUIRED_VARS
|
||||
ZSTD_INCLUDE_DIR
|
||||
ZSTD_LIBRARY
|
||||
VERSION_VAR
|
||||
ZSTD_VERSION
|
||||
)
|
||||
|
||||
if(ZSTD_FOUND)
|
||||
set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR})
|
||||
set(ZSTD_LIBRARIES ${ZSTD_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY)
|
||||
endif()
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
# This macro is intended to be called multiple times with a sequence of
|
||||
# possibly dependent header files. Some headers depend on others to be
|
||||
# compiled correctly.
|
||||
macro(check_include_file_concat _file _variable)
|
||||
macro(check_include_file_concat_curl _file _variable)
|
||||
check_include_files("${CURL_INCLUDES};${_file}" ${_variable})
|
||||
if(${_variable})
|
||||
list(APPEND CURL_INCLUDES ${_file})
|
||||
@@ -62,21 +62,25 @@ macro(curl_internal_test _curl_test)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(curl_dependency_option _dependency)
|
||||
set(CURL_${_dependency} "AUTO" CACHE STRING "Build curl with ${_dependency} support (AUTO, ON or OFF)")
|
||||
set_property(CACHE CURL_${_dependency} PROPERTY STRINGS "AUTO" "ON" "OFF")
|
||||
macro(curl_dependency_option _option_name _find_name _desc_name)
|
||||
set(${_option_name} "AUTO" CACHE STRING "Build curl with ${_desc_name} support (AUTO, ON or OFF)")
|
||||
set_property(CACHE ${_option_name} PROPERTY STRINGS "AUTO" "ON" "OFF")
|
||||
|
||||
if(CURL_${_dependency} STREQUAL "AUTO")
|
||||
find_package(${_dependency})
|
||||
elseif(CURL_${_dependency})
|
||||
find_package(${_dependency} REQUIRED)
|
||||
if(${_option_name} STREQUAL "AUTO")
|
||||
find_package(${_find_name})
|
||||
elseif(${_option_name})
|
||||
find_package(${_find_name} REQUIRED)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Convert the passed paths to libpath linker options and add them to CMAKE_REQUIRED_LINK_OPTIONS.
|
||||
# Convert the passed paths to libpath linker options and add them to CMAKE_REQUIRED_*.
|
||||
macro(curl_required_libpaths _libpaths_arg)
|
||||
set(_libpaths "${_libpaths_arg}")
|
||||
foreach(_libpath IN LISTS _libpaths)
|
||||
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_LIBRARY_PATH_FLAG}${_libpath}")
|
||||
endforeach()
|
||||
if(CMAKE_VERSION VERSION_LESS 3.31)
|
||||
set(_libpaths "${_libpaths_arg}")
|
||||
foreach(_libpath IN LISTS _libpaths)
|
||||
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_LIBRARY_PATH_FLAG}${_libpath}")
|
||||
endforeach()
|
||||
else()
|
||||
list(APPEND CMAKE_REQUIRED_LINK_DIRECTORIES "${_libpaths_arg}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -25,7 +25,7 @@ include(CheckCSourceCompiles)
|
||||
include(CheckCSourceRuns)
|
||||
include(CheckTypeSize)
|
||||
|
||||
macro(add_header_include _check _header)
|
||||
macro(curl_add_header_include _check _header)
|
||||
if(${_check})
|
||||
set(_source_epilogue "${_source_epilogue}
|
||||
#include <${_header}>")
|
||||
@@ -37,10 +37,10 @@ set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
||||
if(NOT DEFINED HAVE_STRUCT_SOCKADDR_STORAGE)
|
||||
cmake_push_check_state()
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "")
|
||||
if(WIN32)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h")
|
||||
set(CMAKE_REQUIRED_LIBRARIES "ws2_32")
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32")
|
||||
elseif(HAVE_SYS_SOCKET_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
|
||||
endif()
|
||||
@@ -51,8 +51,8 @@ endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
set(_source_epilogue "#undef inline")
|
||||
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
curl_add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
curl_add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void)
|
||||
{
|
||||
@@ -63,7 +63,7 @@ if(NOT WIN32)
|
||||
endif()
|
||||
|
||||
set(_source_epilogue "#undef inline")
|
||||
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
curl_add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
#include <time.h>
|
||||
int main(void)
|
||||
@@ -98,9 +98,9 @@ endif()
|
||||
|
||||
if(NOT DEFINED HAVE_GETADDRINFO_THREADSAFE)
|
||||
set(_source_epilogue "#undef inline")
|
||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
add_header_include(HAVE_NETDB_H "netdb.h")
|
||||
curl_add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
curl_add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
curl_add_header_include(HAVE_NETDB_H "netdb.h")
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void)
|
||||
{
|
||||
@@ -141,8 +141,8 @@ endif()
|
||||
|
||||
if(NOT WIN32 AND NOT DEFINED HAVE_CLOCK_GETTIME_MONOTONIC_RAW)
|
||||
set(_source_epilogue "#undef inline")
|
||||
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
curl_add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
curl_add_header_include(HAVE_SYS_TIME_H "sys/time.h")
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
#include <time.h>
|
||||
int main(void)
|
||||
|
||||
@@ -23,17 +23,15 @@
|
||||
###########################################################################
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
unset(_picky)
|
||||
set(_picky "")
|
||||
|
||||
if(CURL_WERROR AND
|
||||
((CMAKE_COMPILER_IS_GNUCC AND
|
||||
NOT DOS AND # Watt-32 headers use the '#include_next' GCC extension
|
||||
NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND
|
||||
NOT CMAKE_VERSION VERSION_LESS 3.23.0) OR # to avoid check_symbol_exists() conflicting with GCC -pedantic-errors
|
||||
CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||
list(APPEND _picky "-pedantic-errors")
|
||||
if(MSVC) # clang-cl
|
||||
list(APPEND _picky "-Wno-language-extension-token") # Override default error to make __int64 size detection pass
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND
|
||||
@@ -77,7 +75,6 @@ if(PICKY_COMPILER)
|
||||
list(APPEND _picky_enable
|
||||
-Wbad-function-cast # clang 2.7 gcc 2.95
|
||||
-Wconversion # clang 2.7 gcc 2.95
|
||||
-Winline # clang 1.0 gcc 1.0
|
||||
-Wmissing-declarations # clang 1.0 gcc 2.7
|
||||
-Wmissing-prototypes # clang 1.0 gcc 1.0
|
||||
-Wnested-externs # clang 1.0 gcc 2.7
|
||||
@@ -106,12 +103,11 @@ if(PICKY_COMPILER)
|
||||
-Wmissing-field-initializers # clang 2.7 gcc 4.1
|
||||
-Wmissing-noreturn # clang 2.7 gcc 4.1
|
||||
-Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0)
|
||||
-Wno-sign-conversion # clang 2.9 gcc 4.3
|
||||
-Wno-system-headers # clang 1.0 gcc 3.0
|
||||
# -Wpadded # clang 2.9 gcc 4.1 # Not used: We cannot change public structs
|
||||
-Wold-style-definition # clang 2.7 gcc 3.4
|
||||
-Wredundant-decls # clang 2.7 gcc 4.1
|
||||
-Wsign-conversion # clang 2.9 gcc 4.3
|
||||
-Wno-error=sign-conversion # FIXME
|
||||
-Wstrict-prototypes # clang 1.0 gcc 3.3
|
||||
# -Wswitch-enum # clang 2.7 gcc 4.1 # Not used: It basically disallows default case
|
||||
-Wtype-limits # clang 2.7 gcc 4.3
|
||||
@@ -121,13 +117,6 @@ if(PICKY_COMPILER)
|
||||
-Wvla # clang 2.8 gcc 4.3
|
||||
)
|
||||
|
||||
set(_picky_common
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0
|
||||
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
|
||||
-Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1
|
||||
)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND _picky_enable
|
||||
${_picky_common_old}
|
||||
@@ -137,17 +126,20 @@ if(PICKY_COMPILER)
|
||||
)
|
||||
if(NOT MSVC)
|
||||
list(APPEND _picky_enable
|
||||
-Wlanguage-extension-token # clang 3.0 # Avoid for clang-cl to allow __int64
|
||||
-Wlanguage-extension-token # clang 3.0
|
||||
)
|
||||
endif()
|
||||
# Enable based on compiler version
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
|
||||
list(APPEND _picky_enable
|
||||
${_picky_common}
|
||||
# -Wunreachable-code-break # clang 3.5 appleclang 6.0 # Not used: Silent in "unity" builds
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0
|
||||
-Wheader-guard # clang 3.4 appleclang 5.1
|
||||
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
|
||||
-Wsometimes-uninitialized # clang 3.2 appleclang 4.6
|
||||
# -Wunreachable-code-break # clang 3.5 appleclang 6.0 # Not used: Silent in "unity" builds
|
||||
-Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR
|
||||
@@ -171,9 +163,6 @@ if(PICKY_COMPILER)
|
||||
)
|
||||
endif()
|
||||
else() # gcc
|
||||
list(APPEND _picky_detect
|
||||
${_picky_common}
|
||||
)
|
||||
# Enable based on compiler version
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3)
|
||||
list(APPEND _picky_enable
|
||||
@@ -181,8 +170,8 @@ if(PICKY_COMPILER)
|
||||
-Wclobbered # gcc 4.3
|
||||
-Wmissing-parameter-type # gcc 4.3
|
||||
-Wold-style-declaration # gcc 4.3
|
||||
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
|
||||
-Wstrict-aliasing=3 # gcc 4.0
|
||||
-Wtrampolines # gcc 4.3
|
||||
)
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5 AND MINGW)
|
||||
@@ -192,7 +181,9 @@ if(PICKY_COMPILER)
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8)
|
||||
list(APPEND _picky_enable
|
||||
-Wdouble-promotion # clang 3.6 gcc 4.6 appleclang 6.3
|
||||
-Wformat=2 # clang 3.0 gcc 4.8
|
||||
-Wtrampolines # gcc 4.6
|
||||
)
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
@@ -207,6 +198,7 @@ if(PICKY_COMPILER)
|
||||
-fdelete-null-pointer-checks
|
||||
-Wshift-negative-value # clang 3.7 gcc 6.0 (clang default)
|
||||
-Wshift-overflow=2 # clang 3.0 gcc 6.0 (clang default: -Wshift-overflow)
|
||||
-Wunused-const-variable # clang 3.4 gcc 6.0 appleclang 5.1
|
||||
)
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0)
|
||||
@@ -221,6 +213,7 @@ if(PICKY_COMPILER)
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0)
|
||||
list(APPEND _picky_enable
|
||||
-Warith-conversion # gcc 10.0
|
||||
-Wenum-conversion # clang 3.2 gcc 10.0 appleclang 4.6 g++ 11.0
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -242,20 +235,41 @@ if(PICKY_COMPILER)
|
||||
list(APPEND _picky "${_ccopt}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if(CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5)
|
||||
# Avoid false positives
|
||||
list(APPEND _picky "-Wno-shadow")
|
||||
list(APPEND _picky "-Wno-unreachable-code")
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.2 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6)
|
||||
# GCC <4.6 do not support #pragma to suppress warnings locally. Disable them globally instead.
|
||||
list(APPEND _picky "-Wno-overlength-strings")
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7)
|
||||
list(APPEND _picky "-Wno-missing-field-initializers") # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36750
|
||||
endif()
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3 AND CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8)
|
||||
list(APPEND _picky "-Wno-type-limits") # Avoid false positives
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# clang-cl
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.12)
|
||||
set(_picky_tmp "")
|
||||
foreach(_ccopt IN LISTS _picky)
|
||||
list(APPEND _picky_tmp "/clang:${_ccopt}")
|
||||
endforeach()
|
||||
set(_picky ${_picky_tmp})
|
||||
else()
|
||||
list(TRANSFORM _picky PREPEND "/clang:")
|
||||
endif()
|
||||
list(APPEND _picky "-Wno-language-extension-token") # Allow __int64
|
||||
|
||||
set(_picky_tmp "")
|
||||
foreach(_ccopt IN LISTS _picky)
|
||||
# Prefix -Wall, otherwise clang-cl interprets it as an MSVC option and translates it to -Weverything
|
||||
if(_ccopt MATCHES "^-W" AND NOT _ccopt STREQUAL "-Wall")
|
||||
list(APPEND _picky_tmp ${_ccopt})
|
||||
else()
|
||||
list(APPEND _picky_tmp "-clang:${_ccopt}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(_picky ${_picky_tmp})
|
||||
endif()
|
||||
|
||||
if(_picky)
|
||||
|
||||
@@ -23,13 +23,31 @@
|
||||
###########################################################################
|
||||
# File containing various utilities
|
||||
|
||||
# Returns number of arguments that evaluate to true
|
||||
function(count_true _output_count_var)
|
||||
set(lst_len 0)
|
||||
foreach(option_var IN LISTS ARGN)
|
||||
if(${option_var})
|
||||
math(EXPR lst_len "${lst_len} + 1")
|
||||
# Return number of arguments that evaluate to true
|
||||
function(curl_count_true _output_count_var)
|
||||
set(_list_len 0)
|
||||
foreach(_option_var IN LISTS ARGN)
|
||||
if(${_option_var})
|
||||
math(EXPR _list_len "${_list_len} + 1")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${_output_count_var} ${lst_len} PARENT_SCOPE)
|
||||
set(${_output_count_var} ${_list_len} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Dump all defined variables with their values
|
||||
function(curl_dumpvars)
|
||||
message("::group::CMake Variable Dump")
|
||||
get_cmake_property(_vars VARIABLES)
|
||||
foreach(_var IN ITEMS ${_vars})
|
||||
get_property(_var_type CACHE ${_var} PROPERTY TYPE)
|
||||
get_property(_var_advanced CACHE ${_var} PROPERTY ADVANCED)
|
||||
if(_var_type)
|
||||
set(_var_type ":${_var_type}")
|
||||
endif()
|
||||
if(_var_advanced)
|
||||
set(_var_advanced " [adv]")
|
||||
endif()
|
||||
message("${_var}${_var_type}${_var_advanced} = ${${_var}}")
|
||||
endforeach()
|
||||
message("::endgroup::")
|
||||
endfunction()
|
||||
|
||||
@@ -23,13 +23,6 @@
|
||||
###########################################################################
|
||||
@PACKAGE_INIT@
|
||||
|
||||
if(UNIX OR VCPKG_TOOLCHAIN OR (MINGW AND NOT CMAKE_CROSSCOMPILING)) # Keep in sync with root CMakeLists.txt
|
||||
set(_curl_use_pkgconfig_default ON)
|
||||
else()
|
||||
set(_curl_use_pkgconfig_default OFF)
|
||||
endif()
|
||||
option(CURL_USE_PKGCONFIG "Enable pkg-config to detect @PROJECT_NAME@ dependencies" ${_curl_use_pkgconfig_default})
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
if("@USE_OPENSSL@")
|
||||
find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
|
||||
@@ -39,7 +32,6 @@ if("@HAVE_LIBZ@")
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
|
||||
# Alias for either shared or static library
|
||||
if(NOT TARGET @PROJECT_NAME@::libcurl)
|
||||
@@ -47,5 +39,32 @@ if(NOT TARGET @PROJECT_NAME@::libcurl)
|
||||
endif()
|
||||
|
||||
# For compatibility with CMake's FindCURL.cmake
|
||||
set(CURL_VERSION_STRING "@CURLVERSION@")
|
||||
set(CURL_LIBRARIES @PROJECT_NAME@::libcurl)
|
||||
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@")
|
||||
|
||||
@@ -32,11 +32,11 @@ if(MINGW)
|
||||
set(HAVE_UNISTD_H 1)
|
||||
set(HAVE_LIBGEN_H 1)
|
||||
set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size()
|
||||
set(HAVE_STDINT_H 1) # detected by CMake internally in check_type_size()
|
||||
set(HAVE_STDBOOL_H 1)
|
||||
set(HAVE_BOOL_T "${HAVE_STDBOOL_H}")
|
||||
set(HAVE_STRTOLL 1)
|
||||
set(HAVE_BASENAME 1)
|
||||
set(HAVE_STRCASECMP 1)
|
||||
set(HAVE_FTRUNCATE 1)
|
||||
set(HAVE_SYS_PARAM_H 1)
|
||||
set(HAVE_SYS_TIME_H 1)
|
||||
@@ -45,9 +45,23 @@ if(MINGW)
|
||||
set(HAVE_UTIME_H 1) # wrapper to sys/utime.h
|
||||
set(HAVE_DIRENT_H 1)
|
||||
set(HAVE_OPENDIR 1)
|
||||
if(MINGW64_VERSION)
|
||||
if(NOT MINGW64_VERSION VERSION_LESS 4.0)
|
||||
set(HAVE_STRTOK_R 1)
|
||||
else()
|
||||
set(HAVE_STRTOK_R 0)
|
||||
endif()
|
||||
endif()
|
||||
if((CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6))
|
||||
set(HAVE_STDATOMIC_H 1)
|
||||
set(HAVE_ATOMIC 1)
|
||||
else()
|
||||
set(HAVE_STDATOMIC_H 0)
|
||||
set(HAVE_ATOMIC 0)
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_LIBGEN_H 0)
|
||||
set(HAVE_STRCASECMP 0)
|
||||
set(HAVE_FTRUNCATE 0)
|
||||
set(HAVE_SYS_PARAM_H 0)
|
||||
set(HAVE_SYS_TIME_H 0)
|
||||
@@ -58,9 +72,13 @@ else()
|
||||
set(HAVE_OPENDIR 0)
|
||||
if(MSVC)
|
||||
set(HAVE_UNISTD_H 0)
|
||||
set(HAVE_LOCALE_H 1)
|
||||
set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size()
|
||||
set(HAVE_STDATOMIC_H 0)
|
||||
if(NOT MSVC_VERSION LESS 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()
|
||||
if(NOT MSVC_VERSION LESS 1800)
|
||||
set(HAVE_STDBOOL_H 1)
|
||||
set(HAVE_STRTOLL 1)
|
||||
@@ -85,7 +103,6 @@ endif()
|
||||
set(HAVE_GETADDRINFO 1)
|
||||
set(HAVE_FREEADDRINFO 1)
|
||||
|
||||
set(HAVE_FCHMOD 0)
|
||||
set(HAVE_SOCKETPAIR 0)
|
||||
set(HAVE_SENDMSG 0)
|
||||
set(HAVE_SENDMMSG 0)
|
||||
@@ -112,10 +129,8 @@ set(HAVE_GETHOSTNAME 1)
|
||||
set(HAVE_RECV 1)
|
||||
set(HAVE_SEND 1)
|
||||
set(HAVE_STROPTS_H 0)
|
||||
set(HAVE_SYS_XATTR_H 0)
|
||||
set(HAVE_ARC4RANDOM 0)
|
||||
set(HAVE_FNMATCH 0)
|
||||
set(HAVE_SCHED_YIELD 0)
|
||||
set(HAVE_ARPA_INET_H 0)
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_IFADDRS_H 0)
|
||||
@@ -132,7 +147,6 @@ set(HAVE_POLL 0)
|
||||
set(HAVE_PWD_H 0)
|
||||
set(HAVE_SYS_EVENTFD_H 0)
|
||||
set(HAVE_SYS_FILIO_H 0)
|
||||
set(HAVE_SYS_WAIT_H 0)
|
||||
set(HAVE_SYS_IOCTL_H 0)
|
||||
set(HAVE_SYS_POLL_H 0)
|
||||
set(HAVE_SYS_RESOURCE_H 0)
|
||||
@@ -147,12 +161,9 @@ set(HAVE_TERMIOS_H 0)
|
||||
set(HAVE_TERMIO_H 0)
|
||||
set(HAVE_LINUX_TCP_H 0)
|
||||
|
||||
set(HAVE_FSEEKO 0) # mingw-w64 2.0.0 and newer has it
|
||||
set(HAVE_SOCKET 1)
|
||||
set(HAVE_SELECT 1)
|
||||
set(HAVE_STRDUP 1)
|
||||
set(HAVE_STRICMP 1)
|
||||
set(HAVE_STRCMPI 1)
|
||||
set(HAVE_MEMRCHR 0)
|
||||
set(HAVE_CLOSESOCKET 1)
|
||||
set(HAVE_SIGSETJMP 0)
|
||||
@@ -178,6 +189,7 @@ set(HAVE_POSIX_STRERROR_R 0)
|
||||
set(HAVE_MSG_NOSIGNAL 0)
|
||||
set(HAVE_STRUCT_TIMEVAL 1)
|
||||
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
|
||||
set(HAVE_TIME_T_UNSIGNED 0)
|
||||
|
||||
set(HAVE_GETHOSTBYNAME_R_3 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
|
||||
@@ -186,7 +198,6 @@ set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_6 0)
|
||||
set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
|
||||
|
||||
set(HAVE_O_NONBLOCK 0)
|
||||
set(HAVE_IN_ADDR_T 0)
|
||||
set(STDC_HEADERS 1)
|
||||
|
||||
914
CMakeLists.txt
914
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
2
COPYING
2
COPYING
@@ -1,6 +1,6 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2024, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
Copyright (c) 1996 - 2025, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
contributors, see the THANKS file.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@@ -1959,10 +1959,10 @@ typedef enum {
|
||||
/* Set stream weight, 1 - 256 (default is 16) */
|
||||
CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239),
|
||||
|
||||
/* Set stream dependency on another CURL handle */
|
||||
/* Set stream dependency on another curl handle */
|
||||
CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240),
|
||||
|
||||
/* Set E-xclusive stream dependency on another CURL handle */
|
||||
/* Set E-xclusive stream dependency on another curl handle */
|
||||
CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241),
|
||||
|
||||
/* Do not send any tftp option requests to the server */
|
||||
@@ -2959,7 +2959,9 @@ typedef enum {
|
||||
CURLINFO_USED_PROXY = CURLINFO_LONG + 66,
|
||||
CURLINFO_POSTTRANSFER_TIME_T = CURLINFO_OFF_T + 67,
|
||||
CURLINFO_EARLYDATA_SENT_T = CURLINFO_OFF_T + 68,
|
||||
CURLINFO_LASTONE = 68
|
||||
CURLINFO_HTTPAUTH_USED = CURLINFO_LONG + 69,
|
||||
CURLINFO_PROXYAUTH_USED = CURLINFO_LONG + 70,
|
||||
CURLINFO_LASTONE = 70
|
||||
} CURLINFO;
|
||||
|
||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||
@@ -3230,6 +3232,50 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
|
||||
#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND)
|
||||
#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
|
||||
|
||||
/*
|
||||
* NAME curl_easy_ssls_import()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* The curl_easy_ssls_import function adds a previously exported SSL session
|
||||
* to the SSL session cache of the easy handle (or the underlying share).
|
||||
*/
|
||||
CURL_EXTERN CURLcode curl_easy_ssls_import(CURL *handle,
|
||||
const char *session_key,
|
||||
const unsigned char *shmac,
|
||||
size_t shmac_len,
|
||||
const unsigned char *sdata,
|
||||
size_t sdata_len);
|
||||
|
||||
/* This is the curl_ssls_export_cb callback prototype. It
|
||||
* is passed to curl_easy_ssls_export() to extract SSL sessions/tickets. */
|
||||
typedef CURLcode curl_ssls_export_cb(CURL *handle,
|
||||
void *userptr,
|
||||
const char *session_key,
|
||||
const unsigned char *shmac,
|
||||
size_t shmac_len,
|
||||
const unsigned char *sdata,
|
||||
size_t sdata_len,
|
||||
curl_off_t valid_until,
|
||||
int ietf_tls_id,
|
||||
const char *alpn,
|
||||
size_t earlydata_max);
|
||||
|
||||
/*
|
||||
* NAME curl_easy_ssls_export()
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* The curl_easy_ssls_export function iterates over all SSL sessions stored
|
||||
* in the easy handle (or underlying share) and invokes the passed
|
||||
* callback.
|
||||
*
|
||||
*/
|
||||
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,13 +32,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "8.11.1-DEV"
|
||||
#define LIBCURL_VERSION "8.12.0-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 8
|
||||
#define LIBCURL_VERSION_MINOR 11
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
#define LIBCURL_VERSION_MINOR 12
|
||||
#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
|
||||
@@ -59,7 +59,7 @@
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x080b01
|
||||
#define LIBCURL_VERSION_NUM 0x080c00
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -78,7 +78,7 @@ CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Re-initializes a CURL handle to the default values. This puts back the
|
||||
* Re-initializes a curl handle to the default values. This puts back the
|
||||
* handle to the same state as it was in when it was just created.
|
||||
*
|
||||
* It does keep: live connections, the Session ID cache, the DNS cache and the
|
||||
|
||||
@@ -52,62 +52,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__DJGPP__) || defined(__GO32__)
|
||||
# if defined(__DJGPP__) && (__DJGPP__ > 1)
|
||||
# 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
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__SALFORDC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
#if defined(__DJGPP__)
|
||||
# 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
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ < 0x520)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# 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
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# 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(__POCC__)
|
||||
# if (__POCC__ < 280)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# elif defined(_MSC_VER)
|
||||
# if defined(_MSC_VER)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "I64u"
|
||||
@@ -159,15 +121,21 @@
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
|
||||
#elif defined(__TANDEM)
|
||||
# if ! defined(__LP64)
|
||||
/* Required for 32-bit NonStop builds only. */
|
||||
# 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
|
||||
# endif
|
||||
# if !defined(__LP64)
|
||||
# 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 long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
# endif
|
||||
|
||||
#elif defined(_WIN32_WCE)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
@@ -220,13 +188,7 @@
|
||||
# define CURL_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T LL
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# else /* _LP64 and default */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
@@ -239,22 +201,13 @@
|
||||
|
||||
#elif defined(__370__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# elif defined(_LP64)
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# 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
|
||||
# elif defined(_LP64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# else /* _LP64 and default */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
@@ -349,24 +302,15 @@
|
||||
#elif defined(_MSC_VER)
|
||||
# if (_MSC_VER >= 1800)
|
||||
# include <inttypes.h>
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_FORMAT_CURL_OFF_T PRId64
|
||||
# define CURL_FORMAT_CURL_OFF_TU PRIu64
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# elif (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# else
|
||||
# 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
|
||||
# else
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURL_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURL_SUFFIX_CURL_OFF_T i64
|
||||
# define CURL_SUFFIX_CURL_OFF_TU ui64
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
|
||||
/* ===================================== */
|
||||
@@ -403,12 +347,12 @@
|
||||
|
||||
#else
|
||||
/* generic "safe guess" on old 32-bit style */
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURL_TYPEOF_CURL_OFF_T long
|
||||
# define CURL_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURL_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURL_SUFFIX_CURL_OFF_T L
|
||||
# define CURL_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURL_TYPEOF_CURL_SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
@@ -462,7 +406,7 @@
|
||||
|
||||
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
|
||||
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
|
||||
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
|
||||
defined(__POCC__) || defined(__HIGHC__) || \
|
||||
defined(__ILEC400__)
|
||||
/* This compiler is believed to have an ISO compatible preprocessor */
|
||||
#define CURL_ISOCPP
|
||||
|
||||
@@ -28,7 +28,7 @@ add_definitions("-DBUILDING_LIBCURL")
|
||||
configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h")
|
||||
|
||||
# Get 'CSOURCES', 'HHEADERS' variables
|
||||
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
|
||||
|
||||
# DllMain is added later for DLL builds only.
|
||||
@@ -105,9 +105,7 @@ if(SHARE_LIB_OBJECT)
|
||||
set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_OBJECT} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
set_target_properties(${LIB_OBJECT} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_OBJECT} INTERFACE
|
||||
@@ -138,9 +136,7 @@ if(BUILD_STATIC_LIBS)
|
||||
set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_STATIC} INTERFACE
|
||||
@@ -177,9 +173,7 @@ if(BUILD_SHARED_LIBS)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_SHARED} INTERFACE
|
||||
@@ -208,7 +202,7 @@ if(BUILD_SHARED_LIBS)
|
||||
|
||||
if(CURL_LIBCURL_SOVERSION OR CURL_LIBCURL_VERSIONED_SYMBOLS)
|
||||
# Get 'VERSIONCHANGE', 'VERSIONADD', 'VERSIONDEL', 'VERSIONINFO' variables
|
||||
transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
|
||||
curl_transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
|
||||
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
|
||||
|
||||
math(EXPR _cmakesoname "${VERSIONCHANGE} - ${VERSIONDEL}")
|
||||
|
||||
@@ -56,6 +56,8 @@ LIB_VTLS_CFILES = \
|
||||
vtls/schannel_verify.c \
|
||||
vtls/sectransp.c \
|
||||
vtls/vtls.c \
|
||||
vtls/vtls_scache.c \
|
||||
vtls/vtls_spack.c \
|
||||
vtls/wolfssl.c \
|
||||
vtls/x509asn1.c
|
||||
|
||||
@@ -74,6 +76,8 @@ LIB_VTLS_HFILES = \
|
||||
vtls/sectransp.h \
|
||||
vtls/vtls.h \
|
||||
vtls/vtls_int.h \
|
||||
vtls/vtls_scache.h \
|
||||
vtls/vtls_spack.h \
|
||||
vtls/wolfssl.h \
|
||||
vtls/x509asn1.h
|
||||
|
||||
@@ -112,7 +116,6 @@ LIB_CFILES = \
|
||||
base64.c \
|
||||
bufq.c \
|
||||
bufref.c \
|
||||
c-hyper.c \
|
||||
cf-h1-proxy.c \
|
||||
cf-h2-proxy.c \
|
||||
cf-haproxy.c \
|
||||
@@ -177,6 +180,7 @@ LIB_CFILES = \
|
||||
http_negotiate.c \
|
||||
http_ntlm.c \
|
||||
http_proxy.c \
|
||||
httpsrr.c \
|
||||
idn.c \
|
||||
if2ip.c \
|
||||
imap.c \
|
||||
@@ -223,6 +227,7 @@ LIB_CFILES = \
|
||||
strcase.c \
|
||||
strdup.c \
|
||||
strerror.c \
|
||||
strparse.c \
|
||||
strtok.c \
|
||||
strtoofft.c \
|
||||
system_win32.c \
|
||||
@@ -245,7 +250,6 @@ LIB_HFILES = \
|
||||
asyn.h \
|
||||
bufq.h \
|
||||
bufref.h \
|
||||
c-hyper.h \
|
||||
cf-h1-proxy.h \
|
||||
cf-h2-proxy.h \
|
||||
cf-haproxy.h \
|
||||
@@ -317,6 +321,7 @@ LIB_HFILES = \
|
||||
http_negotiate.h \
|
||||
http_ntlm.h \
|
||||
http_proxy.h \
|
||||
httpsrr.h \
|
||||
idn.h \
|
||||
if2ip.h \
|
||||
imap.h \
|
||||
@@ -344,7 +349,9 @@ LIB_HFILES = \
|
||||
select.h \
|
||||
sendf.h \
|
||||
setopt.h \
|
||||
setup-os400.h \
|
||||
setup-vms.h \
|
||||
setup-win32.h \
|
||||
share.h \
|
||||
sigpipe.h \
|
||||
slist.h \
|
||||
@@ -358,6 +365,7 @@ LIB_HFILES = \
|
||||
strcase.h \
|
||||
strdup.h \
|
||||
strerror.h \
|
||||
strparse.h \
|
||||
strtok.h \
|
||||
strtoofft.h \
|
||||
system_win32.h \
|
||||
|
||||
143
lib/altsvc.c
143
lib/altsvc.c
@@ -40,6 +40,8 @@
|
||||
#include "rename.h"
|
||||
#include "strdup.h"
|
||||
#include "inet_pton.h"
|
||||
#include "strparse.h"
|
||||
#include "connect.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -47,28 +49,12 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_DATELENSTR "64"
|
||||
#define MAX_ALTSVC_DATELEN 64
|
||||
#define MAX_ALTSVC_HOSTLENSTR "512"
|
||||
#define MAX_ALTSVC_HOSTLEN 512
|
||||
#define MAX_ALTSVC_ALPNLENSTR "10"
|
||||
#define MAX_ALTSVC_DATELEN 256
|
||||
#define MAX_ALTSVC_HOSTLEN 2048
|
||||
#define MAX_ALTSVC_ALPNLEN 10
|
||||
|
||||
#define H3VERSION "h3"
|
||||
|
||||
static enum alpnid alpn2alpnid(char *name)
|
||||
{
|
||||
if(strcasecompare(name, "h1"))
|
||||
return ALPN_h1;
|
||||
if(strcasecompare(name, "h2"))
|
||||
return ALPN_h2;
|
||||
if(strcasecompare(name, H3VERSION))
|
||||
return ALPN_h3;
|
||||
if(strcasecompare(name, "http/1.1"))
|
||||
return ALPN_h1;
|
||||
return ALPN_none; /* unknown, probably rubbish input */
|
||||
}
|
||||
|
||||
/* Given the ALPN ID, return the name */
|
||||
const char *Curl_alpnid2str(enum alpnid id)
|
||||
{
|
||||
@@ -93,33 +79,33 @@ static void altsvc_free(struct altsvc *as)
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_createid(const char *srchost,
|
||||
size_t hlen,
|
||||
const char *dsthost,
|
||||
size_t dlen, /* dsthost length */
|
||||
enum alpnid srcalpnid,
|
||||
enum alpnid dstalpnid,
|
||||
unsigned int srcport,
|
||||
unsigned int dstport)
|
||||
size_t srcport,
|
||||
size_t dstport)
|
||||
{
|
||||
struct altsvc *as = calloc(1, sizeof(struct altsvc));
|
||||
size_t hlen;
|
||||
if(!as)
|
||||
return NULL;
|
||||
hlen = strlen(srchost);
|
||||
DEBUGASSERT(hlen);
|
||||
DEBUGASSERT(dlen);
|
||||
if(!hlen || !dlen) {
|
||||
if(!hlen || !dlen)
|
||||
/* bad input */
|
||||
free(as);
|
||||
return NULL;
|
||||
}
|
||||
goto error;
|
||||
if((hlen > 2) && srchost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
srchost++;
|
||||
hlen -= 2;
|
||||
}
|
||||
else if(srchost[hlen - 1] == '.')
|
||||
else if(srchost[hlen - 1] == '.') {
|
||||
/* strip off trailing dot */
|
||||
hlen--;
|
||||
if(!hlen)
|
||||
goto error;
|
||||
}
|
||||
if((dlen > 2) && dsthost[0] == '[') {
|
||||
/* IPv6 address, strip off brackets */
|
||||
dsthost++;
|
||||
@@ -136,8 +122,8 @@ static struct altsvc *altsvc_createid(const char *srchost,
|
||||
|
||||
as->src.alpnid = srcalpnid;
|
||||
as->dst.alpnid = dstalpnid;
|
||||
as->src.port = curlx_ultous(srcport);
|
||||
as->dst.port = curlx_ultous(dstport);
|
||||
as->src.port = (unsigned short)srcport;
|
||||
as->dst.port = (unsigned short)dstport;
|
||||
|
||||
return as;
|
||||
error:
|
||||
@@ -145,18 +131,19 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_create(char *srchost,
|
||||
char *dsthost,
|
||||
char *srcalpn,
|
||||
char *dstalpn,
|
||||
unsigned int srcport,
|
||||
unsigned int dstport)
|
||||
static struct altsvc *altsvc_create(struct Curl_str *srchost,
|
||||
struct Curl_str *dsthost,
|
||||
struct Curl_str *srcalpn,
|
||||
struct Curl_str *dstalpn,
|
||||
size_t srcport,
|
||||
size_t dstport)
|
||||
{
|
||||
enum alpnid dstalpnid = alpn2alpnid(dstalpn);
|
||||
enum alpnid srcalpnid = alpn2alpnid(srcalpn);
|
||||
enum alpnid dstalpnid = Curl_alpn2alpnid(dstalpn->str, dstalpn->len);
|
||||
enum alpnid srcalpnid = Curl_alpn2alpnid(srcalpn->str, srcalpn->len);
|
||||
if(!srcalpnid || !dstalpnid)
|
||||
return NULL;
|
||||
return altsvc_createid(srchost, dsthost, strlen(dsthost),
|
||||
return altsvc_createid(srchost->str, srchost->len,
|
||||
dsthost->str, dsthost->len,
|
||||
srcalpnid, dstalpnid,
|
||||
srcport, dstport);
|
||||
}
|
||||
@@ -167,31 +154,50 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
|
||||
/* Example line:
|
||||
h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1
|
||||
*/
|
||||
char srchost[MAX_ALTSVC_HOSTLEN + 1];
|
||||
char dsthost[MAX_ALTSVC_HOSTLEN + 1];
|
||||
char srcalpn[MAX_ALTSVC_ALPNLEN + 1];
|
||||
char dstalpn[MAX_ALTSVC_ALPNLEN + 1];
|
||||
char date[MAX_ALTSVC_DATELEN + 1];
|
||||
unsigned int srcport;
|
||||
unsigned int dstport;
|
||||
unsigned int prio;
|
||||
unsigned int persist;
|
||||
int rc;
|
||||
struct Curl_str srchost;
|
||||
struct Curl_str dsthost;
|
||||
struct Curl_str srcalpn;
|
||||
struct Curl_str dstalpn;
|
||||
struct Curl_str date;
|
||||
size_t srcport;
|
||||
size_t dstport;
|
||||
size_t persist;
|
||||
size_t prio;
|
||||
|
||||
rc = sscanf(line,
|
||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
||||
"\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u",
|
||||
srcalpn, srchost, &srcport,
|
||||
dstalpn, dsthost, &dstport,
|
||||
date, &persist, &prio);
|
||||
if(9 == rc) {
|
||||
if(Curl_str_word(&line, &srcalpn, MAX_ALTSVC_ALPNLEN) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_word(&line, &srchost, MAX_ALTSVC_HOSTLEN) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_number(&line, &srcport, 65535) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_word(&line, &dstalpn, MAX_ALTSVC_ALPNLEN) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_word(&line, &dsthost, MAX_ALTSVC_HOSTLEN) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_number(&line, &dstport, 65535) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_quotedword(&line, &date, MAX_ALTSVC_DATELEN) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_number(&line, &persist, 1) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_number(&line, &prio, 0) ||
|
||||
Curl_str_newline(&line))
|
||||
;
|
||||
else {
|
||||
struct altsvc *as;
|
||||
time_t expires = Curl_getdate_capped(date);
|
||||
as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
|
||||
char dbuf[MAX_ALTSVC_DATELEN + 1];
|
||||
time_t expires;
|
||||
|
||||
/* The date parser works on a null terminated string. The maximum length
|
||||
is upheld by Curl_str_quotedword(). */
|
||||
memcpy(dbuf, date.str, date.len);
|
||||
dbuf[date.len] = 0;
|
||||
expires = Curl_getdate_capped(dbuf);
|
||||
as = altsvc_create(&srchost, &dsthost, &srcalpn, &dstalpn, srcport,
|
||||
dstport);
|
||||
if(as) {
|
||||
as->expires = expires;
|
||||
as->prio = prio;
|
||||
as->prio = 0; /* not supported to just set zero */
|
||||
as->persist = persist ? 1 : 0;
|
||||
Curl_llist_append(&asi->list, as, &as->node);
|
||||
}
|
||||
@@ -471,8 +477,6 @@ static time_t altsvc_debugtime(void *unused)
|
||||
#define time(x) altsvc_debugtime(x)
|
||||
#endif
|
||||
|
||||
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
|
||||
|
||||
/*
|
||||
* Curl_altsvc_parse() takes an incoming alt-svc response header and stores
|
||||
* the data correctly in the cache.
|
||||
@@ -495,6 +499,8 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
unsigned short dstport = srcport; /* the same by default */
|
||||
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
||||
size_t entries = 0;
|
||||
size_t alpnlen = strlen(alpnbuf);
|
||||
size_t srchostlen = strlen(srchost);
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
(void)data;
|
||||
#endif
|
||||
@@ -515,7 +521,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
do {
|
||||
if(*p == '=') {
|
||||
/* [protocol]="[host][:port]" */
|
||||
enum alpnid dstalpnid = alpn2alpnid(alpnbuf); /* the same by default */
|
||||
enum alpnid dstalpnid = Curl_alpn2alpnid(alpnbuf, alpnlen);
|
||||
p++;
|
||||
if(*p == '\"') {
|
||||
const char *dsthost = "";
|
||||
@@ -633,13 +639,18 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
this is the first entry of the line. */
|
||||
altsvc_flush(asi, srcalpnid, srchost, srcport);
|
||||
|
||||
as = altsvc_createid(srchost, dsthost, dstlen,
|
||||
as = altsvc_createid(srchost, srchostlen,
|
||||
dsthost, dstlen,
|
||||
srcalpnid, dstalpnid,
|
||||
srcport, dstport);
|
||||
if(as) {
|
||||
/* The expires time also needs to take the Age: value (if any) into
|
||||
account. [See RFC 7838 section 3.1] */
|
||||
as->expires = maxage + time(NULL);
|
||||
time_t secs = time(NULL);
|
||||
/* The expires time also needs to take the Age: value (if any)
|
||||
into account. [See RFC 7838 section 3.1] */
|
||||
if(maxage > (TIME_T_MAX - secs))
|
||||
as->expires = TIME_T_MAX;
|
||||
else
|
||||
as->expires = maxage + secs;
|
||||
as->persist = persist;
|
||||
Curl_llist_append(&asi->list, as, &as->node);
|
||||
infof(data, "Added alt-svc: %s:%d over %s", dsthost, dstport,
|
||||
|
||||
@@ -29,13 +29,6 @@
|
||||
#include <curl/curl.h>
|
||||
#include "llist.h"
|
||||
|
||||
enum alpnid {
|
||||
ALPN_none = 0,
|
||||
ALPN_h1 = CURLALTSVC_H1,
|
||||
ALPN_h2 = CURLALTSVC_H2,
|
||||
ALPN_h3 = CURLALTSVC_H3
|
||||
};
|
||||
|
||||
struct althost {
|
||||
char *host;
|
||||
unsigned short port;
|
||||
|
||||
@@ -196,12 +196,11 @@ int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
*/
|
||||
|
||||
struct Library *SocketBase = NULL;
|
||||
extern int errno, h_errno;
|
||||
|
||||
#ifdef __libnix__
|
||||
void __request(const char *msg);
|
||||
#else
|
||||
# define __request(msg) Printf(msg "\n\a")
|
||||
# define __request(msg) Printf((const unsigned char *)(msg "\n\a"), 0)
|
||||
#endif
|
||||
|
||||
void Curl_amiga_cleanup(void)
|
||||
@@ -215,7 +214,7 @@ void Curl_amiga_cleanup(void)
|
||||
CURLcode Curl_amiga_init(void)
|
||||
{
|
||||
if(!SocketBase)
|
||||
SocketBase = OpenLibrary("bsdsocket.library", 4);
|
||||
SocketBase = OpenLibrary((const unsigned char *)"bsdsocket.library", 4);
|
||||
|
||||
if(!SocketBase) {
|
||||
__request("No TCP/IP Stack running!");
|
||||
|
||||
258
lib/asyn-ares.c
258
lib/asyn-ares.c
@@ -24,14 +24,14 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef USE_ARES
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ares-enabled builds
|
||||
* And only for functions that fulfill the asynch resolver backend API
|
||||
* as defined in asyn.h, nothing else belongs in this file!
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
@@ -59,15 +59,101 @@
|
||||
#include "select.h"
|
||||
#include "progress.h"
|
||||
#include "timediff.h"
|
||||
#include "httpsrr.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
||||
defined(_WIN32)
|
||||
# define CARES_STATICLIB
|
||||
#endif
|
||||
#include <ares.h>
|
||||
#include <ares_version.h> /* really old c-ares did not include this by
|
||||
itself */
|
||||
|
||||
/*
|
||||
* Curl_ares_getsock() is called when the outside world (using
|
||||
* curl_multi_fdset()) wants to get our fd_set setup and we are talking with
|
||||
* ares. The caller must make sure that this function is only called when we
|
||||
* have a working ares channel.
|
||||
*
|
||||
* Returns: sockets-in-use-bitmap
|
||||
*/
|
||||
|
||||
int Curl_ares_getsock(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
curl_socket_t *socks)
|
||||
{
|
||||
struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 };
|
||||
struct timeval timebuf;
|
||||
int max = ares_getsock(channel,
|
||||
(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
|
||||
struct timeval *timeout = ares_timeout(channel, &maxtime, &timebuf);
|
||||
timediff_t milli = curlx_tvtoms(timeout);
|
||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||
return max;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ares_perform()
|
||||
*
|
||||
* 1) Ask ares what sockets it currently plays with, then
|
||||
* 2) wait for the timeout period to check for action on ares' sockets.
|
||||
* 3) tell ares to act on all the sockets marked as "with action"
|
||||
*
|
||||
* return number of sockets it worked on, or -1 on error
|
||||
*/
|
||||
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms)
|
||||
{
|
||||
int nfds;
|
||||
int bitmask;
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
struct pollfd pfd[ARES_GETSOCK_MAXNUM];
|
||||
int i;
|
||||
int num = 0;
|
||||
|
||||
bitmask = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM);
|
||||
|
||||
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
|
||||
pfd[i].events = 0;
|
||||
pfd[i].revents = 0;
|
||||
if(ARES_GETSOCK_READABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLRDNORM|POLLIN;
|
||||
}
|
||||
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLWRNORM|POLLOUT;
|
||||
}
|
||||
if(pfd[i].events)
|
||||
num++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(num) {
|
||||
nfds = Curl_poll(pfd, (unsigned int)num, timeout_ms);
|
||||
if(nfds < 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
nfds = 0;
|
||||
|
||||
if(!nfds)
|
||||
/* Call ares_process() unconditionally here, even if we simply timed out
|
||||
above, as otherwise the ares name resolve will not timeout! */
|
||||
ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||
else {
|
||||
/* 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].fd : ARES_SOCKET_BAD,
|
||||
(pfd[i].revents & (POLLWRNORM|POLLOUT)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD);
|
||||
}
|
||||
return nfds;
|
||||
}
|
||||
|
||||
#ifdef CURLRES_ARES
|
||||
|
||||
#if ARES_VERSION >= 0x010500
|
||||
/* c-ares 1.5.0 or later, the callback proto is modified */
|
||||
#define HAVE_CARES_CALLBACK_TIMEOUTS 1
|
||||
@@ -93,22 +179,19 @@
|
||||
#define HAVE_CARES_GETADDRINFO 1
|
||||
#endif
|
||||
|
||||
#if ARES_VERSION >= 0x011c00
|
||||
/* 1.28.0 and later have ares_query_dnsrec */
|
||||
#define HAVE_ARES_QUERY_DNSREC 1
|
||||
#ifdef USE_HTTPSRR
|
||||
#define USE_HTTPSRR_ARES 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
struct thread_data {
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
||||
parts */
|
||||
int last_status;
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
#endif
|
||||
char hostname[1];
|
||||
};
|
||||
|
||||
/* How long we are willing to wait for additional parallel responses after
|
||||
obtaining a "definitive" one. For old c-ares without getaddrinfo.
|
||||
|
||||
@@ -280,89 +363,13 @@ static void destroy_async_data(struct Curl_async *async)
|
||||
|
||||
/*
|
||||
* Curl_resolver_getsock() is called when someone from the outside world
|
||||
* (using curl_multi_fdset()) wants to get our fd_set setup and we are talking
|
||||
* with ares. The caller must make sure that this function is only called when
|
||||
* we have a working ares channel.
|
||||
*
|
||||
* Returns: sockets-in-use-bitmap
|
||||
* (using curl_multi_fdset()) wants to get our fd_set setup.
|
||||
*/
|
||||
|
||||
int Curl_resolver_getsock(struct Curl_easy *data,
|
||||
curl_socket_t *socks)
|
||||
int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
{
|
||||
struct timeval maxtime = { CURL_TIMEOUT_RESOLVE, 0 };
|
||||
struct timeval timebuf;
|
||||
int max = ares_getsock((ares_channel)data->state.async.resolver,
|
||||
(ares_socket_t *)socks, MAX_SOCKSPEREASYHANDLE);
|
||||
struct timeval *timeout =
|
||||
ares_timeout((ares_channel)data->state.async.resolver, &maxtime, &timebuf);
|
||||
timediff_t milli = curlx_tvtoms(timeout);
|
||||
Curl_expire(data, milli, EXPIRE_ASYNC_NAME);
|
||||
return max;
|
||||
}
|
||||
|
||||
/*
|
||||
* waitperform()
|
||||
*
|
||||
* 1) Ask ares what sockets it currently plays with, then
|
||||
* 2) wait for the timeout period to check for action on ares' sockets.
|
||||
* 3) tell ares to act on all the sockets marked as "with action"
|
||||
*
|
||||
* return number of sockets it worked on, or -1 on error
|
||||
*/
|
||||
|
||||
static int waitperform(struct Curl_easy *data, timediff_t timeout_ms)
|
||||
{
|
||||
int nfds;
|
||||
int bitmask;
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
struct pollfd pfd[ARES_GETSOCK_MAXNUM];
|
||||
int i;
|
||||
int num = 0;
|
||||
|
||||
bitmask = ares_getsock((ares_channel)data->state.async.resolver, socks,
|
||||
ARES_GETSOCK_MAXNUM);
|
||||
|
||||
for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
|
||||
pfd[i].events = 0;
|
||||
pfd[i].revents = 0;
|
||||
if(ARES_GETSOCK_READABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLRDNORM|POLLIN;
|
||||
}
|
||||
if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
|
||||
pfd[i].fd = socks[i];
|
||||
pfd[i].events |= POLLWRNORM|POLLOUT;
|
||||
}
|
||||
if(pfd[i].events)
|
||||
num++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(num) {
|
||||
nfds = Curl_poll(pfd, (unsigned int)num, timeout_ms);
|
||||
if(nfds < 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
nfds = 0;
|
||||
|
||||
if(!nfds)
|
||||
/* Call ares_process() unconditionally here, even if we simply timed out
|
||||
above, as otherwise the ares name resolve will not timeout! */
|
||||
ares_process_fd((ares_channel)data->state.async.resolver, ARES_SOCKET_BAD,
|
||||
ARES_SOCKET_BAD);
|
||||
else {
|
||||
/* move through the descriptors and ask for processing on them */
|
||||
for(i = 0; i < num; i++)
|
||||
ares_process_fd((ares_channel)data->state.async.resolver,
|
||||
(pfd[i].revents & (POLLRDNORM|POLLIN)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD,
|
||||
(pfd[i].revents & (POLLWRNORM|POLLOUT)) ?
|
||||
pfd[i].fd : ARES_SOCKET_BAD);
|
||||
}
|
||||
return nfds;
|
||||
return Curl_ares_getsock(data, (ares_channel)data->state.async.resolver,
|
||||
socks);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -381,7 +388,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||
DEBUGASSERT(dns);
|
||||
*dns = NULL;
|
||||
|
||||
if(waitperform(data, 0) < 0)
|
||||
if(Curl_ares_perform((ares_channel)data->state.async.resolver, 0) < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
@@ -417,8 +424,19 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||
|
||||
if(!data->state.async.dns)
|
||||
result = Curl_resolver_error(data);
|
||||
else
|
||||
else {
|
||||
*dns = data->state.async.dns;
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
{
|
||||
struct Curl_https_rrinfo *lhrr =
|
||||
Curl_memdup(&res->hinfo, sizeof(struct Curl_https_rrinfo));
|
||||
if(!lhrr)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
(*dns)->hinfo = lhrr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
destroy_async_data(&data->state.async);
|
||||
}
|
||||
@@ -481,7 +499,8 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data,
|
||||
else
|
||||
timeout_ms = 1000;
|
||||
|
||||
if(waitperform(data, timeout_ms) < 0)
|
||||
if(Curl_ares_perform((ares_channel)data->state.async.resolver,
|
||||
timeout_ms) < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
result = Curl_resolver_is_resolved(data, entry);
|
||||
|
||||
@@ -745,6 +764,7 @@ static void addrinfo_cb(void *arg, int status, int timeouts,
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_resolver_getaddrinfo() - when using ares
|
||||
*
|
||||
@@ -826,6 +846,16 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data,
|
||||
hostname, PF_INET,
|
||||
query_completed_cb, data);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
{
|
||||
res->num_pending++; /* one more */
|
||||
memset(&res->hinfo, 0, sizeof(struct Curl_https_rrinfo));
|
||||
ares_query_dnsrec((ares_channel)data->state.async.resolver,
|
||||
hostname, ARES_CLASS_IN,
|
||||
ARES_REC_TYPE_HTTPS,
|
||||
Curl_dnsrec_done_cb, data, NULL);
|
||||
}
|
||||
#endif
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
}
|
||||
@@ -838,14 +868,26 @@ CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
CURLcode result = CURLE_NOT_BUILT_IN;
|
||||
int ares_result;
|
||||
|
||||
/* If server is NULL or empty, this would purge all DNS servers
|
||||
* from ares library, which will cause any and all queries to fail.
|
||||
* So, just return OK if none are configured and do not actually make
|
||||
* any changes to c-ares. This lets c-ares use its defaults, which
|
||||
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
|
||||
/* If server is NULL, this purges all DNS servers from c-ares. Reset it to
|
||||
* default.
|
||||
*/
|
||||
if(!(servers && servers[0]))
|
||||
return CURLE_OK;
|
||||
if(!servers) {
|
||||
Curl_resolver_cleanup(data->state.async.resolver);
|
||||
result = Curl_resolver_init(data, &data->state.async.resolver);
|
||||
if(!result) {
|
||||
/* this now needs to restore the other options set to c-ares */
|
||||
if(data->set.str[STRING_DNS_INTERFACE])
|
||||
(void)Curl_set_dns_interface(data,
|
||||
data->set.str[STRING_DNS_INTERFACE]);
|
||||
if(data->set.str[STRING_DNS_LOCAL_IP4])
|
||||
(void)Curl_set_dns_local_ip4(data,
|
||||
data->set.str[STRING_DNS_LOCAL_IP4]);
|
||||
if(data->set.str[STRING_DNS_LOCAL_IP6])
|
||||
(void)Curl_set_dns_local_ip6(data,
|
||||
data->set.str[STRING_DNS_LOCAL_IP6]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CARES_SERVERS_CSV
|
||||
#ifdef HAVE_CARES_PORTS_CSV
|
||||
@@ -947,3 +989,5 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
#endif
|
||||
}
|
||||
#endif /* CURLRES_ARES */
|
||||
|
||||
#endif /* USE_ARES */
|
||||
|
||||
@@ -64,6 +64,15 @@
|
||||
#include "inet_ntop.h"
|
||||
#include "curl_threads.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
|
||||
#ifdef USE_ARES
|
||||
#include <ares.h>
|
||||
#ifdef USE_HTTPSRR
|
||||
#define USE_HTTPSRR_ARES 1 /* the combo */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -145,32 +154,6 @@ static bool init_resolve_thread(struct Curl_easy *data,
|
||||
const struct addrinfo *hints);
|
||||
|
||||
|
||||
/* Data for synchronization between resolver thread and its parent */
|
||||
struct thread_sync_data {
|
||||
curl_mutex_t *mtx;
|
||||
int done;
|
||||
int port;
|
||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
||||
duplicate */
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
struct Curl_easy *data;
|
||||
curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */
|
||||
#endif
|
||||
int sock_error;
|
||||
struct Curl_addrinfo *res;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
struct thread_data *td; /* for thread-self cleanup */
|
||||
};
|
||||
|
||||
struct thread_data {
|
||||
curl_thread_t thread_hnd;
|
||||
unsigned int poll_interval;
|
||||
timediff_t interval_end;
|
||||
struct thread_sync_data tsd;
|
||||
};
|
||||
|
||||
static struct thread_sync_data *conn_thread_sync_data(struct Curl_easy *data)
|
||||
{
|
||||
return &(data->state.async.tdata->tsd);
|
||||
@@ -195,9 +178,11 @@ void destroy_thread_sync_data(struct thread_sync_data *tsd)
|
||||
* close one end of the socket pair (may be done in resolver thread);
|
||||
* the other end (for reading) is always closed in the parent thread.
|
||||
*/
|
||||
#ifndef USE_EVENTFD
|
||||
if(tsd->sock_pair[1] != CURL_SOCKET_BAD) {
|
||||
wakeup_close(tsd->sock_pair[1]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
memset(tsd, 0, sizeof(*tsd));
|
||||
}
|
||||
@@ -218,7 +203,7 @@ int init_thread_sync_data(struct thread_data *td,
|
||||
/* Treat the request as done until the thread actually starts so any early
|
||||
* cleanup gets done properly.
|
||||
*/
|
||||
tsd->done = 1;
|
||||
tsd->done = TRUE;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
DEBUGASSERT(hints);
|
||||
tsd->hints = *hints;
|
||||
@@ -341,7 +326,7 @@ CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
tsd->done = 1;
|
||||
tsd->done = TRUE;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
@@ -380,7 +365,7 @@ CURL_STDCALL gethostbyname_thread(void *arg)
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
tsd->done = TRUE;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
@@ -396,19 +381,22 @@ static void destroy_async_data(struct Curl_async *async)
|
||||
{
|
||||
if(async->tdata) {
|
||||
struct thread_data *td = async->tdata;
|
||||
int done;
|
||||
bool done;
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
curl_socket_t sock_rd = td->tsd.sock_pair[0];
|
||||
struct Curl_easy *data = td->tsd.data;
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
ares_destroy(data->state.async.tdata->channel);
|
||||
#endif
|
||||
/*
|
||||
* if the thread is still blocking in the resolve syscall, detach it and
|
||||
* let the thread do the cleanup...
|
||||
*/
|
||||
Curl_mutex_acquire(td->tsd.mtx);
|
||||
done = td->tsd.done;
|
||||
td->tsd.done = 1;
|
||||
td->tsd.done = TRUE;
|
||||
Curl_mutex_release(td->tsd.mtx);
|
||||
|
||||
if(!done) {
|
||||
@@ -437,6 +425,24 @@ static void destroy_async_data(struct Curl_async *async)
|
||||
async->hostname = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
static CURLcode resolve_httpsrr(struct Curl_easy *data,
|
||||
struct Curl_async *asp)
|
||||
{
|
||||
int status = ares_init_options(&asp->tdata->channel, NULL, 0);
|
||||
if(status != ARES_SUCCESS)
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
memset(&asp->tdata->hinfo, 0, sizeof(struct Curl_https_rrinfo));
|
||||
ares_query_dnsrec(asp->tdata->channel,
|
||||
asp->hostname, ARES_CLASS_IN,
|
||||
ARES_REC_TYPE_HTTPS,
|
||||
Curl_dnsrec_done_cb, data, NULL);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* init_resolve_thread() starts a new thread that performs the actual
|
||||
* resolve. This function returns before the resolve is done.
|
||||
@@ -472,8 +478,8 @@ static bool init_resolve_thread(struct Curl_easy *data,
|
||||
if(!asp->hostname)
|
||||
goto err_exit;
|
||||
|
||||
/* The thread will set this to 1 when complete. */
|
||||
td->tsd.done = 0;
|
||||
/* The thread will set this TRUE when complete. */
|
||||
td->tsd.done = FALSE;
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
|
||||
@@ -483,11 +489,14 @@ static bool init_resolve_thread(struct Curl_easy *data,
|
||||
|
||||
if(td->thread_hnd == curl_thread_t_null) {
|
||||
/* The thread never started, so mark it as done here for proper cleanup. */
|
||||
td->tsd.done = 1;
|
||||
td->tsd.done = TRUE;
|
||||
err = errno;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
if(resolve_httpsrr(data, asp))
|
||||
goto err_exit;
|
||||
#endif
|
||||
return TRUE;
|
||||
|
||||
err_exit:
|
||||
@@ -585,7 +594,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct thread_data *td = data->state.async.tdata;
|
||||
int done = 0;
|
||||
bool done = FALSE;
|
||||
|
||||
DEBUGASSERT(entry);
|
||||
*entry = NULL;
|
||||
@@ -594,6 +603,10 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||
DEBUGASSERT(td);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
if(Curl_ares_perform(data->state.async.tdata->channel, 0) < 0)
|
||||
return CURLE_UNRECOVERABLE_POLL;
|
||||
#endif
|
||||
|
||||
Curl_mutex_acquire(td->tsd.mtx);
|
||||
done = td->tsd.done;
|
||||
@@ -607,6 +620,17 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data,
|
||||
destroy_async_data(&data->state.async);
|
||||
return result;
|
||||
}
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
{
|
||||
struct Curl_https_rrinfo *lhrr =
|
||||
Curl_memdup(&td->hinfo, sizeof(struct Curl_https_rrinfo));
|
||||
if(!lhrr) {
|
||||
destroy_async_data(&data->state.async);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
data->state.async.dns->hinfo = lhrr;
|
||||
}
|
||||
#endif
|
||||
destroy_async_data(&data->state.async);
|
||||
*entry = data->state.async.dns;
|
||||
}
|
||||
@@ -641,18 +665,28 @@ int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks)
|
||||
timediff_t milli;
|
||||
timediff_t ms;
|
||||
struct resdata *reslv = (struct resdata *)data->state.async.resolver;
|
||||
int socketi = 0;
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
struct thread_data *td = data->state.async.tdata;
|
||||
#else
|
||||
(void)socks;
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTPSRR_ARES
|
||||
if(data->state.async.tdata) {
|
||||
ret_val = Curl_ares_getsock(data, data->state.async.tdata->channel, socks);
|
||||
for(socketi = 0; socketi < (MAX_SOCKSPEREASYHANDLE - 1); socketi++)
|
||||
if(!ARES_GETSOCK_READABLE(ret_val, socketi) &&
|
||||
!ARES_GETSOCK_WRITABLE(ret_val, socketi))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
if(td) {
|
||||
/* return read fd to client for polling the DNS resolution status */
|
||||
socks[0] = td->tsd.sock_pair[0];
|
||||
socks[socketi] = td->tsd.sock_pair[0];
|
||||
td->tsd.data = data;
|
||||
ret_val = GETSOCK_READSOCK(0);
|
||||
ret_val = GETSOCK_READSOCK(socketi);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
||||
64
lib/asyn.h
64
lib/asyn.h
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "curl_addrinfo.h"
|
||||
#include "httpsrr.h"
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
@@ -33,6 +34,69 @@ struct Curl_easy;
|
||||
struct connectdata;
|
||||
struct Curl_dns_entry;
|
||||
|
||||
#ifdef CURLRES_THREADED
|
||||
#include "curl_threads.h"
|
||||
|
||||
/* Data for synchronization between resolver thread and its parent */
|
||||
struct thread_sync_data {
|
||||
curl_mutex_t *mtx;
|
||||
bool done;
|
||||
int port;
|
||||
char *hostname; /* hostname to resolve, Curl_async.hostname
|
||||
duplicate */
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
struct Curl_easy *data;
|
||||
curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */
|
||||
#endif
|
||||
int sock_error;
|
||||
struct Curl_addrinfo *res;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
struct thread_data *td; /* for thread-self cleanup */
|
||||
};
|
||||
|
||||
struct thread_data {
|
||||
curl_thread_t thread_hnd;
|
||||
unsigned int poll_interval;
|
||||
timediff_t interval_end;
|
||||
struct thread_sync_data tsd;
|
||||
#if defined(USE_HTTPSRR) && defined(USE_ARES)
|
||||
struct Curl_https_rrinfo hinfo;
|
||||
ares_channel channel;
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif defined(CURLRES_ARES) /* CURLRES_THREADED */
|
||||
|
||||
struct thread_data {
|
||||
int num_pending; /* number of outstanding c-ares requests */
|
||||
struct Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares
|
||||
parts */
|
||||
int last_status;
|
||||
#ifndef HAVE_CARES_GETADDRINFO
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
#endif
|
||||
#ifdef USE_HTTPSRR
|
||||
struct Curl_https_rrinfo hinfo;
|
||||
#endif
|
||||
char hostname[1];
|
||||
};
|
||||
|
||||
#endif /* CURLRES_ARES */
|
||||
|
||||
#ifdef USE_ARES
|
||||
#include <ares.h>
|
||||
|
||||
/* for HTTPS RR purposes as well */
|
||||
int Curl_ares_getsock(struct Curl_easy *data,
|
||||
ares_channel channel,
|
||||
curl_socket_t *socks);
|
||||
int Curl_ares_perform(ares_channel channel,
|
||||
timediff_t timeout_ms);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This header defines all functions in the internal asynch resolver interface.
|
||||
* All asynch resolvers need to provide these functions.
|
||||
|
||||
23
lib/bufq.c
23
lib/bufq.c
@@ -45,11 +45,6 @@ static size_t chunk_len(const struct buf_chunk *chunk)
|
||||
return chunk->w_offset - chunk->r_offset;
|
||||
}
|
||||
|
||||
static size_t chunk_space(const struct buf_chunk *chunk)
|
||||
{
|
||||
return chunk->dlen - chunk->w_offset;
|
||||
}
|
||||
|
||||
static void chunk_reset(struct buf_chunk *chunk)
|
||||
{
|
||||
chunk->next = NULL;
|
||||
@@ -287,24 +282,6 @@ size_t Curl_bufq_len(const struct bufq *q)
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t Curl_bufq_space(const struct bufq *q)
|
||||
{
|
||||
size_t space = 0;
|
||||
if(q->tail)
|
||||
space += chunk_space(q->tail);
|
||||
if(q->spare) {
|
||||
struct buf_chunk *chunk = q->spare;
|
||||
while(chunk) {
|
||||
space += chunk->dlen;
|
||||
chunk = chunk->next;
|
||||
}
|
||||
}
|
||||
if(q->chunk_count < q->max_chunks) {
|
||||
space += (q->max_chunks - q->chunk_count) * q->chunk_size;
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
||||
bool Curl_bufq_is_empty(const struct bufq *q)
|
||||
{
|
||||
return !q->head || chunk_is_empty(q->head);
|
||||
|
||||
@@ -150,14 +150,6 @@ void Curl_bufq_free(struct bufq *q);
|
||||
*/
|
||||
size_t Curl_bufq_len(const struct bufq *q);
|
||||
|
||||
/**
|
||||
* Return the total amount of free space in the queue.
|
||||
* The returned length is the number of bytes that can
|
||||
* be expected to be written successfully to the bufq,
|
||||
* providing no memory allocations fail.
|
||||
*/
|
||||
size_t Curl_bufq_space(const struct bufq *q);
|
||||
|
||||
/**
|
||||
* Returns TRUE iff there is no data in the buffer queue.
|
||||
*/
|
||||
|
||||
1254
lib/c-hyper.c
1254
lib/c-hyper.c
File diff suppressed because it is too large
Load Diff
@@ -1,63 +0,0 @@
|
||||
#ifndef HEADER_CURL_HYPER_H
|
||||
#define HEADER_CURL_HYPER_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER)
|
||||
|
||||
#include <hyper.h>
|
||||
|
||||
struct hyp_io_ctx {
|
||||
struct Curl_easy *data;
|
||||
int sockindex;
|
||||
};
|
||||
|
||||
/* per-transfer data for the Hyper backend */
|
||||
struct hyptransfer {
|
||||
hyper_waker *write_waker;
|
||||
hyper_waker *read_waker;
|
||||
const hyper_executor *exec;
|
||||
hyper_waker *send_body_waker;
|
||||
struct hyp_io_ctx io_ctx;
|
||||
};
|
||||
|
||||
size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
|
||||
uint8_t *buf, size_t buflen);
|
||||
size_t Curl_hyper_send(void *userp, hyper_context *ctx,
|
||||
const uint8_t *buf, size_t buflen);
|
||||
CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int *didwhat,
|
||||
int select_res);
|
||||
|
||||
CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
|
||||
const char *line);
|
||||
void Curl_hyper_done(struct Curl_easy *);
|
||||
|
||||
#else
|
||||
#define Curl_hyper_done(x)
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) */
|
||||
#endif /* HEADER_CURL_HYPER_H */
|
||||
@@ -27,9 +27,6 @@
|
||||
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#ifdef USE_HYPER
|
||||
#include <hyper.h>
|
||||
#endif
|
||||
#include "urldata.h"
|
||||
#include "dynbuf.h"
|
||||
#include "sendf.h"
|
||||
@@ -184,9 +181,6 @@ static void h1_tunnel_go_state(struct Curl_cfilter *cf,
|
||||
make sure that it is not accidentally used for the document request
|
||||
after we have connected. So let's free and clear it here. */
|
||||
Curl_safefree(data->state.aptr.proxyuserpwd);
|
||||
#ifdef USE_HYPER
|
||||
data->state.hconnect = FALSE;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -209,10 +203,9 @@ static void tunnel_free(struct Curl_cfilter *cf,
|
||||
|
||||
static bool tunnel_want_send(struct h1_tunnel_state *ts)
|
||||
{
|
||||
return (ts->tunnel_state == H1_TUNNEL_CONNECT);
|
||||
return ts->tunnel_state == H1_TUNNEL_CONNECT;
|
||||
}
|
||||
|
||||
#ifndef USE_HYPER
|
||||
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts)
|
||||
@@ -529,337 +522,6 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||
return result;
|
||||
}
|
||||
|
||||
#else /* USE_HYPER */
|
||||
|
||||
static CURLcode CONNECT_host(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
char **pauthority,
|
||||
char **phost_header)
|
||||
{
|
||||
const char *hostname;
|
||||
int port;
|
||||
bool ipv6_ip;
|
||||
CURLcode result;
|
||||
char *authority; /* for CONNECT, the destination host + port */
|
||||
char *host_header = NULL; /* Host: authority */
|
||||
|
||||
result = Curl_http_proxy_get_destination(cf, &hostname, &port, &ipv6_ip);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
authority = aprintf("%s%s%s:%d", ipv6_ip ? "[":"", hostname,
|
||||
ipv6_ip ? "]" : "", port);
|
||||
if(!authority)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* If user is not overriding the Host header later */
|
||||
if(!Curl_checkProxyheaders(data, cf->conn, STRCONST("Host"))) {
|
||||
host_header = aprintf("Host: %s\r\n", authority);
|
||||
if(!host_header) {
|
||||
free(authority);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
*pauthority = authority;
|
||||
*phost_header = host_header;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* The Hyper version of CONNECT */
|
||||
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts)
|
||||
{
|
||||
struct connectdata *conn = cf->conn;
|
||||
struct hyptransfer *h = &data->hyp;
|
||||
curl_socket_t tunnelsocket = Curl_conn_cf_get_socket(cf, data);
|
||||
hyper_io *io = NULL;
|
||||
hyper_request *req = NULL;
|
||||
hyper_headers *headers = NULL;
|
||||
hyper_clientconn_options *options = NULL;
|
||||
hyper_task *handshake = NULL;
|
||||
hyper_task *task = NULL; /* for the handshake */
|
||||
hyper_clientconn *client = NULL;
|
||||
hyper_task *sendtask = NULL; /* for the send */
|
||||
char *authority = NULL; /* for CONNECT */
|
||||
char *host_header = NULL; /* Host: */
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
(void)ts;
|
||||
|
||||
io = hyper_io_new();
|
||||
if(!io) {
|
||||
failf(data, "Couldn't create hyper IO");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
/* tell Hyper how to read/write network data */
|
||||
h->io_ctx.data = data;
|
||||
h->io_ctx.sockindex = cf->sockindex;
|
||||
hyper_io_set_userdata(io, &h->io_ctx);
|
||||
hyper_io_set_read(io, Curl_hyper_recv);
|
||||
hyper_io_set_write(io, Curl_hyper_send);
|
||||
conn->sockfd = tunnelsocket;
|
||||
|
||||
data->state.hconnect = TRUE;
|
||||
|
||||
/* create an executor to poll futures */
|
||||
if(!h->exec) {
|
||||
h->exec = hyper_executor_new();
|
||||
if(!h->exec) {
|
||||
failf(data, "Couldn't create hyper executor");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
options = hyper_clientconn_options_new();
|
||||
if(!options) {
|
||||
failf(data, "Couldn't create hyper client options");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
hyper_clientconn_options_set_preserve_header_case(options, 1);
|
||||
hyper_clientconn_options_set_preserve_header_order(options, 1);
|
||||
|
||||
hyper_clientconn_options_exec(options, h->exec);
|
||||
|
||||
/* "Both the `io` and the `options` are consumed in this function
|
||||
call" */
|
||||
handshake = hyper_clientconn_handshake(io, options);
|
||||
if(!handshake) {
|
||||
failf(data, "Couldn't create hyper client handshake");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
io = NULL;
|
||||
options = NULL;
|
||||
|
||||
if(HYPERE_OK != hyper_executor_push(h->exec, handshake)) {
|
||||
failf(data, "Couldn't hyper_executor_push the handshake");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
handshake = NULL; /* ownership passed on */
|
||||
|
||||
task = hyper_executor_poll(h->exec);
|
||||
if(!task) {
|
||||
failf(data, "Couldn't hyper_executor_poll the handshake");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
client = hyper_task_value(task);
|
||||
hyper_task_free(task);
|
||||
|
||||
req = hyper_request_new();
|
||||
if(!req) {
|
||||
failf(data, "Couldn't hyper_request_new");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
if(hyper_request_set_method(req, (uint8_t *)"CONNECT",
|
||||
strlen("CONNECT"))) {
|
||||
failf(data, "error setting method");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* 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 = CONNECT_host(cf, data, &authority, &host_header);
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
infof(data, "Establish HTTP proxy tunnel to %s", authority);
|
||||
|
||||
if(hyper_request_set_uri(req, (uint8_t *)authority,
|
||||
strlen(authority))) {
|
||||
failf(data, "error setting path");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
if(data->set.verbose) {
|
||||
char *se = aprintf("CONNECT %s HTTP/1.1\r\n", authority);
|
||||
if(!se) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, se, strlen(se));
|
||||
free(se);
|
||||
}
|
||||
/* Setup the proxy-authorization header, if any */
|
||||
result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
|
||||
authority, TRUE);
|
||||
if(result)
|
||||
goto error;
|
||||
Curl_safefree(authority);
|
||||
|
||||
/* default is 1.1 */
|
||||
if((conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) &&
|
||||
(HYPERE_OK != hyper_request_set_version(req,
|
||||
HYPER_HTTP_VERSION_1_0))) {
|
||||
failf(data, "error setting HTTP version");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
|
||||
headers = hyper_request_headers(req);
|
||||
if(!headers) {
|
||||
failf(data, "hyper_request_headers");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
if(host_header) {
|
||||
result = Curl_hyper_header(data, headers, host_header);
|
||||
if(result)
|
||||
goto error;
|
||||
Curl_safefree(host_header);
|
||||
}
|
||||
|
||||
if(data->state.aptr.proxyuserpwd) {
|
||||
result = Curl_hyper_header(data, headers,
|
||||
data->state.aptr.proxyuserpwd);
|
||||
if(result)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, STRCONST("User-Agent")) &&
|
||||
data->set.str[STRING_USERAGENT] && *data->set.str[STRING_USERAGENT]) {
|
||||
struct dynbuf ua;
|
||||
Curl_dyn_init(&ua, DYN_HTTP_REQUEST);
|
||||
result = Curl_dyn_addf(&ua, "User-Agent: %s\r\n",
|
||||
data->set.str[STRING_USERAGENT]);
|
||||
if(result)
|
||||
goto error;
|
||||
result = Curl_hyper_header(data, headers, Curl_dyn_ptr(&ua));
|
||||
if(result)
|
||||
goto error;
|
||||
Curl_dyn_free(&ua);
|
||||
}
|
||||
|
||||
if(!Curl_checkProxyheaders(data, conn, STRCONST("Proxy-Connection"))) {
|
||||
result = Curl_hyper_header(data, headers,
|
||||
"Proxy-Connection: Keep-Alive");
|
||||
if(result)
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = Curl_add_custom_headers(data, TRUE, headers);
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
result = Curl_creader_set_null(data);
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
sendtask = hyper_clientconn_send(client, req);
|
||||
if(!sendtask) {
|
||||
failf(data, "hyper_clientconn_send");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
req = NULL;
|
||||
|
||||
if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) {
|
||||
failf(data, "Couldn't hyper_executor_push the send");
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
sendtask = NULL; /* ownership passed on */
|
||||
|
||||
hyper_clientconn_free(client);
|
||||
client = NULL;
|
||||
|
||||
error:
|
||||
free(host_header);
|
||||
free(authority);
|
||||
if(io)
|
||||
hyper_io_free(io);
|
||||
if(options)
|
||||
hyper_clientconn_options_free(options);
|
||||
if(handshake)
|
||||
hyper_task_free(handshake);
|
||||
if(client)
|
||||
hyper_clientconn_free(client);
|
||||
if(req)
|
||||
hyper_request_free(req);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode send_CONNECT(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts,
|
||||
bool *done)
|
||||
{
|
||||
struct hyptransfer *h = &data->hyp;
|
||||
struct connectdata *conn = cf->conn;
|
||||
hyper_task *task = NULL;
|
||||
hyper_error *hypererr = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
(void)ts;
|
||||
(void)conn;
|
||||
do {
|
||||
task = hyper_executor_poll(h->exec);
|
||||
if(task) {
|
||||
bool error = hyper_task_type(task) == HYPER_TASK_ERROR;
|
||||
if(error)
|
||||
hypererr = hyper_task_value(task);
|
||||
hyper_task_free(task);
|
||||
if(error) {
|
||||
/* this could probably use a better error code? */
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} while(task);
|
||||
error:
|
||||
*done = (result == CURLE_OK);
|
||||
if(hypererr) {
|
||||
uint8_t errbuf[256];
|
||||
size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
|
||||
failf(data, "Hyper: %.*s", (int)errlen, errbuf);
|
||||
hyper_error_free(hypererr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts,
|
||||
bool *done)
|
||||
{
|
||||
struct hyptransfer *h = &data->hyp;
|
||||
CURLcode result;
|
||||
int didwhat;
|
||||
|
||||
(void)ts;
|
||||
result = Curl_hyper_stream(data, cf->conn, &didwhat,
|
||||
CURL_CSELECT_IN | CURL_CSELECT_OUT);
|
||||
*done = data->req.done;
|
||||
if(result || !*done)
|
||||
return result;
|
||||
if(h->exec) {
|
||||
hyper_executor_free(h->exec);
|
||||
h->exec = NULL;
|
||||
}
|
||||
if(h->read_waker) {
|
||||
hyper_waker_free(h->read_waker);
|
||||
h->read_waker = NULL;
|
||||
}
|
||||
if(h->write_waker) {
|
||||
hyper_waker_free(h->write_waker);
|
||||
h->write_waker = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_HYPER */
|
||||
|
||||
static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct h1_tunnel_state *ts)
|
||||
|
||||
@@ -865,7 +865,9 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
|
||||
if(nwritten < 0) {
|
||||
if(result != CURLE_AGAIN)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
#ifdef DEBUGBUILD
|
||||
nwritten = 0;
|
||||
#endif
|
||||
}
|
||||
DEBUGASSERT((size_t)nwritten == len);
|
||||
return 0;
|
||||
|
||||
@@ -24,13 +24,14 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
||||
#if !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "curl_trc.h"
|
||||
#include "cfilters.h"
|
||||
#include "connect.h"
|
||||
#include "hostip.h"
|
||||
#include "multiif.h"
|
||||
#include "cf-https-connect.h"
|
||||
#include "http2.h"
|
||||
@@ -42,6 +43,10 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CF_HC_INIT,
|
||||
CF_HC_CONNECT,
|
||||
@@ -55,7 +60,7 @@ struct cf_hc_baller {
|
||||
CURLcode result;
|
||||
struct curltime started;
|
||||
int reply_ms;
|
||||
BIT(enabled);
|
||||
enum alpnid alpn_id;
|
||||
BIT(shutdown);
|
||||
};
|
||||
|
||||
@@ -73,7 +78,7 @@ static void cf_hc_baller_reset(struct cf_hc_baller *b,
|
||||
|
||||
static bool cf_hc_baller_is_active(struct cf_hc_baller *b)
|
||||
{
|
||||
return b->enabled && b->cf && !b->result;
|
||||
return b->cf && !b->result;
|
||||
}
|
||||
|
||||
static bool cf_hc_baller_has_started(struct cf_hc_baller *b)
|
||||
@@ -84,7 +89,7 @@ static bool cf_hc_baller_has_started(struct cf_hc_baller *b)
|
||||
static int cf_hc_baller_reply_ms(struct cf_hc_baller *b,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
if(b->reply_ms < 0)
|
||||
if(b->cf && (b->reply_ms < 0))
|
||||
b->cf->cft->query(b->cf, data, CF_QUERY_CONNECT_REPLY_MS,
|
||||
&b->reply_ms, NULL);
|
||||
return b->reply_ms;
|
||||
@@ -116,26 +121,53 @@ struct cf_hc_ctx {
|
||||
const struct Curl_dns_entry *remotehost;
|
||||
struct curltime started; /* when connect started */
|
||||
CURLcode result; /* overall result */
|
||||
struct cf_hc_baller h3_baller;
|
||||
struct cf_hc_baller h21_baller;
|
||||
struct cf_hc_baller ballers[2];
|
||||
size_t baller_count;
|
||||
unsigned int soft_eyeballs_timeout_ms;
|
||||
unsigned int hard_eyeballs_timeout_ms;
|
||||
};
|
||||
|
||||
static void cf_hc_baller_assign(struct cf_hc_baller *b,
|
||||
enum alpnid alpn_id)
|
||||
{
|
||||
b->alpn_id = alpn_id;
|
||||
switch(b->alpn_id) {
|
||||
case ALPN_h3:
|
||||
b->name = "h3";
|
||||
break;
|
||||
case ALPN_h2:
|
||||
b->name = "h2";
|
||||
break;
|
||||
case ALPN_h1:
|
||||
b->name = "h1";
|
||||
break;
|
||||
default:
|
||||
b->result = CURLE_FAILED_INIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void cf_hc_baller_init(struct cf_hc_baller *b,
|
||||
struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
const char *name,
|
||||
int transport)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct Curl_cfilter *save = cf->next;
|
||||
|
||||
b->name = name;
|
||||
cf->next = NULL;
|
||||
b->started = Curl_now();
|
||||
b->result = Curl_cf_setup_insert_after(cf, data, ctx->remotehost,
|
||||
transport, CURL_CF_SSL_ENABLE);
|
||||
switch(b->alpn_id) {
|
||||
case ALPN_h3:
|
||||
transport = TRNSPRT_QUIC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(!b->result)
|
||||
b->result = Curl_cf_setup_insert_after(cf, data, ctx->remotehost,
|
||||
transport, CURL_CF_SSL_ENABLE);
|
||||
b->cf = cf->next;
|
||||
cf->next = save;
|
||||
}
|
||||
@@ -157,10 +189,11 @@ static CURLcode cf_hc_baller_connect(struct cf_hc_baller *b,
|
||||
static void cf_hc_reset(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
size_t i;
|
||||
|
||||
if(ctx) {
|
||||
cf_hc_baller_reset(&ctx->h3_baller, data);
|
||||
cf_hc_baller_reset(&ctx->h21_baller, data);
|
||||
for(i = 0; i < ctx->baller_count; ++i)
|
||||
cf_hc_baller_reset(&ctx->ballers[i], data);
|
||||
ctx->state = CF_HC_INIT;
|
||||
ctx->result = CURLE_OK;
|
||||
ctx->hard_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout;
|
||||
@@ -175,12 +208,12 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
int reply_ms;
|
||||
size_t i;
|
||||
|
||||
DEBUGASSERT(winner->cf);
|
||||
if(winner != &ctx->h3_baller)
|
||||
cf_hc_baller_reset(&ctx->h3_baller, data);
|
||||
if(winner != &ctx->h21_baller)
|
||||
cf_hc_baller_reset(&ctx->h21_baller, data);
|
||||
for(i = 0; i < ctx->baller_count; ++i)
|
||||
if(winner != &ctx->ballers[i])
|
||||
cf_hc_baller_reset(&ctx->ballers[i], data);
|
||||
|
||||
reply_ms = cf_hc_baller_reply_ms(winner, data);
|
||||
if(reply_ms >= 0)
|
||||
@@ -218,31 +251,40 @@ static CURLcode baller_connected(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
|
||||
static bool time_to_start_h21(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
struct curltime now)
|
||||
static bool time_to_start_next(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
size_t idx, struct curltime now)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
timediff_t elapsed_ms;
|
||||
size_t i;
|
||||
|
||||
if(!ctx->h21_baller.enabled || cf_hc_baller_has_started(&ctx->h21_baller))
|
||||
if(idx >= ctx->baller_count)
|
||||
return FALSE;
|
||||
|
||||
if(!ctx->h3_baller.enabled || !cf_hc_baller_is_active(&ctx->h3_baller))
|
||||
if(cf_hc_baller_has_started(&ctx->ballers[idx]))
|
||||
return FALSE;
|
||||
for(i = 0; i < idx; i++) {
|
||||
if(!ctx->ballers[i].result)
|
||||
break;
|
||||
}
|
||||
if(i == idx) {
|
||||
CURL_TRC_CF(data, cf, "all previous ballers have failed, time to start "
|
||||
"baller %zu [%s]", idx, ctx->ballers[idx].name);
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
elapsed_ms = Curl_timediff(now, ctx->started);
|
||||
if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
|
||||
CURL_TRC_CF(data, cf, "hard timeout of %dms reached, starting h21",
|
||||
ctx->hard_eyeballs_timeout_ms);
|
||||
CURL_TRC_CF(data, cf, "hard timeout of %dms reached, starting %s",
|
||||
ctx->hard_eyeballs_timeout_ms, ctx->ballers[idx].name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(elapsed_ms >= ctx->soft_eyeballs_timeout_ms) {
|
||||
if(cf_hc_baller_reply_ms(&ctx->h3_baller, data) < 0) {
|
||||
CURL_TRC_CF(data, cf, "soft timeout of %dms reached, h3 has not "
|
||||
"seen any data, starting h21",
|
||||
ctx->soft_eyeballs_timeout_ms);
|
||||
if((idx > 0) && (elapsed_ms >= ctx->soft_eyeballs_timeout_ms)) {
|
||||
if(cf_hc_baller_reply_ms(&ctx->ballers[idx - 1], data) < 0) {
|
||||
CURL_TRC_CF(data, cf, "soft timeout of %dms reached, %s has not "
|
||||
"seen any data, starting %s",
|
||||
ctx->soft_eyeballs_timeout_ms,
|
||||
ctx->ballers[idx - 1].name, ctx->ballers[idx].name);
|
||||
return TRUE;
|
||||
}
|
||||
/* set the effective hard timeout again */
|
||||
@@ -259,6 +301,7 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct curltime now;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i, failed_ballers;
|
||||
|
||||
(void)blocking;
|
||||
if(cf->connected) {
|
||||
@@ -270,51 +313,57 @@ static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
|
||||
now = Curl_now();
|
||||
switch(ctx->state) {
|
||||
case CF_HC_INIT:
|
||||
DEBUGASSERT(!ctx->h3_baller.cf);
|
||||
DEBUGASSERT(!ctx->h21_baller.cf);
|
||||
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;
|
||||
if(ctx->h3_baller.enabled) {
|
||||
cf_hc_baller_init(&ctx->h3_baller, cf, data, "h3", TRNSPRT_QUIC);
|
||||
if(ctx->h21_baller.enabled)
|
||||
Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
|
||||
cf_hc_baller_init(&ctx->ballers[0], cf, data, cf->conn->transport);
|
||||
if(ctx->baller_count > 1) {
|
||||
Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
|
||||
CURL_TRC_CF(data, cf, "set expire for starting next baller in %ums",
|
||||
ctx->soft_eyeballs_timeout_ms);
|
||||
}
|
||||
else if(ctx->h21_baller.enabled)
|
||||
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
|
||||
cf->conn->transport);
|
||||
ctx->state = CF_HC_CONNECT;
|
||||
FALLTHROUGH();
|
||||
|
||||
case CF_HC_CONNECT:
|
||||
if(cf_hc_baller_is_active(&ctx->h3_baller)) {
|
||||
result = cf_hc_baller_connect(&ctx->h3_baller, cf, data, done);
|
||||
if(cf_hc_baller_is_active(&ctx->ballers[0])) {
|
||||
result = cf_hc_baller_connect(&ctx->ballers[0], cf, data, done);
|
||||
if(!result && *done) {
|
||||
result = baller_connected(cf, data, &ctx->h3_baller);
|
||||
result = baller_connected(cf, data, &ctx->ballers[0]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(time_to_start_h21(cf, data, now)) {
|
||||
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21",
|
||||
cf->conn->transport);
|
||||
if(time_to_start_next(cf, data, 1, now)) {
|
||||
cf_hc_baller_init(&ctx->ballers[1], cf, data, cf->conn->transport);
|
||||
}
|
||||
|
||||
if(cf_hc_baller_is_active(&ctx->h21_baller)) {
|
||||
CURL_TRC_CF(data, cf, "connect, check h21");
|
||||
result = cf_hc_baller_connect(&ctx->h21_baller, cf, data, done);
|
||||
if((ctx->baller_count > 1) && cf_hc_baller_is_active(&ctx->ballers[1])) {
|
||||
CURL_TRC_CF(data, cf, "connect, check %s", ctx->ballers[1].name);
|
||||
result = cf_hc_baller_connect(&ctx->ballers[1], cf, data, done);
|
||||
if(!result && *done) {
|
||||
result = baller_connected(cf, data, &ctx->h21_baller);
|
||||
result = baller_connected(cf, data, &ctx->ballers[1]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if((!ctx->h3_baller.enabled || ctx->h3_baller.result) &&
|
||||
(!ctx->h21_baller.enabled || ctx->h21_baller.result)) {
|
||||
/* both failed or disabled. we give up */
|
||||
failed_ballers = 0;
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
if(ctx->ballers[i].result)
|
||||
++failed_ballers;
|
||||
}
|
||||
|
||||
if(failed_ballers == ctx->baller_count) {
|
||||
/* all have failed. we give up */
|
||||
CURL_TRC_CF(data, cf, "connect, all failed");
|
||||
result = ctx->result = ctx->h3_baller.enabled ?
|
||||
ctx->h3_baller.result : ctx->h21_baller.result;
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
if(ctx->ballers[i].result) {
|
||||
result = ctx->ballers[i].result;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctx->state = CF_HC_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
@@ -344,7 +393,6 @@ static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data, bool *done)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct cf_hc_baller *ballers[2];
|
||||
size_t i;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@@ -356,10 +404,8 @@ static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf,
|
||||
|
||||
/* shutdown all ballers that have not done so already. If one fails,
|
||||
* continue shutting down others until all are shutdown. */
|
||||
ballers[0] = &ctx->h3_baller;
|
||||
ballers[1] = &ctx->h21_baller;
|
||||
for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
|
||||
struct cf_hc_baller *b = ballers[i];
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
struct cf_hc_baller *b = &ctx->ballers[i];
|
||||
bool bdone = FALSE;
|
||||
if(!cf_hc_baller_is_active(b) || b->shutdown)
|
||||
continue;
|
||||
@@ -369,14 +415,14 @@ static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf,
|
||||
}
|
||||
|
||||
*done = TRUE;
|
||||
for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
|
||||
if(ballers[i] && !ballers[i]->shutdown)
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
if(!ctx->ballers[i].shutdown)
|
||||
*done = FALSE;
|
||||
}
|
||||
if(*done) {
|
||||
for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
|
||||
if(ballers[i] && ballers[i]->result)
|
||||
result = ballers[i]->result;
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
if(ctx->ballers[i].result)
|
||||
result = ctx->ballers[i].result;
|
||||
}
|
||||
}
|
||||
CURL_TRC_CF(data, cf, "shutdown -> %d, done=%d", result, *done);
|
||||
@@ -389,13 +435,10 @@ static void cf_hc_adjust_pollset(struct Curl_cfilter *cf,
|
||||
{
|
||||
if(!cf->connected) {
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct cf_hc_baller *ballers[2];
|
||||
size_t i;
|
||||
|
||||
ballers[0] = &ctx->h3_baller;
|
||||
ballers[1] = &ctx->h21_baller;
|
||||
for(i = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
|
||||
struct cf_hc_baller *b = ballers[i];
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
struct cf_hc_baller *b = &ctx->ballers[i];
|
||||
if(!cf_hc_baller_is_active(b))
|
||||
continue;
|
||||
Curl_conn_cf_adjust_pollset(b->cf, data, ps);
|
||||
@@ -408,13 +451,16 @@ static bool cf_hc_data_pending(struct Curl_cfilter *cf,
|
||||
const struct Curl_easy *data)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
size_t i;
|
||||
|
||||
if(cf->connected)
|
||||
return cf->next->cft->has_data_pending(cf->next, data);
|
||||
|
||||
CURL_TRC_CF((struct Curl_easy *)data, cf, "data_pending");
|
||||
return cf_hc_baller_data_pending(&ctx->h3_baller, data)
|
||||
|| cf_hc_baller_data_pending(&ctx->h21_baller, data);
|
||||
for(i = 0; i < ctx->baller_count; i++)
|
||||
if(cf_hc_baller_data_pending(&ctx->ballers[i], data))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
|
||||
@@ -422,21 +468,17 @@ static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
|
||||
int query)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
struct Curl_cfilter *cfb;
|
||||
struct curltime t, tmax;
|
||||
size_t i;
|
||||
|
||||
memset(&tmax, 0, sizeof(tmax));
|
||||
memset(&t, 0, sizeof(t));
|
||||
cfb = ctx->h21_baller.enabled ? ctx->h21_baller.cf : NULL;
|
||||
if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
|
||||
if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
|
||||
tmax = t;
|
||||
}
|
||||
memset(&t, 0, sizeof(t));
|
||||
cfb = ctx->h3_baller.enabled ? ctx->h3_baller.cf : NULL;
|
||||
if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
|
||||
if((t.tv_sec || t.tv_usec) && Curl_timediff_us(t, tmax) > 0)
|
||||
tmax = t;
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
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) && Curl_timediff_us(t, tmax) > 0)
|
||||
tmax = t;
|
||||
}
|
||||
}
|
||||
return tmax;
|
||||
}
|
||||
@@ -446,6 +488,7 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
|
||||
int query, int *pres1, void *pres2)
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
size_t i;
|
||||
|
||||
if(!cf->connected) {
|
||||
switch(query) {
|
||||
@@ -460,11 +503,11 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
|
||||
return CURLE_OK;
|
||||
}
|
||||
case CF_QUERY_NEED_FLUSH: {
|
||||
if(cf_hc_baller_needs_flush(&ctx->h3_baller, data)
|
||||
|| cf_hc_baller_needs_flush(&ctx->h21_baller, data)) {
|
||||
*pres1 = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
for(i = 0; i < ctx->baller_count; i++)
|
||||
if(cf_hc_baller_needs_flush(&ctx->ballers[i], data)) {
|
||||
*pres1 = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -482,14 +525,17 @@ static CURLcode cf_hc_cntrl(struct Curl_cfilter *cf,
|
||||
{
|
||||
struct cf_hc_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i;
|
||||
|
||||
if(!cf->connected) {
|
||||
result = cf_hc_baller_cntrl(&ctx->h3_baller, data, event, arg1, arg2);
|
||||
if(!result || (result == CURLE_AGAIN))
|
||||
result = cf_hc_baller_cntrl(&ctx->h21_baller, data, event, arg1, arg2);
|
||||
if(result == CURLE_AGAIN)
|
||||
result = CURLE_OK;
|
||||
for(i = 0; i < ctx->baller_count; i++) {
|
||||
result = cf_hc_baller_cntrl(&ctx->ballers[i], data, event, arg1, arg2);
|
||||
if(result && (result != CURLE_AGAIN))
|
||||
goto out;
|
||||
}
|
||||
result = CURLE_OK;
|
||||
}
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -537,23 +583,37 @@ struct Curl_cftype Curl_cft_http_connect = {
|
||||
static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
|
||||
struct Curl_easy *data,
|
||||
const struct Curl_dns_entry *remotehost,
|
||||
bool try_h3, bool try_h21)
|
||||
enum alpnid *alpnids, size_t alpn_count)
|
||||
{
|
||||
struct Curl_cfilter *cf = NULL;
|
||||
struct cf_hc_ctx *ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t i;
|
||||
|
||||
DEBUGASSERT(alpnids);
|
||||
DEBUGASSERT(alpn_count);
|
||||
DEBUGASSERT(alpn_count <= ARRAYSIZE(ctx->ballers));
|
||||
if(!alpn_count || (alpn_count > ARRAYSIZE(ctx->ballers))) {
|
||||
failf(data, "https-connect filter create with unsupported %zu ALPN ids",
|
||||
alpn_count);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
(void)data;
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
ctx->remotehost = remotehost;
|
||||
ctx->h3_baller.enabled = try_h3;
|
||||
ctx->h21_baller.enabled = try_h21;
|
||||
for(i = 0; i < alpn_count; ++i)
|
||||
cf_hc_baller_assign(&ctx->ballers[i], alpnids[i]);
|
||||
for(; i < ARRAYSIZE(ctx->ballers); ++i)
|
||||
ctx->ballers[i].alpn_id = ALPN_none;
|
||||
ctx->baller_count = alpn_count;
|
||||
|
||||
result = Curl_cf_create(&cf, &Curl_cft_http_connect, ctx);
|
||||
CURL_TRC_CF(data, cf, "created with %zu ALPNs -> %d",
|
||||
ctx->baller_count, result);
|
||||
if(result)
|
||||
goto out;
|
||||
ctx = NULL;
|
||||
@@ -569,13 +629,13 @@ static CURLcode cf_http_connect_add(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int sockindex,
|
||||
const struct Curl_dns_entry *remotehost,
|
||||
bool try_h3, bool try_h21)
|
||||
enum alpnid *alpn_ids, size_t alpn_count)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(data);
|
||||
result = cf_hc_create(&cf, data, remotehost, try_h3, try_h21);
|
||||
result = cf_hc_create(&cf, data, remotehost, alpn_ids, alpn_count);
|
||||
if(result)
|
||||
goto out;
|
||||
Curl_conn_cf_add(data, conn, sockindex, cf);
|
||||
@@ -588,33 +648,88 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
||||
int sockindex,
|
||||
const struct Curl_dns_entry *remotehost)
|
||||
{
|
||||
bool try_h3 = FALSE, try_h21 = TRUE; /* defaults, for now */
|
||||
enum alpnid alpn_ids[2];
|
||||
size_t alpn_count = 0;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
(void)sockindex;
|
||||
(void)remotehost;
|
||||
|
||||
if(!conn->bits.tls_enable_alpn)
|
||||
goto out;
|
||||
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_3ONLY) {
|
||||
result = Curl_conn_may_http3(data, conn);
|
||||
if(result) /* cannot do it */
|
||||
goto out;
|
||||
try_h3 = TRUE;
|
||||
try_h21 = FALSE;
|
||||
}
|
||||
else if(data->state.httpwant >= CURL_HTTP_VERSION_3) {
|
||||
/* We assume that silently not even trying H3 is ok here */
|
||||
/* TODO: should we fail instead? */
|
||||
try_h3 = (Curl_conn_may_http3(data, conn) == CURLE_OK);
|
||||
try_h21 = TRUE;
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
switch(data->state.httpwant) {
|
||||
case CURL_HTTP_VERSION_NONE:
|
||||
/* No preferences by transfer setup. Choose best defaults */
|
||||
#ifdef USE_HTTPSRR
|
||||
if(conn->dns_entry && conn->dns_entry->hinfo &&
|
||||
!conn->dns_entry->hinfo->no_def_alpn) {
|
||||
size_t i, j;
|
||||
for(i = 0; i < ARRAYSIZE(conn->dns_entry->hinfo->alpns) &&
|
||||
alpn_count < ARRAYSIZE(alpn_ids); ++i) {
|
||||
bool present = FALSE;
|
||||
enum alpnid alpn = conn->dns_entry->hinfo->alpns[i];
|
||||
for(j = 0; j < alpn_count; ++j) {
|
||||
if(alpn == alpn_ids[j]) {
|
||||
present = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!present) {
|
||||
switch(alpn) {
|
||||
case ALPN_h3:
|
||||
if(Curl_conn_may_http3(data, conn))
|
||||
break; /* not possible */
|
||||
FALLTHROUGH();
|
||||
case ALPN_h2:
|
||||
case ALPN_h1:
|
||||
alpn_ids[alpn_count++] = alpn;
|
||||
break;
|
||||
default: /* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(!alpn_count)
|
||||
alpn_ids[alpn_count++] = ALPN_h2;
|
||||
break;
|
||||
case CURL_HTTP_VERSION_3ONLY:
|
||||
result = Curl_conn_may_http3(data, conn);
|
||||
if(result) /* cannot do it */
|
||||
goto out;
|
||||
alpn_ids[alpn_count++] = ALPN_h3;
|
||||
break;
|
||||
case CURL_HTTP_VERSION_3:
|
||||
/* We assume that silently not even trying H3 is ok here */
|
||||
/* TODO: should we fail instead? */
|
||||
if(Curl_conn_may_http3(data, conn) == CURLE_OK)
|
||||
alpn_ids[alpn_count++] = ALPN_h3;
|
||||
alpn_ids[alpn_count++] = ALPN_h2;
|
||||
break;
|
||||
case CURL_HTTP_VERSION_2_0:
|
||||
case CURL_HTTP_VERSION_2TLS:
|
||||
case CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE:
|
||||
alpn_ids[alpn_count++] = ALPN_h2;
|
||||
break;
|
||||
case CURL_HTTP_VERSION_1_0:
|
||||
case CURL_HTTP_VERSION_1_1:
|
||||
alpn_ids[alpn_count++] = ALPN_h1;
|
||||
break;
|
||||
default:
|
||||
alpn_ids[alpn_count++] = ALPN_h2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we identified ALPNs to use, install our filter. Otherwise,
|
||||
* install nothing, so our call will use a default connect setup. */
|
||||
if(alpn_count) {
|
||||
result = cf_http_connect_add(data, conn, sockindex, remotehost,
|
||||
alpn_ids, alpn_count);
|
||||
}
|
||||
|
||||
result = cf_http_connect_add(data, conn, sockindex, remotehost,
|
||||
try_h3, try_h21);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) */
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
||||
#if !defined(CURL_DISABLE_HTTP)
|
||||
|
||||
struct Curl_cfilter;
|
||||
struct Curl_easy;
|
||||
@@ -54,5 +54,5 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data,
|
||||
const struct Curl_dns_entry *remotehost);
|
||||
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) */
|
||||
#endif /* HEADER_CURL_CF_HTTP_H */
|
||||
|
||||
@@ -306,9 +306,9 @@ tcpkeepalive(struct Curl_easy *data,
|
||||
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
||||
* set the transport used.
|
||||
*/
|
||||
void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
{
|
||||
/*
|
||||
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
||||
@@ -334,9 +334,13 @@ void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
}
|
||||
dest->addrlen = (unsigned int)ai->ai_addrlen;
|
||||
|
||||
if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
|
||||
dest->addrlen = sizeof(struct Curl_sockaddr_storage);
|
||||
if(dest->addrlen > sizeof(struct Curl_sockaddr_storage)) {
|
||||
DEBUGASSERT(0);
|
||||
return CURLE_TOO_LARGE;
|
||||
}
|
||||
|
||||
memcpy(&dest->curl_sa_addr, ai->ai_addr, dest->addrlen);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode socket_open(struct Curl_easy *data,
|
||||
@@ -395,12 +399,16 @@ CURLcode Curl_socket_open(struct Curl_easy *data,
|
||||
curl_socket_t *sockfd)
|
||||
{
|
||||
struct Curl_sockaddr_ex dummy;
|
||||
CURLcode result;
|
||||
|
||||
if(!addr)
|
||||
/* if the caller does not want info back, use a local temp copy */
|
||||
addr = &dummy;
|
||||
|
||||
Curl_sock_assign_addr(addr, ai, transport);
|
||||
result = Curl_sock_assign_addr(addr, ai, transport);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return socket_open(data, addr, sockfd);
|
||||
}
|
||||
|
||||
@@ -959,14 +967,20 @@ struct cf_socket_ctx {
|
||||
BIT(active);
|
||||
};
|
||||
|
||||
static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
static CURLcode cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->sock = CURL_SOCKET_BAD;
|
||||
ctx->transport = transport;
|
||||
Curl_sock_assign_addr(&ctx->addr, ai, transport);
|
||||
|
||||
result = Curl_sock_assign_addr(&ctx->addr, ai, transport);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
{
|
||||
char *p = getenv("CURL_DBG_SOCK_WBLOCK");
|
||||
@@ -995,6 +1009,8 @@ static void cf_socket_ctx_init(struct cf_socket_ctx *ctx,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
@@ -1282,7 +1298,7 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
|
||||
rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
|
||||
#elif defined(MSG_FASTOPEN) /* old Linux */
|
||||
if(cf->conn->given->flags & PROTOPT_SSL)
|
||||
if(Curl_conn_is_ssl(cf->conn, cf->sockindex))
|
||||
rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
|
||||
else
|
||||
rc = 0; /* Do nothing */
|
||||
@@ -1443,7 +1459,7 @@ static bool cf_socket_data_pending(struct Curl_cfilter *cf,
|
||||
|
||||
(void)data;
|
||||
readable = SOCKET_READABLE(ctx->sock, 0);
|
||||
return (readable > 0 && (readable & CURL_CSELECT_IN));
|
||||
return readable > 0 && (readable & CURL_CSELECT_IN);
|
||||
}
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
@@ -1805,7 +1821,10 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
cf_socket_ctx_init(ctx, ai, transport);
|
||||
|
||||
result = cf_socket_ctx_init(ctx, ai, transport);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
result = Curl_cf_create(&cf, &Curl_cft_tcp, ctx);
|
||||
|
||||
@@ -1831,7 +1850,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf,
|
||||
/* QUIC needs a connected socket, nonblocking */
|
||||
DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD);
|
||||
|
||||
rc = connect(ctx->sock, &ctx->addr.curl_sa_addr,
|
||||
rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, /* NOLINT FIXME */
|
||||
(curl_socklen_t)ctx->addr.addrlen);
|
||||
if(-1 == rc) {
|
||||
return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO);
|
||||
@@ -1954,7 +1973,10 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
cf_socket_ctx_init(ctx, ai, transport);
|
||||
|
||||
result = cf_socket_ctx_init(ctx, ai, transport);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
result = Curl_cf_create(&cf, &Curl_cft_udp, ctx);
|
||||
|
||||
@@ -2006,7 +2028,10 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
cf_socket_ctx_init(ctx, ai, transport);
|
||||
|
||||
result = cf_socket_ctx_init(ctx, ai, transport);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
result = Curl_cf_create(&cf, &Curl_cft_unix, ctx);
|
||||
|
||||
|
||||
@@ -95,9 +95,9 @@ void Curl_sndbuf_init(curl_socket_t sockfd);
|
||||
* Assign the address `ai` to the Curl_sockaddr_ex `dest` and
|
||||
* set the transport used.
|
||||
*/
|
||||
void Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
CURLcode Curl_sock_assign_addr(struct Curl_sockaddr_ex *dest,
|
||||
const struct Curl_addrinfo *ai,
|
||||
int transport);
|
||||
|
||||
/**
|
||||
* Creates a cfilter that opens a TCP socket to the given address
|
||||
|
||||
@@ -494,13 +494,35 @@ 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->cft->flags & CF_TYPE_SSL)
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unsigned char Curl_conn_http_version(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
CURLcode result = CURLE_UNKNOWN_OPTION;
|
||||
unsigned char v = 0;
|
||||
|
||||
cf = data->conn ? data->conn->cfilter[FIRSTSOCKET] : NULL;
|
||||
for(; cf; cf = cf->next) {
|
||||
if(cf->cft->flags & CF_TYPE_HTTP) {
|
||||
int value = 0;
|
||||
result = cf->cft->query(cf, data, CF_QUERY_HTTP_VERSION, &value, NULL);
|
||||
if(!result && ((value < 0) || (value > 255)))
|
||||
result = CURLE_FAILED_INIT;
|
||||
else
|
||||
v = (unsigned char)value;
|
||||
break;
|
||||
}
|
||||
if(cf->cft->flags & (CF_TYPE_IP_CONNECT|CF_TYPE_SSL))
|
||||
break;
|
||||
}
|
||||
return (unsigned char)(result ? 0 : v);
|
||||
}
|
||||
|
||||
bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
|
||||
{
|
||||
struct Curl_cfilter *cf;
|
||||
@@ -711,18 +733,6 @@ static CURLcode cf_cntrl_all(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_conn_ev_data_attach(struct connectdata *conn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
cf_cntrl_all(conn, data, TRUE, CF_CTRL_DATA_ATTACH, 0, NULL);
|
||||
}
|
||||
|
||||
void Curl_conn_ev_data_detach(struct connectdata *conn,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
cf_cntrl_all(conn, data, TRUE, CF_CTRL_DATA_DETACH, 0, NULL);
|
||||
}
|
||||
|
||||
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data)
|
||||
{
|
||||
return cf_cntrl_all(data->conn, data, FALSE,
|
||||
|
||||
@@ -132,8 +132,6 @@ typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
|
||||
* to all filters in the chain. Overall result is always CURLE_OK.
|
||||
*/
|
||||
/* data event arg1 arg2 return */
|
||||
#define CF_CTRL_DATA_ATTACH 1 /* 0 NULL ignored */
|
||||
#define CF_CTRL_DATA_DETACH 2 /* 0 NULL ignored */
|
||||
#define CF_CTRL_DATA_SETUP 4 /* 0 NULL first fail */
|
||||
#define CF_CTRL_DATA_IDLE 5 /* 0 NULL first fail */
|
||||
#define CF_CTRL_DATA_PAUSE 6 /* on/off NULL first fail */
|
||||
@@ -178,6 +176,7 @@ typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
|
||||
#define CF_QUERY_STREAM_ERROR 6 /* error code - */
|
||||
#define CF_QUERY_NEED_FLUSH 7 /* TRUE/FALSE - */
|
||||
#define CF_QUERY_IP_INFO 8 /* TRUE/FALSE struct ip_quadruple */
|
||||
#define CF_QUERY_HTTP_VERSION 9 /* number (10/11/20/30) - */
|
||||
|
||||
/**
|
||||
* Query the cfilter for properties. Filters ignorant of a query will
|
||||
@@ -197,11 +196,13 @@ typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
|
||||
* CF_TYPE_SSL: provide SSL/TLS
|
||||
* CF_TYPE_MULTIPLEX: provides multiplexing of easy handles
|
||||
* CF_TYPE_PROXY provides proxying
|
||||
* CF_TYPE_HTTP implement a version of the HTTP protocol
|
||||
*/
|
||||
#define CF_TYPE_IP_CONNECT (1 << 0)
|
||||
#define CF_TYPE_SSL (1 << 1)
|
||||
#define CF_TYPE_MULTIPLEX (1 << 2)
|
||||
#define CF_TYPE_PROXY (1 << 3)
|
||||
#define CF_TYPE_HTTP (1 << 4)
|
||||
|
||||
/* A connection filter type, e.g. specific implementation. */
|
||||
struct Curl_cftype {
|
||||
@@ -394,6 +395,12 @@ bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex);
|
||||
*/
|
||||
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex);
|
||||
|
||||
/**
|
||||
* Return the HTTP version used on the FIRSTSOCKET connection filters
|
||||
* or 0 if unknown. Value otherwise is 09, 10, 11, etc.
|
||||
*/
|
||||
unsigned char Curl_conn_http_version(struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* Close the filter chain at `sockindex` for connection `data->conn`.
|
||||
* Filters remain in place and may be connected again afterwards.
|
||||
@@ -476,24 +483,6 @@ ssize_t Curl_cf_recv(struct Curl_easy *data, int sockindex, char *buf,
|
||||
ssize_t Curl_cf_send(struct Curl_easy *data, int sockindex,
|
||||
const void *buf, size_t len, bool eos, CURLcode *code);
|
||||
|
||||
/**
|
||||
* The easy handle `data` is being attached to `conn`. This does
|
||||
* not mean that data will actually do a transfer. Attachment is
|
||||
* also used for temporary actions on the connection.
|
||||
*/
|
||||
void Curl_conn_ev_data_attach(struct connectdata *conn,
|
||||
struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* The easy handle `data` is being detached (no longer served)
|
||||
* by connection `conn`. All filters are informed to release any resources
|
||||
* related to `data`.
|
||||
* Note: there may be several `data` attached to a connection at the same
|
||||
* time.
|
||||
*/
|
||||
void Curl_conn_ev_data_detach(struct connectdata *conn,
|
||||
struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* Notify connection filters that they need to setup data for
|
||||
* a transfer.
|
||||
|
||||
110
lib/conncache.c
110
lib/conncache.c
@@ -100,6 +100,8 @@ static void cpool_shutdown_all(struct cpool *cpool,
|
||||
struct Curl_easy *data, int timeout_ms);
|
||||
static void cpool_close_and_destroy_all(struct cpool *cpool);
|
||||
static struct connectdata *cpool_get_oldest_idle(struct cpool *cpool);
|
||||
static size_t cpool_shutdown_dest_count(struct cpool *cpool,
|
||||
const char *destination);
|
||||
|
||||
static struct cpool_bundle *cpool_bundle_create(const char *dest,
|
||||
size_t dest_len)
|
||||
@@ -285,6 +287,7 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
struct cpool_bundle *bundle;
|
||||
size_t dest_limit = 0;
|
||||
size_t total_limit = 0;
|
||||
size_t shutdowns;
|
||||
int result = CPOOL_LIMIT_OK;
|
||||
|
||||
if(!cpool)
|
||||
@@ -300,8 +303,12 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
|
||||
CPOOL_LOCK(cpool);
|
||||
if(dest_limit) {
|
||||
size_t live;
|
||||
|
||||
bundle = cpool_find_bundle(cpool, conn);
|
||||
while(bundle && (Curl_llist_count(&bundle->conns) >= dest_limit)) {
|
||||
live = bundle ? Curl_llist_count(&bundle->conns) : 0;
|
||||
shutdowns = cpool_shutdown_dest_count(cpool, conn->destination);
|
||||
while(!shutdowns && bundle && live >= dest_limit) {
|
||||
struct connectdata *oldest_idle = NULL;
|
||||
/* The bundle is full. Extract the oldest connection that may
|
||||
* be removed now, if there is one. */
|
||||
@@ -317,15 +324,18 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
|
||||
/* in case the bundle was destroyed in disconnect, look it up again */
|
||||
bundle = cpool_find_bundle(cpool, conn);
|
||||
live = bundle ? Curl_llist_count(&bundle->conns) : 0;
|
||||
shutdowns = cpool_shutdown_dest_count(cpool, conn->destination);
|
||||
}
|
||||
if(bundle && (Curl_llist_count(&bundle->conns) >= dest_limit)) {
|
||||
if((live + shutdowns) >= dest_limit) {
|
||||
result = CPOOL_LIMIT_DEST;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(total_limit) {
|
||||
while(cpool->num_conn >= total_limit) {
|
||||
shutdowns = Curl_llist_count(&cpool->shutdowns);
|
||||
while((cpool->num_conn + shutdowns) >= total_limit) {
|
||||
struct connectdata *oldest_idle = cpool_get_oldest_idle(cpool);
|
||||
if(!oldest_idle)
|
||||
break;
|
||||
@@ -335,8 +345,9 @@ int Curl_cpool_check_limits(struct Curl_easy *data,
|
||||
"limit of %zu",
|
||||
oldest_idle->connection_id, cpool->num_conn, total_limit));
|
||||
Curl_cpool_disconnect(data, oldest_idle, FALSE);
|
||||
shutdowns = Curl_llist_count(&cpool->shutdowns);
|
||||
}
|
||||
if(cpool->num_conn >= total_limit) {
|
||||
if((cpool->num_conn + shutdowns) >= total_limit) {
|
||||
result = CPOOL_LIMIT_TOTAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -374,7 +385,8 @@ CURLcode Curl_cpool_add_conn(struct Curl_easy *data,
|
||||
cpool->num_conn++;
|
||||
DEBUGF(infof(data, "Added connection %" FMT_OFF_T ". "
|
||||
"The cache now contains %zu members",
|
||||
conn->connection_id, cpool->num_conn));
|
||||
conn->connection_id,
|
||||
cpool->num_conn + Curl_llist_count(&cpool->shutdowns)));
|
||||
out:
|
||||
CPOOL_UNLOCK(cpool);
|
||||
|
||||
@@ -612,6 +624,21 @@ bool Curl_cpool_find(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* How many connections to the given destination are in shutdown? */
|
||||
static size_t cpool_shutdown_dest_count(struct cpool *cpool,
|
||||
const char *destination)
|
||||
{
|
||||
size_t n = 0;
|
||||
struct Curl_llist_node *e = Curl_llist_head(&cpool->shutdowns);
|
||||
while(e) {
|
||||
struct connectdata *conn = Curl_node_elem(e);
|
||||
if(!strcmp(destination, conn->destination))
|
||||
++n;
|
||||
e = Curl_node_next(e);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void cpool_shutdown_discard_all(struct cpool *cpool)
|
||||
{
|
||||
struct Curl_llist_node *e = Curl_llist_head(&cpool->shutdowns);
|
||||
@@ -742,12 +769,12 @@ static void cpool_discard_conn(struct cpool *cpool,
|
||||
|
||||
/* Add the connection to our shutdown list for non-blocking shutdown
|
||||
* during multi processing. */
|
||||
if(data->multi && data->multi->max_shutdown_connections > 0 &&
|
||||
(data->multi->max_shutdown_connections >=
|
||||
(long)Curl_llist_count(&cpool->shutdowns))) {
|
||||
if(data->multi && data->multi->max_total_connections > 0 &&
|
||||
(data->multi->max_total_connections <=
|
||||
(long)(cpool->num_conn + Curl_llist_count(&cpool->shutdowns)))) {
|
||||
DEBUGF(infof(data, "[CCACHE] discarding oldest shutdown connection "
|
||||
"due to limit of %ld",
|
||||
data->multi->max_shutdown_connections));
|
||||
"due to connection limit of %ld",
|
||||
data->multi->max_total_connections));
|
||||
cpool_shutdown_destroy_oldest(cpool);
|
||||
}
|
||||
|
||||
@@ -767,8 +794,8 @@ static void cpool_discard_conn(struct cpool *cpool,
|
||||
|
||||
Curl_llist_append(&cpool->shutdowns, conn, &conn->cpool_node);
|
||||
DEBUGF(infof(data, "[CCACHE] added #%" FMT_OFF_T
|
||||
" to shutdown list of length %zu", conn->connection_id,
|
||||
Curl_llist_count(&cpool->shutdowns)));
|
||||
" to shutdowns, now %zu conns in shutdown",
|
||||
conn->connection_id, Curl_llist_count(&cpool->shutdowns)));
|
||||
}
|
||||
|
||||
void Curl_cpool_disconnect(struct Curl_easy *data,
|
||||
@@ -926,10 +953,11 @@ CURLcode Curl_cpool_add_pollfds(struct cpool *cpool,
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_cpool_add_waitfds(struct cpool *cpool,
|
||||
struct curl_waitfds *cwfds)
|
||||
/* return information about the shutdown connections */
|
||||
unsigned int Curl_cpool_add_waitfds(struct cpool *cpool,
|
||||
struct Curl_waitfds *cwfds)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
unsigned int need = 0;
|
||||
|
||||
CPOOL_LOCK(cpool);
|
||||
if(Curl_llist_head(&cpool->shutdowns)) {
|
||||
@@ -945,14 +973,51 @@ CURLcode Curl_cpool_add_waitfds(struct cpool *cpool,
|
||||
Curl_conn_adjust_pollset(cpool->idata, &ps);
|
||||
Curl_detach_connection(cpool->idata);
|
||||
|
||||
result = Curl_waitfds_add_ps(cwfds, &ps);
|
||||
if(result)
|
||||
goto out;
|
||||
need += Curl_waitfds_add_ps(cwfds, &ps);
|
||||
}
|
||||
}
|
||||
CPOOL_UNLOCK(cpool);
|
||||
return need;
|
||||
}
|
||||
|
||||
/* return fd_set info about the shutdown connections */
|
||||
void Curl_cpool_setfds(struct cpool *cpool,
|
||||
fd_set *read_fd_set, fd_set *write_fd_set,
|
||||
int *maxfd)
|
||||
{
|
||||
CPOOL_LOCK(cpool);
|
||||
if(Curl_llist_head(&cpool->shutdowns)) {
|
||||
struct Curl_llist_node *e;
|
||||
|
||||
for(e = Curl_llist_head(&cpool->shutdowns); e;
|
||||
e = Curl_node_next(e)) {
|
||||
struct easy_pollset ps;
|
||||
unsigned int i;
|
||||
struct connectdata *conn = Curl_node_elem(e);
|
||||
memset(&ps, 0, sizeof(ps));
|
||||
Curl_attach_connection(cpool->idata, conn);
|
||||
Curl_conn_adjust_pollset(cpool->idata, &ps);
|
||||
Curl_detach_connection(cpool->idata);
|
||||
|
||||
for(i = 0; i < ps.num; i++) {
|
||||
#if defined(__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);
|
||||
if(ps.actions[i] & CURL_POLL_OUT)
|
||||
FD_SET(ps.sockets[i], write_fd_set);
|
||||
#if defined(__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];
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
CPOOL_UNLOCK(cpool);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void cpool_perform(struct cpool *cpool)
|
||||
@@ -1052,6 +1117,11 @@ static void cpool_close_and_destroy(struct cpool *cpool,
|
||||
Curl_detach_connection(data);
|
||||
|
||||
Curl_conn_free(data, conn);
|
||||
|
||||
if(cpool && cpool->multi) {
|
||||
DEBUGF(infof(data, "[CCACHE] trigger multi connchanged"));
|
||||
Curl_multi_connchanged(cpool->multi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
struct connectdata;
|
||||
struct Curl_easy;
|
||||
struct curl_pollfds;
|
||||
struct curl_waitfds;
|
||||
struct Curl_waitfds;
|
||||
struct Curl_multi;
|
||||
struct Curl_share;
|
||||
|
||||
@@ -113,8 +113,6 @@ typedef bool Curl_cpool_done_match_cb(bool result, void *userdata);
|
||||
* @param dest_len destination length, including terminating NUL
|
||||
* @param conn_cb must be present, called for each connection in the
|
||||
* bundle until it returns TRUE
|
||||
* @param result_cb if not NULL, is called at the end with the result
|
||||
* of the `conn_cb` or FALSE if never called.
|
||||
* @return combined result of last conn_db and result_cb or FALSE if no
|
||||
connections were present.
|
||||
*/
|
||||
@@ -185,8 +183,12 @@ void Curl_cpool_do_locked(struct Curl_easy *data,
|
||||
*/
|
||||
CURLcode Curl_cpool_add_pollfds(struct cpool *connc,
|
||||
struct curl_pollfds *cpfds);
|
||||
CURLcode Curl_cpool_add_waitfds(struct cpool *connc,
|
||||
struct curl_waitfds *cwfds);
|
||||
unsigned int Curl_cpool_add_waitfds(struct cpool *connc,
|
||||
struct Curl_waitfds *cwfds);
|
||||
|
||||
void Curl_cpool_setfds(struct cpool *cpool,
|
||||
fd_set *read_fd_set, fd_set *write_fd_set,
|
||||
int *maxfd);
|
||||
|
||||
/**
|
||||
* Perform maintenance on connections in the pool. Specifically,
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include "vquic/vquic.h" /* for quic cfilters */
|
||||
#include "http_proxy.h"
|
||||
#include "socks.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -88,6 +89,27 @@
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_DISABLE_ALTSVC) || defined(USE_HTTPSRR)
|
||||
|
||||
enum alpnid Curl_alpn2alpnid(char *name, size_t len)
|
||||
{
|
||||
if(len == 2) {
|
||||
if(strncasecompare(name, "h1", 2))
|
||||
return ALPN_h1;
|
||||
if(strncasecompare(name, "h2", 2))
|
||||
return ALPN_h2;
|
||||
if(strncasecompare(name, "h3", 2))
|
||||
return ALPN_h3;
|
||||
}
|
||||
else if(len == 8) {
|
||||
if(strncasecompare(name, "http/1.1", 8))
|
||||
return ALPN_h1;
|
||||
}
|
||||
return ALPN_none; /* unknown, probably rubbish input */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
||||
* transfer/connection. If the value is 0, there is no timeout (ie there is
|
||||
@@ -1485,7 +1507,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(conn->handler);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
||||
#if !defined(CURL_DISABLE_HTTP)
|
||||
if(!conn->cfilter[sockindex] &&
|
||||
conn->handler->protocol == CURLPROTO_HTTPS) {
|
||||
DEBUGASSERT(ssl_mode != CURL_CF_SSL_DISABLE);
|
||||
@@ -1493,7 +1515,7 @@ CURLcode Curl_conn_setup(struct Curl_easy *data,
|
||||
if(result)
|
||||
goto out;
|
||||
}
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) */
|
||||
|
||||
/* Still no cfilter set, apply default. */
|
||||
if(!conn->cfilter[sockindex]) {
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
struct Curl_dns_entry;
|
||||
struct ip_quadruple;
|
||||
|
||||
enum alpnid Curl_alpn2alpnid(char *name, size_t len);
|
||||
|
||||
/* 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,
|
||||
|
||||
@@ -65,34 +65,15 @@
|
||||
|
||||
/* allow no more than 5 "chained" compression steps */
|
||||
#define MAX_ENCODE_STACK 5
|
||||
|
||||
#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
|
||||
|
||||
#define DECOMPRESS_BUFFER_SIZE 16384 /* buffer size for decompressed data */
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
|
||||
/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
|
||||
(doing so will reduce code size slightly). */
|
||||
#define OLD_ZLIB_SUPPORT 1
|
||||
|
||||
#define GZIP_MAGIC_0 0x1f
|
||||
#define GZIP_MAGIC_1 0x8b
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
|
||||
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
|
||||
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||
#define ORIG_NAME 0x08 /* bit 3 set: original filename present */
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define RESERVED 0xE0 /* bits 5..7: reserved */
|
||||
|
||||
typedef enum {
|
||||
ZLIB_UNINIT, /* uninitialized */
|
||||
ZLIB_INIT, /* initialized */
|
||||
ZLIB_INFLATING, /* inflating started. */
|
||||
ZLIB_EXTERNAL_TRAILER, /* reading external trailer */
|
||||
ZLIB_GZIP_HEADER, /* reading gzip header */
|
||||
ZLIB_GZIP_INFLATING, /* inflating gzip stream */
|
||||
ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
|
||||
} zlibInitState;
|
||||
|
||||
@@ -100,6 +81,7 @@ typedef enum {
|
||||
struct zlib_writer {
|
||||
struct Curl_cwriter super;
|
||||
zlibInitState zlib_init; /* zlib init state */
|
||||
char buffer[DECOMPRESS_BUFFER_SIZE]; /* Put the decompressed data here. */
|
||||
uInt trailerlen; /* Remaining trailer byte count. */
|
||||
z_stream z; /* State structure for zlib. */
|
||||
};
|
||||
@@ -137,9 +119,6 @@ static CURLcode
|
||||
exit_zlib(struct Curl_easy *data,
|
||||
z_stream *z, zlibInitState *zlib_init, CURLcode result)
|
||||
{
|
||||
if(*zlib_init == ZLIB_GZIP_HEADER)
|
||||
Curl_safefree(z->next_in);
|
||||
|
||||
if(*zlib_init != ZLIB_UNINIT) {
|
||||
if(inflateEnd(z) != Z_OK && result == CURLE_OK)
|
||||
result = process_zlib_error(data, z);
|
||||
@@ -183,21 +162,13 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
Bytef *orig_in = z->next_in;
|
||||
bool done = FALSE;
|
||||
CURLcode result = CURLE_OK; /* Curl_client_write status */
|
||||
char *decomp; /* Put the decompressed data here. */
|
||||
|
||||
/* Check state. */
|
||||
if(zp->zlib_init != ZLIB_INIT &&
|
||||
zp->zlib_init != ZLIB_INFLATING &&
|
||||
zp->zlib_init != ZLIB_INIT_GZIP &&
|
||||
zp->zlib_init != ZLIB_GZIP_INFLATING)
|
||||
zp->zlib_init != ZLIB_INIT_GZIP)
|
||||
return exit_zlib(data, z, &zp->zlib_init, CURLE_WRITE_ERROR);
|
||||
|
||||
/* Dynamically allocate a buffer for decompression because it is uncommonly
|
||||
large to hold on the stack */
|
||||
decomp = malloc(DSIZ);
|
||||
if(!decomp)
|
||||
return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
|
||||
|
||||
/* because the buffer size is fixed, iteratively decompress and transfer to
|
||||
the client via next_write function. */
|
||||
while(!done) {
|
||||
@@ -205,8 +176,8 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
done = TRUE;
|
||||
|
||||
/* (re)set buffer for decompressed output for every iteration */
|
||||
z->next_out = (Bytef *) decomp;
|
||||
z->avail_out = DSIZ;
|
||||
z->next_out = (Bytef *) zp->buffer;
|
||||
z->avail_out = DECOMPRESS_BUFFER_SIZE;
|
||||
|
||||
#ifdef Z_BLOCK
|
||||
/* Z_BLOCK is only available in zlib ver. >= 1.2.0.5 */
|
||||
@@ -217,11 +188,11 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
#endif
|
||||
|
||||
/* Flush output data if some. */
|
||||
if(z->avail_out != DSIZ) {
|
||||
if(z->avail_out != DECOMPRESS_BUFFER_SIZE) {
|
||||
if(status == Z_OK || status == Z_STREAM_END) {
|
||||
zp->zlib_init = started; /* Data started. */
|
||||
result = Curl_cwriter_write(data, writer->next, type, decomp,
|
||||
DSIZ - z->avail_out);
|
||||
result = Curl_cwriter_write(data, writer->next, type, zp->buffer,
|
||||
DECOMPRESS_BUFFER_SIZE - z->avail_out);
|
||||
if(result) {
|
||||
exit_zlib(data, z, &zp->zlib_init, result);
|
||||
break;
|
||||
@@ -264,7 +235,6 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(decomp);
|
||||
|
||||
/* We are about to leave this call so the `nread' data bytes will not be seen
|
||||
again. If we are in a state that would wrongly allow restart in raw mode
|
||||
@@ -278,7 +248,7 @@ static CURLcode inflate_stream(struct Curl_easy *data,
|
||||
|
||||
/* Deflate handler. */
|
||||
static CURLcode deflate_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
@@ -294,8 +264,8 @@ static CURLcode deflate_do_init(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
static CURLcode deflate_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
@@ -315,7 +285,7 @@ static CURLcode deflate_do_write(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
static void deflate_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
@@ -335,124 +305,34 @@ static const struct Curl_cwtype deflate_encoding = {
|
||||
|
||||
/* Gzip handler. */
|
||||
static CURLcode gzip_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
const char *v = zlibVersion();
|
||||
|
||||
/* Initialize zlib */
|
||||
z->zalloc = (alloc_func) zalloc_cb;
|
||||
z->zfree = (free_func) zfree_cb;
|
||||
|
||||
if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
|
||||
/* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
|
||||
if(strcmp(v, "1.2.0.4") >= 0) {
|
||||
/* zlib version >= 1.2.0.4 supports transparent gzip decompressing */
|
||||
if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) {
|
||||
return process_zlib_error(data, z);
|
||||
}
|
||||
zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
|
||||
}
|
||||
else {
|
||||
/* we must parse the gzip header and trailer ourselves */
|
||||
if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
|
||||
return process_zlib_error(data, z);
|
||||
}
|
||||
zp->trailerlen = 8; /* A CRC-32 and a 32-bit input size (RFC 1952, 2.2) */
|
||||
zp->zlib_init = ZLIB_INIT; /* Initial call state */
|
||||
failf(data, "too old zlib version: %s", v);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef OLD_ZLIB_SUPPORT
|
||||
/* Skip over the gzip header */
|
||||
typedef enum {
|
||||
GZIP_OK,
|
||||
GZIP_BAD,
|
||||
GZIP_UNDERFLOW
|
||||
} gzip_status;
|
||||
|
||||
static gzip_status check_gzip_header(unsigned char const *data, ssize_t len,
|
||||
ssize_t *headerlen)
|
||||
{
|
||||
int method, flags;
|
||||
const ssize_t totallen = len;
|
||||
|
||||
/* The shortest header is 10 bytes */
|
||||
if(len < 10)
|
||||
return GZIP_UNDERFLOW;
|
||||
|
||||
if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
|
||||
return GZIP_BAD;
|
||||
|
||||
method = data[2];
|
||||
flags = data[3];
|
||||
|
||||
if(method != Z_DEFLATED || (flags & RESERVED) != 0) {
|
||||
/* cannot handle this compression method or unknown flag */
|
||||
return GZIP_BAD;
|
||||
}
|
||||
|
||||
/* Skip over time, xflags, OS code and all previous bytes */
|
||||
len -= 10;
|
||||
data += 10;
|
||||
|
||||
if(flags & EXTRA_FIELD) {
|
||||
ssize_t extra_len;
|
||||
|
||||
if(len < 2)
|
||||
return GZIP_UNDERFLOW;
|
||||
|
||||
extra_len = (data[1] << 8) | data[0];
|
||||
|
||||
if(len < (extra_len + 2))
|
||||
return GZIP_UNDERFLOW;
|
||||
|
||||
len -= (extra_len + 2);
|
||||
data += (extra_len + 2);
|
||||
}
|
||||
|
||||
if(flags & ORIG_NAME) {
|
||||
/* Skip over NUL-terminated filename */
|
||||
while(len && *data) {
|
||||
--len;
|
||||
++data;
|
||||
}
|
||||
if(!len || *data)
|
||||
return GZIP_UNDERFLOW;
|
||||
|
||||
/* Skip over the NUL */
|
||||
--len;
|
||||
++data;
|
||||
}
|
||||
|
||||
if(flags & COMMENT) {
|
||||
/* Skip over NUL-terminated comment */
|
||||
while(len && *data) {
|
||||
--len;
|
||||
++data;
|
||||
}
|
||||
if(!len || *data)
|
||||
return GZIP_UNDERFLOW;
|
||||
|
||||
/* Skip over the NUL */
|
||||
--len;
|
||||
}
|
||||
|
||||
if(flags & HEAD_CRC) {
|
||||
if(len < 2)
|
||||
return GZIP_UNDERFLOW;
|
||||
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
*headerlen = totallen - len;
|
||||
return GZIP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode gzip_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
struct zlib_writer *zp = (struct zlib_writer *) writer;
|
||||
z_stream *z = &zp->z; /* zlib state structure */
|
||||
@@ -468,117 +348,8 @@ static CURLcode gzip_do_write(struct Curl_easy *data,
|
||||
return inflate_stream(data, writer, type, ZLIB_INIT_GZIP);
|
||||
}
|
||||
|
||||
#ifndef OLD_ZLIB_SUPPORT
|
||||
/* Support for old zlib versions is compiled away and we are running with
|
||||
an old version, so return an error. */
|
||||
/* We are running with an old version: return error. */
|
||||
return exit_zlib(data, z, &zp->zlib_init, CURLE_WRITE_ERROR);
|
||||
|
||||
#else
|
||||
/* This next mess is to get around the potential case where there is not
|
||||
* enough data passed in to skip over the gzip header. If that happens, we
|
||||
* malloc a block and copy what we have then wait for the next call. If
|
||||
* there still is not enough (this is definitely a worst-case scenario), we
|
||||
* make the block bigger, copy the next part in and keep waiting.
|
||||
*
|
||||
* This is only required with zlib versions < 1.2.0.4 as newer versions
|
||||
* can handle the gzip header themselves.
|
||||
*/
|
||||
|
||||
switch(zp->zlib_init) {
|
||||
/* Skip over gzip header? */
|
||||
case ZLIB_INIT:
|
||||
{
|
||||
/* Initial call state */
|
||||
ssize_t hlen;
|
||||
|
||||
switch(check_gzip_header((unsigned char *) buf, nbytes, &hlen)) {
|
||||
case GZIP_OK:
|
||||
z->next_in = (Bytef *) buf + hlen;
|
||||
z->avail_in = (uInt) (nbytes - hlen);
|
||||
zp->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
|
||||
break;
|
||||
|
||||
case GZIP_UNDERFLOW:
|
||||
/* We need more data so we can find the end of the gzip header. it is
|
||||
* possible that the memory block we malloc here will never be freed if
|
||||
* the transfer abruptly aborts after this point. Since it is unlikely
|
||||
* that circumstances will be right for this code path to be followed in
|
||||
* the first place, and it is even more unlikely for a transfer to fail
|
||||
* immediately afterwards, it should seldom be a problem.
|
||||
*/
|
||||
z->avail_in = (uInt) nbytes;
|
||||
z->next_in = malloc(z->avail_in);
|
||||
if(!z->next_in) {
|
||||
return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
|
||||
}
|
||||
memcpy(z->next_in, buf, z->avail_in);
|
||||
zp->zlib_init = ZLIB_GZIP_HEADER; /* Need more gzip header data state */
|
||||
/* We do not have any data to inflate yet */
|
||||
return CURLE_OK;
|
||||
|
||||
case GZIP_BAD:
|
||||
default:
|
||||
return exit_zlib(data, z, &zp->zlib_init, process_zlib_error(data, z));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ZLIB_GZIP_HEADER:
|
||||
{
|
||||
/* Need more gzip header data state */
|
||||
ssize_t hlen;
|
||||
z->avail_in += (uInt) nbytes;
|
||||
z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
|
||||
if(!z->next_in) {
|
||||
return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
|
||||
}
|
||||
/* Append the new block of data to the previous one */
|
||||
memcpy(z->next_in + z->avail_in - nbytes, buf, nbytes);
|
||||
|
||||
switch(check_gzip_header(z->next_in, (ssize_t)z->avail_in, &hlen)) {
|
||||
case GZIP_OK:
|
||||
/* This is the zlib stream data */
|
||||
free(z->next_in);
|
||||
/* Do not point into the malloced block since we just freed it */
|
||||
z->next_in = (Bytef *) buf + hlen + nbytes - z->avail_in;
|
||||
z->avail_in = z->avail_in - (uInt)hlen;
|
||||
zp->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
|
||||
break;
|
||||
|
||||
case GZIP_UNDERFLOW:
|
||||
/* We still do not have any data to inflate! */
|
||||
return CURLE_OK;
|
||||
|
||||
case GZIP_BAD:
|
||||
default:
|
||||
return exit_zlib(data, z, &zp->zlib_init, process_zlib_error(data, z));
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ZLIB_EXTERNAL_TRAILER:
|
||||
z->next_in = (Bytef *) buf;
|
||||
z->avail_in = (uInt) nbytes;
|
||||
return process_trailer(data, zp);
|
||||
|
||||
case ZLIB_GZIP_INFLATING:
|
||||
default:
|
||||
/* Inflating stream state */
|
||||
z->next_in = (Bytef *) buf;
|
||||
z->avail_in = (uInt) nbytes;
|
||||
break;
|
||||
}
|
||||
|
||||
if(z->avail_in == 0) {
|
||||
/* We do not have any data to inflate; wait until next time */
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* We have parsed the header, now uncompress the data */
|
||||
return inflate_stream(data, writer, type, ZLIB_GZIP_INFLATING);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gzip_do_close(struct Curl_easy *data,
|
||||
@@ -601,11 +372,11 @@ static const struct Curl_cwtype gzip_encoding = {
|
||||
|
||||
#endif /* HAVE_LIBZ */
|
||||
|
||||
|
||||
#ifdef HAVE_BROTLI
|
||||
/* Brotli writer. */
|
||||
struct brotli_writer {
|
||||
struct Curl_cwriter super;
|
||||
char buffer[DECOMPRESS_BUFFER_SIZE];
|
||||
BrotliDecoderState *br; /* State structure for brotli. */
|
||||
};
|
||||
|
||||
@@ -648,7 +419,7 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
|
||||
}
|
||||
|
||||
static CURLcode brotli_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
(void) data;
|
||||
@@ -658,12 +429,11 @@ static CURLcode brotli_do_init(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
static CURLcode brotli_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
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;
|
||||
char *decomp;
|
||||
uint8_t *dst;
|
||||
size_t dstleft;
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -675,18 +445,14 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
||||
if(!bp->br)
|
||||
return CURLE_WRITE_ERROR; /* Stream already ended. */
|
||||
|
||||
decomp = malloc(DSIZ);
|
||||
if(!decomp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) &&
|
||||
result == CURLE_OK) {
|
||||
dst = (uint8_t *) decomp;
|
||||
dstleft = DSIZ;
|
||||
dst = (uint8_t *) bp->buffer;
|
||||
dstleft = DECOMPRESS_BUFFER_SIZE;
|
||||
r = BrotliDecoderDecompressStream(bp->br,
|
||||
&nbytes, &src, &dstleft, &dst, NULL);
|
||||
result = Curl_cwriter_write(data, writer->next, type,
|
||||
decomp, DSIZ - dstleft);
|
||||
bp->buffer, DECOMPRESS_BUFFER_SIZE - dstleft);
|
||||
if(result)
|
||||
break;
|
||||
switch(r) {
|
||||
@@ -704,7 +470,6 @@ static CURLcode brotli_do_write(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(decomp);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -712,7 +477,6 @@ static void brotli_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct brotli_writer *bp = (struct brotli_writer *) writer;
|
||||
|
||||
(void) data;
|
||||
|
||||
if(bp->br) {
|
||||
@@ -731,30 +495,51 @@ static const struct Curl_cwtype brotli_encoding = {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
/* Zstd writer. */
|
||||
struct zstd_writer {
|
||||
struct Curl_cwriter super;
|
||||
ZSTD_DStream *zds; /* State structure for zstd. */
|
||||
void *decomp;
|
||||
char buffer[DECOMPRESS_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
#ifdef ZSTD_STATIC_LINKING_ONLY
|
||||
static void *Curl_zstd_alloc(void *opaque, size_t size)
|
||||
{
|
||||
(void)opaque;
|
||||
return Curl_cmalloc(size);
|
||||
}
|
||||
|
||||
static void Curl_zstd_free(void *opaque, void *address)
|
||||
{
|
||||
(void)opaque;
|
||||
Curl_cfree(address);
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode zstd_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
|
||||
(void)data;
|
||||
|
||||
#ifdef ZSTD_STATIC_LINKING_ONLY
|
||||
zp->zds = ZSTD_createDStream_advanced((ZSTD_customMem) {
|
||||
.customAlloc = Curl_zstd_alloc,
|
||||
.customFree = Curl_zstd_free,
|
||||
.opaque = NULL
|
||||
});
|
||||
#else
|
||||
zp->zds = ZSTD_createDStream();
|
||||
zp->decomp = NULL;
|
||||
#endif
|
||||
|
||||
return zp->zds ? CURLE_OK : CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static CURLcode zstd_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
@@ -765,19 +550,14 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
||||
if(!(type & CLIENTWRITE_BODY) || !nbytes)
|
||||
return Curl_cwriter_write(data, writer->next, type, buf, nbytes);
|
||||
|
||||
if(!zp->decomp) {
|
||||
zp->decomp = malloc(DSIZ);
|
||||
if(!zp->decomp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
in.pos = 0;
|
||||
in.src = buf;
|
||||
in.size = nbytes;
|
||||
|
||||
for(;;) {
|
||||
out.pos = 0;
|
||||
out.dst = zp->decomp;
|
||||
out.size = DSIZ;
|
||||
out.dst = zp->buffer;
|
||||
out.size = DECOMPRESS_BUFFER_SIZE;
|
||||
|
||||
errorCode = ZSTD_decompressStream(zp->zds, &out, &in);
|
||||
if(ZSTD_isError(errorCode)) {
|
||||
@@ -785,7 +565,7 @@ static CURLcode zstd_do_write(struct Curl_easy *data,
|
||||
}
|
||||
if(out.pos > 0) {
|
||||
result = Curl_cwriter_write(data, writer->next, type,
|
||||
zp->decomp, out.pos);
|
||||
zp->buffer, out.pos);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
@@ -800,13 +580,8 @@ static void zstd_do_close(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
struct zstd_writer *zp = (struct zstd_writer *) writer;
|
||||
|
||||
(void)data;
|
||||
|
||||
if(zp->decomp) {
|
||||
free(zp->decomp);
|
||||
zp->decomp = NULL;
|
||||
}
|
||||
if(zp->zds) {
|
||||
ZSTD_freeDStream(zp->zds);
|
||||
zp->zds = NULL;
|
||||
@@ -823,7 +598,6 @@ static const struct Curl_cwtype zstd_encoding = {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* Identity handler. */
|
||||
static const struct Curl_cwtype identity_encoding = {
|
||||
"identity",
|
||||
@@ -834,7 +608,6 @@ static const struct Curl_cwtype identity_encoding = {
|
||||
sizeof(struct Curl_cwriter)
|
||||
};
|
||||
|
||||
|
||||
/* supported general content decoders. */
|
||||
static const struct Curl_cwtype * const general_unencoders[] = {
|
||||
&identity_encoding,
|
||||
@@ -898,7 +671,7 @@ void Curl_all_content_encodings(char *buf, size_t blen)
|
||||
|
||||
/* Deferred error dummy writer. */
|
||||
static CURLcode error_do_init(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer)
|
||||
struct Curl_cwriter *writer)
|
||||
{
|
||||
(void)data;
|
||||
(void)writer;
|
||||
@@ -906,8 +679,8 @@ static CURLcode error_do_init(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
static CURLcode error_do_write(struct Curl_easy *data,
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
struct Curl_cwriter *writer, int type,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
(void) writer;
|
||||
(void) buf;
|
||||
@@ -1082,5 +855,4 @@ void Curl_all_content_encodings(char *buf, size_t blen)
|
||||
strcpy(buf, CONTENT_ENCODING_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
|
||||
96
lib/cookie.c
96
lib/cookie.c
@@ -97,6 +97,26 @@ Example set of cookies:
|
||||
|
||||
static void strstore(char **str, const char *newstr, size_t len);
|
||||
|
||||
/* number of seconds in 400 days */
|
||||
#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)
|
||||
|
||||
For the sake of easier testing, align the capped time to an even 60 second
|
||||
boundary.
|
||||
*/
|
||||
static void cap_expires(time_t now, struct Cookie *co)
|
||||
{
|
||||
if((TIME_T_MAX - COOKIES_MAXAGE - 30) > now) {
|
||||
timediff_t cap = now + COOKIES_MAXAGE;
|
||||
if(co->expires > cap) {
|
||||
cap += 30;
|
||||
co->expires = (cap/60)*60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void freecookie(struct Cookie *co)
|
||||
{
|
||||
free(co->domain);
|
||||
@@ -438,7 +458,7 @@ 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 int invalid_octets(const char *p)
|
||||
static bool invalid_octets(const char *p)
|
||||
{
|
||||
/* Reject all bytes \x01 - \x1f (*except* \x09, TAB) + \x7f */
|
||||
static const char badoctets[] = {
|
||||
@@ -449,7 +469,7 @@ static int invalid_octets(const char *p)
|
||||
size_t len;
|
||||
/* scan for all the octets that are *not* in cookie-octet */
|
||||
len = strcspn(p, badoctets);
|
||||
return (p[len] != '\0');
|
||||
return p[len] != '\0';
|
||||
}
|
||||
|
||||
#define CERR_OK 0
|
||||
@@ -469,6 +489,13 @@ static int invalid_octets(const char *p)
|
||||
#define CERR_PSL 14 /* a public suffix */
|
||||
#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
|
||||
there.
|
||||
*/
|
||||
#define MAX_DATE_LENGTH 80
|
||||
|
||||
static int
|
||||
parse_cookie_header(struct Curl_easy *data,
|
||||
struct Cookie *co,
|
||||
@@ -707,16 +734,20 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
co->expires += now;
|
||||
break;
|
||||
}
|
||||
cap_expires(now, co);
|
||||
}
|
||||
else if((nlen == 7) && strncasecompare("expires", namep, 7)) {
|
||||
if(!co->expires) {
|
||||
if(!co->expires && (vlen < 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
|
||||
*/
|
||||
co->expires = Curl_getdate_capped(valuep);
|
||||
char dbuf[MAX_DATE_LENGTH + 1];
|
||||
memcpy(dbuf, valuep, vlen);
|
||||
dbuf[vlen] = 0;
|
||||
co->expires = Curl_getdate_capped(dbuf);
|
||||
|
||||
/*
|
||||
* Session cookies have expires set to 0 so if we get that back
|
||||
@@ -727,6 +758,7 @@ parse_cookie_header(struct Curl_easy *data,
|
||||
co->expires = 1;
|
||||
else if(co->expires < 0)
|
||||
co->expires = 0;
|
||||
cap_expires(now, co);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,10 +837,9 @@ parse_netscape(struct Cookie *co,
|
||||
* This line is NOT an HTTP header style line, we do offer support for
|
||||
* reading the odd netscape cookies-file format here
|
||||
*/
|
||||
char *ptr;
|
||||
char *firstptr;
|
||||
char *tok_buf = NULL;
|
||||
const char *ptr, *next;
|
||||
int fields;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* In 2008, Internet Explorer introduced HTTP-only cookies to prevent XSS
|
||||
@@ -825,29 +856,22 @@ parse_netscape(struct Cookie *co,
|
||||
/* do not even try the comments */
|
||||
return CERR_COMMENT;
|
||||
|
||||
/* strip off the possible end-of-line characters */
|
||||
ptr = strchr(lineptr, '\r');
|
||||
if(ptr)
|
||||
*ptr = 0; /* clear it */
|
||||
ptr = strchr(lineptr, '\n');
|
||||
if(ptr)
|
||||
*ptr = 0; /* clear it */
|
||||
|
||||
/* tokenize on TAB */
|
||||
firstptr = Curl_strtok_r((char *)lineptr, "\t", &tok_buf);
|
||||
|
||||
/*
|
||||
* Now loop through the fields and init the struct we already have
|
||||
* allocated
|
||||
*/
|
||||
fields = 0;
|
||||
for(ptr = firstptr; ptr;
|
||||
ptr = Curl_strtok_r(NULL, "\t", &tok_buf), fields++) {
|
||||
for(next = lineptr; next; fields++) {
|
||||
ptr = next;
|
||||
len = strcspn(ptr, "\t\r\n");
|
||||
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++;
|
||||
co->domain = strdup(ptr);
|
||||
len--;
|
||||
}
|
||||
co->domain = Curl_memdup0(ptr, len);
|
||||
if(!co->domain)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
break;
|
||||
@@ -857,13 +881,13 @@ parse_netscape(struct Cookie *co,
|
||||
* domain can access the variable. Set TRUE when the cookie says
|
||||
* .domain.com and to false when the domain is complete www.domain.com
|
||||
*/
|
||||
co->tailmatch = !!strcasecompare(ptr, "TRUE");
|
||||
co->tailmatch = !!strncasecompare(ptr, "TRUE", len);
|
||||
break;
|
||||
case 2:
|
||||
/* The file format allows the path field to remain not filled in */
|
||||
if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
|
||||
if(strncmp("TRUE", ptr, len) && strncmp("FALSE", ptr, len)) {
|
||||
/* only if the path does not look like a boolean option! */
|
||||
co->path = strdup(ptr);
|
||||
co->path = Curl_memdup0(ptr, len);
|
||||
if(!co->path)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
else {
|
||||
@@ -884,7 +908,7 @@ parse_netscape(struct Cookie *co,
|
||||
FALLTHROUGH();
|
||||
case 3:
|
||||
co->secure = FALSE;
|
||||
if(strcasecompare(ptr, "TRUE")) {
|
||||
if(strncasecompare(ptr, "TRUE", len)) {
|
||||
if(secure || ci->running)
|
||||
co->secure = TRUE;
|
||||
else
|
||||
@@ -892,11 +916,19 @@ parse_netscape(struct Cookie *co,
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(curlx_strtoofft(ptr, NULL, 10, &co->expires))
|
||||
return CERR_RANGE;
|
||||
{
|
||||
char *endp;
|
||||
const char *p;
|
||||
/* make sure curlx_strtoofft won't read past the current field */
|
||||
for(p = ptr; p < &ptr[len] && ISDIGIT(*p); ++p)
|
||||
;
|
||||
if(p == ptr || p != &ptr[len] ||
|
||||
curlx_strtoofft(ptr, &endp, 10, &co->expires) || endp != &ptr[len])
|
||||
return CERR_RANGE;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
co->name = strdup(ptr);
|
||||
co->name = Curl_memdup0(ptr, len);
|
||||
if(!co->name)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
else {
|
||||
@@ -908,7 +940,7 @@ parse_netscape(struct Cookie *co,
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
co->value = strdup(ptr);
|
||||
co->value = Curl_memdup0(ptr, len);
|
||||
if(!co->value)
|
||||
return CERR_OUT_OF_MEMORY;
|
||||
break;
|
||||
@@ -1303,14 +1335,14 @@ static int cookie_sort(const void *p1, const void *p2)
|
||||
l2 = c2->path ? strlen(c2->path) : 0;
|
||||
|
||||
if(l1 != l2)
|
||||
return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
|
||||
return (l2 > l1) ? 1 : -1; /* avoid size_t <=> int conversions */
|
||||
|
||||
/* 2 - compare cookie domain lengths */
|
||||
l1 = c1->domain ? strlen(c1->domain) : 0;
|
||||
l2 = c2->domain ? strlen(c2->domain) : 0;
|
||||
|
||||
if(l1 != l2)
|
||||
return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
|
||||
return (l2 > l1) ? 1 : -1; /* avoid size_t <=> int conversions */
|
||||
|
||||
/* 3 - compare cookie name lengths */
|
||||
l1 = c1->name ? strlen(c1->name) : 0;
|
||||
|
||||
10
lib/cookie.h
10
lib/cookie.h
@@ -38,7 +38,7 @@ struct Cookie {
|
||||
char *spath; /* sanitized cookie path */
|
||||
char *domain; /* domain = <this> */
|
||||
curl_off_t expires; /* expires = <this> */
|
||||
int creationtime; /* time when the cookie was written */
|
||||
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 */
|
||||
@@ -60,10 +60,10 @@ 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 */
|
||||
int numcookies; /* number of cookies in the "jar" */
|
||||
int lastct; /* last creation-time used in the jar */
|
||||
bool running; /* state info, for cookie adding information */
|
||||
bool newsession; /* new session, discard session cookies on load */
|
||||
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 */
|
||||
};
|
||||
|
||||
/* The maximum sizes we accept for cookies. RFC 6265 section 6.1 says
|
||||
|
||||
@@ -318,11 +318,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
addr = (void *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
|
||||
#ifdef __MINGW32__
|
||||
addr->sin_family = (short)(he->h_addrtype);
|
||||
#else
|
||||
addr->sin_family = (CURL_SA_FAMILY_T)(he->h_addrtype);
|
||||
#endif
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
@@ -331,11 +327,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
addr6 = (void *)ai->ai_addr; /* storage area for this info */
|
||||
|
||||
memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
|
||||
#ifdef __MINGW32__
|
||||
addr6->sin6_family = (short)(he->h_addrtype);
|
||||
#else
|
||||
addr6->sin6_family = (CURL_SA_FAMILY_T)(he->h_addrtype);
|
||||
#endif
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -565,9 +565,6 @@
|
||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||
#cmakedefine HAVE_SYS_FILIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#cmakedefine HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#cmakedefine HAVE_SYS_IOCTL_H 1
|
||||
|
||||
@@ -625,8 +622,8 @@
|
||||
/* Define this symbol if your OS supports changing the contents of argv */
|
||||
#cmakedefine HAVE_WRITABLE_ARGV 1
|
||||
|
||||
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
|
||||
#cmakedefine NEED_MALLOC_H 1
|
||||
/* Define this if time_t is unsigned */
|
||||
#cmakedefine HAVE_TIME_T_UNSIGNED 1
|
||||
|
||||
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
|
||||
#cmakedefine NEED_REENTRANT 1
|
||||
@@ -634,24 +631,6 @@
|
||||
/* cpu-machine-OS */
|
||||
#cmakedefine CURL_OS ${CURL_OS}
|
||||
|
||||
/* Name of package */
|
||||
#cmakedefine PACKAGE ${PACKAGE}
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT}
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#cmakedefine PACKAGE_NAME ${PACKAGE_NAME}
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#cmakedefine PACKAGE_STRING ${PACKAGE_STRING}
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME}
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION}
|
||||
|
||||
/*
|
||||
Note: SIZEOF_* variables are fetched with CMake through check_type_size().
|
||||
As per CMake documentation on CheckTypeSize, C preprocessor code is
|
||||
@@ -703,6 +682,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if Secure Transport is enabled */
|
||||
#cmakedefine USE_SECTRANSP 1
|
||||
|
||||
/* if SSL session export support is available */
|
||||
#cmakedefine USE_SSLS_EXPORT 1
|
||||
|
||||
/* if mbedTLS is enabled */
|
||||
#cmakedefine USE_MBEDTLS 1
|
||||
|
||||
@@ -742,6 +724,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* if OpenSSL is in use */
|
||||
#cmakedefine USE_OPENSSL 1
|
||||
|
||||
/* if AmiSSL is in use */
|
||||
#cmakedefine USE_AMISSL 1
|
||||
|
||||
/* if librtmp/rtmpdump is in use */
|
||||
#cmakedefine USE_LIBRTMP 1
|
||||
|
||||
@@ -791,12 +776,12 @@ ${SIZEOF_TIME_T_CODE}
|
||||
/* to enable Windows SSL */
|
||||
#cmakedefine USE_SCHANNEL 1
|
||||
|
||||
/* if Watt-32 is in use */
|
||||
#cmakedefine USE_WATT32 1
|
||||
|
||||
/* enable multiple SSL backends */
|
||||
#cmakedefine CURL_WITH_MULTI_SSL 1
|
||||
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION ${VERSION}
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
|
||||
|
||||
@@ -841,3 +826,9 @@ ${SIZEOF_TIME_T_CODE}
|
||||
|
||||
/* if ECH support is available */
|
||||
#cmakedefine USE_ECH 1
|
||||
|
||||
/* Define to 1 if you have the wolfSSL_CTX_GenerateEchConfig function. */
|
||||
#cmakedefine HAVE_WOLFSSL_CTX_GENERATEECHCONFIG
|
||||
|
||||
/* Define to 1 if you have the SSL_set1_ech_config_list function. */
|
||||
#cmakedefine HAVE_SSL_SET1_ECH_CONFIG_LIST
|
||||
|
||||
@@ -46,6 +46,6 @@
|
||||
#define ISURLPUNTCS(x) (((x) == '-') || ((x) == '.') || ((x) == '_') || \
|
||||
((x) == '~'))
|
||||
#define ISUNRESERVED(x) (ISALNUM(x) || ISURLPUNTCS(x))
|
||||
|
||||
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
|
||||
|
||||
#endif /* HEADER_CURL_CTYPE_H */
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
!defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC)
|
||||
|
||||
#include "curl_get_line.h"
|
||||
#ifdef BUILDING_LIBCURL
|
||||
#include "curl_memory.h"
|
||||
#endif
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
|
||||
#include "dynbuf.h"
|
||||
|
||||
#ifndef BUILDING_LIBCURL
|
||||
/* this renames functions so that the tool code can use the same code
|
||||
without getting symbol collisions */
|
||||
#define Curl_get_line(a,b) curlx_get_line(a,b)
|
||||
#endif
|
||||
|
||||
/* Curl_get_line() returns complete lines that end with a newline. */
|
||||
int Curl_get_line(struct dynbuf *buf, FILE *input);
|
||||
|
||||
|
||||
@@ -73,7 +73,11 @@ int Curl_gethostname(char * const name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
#else /* DEBUGBUILD */
|
||||
|
||||
name[0] = '\0';
|
||||
#ifdef __AMIGA__
|
||||
err = gethostname((unsigned char *)name, namelen);
|
||||
#else
|
||||
err = gethostname(name, namelen);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
#define CURL_ALIGN8
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(__APPLE__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
gss_OID_desc Curl_spnego_mech_oid CURL_ALIGN8 = {
|
||||
6, (char *)"\x2b\x06\x01\x05\x05\x02"
|
||||
};
|
||||
@@ -149,4 +154,8 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && defined(__APPLE__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \
|
||||
|| !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \
|
||||
|| defined(USE_LIBSSH2)
|
||||
#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \
|
||||
!defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \
|
||||
defined(USE_SSL)
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
@@ -84,16 +84,170 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
/* declare GetFullPathNameW for mingw-w64 UWP builds targeting old windows */
|
||||
#if defined(CURL_WINDOWS_UWP) && defined(__MINGW32__) && \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN10)
|
||||
WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR, DWORD, LPWSTR, LPWSTR *);
|
||||
#endif
|
||||
|
||||
#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
|
||||
/* Fix excessive paths (paths that exceed MAX_PATH length of 260).
|
||||
*
|
||||
* This is a helper function to fix paths that would exceed the MAX_PATH
|
||||
* limitation check done by Windows APIs. It does so by normalizing the passed
|
||||
* in filename or path 'in' to its full canonical path, and if that path is
|
||||
* longer than MAX_PATH then setting 'out' to "\\?\" prefix + that full path.
|
||||
*
|
||||
* For example 'in' filename255chars in current directory C:\foo\bar is
|
||||
* fixed as \\?\C:\foo\bar\filename255chars for 'out' which will tell Windows
|
||||
* it is ok to access that filename even though the actual full path is longer
|
||||
* than 260 chars.
|
||||
*
|
||||
* For non-Unicode builds this function may fail sometimes because only the
|
||||
* Unicode versions of some Windows API functions can access paths longer than
|
||||
* MAX_PATH, for example GetFullPathNameW which is used in this function. When
|
||||
* the full path is then converted from Unicode to multibyte that fails if any
|
||||
* directories in the path contain characters not in the current codepage.
|
||||
*/
|
||||
static bool fix_excessive_path(const TCHAR *in, TCHAR **out)
|
||||
{
|
||||
size_t needed, count;
|
||||
const wchar_t *in_w;
|
||||
wchar_t *fbuf = NULL;
|
||||
|
||||
/* MS documented "approximate" limit for the maximum path length */
|
||||
const size_t max_path_len = 32767;
|
||||
|
||||
#ifndef _UNICODE
|
||||
wchar_t *ibuf = NULL;
|
||||
char *obuf = NULL;
|
||||
#endif
|
||||
|
||||
*out = NULL;
|
||||
|
||||
/* skip paths already normalized */
|
||||
if(!_tcsncmp(in, _T("\\\\?\\"), 4))
|
||||
goto cleanup;
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert multibyte input to unicode */
|
||||
needed = mbstowcs(NULL, in, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
ibuf = malloc(needed * sizeof(wchar_t));
|
||||
if(!ibuf)
|
||||
goto cleanup;
|
||||
count = mbstowcs(ibuf, in, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
goto cleanup;
|
||||
in_w = ibuf;
|
||||
#else
|
||||
in_w = in;
|
||||
#endif
|
||||
|
||||
/* GetFullPathNameW returns the normalized full path in unicode. It converts
|
||||
forward slashes to backslashes, processes .. to remove directory segments,
|
||||
etc. Unlike GetFullPathNameA it can process paths that exceed MAX_PATH. */
|
||||
needed = (size_t)GetFullPathNameW(in_w, 0, NULL, NULL);
|
||||
if(!needed || needed > max_path_len)
|
||||
goto cleanup;
|
||||
/* skip paths that are not excessive and do not need modification */
|
||||
if(needed <= MAX_PATH)
|
||||
goto cleanup;
|
||||
fbuf = malloc(needed * sizeof(wchar_t));
|
||||
if(!fbuf)
|
||||
goto cleanup;
|
||||
count = (size_t)GetFullPathNameW(in_w, (DWORD)needed, fbuf, NULL);
|
||||
if(!count || count >= needed)
|
||||
goto cleanup;
|
||||
|
||||
/* prepend \\?\ or \\?\UNC\ to the excessively long path.
|
||||
*
|
||||
* c:\longpath ---> \\?\c:\longpath
|
||||
* \\.\c:\longpath ---> \\?\c:\longpath
|
||||
* \\?\c:\longpath ---> \\?\c:\longpath (unchanged)
|
||||
* \\server\c$\longpath ---> \\?\UNC\server\c$\longpath
|
||||
*
|
||||
* https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
|
||||
*/
|
||||
if(!wcsncmp(fbuf, L"\\\\?\\", 4))
|
||||
; /* do nothing */
|
||||
else if(!wcsncmp(fbuf, L"\\\\.\\", 4))
|
||||
fbuf[2] = '?';
|
||||
else if(!wcsncmp(fbuf, L"\\\\.", 3) || !wcsncmp(fbuf, L"\\\\?", 3)) {
|
||||
/* Unexpected, not UNC. The formatting doc doesn't allow this AFAICT. */
|
||||
goto cleanup;
|
||||
}
|
||||
else {
|
||||
wchar_t *temp;
|
||||
|
||||
if(!wcsncmp(fbuf, L"\\\\", 2)) {
|
||||
/* "\\?\UNC\" + full path without "\\" + null */
|
||||
needed = 8 + (count - 2) + 1;
|
||||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = malloc(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\UNC\\", 8);
|
||||
wcscpy(temp + 8, fbuf + 2);
|
||||
}
|
||||
else {
|
||||
/* "\\?\" + full path + null */
|
||||
needed = 4 + count + 1;
|
||||
if(needed > max_path_len)
|
||||
goto cleanup;
|
||||
|
||||
temp = malloc(needed * sizeof(wchar_t));
|
||||
if(!temp)
|
||||
goto cleanup;
|
||||
|
||||
wcsncpy(temp, L"\\\\?\\", 4);
|
||||
wcscpy(temp + 4, fbuf);
|
||||
}
|
||||
|
||||
free(fbuf);
|
||||
fbuf = temp;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
/* convert unicode full path to multibyte output */
|
||||
needed = wcstombs(NULL, fbuf, 0);
|
||||
if(needed == (size_t)-1 || needed >= max_path_len)
|
||||
goto cleanup;
|
||||
++needed; /* for NUL */
|
||||
obuf = malloc(needed);
|
||||
if(!obuf)
|
||||
goto cleanup;
|
||||
count = wcstombs(obuf, fbuf, needed);
|
||||
if(count == (size_t)-1 || count >= needed)
|
||||
goto cleanup;
|
||||
*out = obuf;
|
||||
obuf = NULL;
|
||||
#else
|
||||
*out = fbuf;
|
||||
fbuf = NULL;
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
free(fbuf);
|
||||
#ifndef _UNICODE
|
||||
free(ibuf);
|
||||
free(obuf);
|
||||
#endif
|
||||
return *out ? true : false;
|
||||
}
|
||||
|
||||
int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
{
|
||||
int pmode = 0;
|
||||
int result = -1;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
int result = -1;
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
#endif
|
||||
|
||||
@@ -105,58 +259,95 @@ int curlx_win32_open(const char *filename, int oflag, ...)
|
||||
|
||||
#ifdef _UNICODE
|
||||
if(filename_w) {
|
||||
result = _wopen(filename_w, oflag, pmode);
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wopen(target, oflag, pmode);
|
||||
curlx_unicodefree(filename_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
return result;
|
||||
#else
|
||||
return (_open)(filename, oflag, pmode);
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
result = (_open)(target, oflag, pmode);
|
||||
#endif
|
||||
|
||||
free(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
FILE *result = NULL;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
|
||||
wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
|
||||
if(filename_w && mode_w)
|
||||
result = _wfopen(filename_w, mode_w);
|
||||
if(filename_w && mode_w) {
|
||||
if(fix_excessive_path(filename_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename_w;
|
||||
result = _wfopen(target, mode_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
curlx_unicodefree(filename_w);
|
||||
curlx_unicodefree(mode_w);
|
||||
return result;
|
||||
#else
|
||||
return (fopen)(filename, mode);
|
||||
if(fix_excessive_path(filename, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = filename;
|
||||
result = (fopen)(target, mode);
|
||||
#endif
|
||||
|
||||
free(fixed);
|
||||
return result;
|
||||
}
|
||||
|
||||
int curlx_win32_stat(const char *path, struct_stat *buffer)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
int result = -1;
|
||||
TCHAR *fixed = NULL;
|
||||
const TCHAR *target = NULL;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
|
||||
if(path_w) {
|
||||
#if defined(USE_WIN32_SMALL_FILES)
|
||||
result = _wstat(path_w, buffer);
|
||||
if(fix_excessive_path(path_w, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path_w;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _wstat(target, buffer);
|
||||
#else
|
||||
result = _wstati64(path_w, buffer);
|
||||
result = _wstati64(target, buffer);
|
||||
#endif
|
||||
curlx_unicodefree(path_w);
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
#else
|
||||
if(fix_excessive_path(path, &fixed))
|
||||
target = fixed;
|
||||
else
|
||||
target = path;
|
||||
#ifndef USE_WIN32_LARGE_FILES
|
||||
result = _stat(target, buffer);
|
||||
#else
|
||||
result = _stati64(target, buffer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
free(fixed);
|
||||
return result;
|
||||
#else
|
||||
#if defined(USE_WIN32_SMALL_FILES)
|
||||
return _stat(path, buffer);
|
||||
#else
|
||||
return _stati64(path, buffer);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
@@ -85,6 +85,7 @@ const struct Curl_handler Curl_handler_rtmp = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMP, /* protocol */
|
||||
CURLPROTO_RTMP, /* family */
|
||||
@@ -109,6 +110,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPT, /* protocol */
|
||||
CURLPROTO_RTMPT, /* family */
|
||||
@@ -133,6 +135,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_RTMP, /* defport */
|
||||
CURLPROTO_RTMPE, /* protocol */
|
||||
CURLPROTO_RTMPE, /* family */
|
||||
@@ -157,6 +160,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_RTMPT, /* defport */
|
||||
CURLPROTO_RTMPTE, /* protocol */
|
||||
CURLPROTO_RTMPTE, /* family */
|
||||
@@ -181,6 +185,7 @@ const struct Curl_handler Curl_handler_rtmps = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPS, /* protocol */
|
||||
CURLPROTO_RTMP, /* family */
|
||||
@@ -205,6 +210,7 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_RTMPS, /* defport */
|
||||
CURLPROTO_RTMPTS, /* protocol */
|
||||
CURLPROTO_RTMPT, /* family */
|
||||
|
||||
196
lib/curl_setup.h
196
lib/curl_setup.h
@@ -31,13 +31,6 @@
|
||||
/* Tell "curl/curl.h" not to include "curl/mprintf.h" */
|
||||
#define CURL_SKIP_INCLUDE_MPRINTF
|
||||
|
||||
/* FIXME: Delete this once the warnings have been fixed. */
|
||||
#if !defined(CURL_WARN_SIGN_CONVERSION)
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Set default _WIN32_WINNT */
|
||||
#ifdef __MINGW32__
|
||||
#include <_mingw.h>
|
||||
@@ -85,13 +78,17 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disable Visual Studio warnings:
|
||||
* 4127 "conditional expression is constant"
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
/* Disable Visual Studio warnings: 4127 "conditional expression is constant" */
|
||||
#pragma warning(disable:4127)
|
||||
/* Avoid VS2005 and upper complaining about portable C functions. */
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write(), etc. */
|
||||
#endif
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE /* for fopen(), getenv(), etc. */
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
@@ -100,26 +97,26 @@
|
||||
* Make sure to define this macro before including any Windows headers.
|
||||
*/
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifndef NOGDI
|
||||
# define NOGDI
|
||||
# define NOGDI
|
||||
# endif
|
||||
/* Detect Windows App environment which has a restricted access
|
||||
* to the Win32 APIs. */
|
||||
# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
|
||||
defined(WINAPI_FAMILY)
|
||||
# include <winapifamily.h>
|
||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
|
||||
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define CURL_WINDOWS_UWP
|
||||
# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
|
||||
defined(WINAPI_FAMILY)
|
||||
# include <winapifamily.h>
|
||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
|
||||
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define CURL_WINDOWS_UWP
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Compatibility */
|
||||
#if defined(ENABLE_IPV6)
|
||||
# define USE_IPV6 1
|
||||
#ifdef ENABLE_IPV6
|
||||
#define USE_IPV6 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -133,12 +130,8 @@
|
||||
|
||||
#else /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# include "config-win32ce.h"
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
# include "config-win32.h"
|
||||
# endif
|
||||
#ifdef _WIN32
|
||||
# include "config-win32.h"
|
||||
#endif
|
||||
|
||||
#ifdef macintosh
|
||||
@@ -149,10 +142,6 @@
|
||||
# include "config-riscos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include "config-amigaos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "config-os400.h"
|
||||
#endif
|
||||
@@ -161,10 +150,6 @@
|
||||
# include "config-plan9.h"
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
# include "config-dos.h"
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* ================================================================ */
|
||||
@@ -183,7 +168,7 @@
|
||||
|
||||
#ifdef NEED_THREAD_SAFE
|
||||
# ifndef _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -195,14 +180,14 @@
|
||||
|
||||
#ifdef NEED_REENTRANT
|
||||
# ifndef _REENTRANT
|
||||
# define _REENTRANT
|
||||
# define _REENTRANT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Solaris needs this to get a POSIX-conformant getpwuid_r */
|
||||
#if defined(sun) || defined(__sun)
|
||||
# ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -290,14 +275,6 @@
|
||||
# define CURL_DISABLE_HTTP_AUTH 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ECH requires HTTPSRR.
|
||||
*/
|
||||
|
||||
#if defined(USE_ECH) && !defined(USE_HTTPSRR)
|
||||
# define USE_HTTPSRR
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* No system header file shall be included in this file before this */
|
||||
/* point. */
|
||||
@@ -393,17 +370,23 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARES
|
||||
# ifndef CARES_NO_DEPRECATED
|
||||
# define CARES_NO_DEPRECATED /* for ares_getsock() */
|
||||
# endif
|
||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && defined(_WIN32)
|
||||
# define CARES_STATICLIB /* define it before including ares.h */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_LWIPSOCK
|
||||
# include <lwip/init.h>
|
||||
# include <lwip/sockets.h>
|
||||
# include <lwip/netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRICMP_H
|
||||
#ifdef macintosh
|
||||
# include <extra/stricmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRDUP_H
|
||||
# include <extra/strdup.h>
|
||||
#endif
|
||||
|
||||
@@ -456,9 +439,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __TANDEM /* for ns*-tandem-nsk systems */
|
||||
# if ! defined __LP64
|
||||
# include <floss.h> /* FLOSS is only used for 32-bit builds. */
|
||||
# endif
|
||||
# if ! defined __LP64
|
||||
# include <floss.h> /* FLOSS is only used for 32-bit builds. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS /* no standard C headers! */
|
||||
@@ -494,11 +477,19 @@
|
||||
FILE *curlx_win32_fopen(const char *filename, const char *mode);
|
||||
#endif
|
||||
|
||||
#ifdef __DJGPP__
|
||||
/* Requires DJGPP 2.04 */
|
||||
# include <unistd.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) llseek(fdes, offset, whence)
|
||||
# define LSEEK_ERROR (offset_t)-1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Small file (<2Gb) support using Win32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_SMALL_FILES
|
||||
#if defined(_WIN32) && !defined(USE_WIN32_LARGE_FILES)
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
@@ -518,11 +509,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef struct_stat
|
||||
# define struct_stat struct stat
|
||||
#define struct_stat struct stat
|
||||
#endif
|
||||
|
||||
#ifndef LSEEK_ERROR
|
||||
# define LSEEK_ERROR (off_t)-1
|
||||
#define LSEEK_ERROR (off_t)-1
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_TIME_T
|
||||
@@ -593,8 +584,8 @@
|
||||
# endif
|
||||
# define CURL_UINT64_SUFFIX CURL_SUFFIX_CURL_OFF_TU
|
||||
# define CURL_UINT64_C(val) CURL_CONC_MACROS(val,CURL_UINT64_SUFFIX)
|
||||
# define FMT_PRId64 CURL_FORMAT_CURL_OFF_T
|
||||
# define FMT_PRIu64 CURL_FORMAT_CURL_OFF_TU
|
||||
# define FMT_PRId64 CURL_FORMAT_CURL_OFF_T
|
||||
# define FMT_PRIu64 CURL_FORMAT_CURL_OFF_TU
|
||||
#endif
|
||||
|
||||
#define FMT_OFF_T CURL_FORMAT_CURL_OFF_T
|
||||
@@ -693,9 +684,9 @@
|
||||
/*
|
||||
* MSVC threads support requires a multi-threaded runtime library.
|
||||
* _beginthreadex() is not available in single-threaded ones.
|
||||
* Single-threaded option was last available in VS2005: _MSC_VER <= 1400
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_MT)
|
||||
#if defined(_MSC_VER) && !defined(_MT) /* available in _MSC_VER <= 1400 */
|
||||
# undef USE_THREADS_POSIX
|
||||
# undef USE_THREADS_WIN32
|
||||
#endif
|
||||
@@ -713,15 +704,15 @@
|
||||
# define CURLRES_IPV4
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARES
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_THREADED
|
||||
#elif defined(USE_ARES)
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_ARES
|
||||
/* now undef the stock libc functions just to avoid them being used */
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_FREEADDRINFO
|
||||
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_THREADED
|
||||
#else
|
||||
# define CURLRES_SYNCH
|
||||
#endif
|
||||
@@ -738,14 +729,23 @@
|
||||
#error "libidn2 cannot be enabled with WinIDN or AppleIDN, choose one."
|
||||
#endif
|
||||
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_BEARSSL) || defined(USE_RUSTLS)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
#if defined(USE_OPENSSL) && defined(USE_WOLFSSL)
|
||||
# include <wolfssl/version.h>
|
||||
# if LIBWOLFSSL_VERSION_HEX >= 0x05007006
|
||||
# ifndef OPENSSL_COEXIST
|
||||
# define OPENSSL_COEXIST
|
||||
# endif
|
||||
# else
|
||||
# error "OpenSSL can only coexist with wolfSSL v5.7.6 or upper"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_WOLFSSL) && defined(USE_GNUTLS)
|
||||
/* Avoid defining unprefixed wolfSSL SHA macros colliding with nettle ones */
|
||||
#define NO_OLD_WC_NAMES
|
||||
@@ -776,10 +776,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CURL_WANTS_CA_BUNDLE_ENV
|
||||
#error "No longer supported. Set CURLOPT_CAINFO at runtime instead."
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH)
|
||||
#define USE_SSH
|
||||
#endif
|
||||
@@ -812,7 +808,7 @@
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) || \
|
||||
defined(__IAR_SYSTEMS_ICC__)
|
||||
# define CURL_NORETURN __attribute__((__noreturn__))
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
#elif defined(_MSC_VER)
|
||||
# define CURL_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
# define CURL_NORETURN
|
||||
@@ -843,7 +839,7 @@
|
||||
*/
|
||||
|
||||
#ifndef Curl_nop_stmt
|
||||
# define Curl_nop_stmt do { } while(0)
|
||||
#define Curl_nop_stmt do { } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -882,6 +878,14 @@
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* Since O_BINARY is used in bitmasks, setting it to zero makes it usable in
|
||||
source code but yet it does not ruin anything */
|
||||
#ifdef O_BINARY
|
||||
#define CURL_O_BINARY O_BINARY
|
||||
#else
|
||||
#define CURL_O_BINARY 0
|
||||
#endif
|
||||
|
||||
/* In Windows the default file mode is text but an application can override it.
|
||||
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
|
||||
*/
|
||||
@@ -911,6 +915,8 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
# define CURL_SA_FAMILY_T sa_family_t
|
||||
# elif defined(HAVE_ADDRESS_FAMILY)
|
||||
# define CURL_SA_FAMILY_T ADDRESS_FAMILY
|
||||
# elif defined(__AMIGA__)
|
||||
# define CURL_SA_FAMILY_T unsigned char
|
||||
# else
|
||||
/* use a sensible default */
|
||||
# define CURL_SA_FAMILY_T unsigned short
|
||||
@@ -927,8 +933,9 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
as their argument */
|
||||
#define STRCONST(x) x,sizeof(x)-1
|
||||
|
||||
/* Some versions of the Android SDK is missing the declaration */
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
|
||||
/* Some versions of the Android NDK is missing the declaration */
|
||||
#if defined(HAVE_GETPWUID_R) && \
|
||||
defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
|
||||
struct passwd;
|
||||
int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
size_t buflen, struct passwd **result);
|
||||
@@ -940,8 +947,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
#define UNITTEST static
|
||||
#endif
|
||||
|
||||
/* Hyper supports HTTP2 also, but Curl's integration with Hyper does not */
|
||||
#if defined(USE_NGHTTP2)
|
||||
#ifdef USE_NGHTTP2
|
||||
#define USE_HTTP2
|
||||
#endif
|
||||
|
||||
@@ -950,7 +956,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
defined(USE_QUICHE) || defined(USE_MSH3)
|
||||
|
||||
#ifdef CURL_WITH_MULTI_SSL
|
||||
#error "Multi-SSL combined with QUIC is not supported"
|
||||
#error "MultiSSL combined with QUIC is not supported"
|
||||
#endif
|
||||
|
||||
#define USE_HTTP3
|
||||
@@ -970,7 +976,7 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
# define UNIX_PATH_MAX 108
|
||||
/* !checksrc! disable TYPEDEFSTRUCT 1 */
|
||||
typedef struct sockaddr_un {
|
||||
ADDRESS_FAMILY sun_family;
|
||||
CURL_SA_FAMILY_T sun_family;
|
||||
char sun_path[UNIX_PATH_MAX];
|
||||
} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||
# define WIN32_SOCKADDR_UN
|
||||
@@ -983,26 +989,26 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#if defined(inline)
|
||||
/* 'inline' is defined as macro and assumed to be correct */
|
||||
/* No need for 'inline' replacement */
|
||||
#if defined(CURL_INLINE)
|
||||
/* 'CURL_INLINE' defined, use as-is */
|
||||
#elif defined(inline)
|
||||
# define CURL_INLINE inline /* 'inline' defined, assumed correct */
|
||||
#elif defined(__cplusplus)
|
||||
/* The code is compiled with C++ compiler.
|
||||
C++ always supports 'inline'. */
|
||||
/* No need for 'inline' replacement */
|
||||
/* The code is compiled with C++ compiler.
|
||||
C++ always supports 'inline'. */
|
||||
# define CURL_INLINE inline /* 'inline' keyword supported */
|
||||
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901
|
||||
/* C99 (and later) supports 'inline' keyword */
|
||||
/* No need for 'inline' replacement */
|
||||
/* C99 (and later) supports 'inline' keyword */
|
||||
# define CURL_INLINE inline /* 'inline' keyword supported */
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 3
|
||||
/* GCC supports '__inline__' as an extension */
|
||||
# define inline __inline__
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
/* MSC supports '__inline' from VS 2005 (or even earlier) */
|
||||
# define inline __inline
|
||||
/* GCC supports '__inline__' as an extension */
|
||||
# define CURL_INLINE __inline__
|
||||
#elif defined(_MSC_VER)
|
||||
# define CURL_INLINE __inline
|
||||
#else
|
||||
/* Probably 'inline' is not supported by compiler.
|
||||
Define to the empty string to be on the safe side. */
|
||||
# define inline /* empty */
|
||||
/* Probably 'inline' is not supported by compiler.
|
||||
Define to the empty string to be on the safe side. */
|
||||
# define CURL_INLINE /* empty */
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* Inclusion of common header files.
|
||||
*/
|
||||
@@ -40,14 +39,6 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifdef NEED_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
@@ -56,8 +47,11 @@
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
@@ -111,8 +105,8 @@
|
||||
|
||||
#ifndef HAVE_STRUCT_TIMEVAL
|
||||
struct timeval {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -195,7 +189,7 @@ struct timeval {
|
||||
# define sclose(x) closesocket((x))
|
||||
#elif defined(HAVE_CLOSESOCKET_CAMEL)
|
||||
# define sclose(x) CloseSocket((x))
|
||||
#elif defined(HAVE_CLOSE_S)
|
||||
#elif defined(MSDOS) /* Watt-32 */
|
||||
# define sclose(x) close_s((x))
|
||||
#elif defined(USE_LWIPSOCK)
|
||||
# define sclose(x) lwip_close((x))
|
||||
@@ -233,8 +227,8 @@ struct timeval {
|
||||
|
||||
#ifndef HAVE_BOOL_T
|
||||
typedef enum {
|
||||
bool_false = 0,
|
||||
bool_true = 1
|
||||
bool_false = 0,
|
||||
bool_true = 1
|
||||
} bool;
|
||||
|
||||
/*
|
||||
@@ -397,7 +391,7 @@ typedef unsigned int bit;
|
||||
#ifdef __VMS
|
||||
#define argv_item_t __char_ptr32
|
||||
#elif defined(_UNICODE)
|
||||
#define argv_item_t wchar_t *
|
||||
#define argv_item_t wchar_t *
|
||||
#else
|
||||
#define argv_item_t char *
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#if !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) \
|
||||
|| defined(USE_LIBSSH2)
|
||||
|| defined(USE_LIBSSH2) || defined(USE_SSL)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_hmac.h"
|
||||
|
||||
@@ -283,28 +283,26 @@ Curl_sha512_256_finish(unsigned char *digest,
|
||||
#ifdef __GNUC__
|
||||
# if defined(__has_attribute) && defined(__STDC_VERSION__)
|
||||
# if __has_attribute(always_inline) && __STDC_VERSION__ >= 199901
|
||||
# define MHDX_INLINE inline __attribute__((always_inline))
|
||||
# define CURL_FORCEINLINE CURL_INLINE __attribute__((always_inline))
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(MHDX_INLINE) && \
|
||||
#if !defined(CURL_FORCEINLINE) && \
|
||||
defined(_MSC_VER) && !defined(__GNUC__) && !defined(__clang__)
|
||||
# if _MSC_VER >= 1400
|
||||
# define MHDX_INLINE __forceinline
|
||||
# endif
|
||||
# define CURL_FORCEINLINE __forceinline
|
||||
#endif
|
||||
|
||||
#if !defined(MHDX_INLINE)
|
||||
/* Assume that 'inline' keyword works or the
|
||||
#if !defined(CURL_FORCEINLINE)
|
||||
/* Assume that 'CURL_INLINE' keyword works or the
|
||||
* macro was already defined correctly. */
|
||||
# define MHDX_INLINE inline
|
||||
# define CURL_FORCEINLINE CURL_INLINE
|
||||
#endif
|
||||
|
||||
/* Bits manipulation macros and functions.
|
||||
Can be moved to other headers to reuse. */
|
||||
|
||||
#define MHDX_GET_64BIT_BE(ptr) \
|
||||
#define CURL_GET_64BIT_BE(ptr) \
|
||||
( ((curl_uint64_t)(((const unsigned char*)(ptr))[0]) << 56) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[1]) << 48) | \
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[2]) << 40) | \
|
||||
@@ -314,7 +312,7 @@ Curl_sha512_256_finish(unsigned char *digest,
|
||||
((curl_uint64_t)(((const unsigned char*)(ptr))[6]) << 8) | \
|
||||
(curl_uint64_t)(((const unsigned char*)(ptr))[7]) )
|
||||
|
||||
#define MHDX_PUT_64BIT_BE(ptr,val) do { \
|
||||
#define CURL_PUT_64BIT_BE(ptr,val) do { \
|
||||
((unsigned char*)(ptr))[7]=(unsigned char)((curl_uint64_t)(val)); \
|
||||
((unsigned char*)(ptr))[6]=(unsigned char)(((curl_uint64_t)(val)) >> 8); \
|
||||
((unsigned char*)(ptr))[5]=(unsigned char)(((curl_uint64_t)(val)) >> 16); \
|
||||
@@ -328,8 +326,8 @@ Curl_sha512_256_finish(unsigned char *digest,
|
||||
/* Defined as a function. The macro version may duplicate the binary code
|
||||
* size as each argument is used twice, so if any calculation is used
|
||||
* as an argument, the calculation could be done twice. */
|
||||
static MHDX_INLINE curl_uint64_t
|
||||
MHDx_rotr64(curl_uint64_t value, unsigned int bits)
|
||||
static CURL_FORCEINLINE curl_uint64_t
|
||||
Curl_rotr64(curl_uint64_t value, unsigned int bits)
|
||||
{
|
||||
bits %= 64;
|
||||
if(0 == bits)
|
||||
@@ -388,7 +386,7 @@ MHDx_rotr64(curl_uint64_t value, unsigned int bits)
|
||||
/**
|
||||
* SHA-512/256 calculation context
|
||||
*/
|
||||
struct mhdx_sha512_256ctx
|
||||
struct Curl_sha512_256ctx
|
||||
{
|
||||
/**
|
||||
* Intermediate hash value. The variable is properly aligned. Smart
|
||||
@@ -416,7 +414,7 @@ struct mhdx_sha512_256ctx
|
||||
/**
|
||||
* Context type used for SHA-512/256 calculations
|
||||
*/
|
||||
typedef struct mhdx_sha512_256ctx Curl_sha512_256_ctx;
|
||||
typedef struct Curl_sha512_256ctx Curl_sha512_256_ctx;
|
||||
|
||||
|
||||
/**
|
||||
@@ -426,9 +424,9 @@ typedef struct mhdx_sha512_256ctx Curl_sha512_256_ctx;
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
MHDx_sha512_256_init(void *context)
|
||||
Curl_sha512_256_init(void *context)
|
||||
{
|
||||
struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *) context;
|
||||
struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
|
||||
/* Check whether the header and this file use the same numbers */
|
||||
DEBUGASSERT(CURL_SHA512_256_DIGEST_LENGTH == CURL_SHA512_256_DIGEST_SIZE);
|
||||
@@ -462,7 +460,7 @@ MHDx_sha512_256_init(void *context)
|
||||
* @param data the data buffer with #CURL_SHA512_256_BLOCK_SIZE bytes block
|
||||
*/
|
||||
static void
|
||||
MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
Curl_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
const void *data)
|
||||
{
|
||||
/* Working variables,
|
||||
@@ -488,13 +486,13 @@ MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
/* Four 'Sigma' macro functions.
|
||||
See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */
|
||||
#define SIG0(x) \
|
||||
( MHDx_rotr64((x), 28) ^ MHDx_rotr64((x), 34) ^ MHDx_rotr64((x), 39) )
|
||||
( Curl_rotr64((x), 28) ^ Curl_rotr64((x), 34) ^ Curl_rotr64((x), 39) )
|
||||
#define SIG1(x) \
|
||||
( MHDx_rotr64((x), 14) ^ MHDx_rotr64((x), 18) ^ MHDx_rotr64((x), 41) )
|
||||
( Curl_rotr64((x), 14) ^ Curl_rotr64((x), 18) ^ Curl_rotr64((x), 41) )
|
||||
#define sig0(x) \
|
||||
( MHDx_rotr64((x), 1) ^ MHDx_rotr64((x), 8) ^ ((x) >> 7) )
|
||||
( Curl_rotr64((x), 1) ^ Curl_rotr64((x), 8) ^ ((x) >> 7) )
|
||||
#define sig1(x) \
|
||||
( MHDx_rotr64((x), 19) ^ MHDx_rotr64((x), 61) ^ ((x) >> 6) )
|
||||
( Curl_rotr64((x), 19) ^ Curl_rotr64((x), 61) ^ ((x) >> 6) )
|
||||
|
||||
if(1) {
|
||||
unsigned int t;
|
||||
@@ -577,7 +575,7 @@ MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
Input data must be read in big-endian bytes order,
|
||||
see FIPS PUB 180-4 section 3.1.2. */
|
||||
#define SHA512_GET_W_FROM_DATA(buf,t) \
|
||||
MHDX_GET_64BIT_BE( \
|
||||
CURL_GET_64BIT_BE( \
|
||||
((const unsigned char*) (buf)) + (t) * SHA512_256_BYTES_IN_WORD)
|
||||
|
||||
/* During first 16 steps, before making any calculation on each step, the
|
||||
@@ -628,12 +626,12 @@ MHDx_sha512_256_transform(curl_uint64_t H[SHA512_256_HASH_SIZE_WORDS],
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
MHDx_sha512_256_update(void *context,
|
||||
Curl_sha512_256_update(void *context,
|
||||
const unsigned char *data,
|
||||
size_t length)
|
||||
{
|
||||
unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
||||
struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *)context;
|
||||
struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
/* the void pointer here is required to mute Intel compiler warning */
|
||||
void *const ctx_buf = ctx->buffer;
|
||||
|
||||
@@ -661,7 +659,7 @@ MHDx_sha512_256_update(void *context,
|
||||
bytes_left);
|
||||
data += bytes_left;
|
||||
length -= bytes_left;
|
||||
MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
Curl_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
bytes_have = 0;
|
||||
}
|
||||
}
|
||||
@@ -669,7 +667,7 @@ MHDx_sha512_256_update(void *context,
|
||||
while(CURL_SHA512_256_BLOCK_SIZE <= length) {
|
||||
/* Process any full blocks of new data directly,
|
||||
without copying to the buffer. */
|
||||
MHDx_sha512_256_transform(ctx->H, data);
|
||||
Curl_sha512_256_transform(ctx->H, data);
|
||||
data += CURL_SHA512_256_BLOCK_SIZE;
|
||||
length -= CURL_SHA512_256_BLOCK_SIZE;
|
||||
}
|
||||
@@ -705,10 +703,10 @@ MHDx_sha512_256_update(void *context,
|
||||
* @return always CURLE_OK
|
||||
*/
|
||||
static CURLcode
|
||||
MHDx_sha512_256_finish(unsigned char *digest,
|
||||
Curl_sha512_256_finish(unsigned char *digest,
|
||||
void *context)
|
||||
{
|
||||
struct mhdx_sha512_256ctx *const ctx = (struct mhdx_sha512_256ctx *)context;
|
||||
struct Curl_sha512_256ctx *const ctx = (struct Curl_sha512_256ctx *)context;
|
||||
curl_uint64_t num_bits; /**< Number of processed bits */
|
||||
unsigned int bytes_have; /**< Number of bytes in the context buffer */
|
||||
/* the void pointer here is required to mute Intel compiler warning */
|
||||
@@ -742,7 +740,7 @@ MHDx_sha512_256_finish(unsigned char *digest,
|
||||
memset(((unsigned char *) ctx_buf) + bytes_have, 0,
|
||||
CURL_SHA512_256_BLOCK_SIZE - bytes_have);
|
||||
/* Process the full block. */
|
||||
MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
Curl_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
/* Start the new block. */
|
||||
bytes_have = 0;
|
||||
}
|
||||
@@ -754,37 +752,32 @@ MHDx_sha512_256_finish(unsigned char *digest,
|
||||
part of number of bits as big-endian values.
|
||||
See FIPS PUB 180-4 section 5.1.2. */
|
||||
/* Note: the target location is predefined and buffer is always aligned */
|
||||
MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
+ CURL_SHA512_256_BLOCK_SIZE \
|
||||
- SHA512_256_SIZE_OF_LEN_ADD, \
|
||||
ctx->count_bits_hi);
|
||||
MHDX_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
CURL_PUT_64BIT_BE(((unsigned char *) ctx_buf) \
|
||||
+ CURL_SHA512_256_BLOCK_SIZE \
|
||||
- SHA512_256_SIZE_OF_LEN_ADD \
|
||||
+ SHA512_256_BYTES_IN_WORD, \
|
||||
num_bits);
|
||||
/* Process the full final block. */
|
||||
MHDx_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
Curl_sha512_256_transform(ctx->H, ctx->buffer);
|
||||
|
||||
/* Put in BE mode the leftmost part of the hash as the final digest.
|
||||
See FIPS PUB 180-4 section 6.7. */
|
||||
|
||||
MHDX_PUT_64BIT_BE((digest + 0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]);
|
||||
MHDX_PUT_64BIT_BE((digest + 1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]);
|
||||
MHDX_PUT_64BIT_BE((digest + 2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]);
|
||||
MHDX_PUT_64BIT_BE((digest + 3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]);
|
||||
CURL_PUT_64BIT_BE((digest + 0 * SHA512_256_BYTES_IN_WORD), ctx->H[0]);
|
||||
CURL_PUT_64BIT_BE((digest + 1 * SHA512_256_BYTES_IN_WORD), ctx->H[1]);
|
||||
CURL_PUT_64BIT_BE((digest + 2 * SHA512_256_BYTES_IN_WORD), ctx->H[2]);
|
||||
CURL_PUT_64BIT_BE((digest + 3 * SHA512_256_BYTES_IN_WORD), ctx->H[3]);
|
||||
|
||||
/* Erase potentially sensitive data. */
|
||||
memset(ctx, 0, sizeof(struct mhdx_sha512_256ctx));
|
||||
memset(ctx, 0, sizeof(struct Curl_sha512_256ctx));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Map to the local implementation */
|
||||
#define Curl_sha512_256_init MHDx_sha512_256_init
|
||||
#define Curl_sha512_256_update MHDx_sha512_256_update
|
||||
#define Curl_sha512_256_finish MHDx_sha512_256_finish
|
||||
|
||||
#endif /* Local SHA-512/256 code */
|
||||
|
||||
|
||||
|
||||
@@ -81,27 +81,27 @@ extern PSecurityFunctionTable Curl_pSecFn;
|
||||
#endif
|
||||
|
||||
#ifndef SEC_I_SIGNATURE_NEEDED
|
||||
# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL)
|
||||
#define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_REVOKED
|
||||
# define CRYPT_E_REVOKED ((HRESULT)0x80092010L)
|
||||
#define CRYPT_E_REVOKED ((HRESULT)0x80092010L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_NO_REVOCATION_DLL
|
||||
# define CRYPT_E_NO_REVOCATION_DLL ((HRESULT)0x80092011L)
|
||||
#define CRYPT_E_NO_REVOCATION_DLL ((HRESULT)0x80092011L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_NO_REVOCATION_CHECK
|
||||
# define CRYPT_E_NO_REVOCATION_CHECK ((HRESULT)0x80092012L)
|
||||
#define CRYPT_E_NO_REVOCATION_CHECK ((HRESULT)0x80092012L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_REVOCATION_OFFLINE
|
||||
# define CRYPT_E_REVOCATION_OFFLINE ((HRESULT)0x80092013L)
|
||||
#define CRYPT_E_REVOCATION_OFFLINE ((HRESULT)0x80092013L)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_NOT_IN_REVOCATION_DATABASE
|
||||
# define CRYPT_E_NOT_IN_REVOCATION_DATABASE ((HRESULT)0x80092014L)
|
||||
#define CRYPT_E_NOT_IN_REVOCATION_DATABASE ((HRESULT)0x80092014L)
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
|
||||
@@ -239,6 +239,24 @@ void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
|
||||
}
|
||||
#endif /* !CURL_DISABLE_SMTP */
|
||||
|
||||
#ifdef USE_SSL
|
||||
struct curl_trc_feat Curl_trc_feat_ssls = {
|
||||
"SSLS",
|
||||
CURL_LOG_LVL_NONE,
|
||||
};
|
||||
|
||||
void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
DEBUGASSERT(!strchr(fmt, '\n'));
|
||||
if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssls)) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
trc_infof(data, &Curl_trc_feat_ssls, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#endif /* USE_SSL */
|
||||
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
struct curl_trc_feat Curl_trc_feat_ws = {
|
||||
"WS",
|
||||
@@ -279,6 +297,9 @@ static struct trc_feat_def trc_feats[] = {
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
{ &Curl_trc_feat_smtp, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
{ &Curl_trc_feat_ssls, TRC_CT_NETWORK },
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
{ &Curl_trc_feat_ws, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
@@ -319,7 +340,7 @@ static struct trc_cft_def trc_cfts[] = {
|
||||
#ifdef USE_HTTP3
|
||||
{ &Curl_cft_http3, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
|
||||
#if !defined(CURL_DISABLE_HTTP)
|
||||
{ &Curl_cft_http_connect, TRC_CT_PROTOCOL },
|
||||
#endif
|
||||
};
|
||||
@@ -427,4 +448,53 @@ CURLcode Curl_trc_init(void)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_cf_infof(struct Curl_easy *data,
|
||||
struct Curl_cfilter *cf,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)cf; (void)fmt;
|
||||
}
|
||||
|
||||
struct curl_trc_feat;
|
||||
|
||||
void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) || !defined(CURL_DISABLE_HTTP)
|
||||
void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Curl_trc_ssls(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data;
|
||||
(void)fmt;
|
||||
}
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
||||
|
||||
125
lib/curl_trc.h
125
lib/curl_trc.h
@@ -70,7 +70,45 @@ void Curl_failf(struct Curl_easy *data,
|
||||
#define CURL_HAVE_C99
|
||||
#endif
|
||||
|
||||
#ifdef CURL_HAVE_C99
|
||||
/**
|
||||
* Output an informational message when transfer's verbose logging is enabled.
|
||||
*/
|
||||
void Curl_infof(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
/**
|
||||
* Output an informational message when both transfer's verbose logging
|
||||
* and connection filters verbose logging are enabled.
|
||||
*/
|
||||
void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
|
||||
const char *fmt, ...) CURL_PRINTF(3, 4);
|
||||
void Curl_trc_write(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
void Curl_trc_read(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
extern struct curl_trc_feat Curl_trc_feat_ftp;
|
||||
void Curl_trc_ftp(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
extern struct curl_trc_feat Curl_trc_feat_smtp;
|
||||
void Curl_trc_smtp(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
extern struct curl_trc_feat Curl_trc_feat_ssls;
|
||||
void Curl_trc_ssls(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
extern struct curl_trc_feat Curl_trc_feat_ws;
|
||||
void Curl_trc_ws(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
|
||||
#if defined(CURL_HAVE_C99) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#define infof(data, ...) \
|
||||
do { if(Curl_trc_is_verbose(data)) \
|
||||
Curl_infof(data, __VA_ARGS__); } while(0)
|
||||
@@ -94,6 +132,11 @@ void Curl_failf(struct Curl_easy *data,
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_smtp)) \
|
||||
Curl_trc_smtp(data, __VA_ARGS__); } while(0)
|
||||
#endif /* !CURL_DISABLE_SMTP */
|
||||
#ifdef USE_SSL
|
||||
#define CURL_TRC_SSLS(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ssls)) \
|
||||
Curl_trc_ssls(data, __VA_ARGS__); } while(0)
|
||||
#endif /* USE_SSL */
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
#define CURL_TRC_WS(data, ...) \
|
||||
do { if(Curl_trc_ft_is_verbose(data, &Curl_trc_feat_ws)) \
|
||||
@@ -113,6 +156,9 @@ void Curl_failf(struct Curl_easy *data,
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
#define CURL_TRC_SMTP Curl_trc_smtp
|
||||
#endif
|
||||
#ifdef USE_SSL
|
||||
#define CURL_TRC_SSLS Curl_trc_ssls
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
#define CURL_TRC_WS Curl_trc_ws
|
||||
#endif
|
||||
@@ -140,40 +186,6 @@ extern struct curl_trc_feat Curl_trc_feat_write;
|
||||
(Curl_trc_is_verbose(data) && \
|
||||
(ft)->log_level >= CURL_LOG_LVL_INFO)
|
||||
|
||||
/**
|
||||
* Output an informational message when transfer's verbose logging is enabled.
|
||||
*/
|
||||
void Curl_infof(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
/**
|
||||
* Output an informational message when both transfer's verbose logging
|
||||
* and connection filters verbose logging are enabled.
|
||||
*/
|
||||
void Curl_trc_cf_infof(struct Curl_easy *data, struct Curl_cfilter *cf,
|
||||
const char *fmt, ...) CURL_PRINTF(3, 4);
|
||||
void Curl_trc_write(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
void Curl_trc_read(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
extern struct curl_trc_feat Curl_trc_feat_ftp;
|
||||
void Curl_trc_ftp(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
extern struct curl_trc_feat Curl_trc_feat_smtp;
|
||||
void Curl_trc_smtp(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
|
||||
extern struct curl_trc_feat Curl_trc_feat_ws;
|
||||
void Curl_trc_ws(struct Curl_easy *data,
|
||||
const char *fmt, ...) CURL_PRINTF(2, 3);
|
||||
#endif
|
||||
|
||||
|
||||
#else /* defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
||||
/* All informational messages are not compiled in for size savings */
|
||||
|
||||
@@ -181,49 +193,6 @@ void Curl_trc_ws(struct Curl_easy *data,
|
||||
#define Curl_trc_cf_is_verbose(x,y) (FALSE)
|
||||
#define Curl_trc_ft_is_verbose(x,y) (FALSE)
|
||||
|
||||
static void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
static void Curl_trc_cf_infof(struct Curl_easy *data,
|
||||
struct Curl_cfilter *cf,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)cf; (void)fmt;
|
||||
}
|
||||
|
||||
struct curl_trc_feat;
|
||||
|
||||
static void Curl_trc_write(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
static void Curl_trc_read(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
static void Curl_trc_ftp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
static void Curl_trc_smtp(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_WEBSOCKETS) || !defined(CURL_DISABLE_HTTP)
|
||||
static void Curl_trc_ws(struct Curl_easy *data, const char *fmt, ...)
|
||||
{
|
||||
(void)data; (void)fmt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_VERBOSE_STRINGS) */
|
||||
|
||||
#endif /* HEADER_CURL_TRC_H */
|
||||
|
||||
@@ -93,6 +93,7 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_DICT, /* defport */
|
||||
CURLPROTO_DICT, /* protocol */
|
||||
CURLPROTO_DICT, /* family */
|
||||
|
||||
192
lib/doh.c
192
lib/doh.c
@@ -410,12 +410,6 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
struct doh_probes *dohp;
|
||||
struct connectdata *conn = data->conn;
|
||||
size_t i;
|
||||
#ifdef USE_HTTPSRR
|
||||
/* for now, this is only used when ECH is enabled */
|
||||
# ifdef USE_ECH
|
||||
char *qname = NULL;
|
||||
# endif
|
||||
#endif
|
||||
*waitp = FALSE;
|
||||
(void)hostname;
|
||||
(void)port;
|
||||
@@ -462,34 +456,23 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data,
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTPSRR
|
||||
/*
|
||||
* TODO: Figure out the conditions under which we want to make
|
||||
* a request for an HTTPS RR when we are not doing ECH. For now,
|
||||
* making this request breaks a bunch of DoH tests, e.g. test2100,
|
||||
* where the additional request does not match the pre-cooked data
|
||||
* files, so there is a bit of work attached to making the request
|
||||
* in a non-ECH use-case. For the present, we will only make the
|
||||
* request when ECH is enabled in the build and is being used for
|
||||
* the curl operation.
|
||||
*/
|
||||
# ifdef USE_ECH
|
||||
if(data->set.tls_ech & CURLECH_ENABLE
|
||||
|| data->set.tls_ech & CURLECH_HARD) {
|
||||
if(port == 443)
|
||||
qname = strdup(hostname);
|
||||
else
|
||||
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
|
||||
/* Only use HTTPS RR for HTTP(S) transfers */
|
||||
char *qname = NULL;
|
||||
if(port != PORT_HTTPS) {
|
||||
qname = aprintf("_%d._https.%s", port, hostname);
|
||||
if(!qname)
|
||||
goto error;
|
||||
if(!qname)
|
||||
goto error;
|
||||
}
|
||||
result = doh_run_probe(data, &dohp->probe[DOH_SLOT_HTTPS_RR],
|
||||
DNS_TYPE_HTTPS, qname, data->set.str[STRING_DOH],
|
||||
DNS_TYPE_HTTPS,
|
||||
qname ? qname : hostname, data->set.str[STRING_DOH],
|
||||
data->multi, dohp->req_hds);
|
||||
Curl_safefree(qname);
|
||||
free(qname);
|
||||
if(result)
|
||||
goto error;
|
||||
dohp->pending++;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
*waitp = TRUE; /* this never returns synchronously */
|
||||
return NULL;
|
||||
@@ -961,11 +944,7 @@ static CURLcode doh2ai(const struct dohentry *de, const char *hostname,
|
||||
addr = (void *)ai->ai_addr; /* storage area for this info */
|
||||
DEBUGASSERT(sizeof(struct in_addr) == sizeof(de->addr[i].ip.v4));
|
||||
memcpy(&addr->sin_addr, &de->addr[i].ip.v4, sizeof(struct in_addr));
|
||||
#ifdef __MINGW32__
|
||||
addr->sin_family = (short)addrtype;
|
||||
#else
|
||||
addr->sin_family = addrtype;
|
||||
#endif
|
||||
addr->sin_family = (CURL_SA_FAMILY_T)addrtype;
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
@@ -974,11 +953,7 @@ static CURLcode doh2ai(const struct dohentry *de, const char *hostname,
|
||||
addr6 = (void *)ai->ai_addr; /* storage area for this info */
|
||||
DEBUGASSERT(sizeof(struct in6_addr) == sizeof(de->addr[i].ip.v6));
|
||||
memcpy(&addr6->sin6_addr, &de->addr[i].ip.v6, sizeof(struct in6_addr));
|
||||
#ifdef __MINGW32__
|
||||
addr6->sin6_family = (short)addrtype;
|
||||
#else
|
||||
addr6->sin6_family = addrtype;
|
||||
#endif
|
||||
addr6->sin6_family = (CURL_SA_FAMILY_T)addrtype;
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
@@ -1089,62 +1064,6 @@ static CURLcode doh_decode_rdata_name(unsigned char **buf, size_t *remaining,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode doh_decode_rdata_alpn(unsigned char *rrval, size_t len,
|
||||
char **alpns)
|
||||
{
|
||||
/*
|
||||
* spec here is as per draft-ietf-dnsop-svcb-https, section-7.1.1
|
||||
* encoding is catenated list of strings each preceded by a one
|
||||
* octet length
|
||||
* output is comma-sep list of the strings
|
||||
* implementations may or may not handle quoting of comma within
|
||||
* string values, so we might see a comma within the wire format
|
||||
* version of a string, in which case we will precede that by a
|
||||
* backslash - same goes for a backslash character, and of course
|
||||
* we need to use two backslashes in strings when we mean one;-)
|
||||
*/
|
||||
int remaining = (int) len;
|
||||
char *oval;
|
||||
size_t i;
|
||||
unsigned char *cp = rrval;
|
||||
struct dynbuf dval;
|
||||
|
||||
if(!alpns)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
Curl_dyn_init(&dval, DYN_DOH_RESPONSE);
|
||||
remaining = (int)len;
|
||||
cp = rrval;
|
||||
while(remaining > 0) {
|
||||
size_t tlen = (size_t) *cp++;
|
||||
|
||||
/* if not 1st time, add comma */
|
||||
if(remaining != (int)len && Curl_dyn_addn(&dval, ",", 1))
|
||||
goto err;
|
||||
remaining--;
|
||||
if(tlen > (size_t)remaining)
|
||||
goto err;
|
||||
/* add escape char if needed, clunky but easier to read */
|
||||
for(i = 0; i != tlen; i++) {
|
||||
if('\\' == *cp || ',' == *cp) {
|
||||
if(Curl_dyn_addn(&dval, "\\", 1))
|
||||
goto err;
|
||||
}
|
||||
if(Curl_dyn_addn(&dval, cp++, 1))
|
||||
goto err;
|
||||
}
|
||||
remaining -= (int)tlen;
|
||||
}
|
||||
/* this string is always null terminated */
|
||||
oval = Curl_dyn_ptr(&dval);
|
||||
if(!oval)
|
||||
goto err;
|
||||
*alpns = oval;
|
||||
return CURLE_OK;
|
||||
err:
|
||||
Curl_dyn_free(&dval);
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
static CURLcode doh_test_alpn_escapes(void)
|
||||
{
|
||||
@@ -1156,24 +1075,20 @@ static CURLcode doh_test_alpn_escapes(void)
|
||||
0x68, 0x32 /* value "h2" */
|
||||
};
|
||||
size_t example_len = sizeof(example);
|
||||
char *aval = NULL;
|
||||
static const char *expected = "f\\\\oo\\,bar,h2";
|
||||
unsigned char aval[MAX_HTTPSRR_ALPNS] = { 0 };
|
||||
static const char expected[2] = { ALPN_h2, ALPN_none };
|
||||
|
||||
if(doh_decode_rdata_alpn(example, example_len, &aval) != CURLE_OK)
|
||||
if(Curl_httpsrr_decode_alpn(example, example_len, aval) != CURLE_OK)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
if(strlen(aval) != strlen(expected))
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
if(memcmp(aval, expected, strlen(aval)))
|
||||
if(memcmp(aval, expected, sizeof(expected)))
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode doh_resp_decode_httpsrr(unsigned char *rrval, size_t len,
|
||||
static CURLcode doh_resp_decode_httpsrr(unsigned char *cp, size_t len,
|
||||
struct Curl_https_rrinfo **hrr)
|
||||
{
|
||||
size_t remaining = len;
|
||||
unsigned char *cp = rrval;
|
||||
uint16_t pcode = 0, plen = 0;
|
||||
struct Curl_https_rrinfo *lhrr = NULL;
|
||||
char *dnsname = NULL;
|
||||
@@ -1183,73 +1098,73 @@ static CURLcode doh_resp_decode_httpsrr(unsigned char *rrval, size_t len,
|
||||
if(doh_test_alpn_escapes() != CURLE_OK)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
if(len <= 2)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
lhrr = calloc(1, sizeof(struct Curl_https_rrinfo));
|
||||
if(!lhrr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
lhrr->val = Curl_memdup(rrval, len);
|
||||
if(!lhrr->val)
|
||||
goto err;
|
||||
lhrr->len = len;
|
||||
if(remaining <= 2)
|
||||
goto err;
|
||||
lhrr->priority = (uint16_t)((cp[0] << 8) + cp[1]);
|
||||
lhrr->priority = doh_get16bit(cp, 0);
|
||||
cp += 2;
|
||||
remaining -= (uint16_t)2;
|
||||
if(doh_decode_rdata_name(&cp, &remaining, &dnsname) != CURLE_OK)
|
||||
len -= 2;
|
||||
if(doh_decode_rdata_name(&cp, &len, &dnsname) != CURLE_OK)
|
||||
goto err;
|
||||
lhrr->target = dnsname;
|
||||
while(remaining >= 4) {
|
||||
pcode = (uint16_t)((*cp << 8) + (*(cp + 1)));
|
||||
cp += 2;
|
||||
plen = (uint16_t)((*cp << 8) + (*(cp + 1)));
|
||||
cp += 2;
|
||||
remaining -= 4;
|
||||
if(pcode == HTTPS_RR_CODE_ALPN) {
|
||||
if(doh_decode_rdata_alpn(cp, plen, &lhrr->alpns) != CURLE_OK)
|
||||
lhrr->port = -1; /* until set */
|
||||
while(len >= 4) {
|
||||
pcode = doh_get16bit(cp, 0);
|
||||
plen = doh_get16bit(cp, 2);
|
||||
cp += 4;
|
||||
len -= 4;
|
||||
switch(pcode) {
|
||||
case HTTPS_RR_CODE_ALPN:
|
||||
if(Curl_httpsrr_decode_alpn(cp, plen, lhrr->alpns) != CURLE_OK)
|
||||
goto err;
|
||||
}
|
||||
if(pcode == HTTPS_RR_CODE_NO_DEF_ALPN)
|
||||
break;
|
||||
case HTTPS_RR_CODE_NO_DEF_ALPN:
|
||||
lhrr->no_def_alpn = TRUE;
|
||||
else if(pcode == HTTPS_RR_CODE_IPV4) {
|
||||
break;
|
||||
case HTTPS_RR_CODE_IPV4:
|
||||
if(!plen)
|
||||
goto err;
|
||||
lhrr->ipv4hints = Curl_memdup(cp, plen);
|
||||
if(!lhrr->ipv4hints)
|
||||
goto err;
|
||||
lhrr->ipv4hints_len = (size_t)plen;
|
||||
}
|
||||
else if(pcode == HTTPS_RR_CODE_ECH) {
|
||||
break;
|
||||
case HTTPS_RR_CODE_ECH:
|
||||
if(!plen)
|
||||
goto err;
|
||||
lhrr->echconfiglist = Curl_memdup(cp, plen);
|
||||
if(!lhrr->echconfiglist)
|
||||
goto err;
|
||||
lhrr->echconfiglist_len = (size_t)plen;
|
||||
}
|
||||
else if(pcode == HTTPS_RR_CODE_IPV6) {
|
||||
break;
|
||||
case HTTPS_RR_CODE_IPV6:
|
||||
if(!plen)
|
||||
goto err;
|
||||
lhrr->ipv6hints = Curl_memdup(cp, plen);
|
||||
if(!lhrr->ipv6hints)
|
||||
goto err;
|
||||
lhrr->ipv6hints_len = (size_t)plen;
|
||||
break;
|
||||
case HTTPS_RR_CODE_PORT:
|
||||
lhrr->port = doh_get16bit(cp, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(plen > 0 && plen <= remaining) {
|
||||
if(plen > 0 && plen <= len) {
|
||||
cp += plen;
|
||||
remaining -= plen;
|
||||
len -= plen;
|
||||
}
|
||||
}
|
||||
DEBUGASSERT(!remaining);
|
||||
DEBUGASSERT(!len);
|
||||
*hrr = lhrr;
|
||||
return CURLE_OK;
|
||||
err:
|
||||
if(lhrr) {
|
||||
Curl_safefree(lhrr->target);
|
||||
Curl_safefree(lhrr->echconfiglist);
|
||||
Curl_safefree(lhrr->val);
|
||||
Curl_safefree(lhrr->alpns);
|
||||
Curl_safefree(lhrr);
|
||||
}
|
||||
Curl_safefree(lhrr->target);
|
||||
Curl_safefree(lhrr->echconfiglist);
|
||||
Curl_safefree(lhrr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -1260,8 +1175,9 @@ static void doh_print_httpsrr(struct Curl_easy *data,
|
||||
DEBUGASSERT(hrr);
|
||||
infof(data, "HTTPS RR: priority %d, target: %s",
|
||||
hrr->priority, hrr->target);
|
||||
if(hrr->alpns)
|
||||
infof(data, "HTTPS RR: alpns %s", hrr->alpns);
|
||||
if(hrr->alpns[0] != ALPN_none)
|
||||
infof(data, "HTTPS RR: alpns %u %u %u %u",
|
||||
hrr->alpns[0], hrr->alpns[1], hrr->alpns[2], hrr->alpns[3]);
|
||||
else
|
||||
infof(data, "HTTPS RR: no alpns");
|
||||
if(hrr->no_def_alpn)
|
||||
|
||||
14
lib/doh.h
14
lib/doh.h
@@ -28,6 +28,7 @@
|
||||
#include "curl_addrinfo.h"
|
||||
#ifdef USE_HTTPSRR
|
||||
# include <stdint.h>
|
||||
# include "httpsrr.h"
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
@@ -123,19 +124,6 @@ struct dohaddr {
|
||||
|
||||
#ifdef USE_HTTPSRR
|
||||
|
||||
/*
|
||||
* These are the code points for DNS wire format SvcParams as
|
||||
* per draft-ietf-dnsop-svcb-https
|
||||
* Not all are supported now, and even those that are may need
|
||||
* more work in future to fully support the spec.
|
||||
*/
|
||||
#define HTTPS_RR_CODE_ALPN 0x01
|
||||
#define HTTPS_RR_CODE_NO_DEF_ALPN 0x02
|
||||
#define HTTPS_RR_CODE_PORT 0x03
|
||||
#define HTTPS_RR_CODE_IPV4 0x04
|
||||
#define HTTPS_RR_CODE_ECH 0x05
|
||||
#define HTTPS_RR_CODE_IPV6 0x06
|
||||
|
||||
/*
|
||||
* These may need escaping when found within an ALPN string
|
||||
* value.
|
||||
|
||||
12
lib/dynbuf.c
12
lib/dynbuf.c
@@ -244,6 +244,18 @@ char *Curl_dyn_ptr(const struct dynbuf *s)
|
||||
return s->bufr;
|
||||
}
|
||||
|
||||
char *Curl_dyn_take(struct dynbuf *s, size_t *plen)
|
||||
{
|
||||
char *ptr = s->bufr;
|
||||
DEBUGASSERT(s);
|
||||
DEBUGASSERT(s->init == DYNINIT);
|
||||
*plen = s->leng;
|
||||
s->bufr = NULL;
|
||||
s->leng = 0;
|
||||
s->allc = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an unsigned pointer to the buffer.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#define Curl_dyn_uptr(a) curlx_dyn_uptr(a)
|
||||
#define Curl_dyn_len(a) curlx_dyn_len(a)
|
||||
#define Curl_dyn_reset(a) curlx_dyn_reset(a)
|
||||
#define Curl_dyn_take(a,b) curlx_dyn_take(a,b)
|
||||
#define Curl_dyn_tail(a,b) curlx_dyn_tail(a,b)
|
||||
#define Curl_dyn_setlen(a,b) curlx_dyn_setlen(a,b)
|
||||
#define curlx_dynbuf dynbuf /* for the struct name */
|
||||
@@ -75,6 +76,10 @@ size_t Curl_dyn_len(const struct dynbuf *s);
|
||||
/* The implementation of this function exists in mprintf.c */
|
||||
int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
|
||||
|
||||
/* Take the buffer out of the dynbuf. Caller has ownership and
|
||||
* dynbuf resets to initial state. */
|
||||
char *Curl_dyn_take(struct dynbuf *s, size_t *plen);
|
||||
|
||||
/* Dynamic buffer max sizes */
|
||||
#define DYN_DOH_RESPONSE 3000
|
||||
#define DYN_DOH_CNAME 256
|
||||
|
||||
58
lib/easy.c
58
lib/easy.c
@@ -48,6 +48,7 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "vtls/vtls_scache.h"
|
||||
#include "url.h"
|
||||
#include "getinfo.h"
|
||||
#include "hostip.h"
|
||||
@@ -761,12 +762,25 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
/* if the handle has a connection still attached (it is/was a connect-only
|
||||
handle) then disconnect before performing */
|
||||
if(data->conn) {
|
||||
struct connectdata *c;
|
||||
curl_socket_t s;
|
||||
Curl_detach_connection(data);
|
||||
s = Curl_getconnectinfo(data, &c);
|
||||
if((s != CURL_SOCKET_BAD) && c) {
|
||||
Curl_cpool_disconnect(data, c, TRUE);
|
||||
}
|
||||
DEBUGASSERT(!data->conn);
|
||||
}
|
||||
|
||||
if(data->multi_easy)
|
||||
multi = data->multi_easy;
|
||||
else {
|
||||
/* this multi handle will only ever have a single easy handled attached
|
||||
to it, so make it use minimal hashes */
|
||||
multi = Curl_multi_handle(1, 3, 7);
|
||||
/* this multi handle will only ever have a single easy handle attached to
|
||||
it, so make it use minimal hash sizes */
|
||||
multi = Curl_multi_handle(1, 3, 7, 3);
|
||||
if(!multi)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -1336,3 +1350,41 @@ CURLcode curl_easy_upkeep(CURL *d)
|
||||
/* Use the common function to keep connections alive. */
|
||||
return Curl_cpool_upkeep(data);
|
||||
}
|
||||
|
||||
CURLcode curl_easy_ssls_import(CURL *d, const char *session_key,
|
||||
const unsigned char *shmac, size_t shmac_len,
|
||||
const unsigned char *sdata, size_t sdata_len)
|
||||
{
|
||||
#ifdef USE_SSLS_EXPORT
|
||||
struct Curl_easy *data = d;
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return Curl_ssl_session_import(data, session_key,
|
||||
shmac, shmac_len, sdata, sdata_len);
|
||||
#else
|
||||
(void)d;
|
||||
(void)session_key;
|
||||
(void)shmac;
|
||||
(void)shmac_len;
|
||||
(void)sdata;
|
||||
(void)sdata_len;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode curl_easy_ssls_export(CURL *d,
|
||||
curl_ssls_export_cb *export_fn,
|
||||
void *userptr)
|
||||
{
|
||||
#ifdef USE_SSLS_EXPORT
|
||||
struct Curl_easy *data = d;
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return Curl_ssl_session_export(data, export_fn, userptr);
|
||||
#else
|
||||
(void)d;
|
||||
(void)export_fn;
|
||||
(void)userptr;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
static inline void curl_simple_lock_lock(curl_simple_lock *lock)
|
||||
static CURL_INLINE void curl_simple_lock_lock(curl_simple_lock *lock)
|
||||
{
|
||||
for(;;) {
|
||||
if(!atomic_exchange_explicit(lock, true, memory_order_acquire))
|
||||
@@ -81,6 +81,8 @@ static inline void curl_simple_lock_lock(curl_simple_lock *lock)
|
||||
__builtin_ia32_pause();
|
||||
#elif defined(__aarch64__)
|
||||
__asm__ volatile("yield" ::: "memory");
|
||||
#elif defined(_WIN32)
|
||||
Sleep(1);
|
||||
#elif defined(HAVE_SCHED_YIELD)
|
||||
sched_yield();
|
||||
#endif
|
||||
@@ -88,7 +90,7 @@ static inline void curl_simple_lock_lock(curl_simple_lock *lock)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void curl_simple_lock_unlock(curl_simple_lock *lock)
|
||||
static CURL_INLINE void curl_simple_lock_unlock(curl_simple_lock *lock)
|
||||
{
|
||||
atomic_store_explicit(lock, false, memory_order_release);
|
||||
}
|
||||
|
||||
@@ -377,6 +377,6 @@ struct curl_easyoption Curl_easyopts[] = {
|
||||
*/
|
||||
int Curl_easyopts_check(void)
|
||||
{
|
||||
return ((CURLOPT_LASTENTRY%10000) != (326 + 1));
|
||||
return (CURLOPT_LASTENTRY % 10000) != (326 + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
38
lib/file.c
38
lib/file.c
@@ -78,18 +78,12 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(_WIN32) || defined(MSDOS) || defined(__EMX__)
|
||||
#if defined(_WIN32) || defined(MSDOS)
|
||||
#define DOS_FILESYSTEM 1
|
||||
#elif defined(__amigaos4__)
|
||||
#define AMIGA_FILESYSTEM 1
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_NEEDS_ARG3
|
||||
# define open_readonly(p,f) open((p),(f),(0))
|
||||
#else
|
||||
# define open_readonly(p,f) open((p),(f))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
@@ -126,6 +120,7 @@ const struct Curl_handler Curl_handler_file = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
0, /* defport */
|
||||
CURLPROTO_FILE, /* protocol */
|
||||
CURLPROTO_FILE, /* family */
|
||||
@@ -209,7 +204,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
fd = open(actual_path, O_RDONLY|CURL_O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
if(memchr(real_path, 0, real_path_len)) {
|
||||
@@ -233,16 +228,16 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||
extern int __unix_path_semantics;
|
||||
if(strchr(real_path + 1, ':')) {
|
||||
/* Amiga absolute path */
|
||||
fd = open_readonly(real_path + 1, O_RDONLY);
|
||||
fd = open(real_path + 1, O_RDONLY);
|
||||
file->path++;
|
||||
}
|
||||
else if(__unix_path_semantics) {
|
||||
/* -lunix fallback */
|
||||
fd = open_readonly(real_path, O_RDONLY);
|
||||
fd = open(real_path, O_RDONLY);
|
||||
}
|
||||
}
|
||||
#else
|
||||
fd = open_readonly(real_path, O_RDONLY);
|
||||
fd = open(real_path, O_RDONLY);
|
||||
file->path = real_path;
|
||||
#endif
|
||||
#endif
|
||||
@@ -318,18 +313,18 @@ static CURLcode file_upload(struct Curl_easy *data)
|
||||
if(!dir[1])
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
|
||||
#ifdef O_BINARY
|
||||
#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
|
||||
#else
|
||||
#define MODE_DEFAULT O_WRONLY|O_CREAT
|
||||
#endif
|
||||
|
||||
mode = O_WRONLY|O_CREAT|CURL_O_BINARY;
|
||||
if(data->state.resume_from)
|
||||
mode = MODE_DEFAULT|O_APPEND;
|
||||
mode |= O_APPEND;
|
||||
else
|
||||
mode = MODE_DEFAULT|O_TRUNC;
|
||||
mode |= O_TRUNC;
|
||||
|
||||
#if (defined(ANDROID) || defined(__ANDROID__)) && \
|
||||
(defined(__i386__) || defined(__arm__))
|
||||
fd = open(file->path, mode, (mode_t)data->set.new_file_perms);
|
||||
#else
|
||||
fd = open(file->path, mode, data->set.new_file_perms);
|
||||
#endif
|
||||
if(fd < 0) {
|
||||
failf(data, "cannot open %s for writing", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
@@ -553,8 +548,13 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
|
||||
|
||||
if(data->state.resume_from) {
|
||||
if(!S_ISDIR(statbuf.st_mode)) {
|
||||
#ifdef __AMIGA__
|
||||
if(data->state.resume_from !=
|
||||
lseek(fd, (off_t)data->state.resume_from, SEEK_SET))
|
||||
#else
|
||||
if(data->state.resume_from !=
|
||||
lseek(fd, data->state.resume_from, SEEK_SET))
|
||||
#endif
|
||||
return CURLE_BAD_DOWNLOAD_RESUME;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#ifdef _WIN32
|
||||
#define PATHSEP "\\"
|
||||
#define IS_SEP(x) (((x) == '/') || ((x) == '\\'))
|
||||
#elif defined(MSDOS) || defined(__EMX__) || defined(OS2)
|
||||
#elif defined(MSDOS) || defined(OS2)
|
||||
#define PATHSEP "\\"
|
||||
#define IS_SEP(x) ((x) == '\\')
|
||||
#else
|
||||
|
||||
23
lib/ftp.c
23
lib/ftp.c
@@ -250,6 +250,7 @@ const struct Curl_handler Curl_handler_ftp = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_FTP, /* defport */
|
||||
CURLPROTO_FTP, /* protocol */
|
||||
CURLPROTO_FTP, /* family */
|
||||
@@ -282,6 +283,7 @@ const struct Curl_handler Curl_handler_ftps = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_FTPS, /* defport */
|
||||
CURLPROTO_FTPS, /* protocol */
|
||||
CURLPROTO_FTP, /* family */
|
||||
@@ -2079,10 +2081,19 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||
/* If we asked for a time of the file and we actually got one as well,
|
||||
we "emulate" an HTTP-style header in our output. */
|
||||
|
||||
#if defined(__GNUC__) && (defined(__DJGPP__) || defined(__AMIGA__))
|
||||
#pragma GCC diagnostic push
|
||||
/* 'time_t' is unsigned in MSDOS and AmigaOS. Silence:
|
||||
warning: comparison of unsigned expression in '>= 0' is always true */
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
if(data->req.no_body &&
|
||||
ftpc->file &&
|
||||
data->set.get_filetime &&
|
||||
(data->info.filetime >= 0) ) {
|
||||
#if defined(__GNUC__) && (defined(__DJGPP__) || defined(__AMIGA__))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
char headerbuf[128];
|
||||
int headerbuflen;
|
||||
time_t filetime = data->info.filetime;
|
||||
@@ -3154,7 +3165,7 @@ static CURLcode ftp_connect(struct Curl_easy *data,
|
||||
|
||||
PINGPONG_SETUP(pp, ftp_statemachine, ftp_endofresp);
|
||||
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
|
||||
/* BLOCKING */
|
||||
result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done);
|
||||
if(result)
|
||||
@@ -4097,8 +4108,8 @@ static CURLcode ftp_disconnect(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* warning C4706: assignment within conditional expression */
|
||||
#pragma warning(disable:4706)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4706) /* assignment within conditional expression */
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
@@ -4244,7 +4255,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
|
||||
else
|
||||
n -= ftpc->file ? strlen(ftpc->file) : 0;
|
||||
|
||||
if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) {
|
||||
if((strlen(oldPath) == n) && rawPath && !strncmp(rawPath, oldPath, n)) {
|
||||
infof(data, "Request has same path as previous transfer");
|
||||
ftpc->cwddone = TRUE;
|
||||
}
|
||||
@@ -4255,6 +4266,10 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/* call this when the DO phase has completed */
|
||||
static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
/* int send(int, const char *, int, int); */
|
||||
#define SEND_TYPE_ARG1 int
|
||||
#define SEND_QUAL_ARG2
|
||||
#define SEND_TYPE_ARG2 char *
|
||||
#define SEND_TYPE_ARG3 int
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
@@ -69,6 +69,8 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
|
||||
info->request_size = 0;
|
||||
info->proxyauthavail = 0;
|
||||
info->httpauthavail = 0;
|
||||
info->proxyauthpicked = 0;
|
||||
info->httpauthpicked = 0;
|
||||
info->numconnects = 0;
|
||||
|
||||
free(info->contenttype);
|
||||
@@ -238,8 +240,10 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
case CURLINFO_FILETIME:
|
||||
if(data->info.filetime > LONG_MAX)
|
||||
*param_longp = LONG_MAX;
|
||||
#if !defined(MSDOS) && !defined(__AMIGA__)
|
||||
else if(data->info.filetime < LONG_MIN)
|
||||
*param_longp = LONG_MIN;
|
||||
#endif
|
||||
else
|
||||
*param_longp = (long)data->info.filetime;
|
||||
break;
|
||||
@@ -270,6 +274,14 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
lptr.to_long = param_longp;
|
||||
*lptr.to_ulong = data->info.proxyauthavail;
|
||||
break;
|
||||
case CURLINFO_HTTPAUTH_USED:
|
||||
lptr.to_long = param_longp;
|
||||
*lptr.to_ulong = data->info.httpauthpicked;
|
||||
break;
|
||||
case CURLINFO_PROXYAUTH_USED:
|
||||
lptr.to_long = param_longp;
|
||||
*lptr.to_ulong = data->info.proxyauthpicked;
|
||||
break;
|
||||
case CURLINFO_OS_ERRNO:
|
||||
*param_longp = data->state.os_errno;
|
||||
break;
|
||||
@@ -377,6 +389,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
|
||||
case CURLINFO_APPCONNECT_TIME_T:
|
||||
case CURLINFO_PRETRANSFER_TIME_T:
|
||||
case CURLINFO_POSTTRANSFER_TIME_T:
|
||||
case CURLINFO_QUEUE_TIME_T:
|
||||
case CURLINFO_STARTTRANSFER_TIME_T:
|
||||
case CURLINFO_REDIRECT_TIME_T:
|
||||
case CURLINFO_SPEED_DOWNLOAD_T:
|
||||
|
||||
@@ -79,6 +79,7 @@ const struct Curl_handler Curl_handler_gopher = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_GOPHER, /* defport */
|
||||
CURLPROTO_GOPHER, /* protocol */
|
||||
CURLPROTO_GOPHER, /* family */
|
||||
@@ -104,6 +105,7 @@ const struct Curl_handler Curl_handler_gophers = {
|
||||
ZERO_NULL, /* write_resp_hd */
|
||||
ZERO_NULL, /* connection_check */
|
||||
ZERO_NULL, /* attach connection */
|
||||
ZERO_NULL, /* follow */
|
||||
PORT_GOPHER, /* defport */
|
||||
CURLPROTO_GOPHERS, /* protocol */
|
||||
CURLPROTO_GOPHER, /* family */
|
||||
|
||||
@@ -42,6 +42,8 @@ hash_element_dtor(void *user, void *element)
|
||||
{
|
||||
struct Curl_hash *h = (struct Curl_hash *) user;
|
||||
struct Curl_hash_element *e = (struct Curl_hash_element *) element;
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(e);
|
||||
|
||||
if(e->ptr) {
|
||||
if(e->dtor)
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \
|
||||
|| !defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH)
|
||||
#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) || \
|
||||
!defined(CURL_DISABLE_AWS) || !defined(CURL_DISABLE_DIGEST_AUTH) || \
|
||||
defined(USE_SSL)
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
22
lib/hostip.c
22
lib/hostip.c
@@ -198,7 +198,7 @@ hostcache_entry_is_stale(void *datap, void *hc)
|
||||
if(dns->timestamp) {
|
||||
/* age in seconds */
|
||||
time_t age = prune->now - dns->timestamp;
|
||||
if(age >= prune->max_age_sec)
|
||||
if(age >= (time_t)prune->max_age_sec)
|
||||
return TRUE;
|
||||
if(age > prune->oldest)
|
||||
prune->oldest = age;
|
||||
@@ -541,7 +541,9 @@ static struct Curl_addrinfo *get_localhost6(int port, const char *name)
|
||||
sa6.sin6_family = AF_INET6;
|
||||
sa6.sin6_port = htons(port16);
|
||||
sa6.sin6_flowinfo = 0;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
sa6.sin6_scope_id = 0;
|
||||
#endif
|
||||
|
||||
(void)Curl_inet_pton(AF_INET6, "::1", ipv6);
|
||||
memcpy(&sa6.sin6_addr, ipv6, sizeof(ipv6));
|
||||
@@ -630,7 +632,7 @@ bool Curl_ipv6works(struct Curl_easy *data)
|
||||
ipv6_works = 1;
|
||||
sclose(s);
|
||||
}
|
||||
return (ipv6_works > 0);
|
||||
return ipv6_works > 0;
|
||||
}
|
||||
}
|
||||
#endif /* USE_IPV6 */
|
||||
@@ -1077,18 +1079,10 @@ static void hostcache_unlink_entry(void *entry)
|
||||
Curl_freeaddrinfo(dns->addr);
|
||||
#ifdef USE_HTTPSRR
|
||||
if(dns->hinfo) {
|
||||
if(dns->hinfo->target)
|
||||
free(dns->hinfo->target);
|
||||
if(dns->hinfo->alpns)
|
||||
free(dns->hinfo->alpns);
|
||||
if(dns->hinfo->ipv4hints)
|
||||
free(dns->hinfo->ipv4hints);
|
||||
if(dns->hinfo->echconfiglist)
|
||||
free(dns->hinfo->echconfiglist);
|
||||
if(dns->hinfo->ipv6hints)
|
||||
free(dns->hinfo->ipv6hints);
|
||||
if(dns->hinfo->val)
|
||||
free(dns->hinfo->val);
|
||||
free(dns->hinfo->target);
|
||||
free(dns->hinfo->ipv4hints);
|
||||
free(dns->hinfo->echconfiglist);
|
||||
free(dns->hinfo->ipv6hints);
|
||||
free(dns->hinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
38
lib/hostip.h
38
lib/hostip.h
@@ -29,6 +29,7 @@
|
||||
#include "curl_addrinfo.h"
|
||||
#include "timeval.h" /* for timediff_t */
|
||||
#include "asyn.h"
|
||||
#include "httpsrr.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
@@ -53,6 +54,13 @@ struct hostent;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
|
||||
enum alpnid {
|
||||
ALPN_none = 0,
|
||||
ALPN_h1 = CURLALTSVC_H1,
|
||||
ALPN_h2 = CURLALTSVC_H2,
|
||||
ALPN_h3 = CURLALTSVC_H3
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_global_host_cache_init() initializes and sets up a global DNS cache.
|
||||
* Global DNS cache is general badness. Do not use. This will be removed in
|
||||
@@ -62,36 +70,6 @@ struct connectdata;
|
||||
*/
|
||||
struct Curl_hash *Curl_global_host_cache_init(void);
|
||||
|
||||
#ifdef USE_HTTPSRR
|
||||
|
||||
#define CURL_MAXLEN_host_name 253
|
||||
|
||||
struct Curl_https_rrinfo {
|
||||
size_t len; /* raw encoded length */
|
||||
unsigned char *val; /* raw encoded octets */
|
||||
/*
|
||||
* fields from HTTPS RR, with the mandatory fields
|
||||
* first (priority, target), then the others in the
|
||||
* order of the keytag numbers defined at
|
||||
* https://datatracker.ietf.org/doc/html/rfc9460#section-14.3.2
|
||||
*/
|
||||
uint16_t priority;
|
||||
char *target;
|
||||
char *alpns; /* keytag = 1 */
|
||||
bool no_def_alpn; /* keytag = 2 */
|
||||
/*
|
||||
* we do not support ports (keytag = 3) as we do not support
|
||||
* port-switching yet
|
||||
*/
|
||||
unsigned char *ipv4hints; /* keytag = 4 */
|
||||
size_t ipv4hints_len;
|
||||
unsigned char *echconfiglist; /* keytag = 5 */
|
||||
size_t echconfiglist_len;
|
||||
unsigned char *ipv6hints; /* keytag = 6 */
|
||||
size_t ipv6hints_len;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Curl_dns_entry {
|
||||
struct Curl_addrinfo *addr;
|
||||
#ifdef USE_HTTPSRR
|
||||
|
||||
63
lib/hsts.c
63
lib/hsts.c
@@ -41,6 +41,7 @@
|
||||
#include "rename.h"
|
||||
#include "share.h"
|
||||
#include "strdup.h"
|
||||
#include "strparse.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -48,10 +49,8 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_HSTS_LINE 4095
|
||||
#define MAX_HSTS_HOSTLEN 256
|
||||
#define MAX_HSTS_HOSTLENSTR "256"
|
||||
#define MAX_HSTS_DATELEN 64
|
||||
#define MAX_HSTS_DATELENSTR "64"
|
||||
#define MAX_HSTS_HOSTLEN 2048
|
||||
#define MAX_HSTS_DATELEN 256
|
||||
#define UNLIMITED "unlimited"
|
||||
|
||||
#if defined(DEBUGBUILD) || defined(UNITTESTS)
|
||||
@@ -109,14 +108,13 @@ void Curl_hsts_cleanup(struct hsts **hp)
|
||||
|
||||
static CURLcode hsts_create(struct hsts *h,
|
||||
const char *hostname,
|
||||
size_t hlen,
|
||||
bool subdomains,
|
||||
curl_off_t expires)
|
||||
{
|
||||
size_t hlen;
|
||||
DEBUGASSERT(h);
|
||||
DEBUGASSERT(hostname);
|
||||
|
||||
hlen = strlen(hostname);
|
||||
if(hlen && (hostname[hlen - 1] == '.'))
|
||||
/* strip off any trailing dot */
|
||||
--hlen;
|
||||
@@ -150,6 +148,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
|
||||
bool subdomains = FALSE;
|
||||
struct stsentry *sts;
|
||||
time_t now = time(NULL);
|
||||
size_t hlen = strlen(hostname);
|
||||
|
||||
if(Curl_host_is_ipnum(hostname))
|
||||
/* "explicit IP address identification of all forms is excluded."
|
||||
@@ -218,7 +217,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
|
||||
|
||||
if(!expires) {
|
||||
/* remove the entry if present verbatim (without subdomain match) */
|
||||
sts = Curl_hsts(h, hostname, FALSE);
|
||||
sts = Curl_hsts(h, hostname, hlen, FALSE);
|
||||
if(sts) {
|
||||
Curl_node_remove(&sts->node);
|
||||
hsts_free(sts);
|
||||
@@ -233,14 +232,14 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
|
||||
expires += now;
|
||||
|
||||
/* check if it already exists */
|
||||
sts = Curl_hsts(h, hostname, FALSE);
|
||||
sts = Curl_hsts(h, hostname, hlen, FALSE);
|
||||
if(sts) {
|
||||
/* just update these fields */
|
||||
sts->expires = expires;
|
||||
sts->includeSubDomains = subdomains;
|
||||
}
|
||||
else
|
||||
return hsts_create(h, hostname, subdomains, expires);
|
||||
return hsts_create(h, hostname, hlen, subdomains, expires);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -252,12 +251,11 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
|
||||
* attempted.
|
||||
*/
|
||||
struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
|
||||
bool subdomain)
|
||||
size_t hlen, bool subdomain)
|
||||
{
|
||||
struct stsentry *bestsub = NULL;
|
||||
if(h) {
|
||||
time_t now = time(NULL);
|
||||
size_t hlen = strlen(hostname);
|
||||
struct Curl_llist_node *e;
|
||||
struct Curl_llist_node *n;
|
||||
size_t blen = 0;
|
||||
@@ -424,29 +422,40 @@ static CURLcode hsts_add(struct hsts *h, char *line)
|
||||
example.com "20191231 10:00:00"
|
||||
.example.net "20191231 10:00:00"
|
||||
*/
|
||||
char host[MAX_HSTS_HOSTLEN + 1];
|
||||
char date[MAX_HSTS_DATELEN + 1];
|
||||
int rc;
|
||||
struct Curl_str host;
|
||||
struct Curl_str date;
|
||||
|
||||
rc = sscanf(line,
|
||||
"%" MAX_HSTS_HOSTLENSTR "s \"%" MAX_HSTS_DATELENSTR "[^\"]\"",
|
||||
host, date);
|
||||
if(2 == rc) {
|
||||
time_t expires = strcmp(date, UNLIMITED) ? Curl_getdate_capped(date) :
|
||||
TIME_T_MAX;
|
||||
if(Curl_str_word(&line, &host, MAX_HSTS_HOSTLEN) ||
|
||||
Curl_str_singlespace(&line) ||
|
||||
Curl_str_quotedword(&line, &date, MAX_HSTS_DATELEN) ||
|
||||
Curl_str_newline(&line))
|
||||
;
|
||||
else {
|
||||
CURLcode result = CURLE_OK;
|
||||
char *p = host;
|
||||
bool subdomain = FALSE;
|
||||
struct stsentry *e;
|
||||
if(p[0] == '.') {
|
||||
p++;
|
||||
char dbuf[MAX_HSTS_DATELEN + 1];
|
||||
time_t expires;
|
||||
|
||||
/* The date parser works on a null terminated string. The maximum length
|
||||
is upheld by Curl_str_quotedword(). */
|
||||
memcpy(dbuf, date.str, date.len);
|
||||
dbuf[date.len] = 0;
|
||||
|
||||
expires = strcmp(dbuf, UNLIMITED) ? Curl_getdate_capped(dbuf) :
|
||||
TIME_T_MAX;
|
||||
|
||||
if(host.str[0] == '.') {
|
||||
host.str++;
|
||||
host.len--;
|
||||
subdomain = TRUE;
|
||||
}
|
||||
/* only add it if not already present */
|
||||
e = Curl_hsts(h, p, subdomain);
|
||||
e = Curl_hsts(h, host.str, host.len, subdomain);
|
||||
if(!e)
|
||||
result = hsts_create(h, p, subdomain, expires);
|
||||
else if(strcasecompare(p, e->host)) {
|
||||
result = hsts_create(h, host.str, host.len, subdomain, expires);
|
||||
else if((strlen(e->host) == host.len) &&
|
||||
strncasecompare(host.str, e->host, host.len)) {
|
||||
/* the same hostname, use the largest expire time */
|
||||
if(expires > e->expires)
|
||||
e->expires = expires;
|
||||
@@ -488,7 +497,7 @@ static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h)
|
||||
expires = Curl_getdate_capped(e.expire);
|
||||
else
|
||||
expires = TIME_T_MAX; /* the end of time */
|
||||
result = hsts_create(h, e.name,
|
||||
result = hsts_create(h, e.name, strlen(e.name),
|
||||
/* bitfield to bool conversion: */
|
||||
e.includeSubDomains ? TRUE : FALSE,
|
||||
expires);
|
||||
|
||||
@@ -52,7 +52,7 @@ void Curl_hsts_cleanup(struct hsts **hp);
|
||||
CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
|
||||
const char *sts);
|
||||
struct stsentry *Curl_hsts(struct hsts *h, const char *hostname,
|
||||
bool subdomain);
|
||||
size_t hlen, bool subdomain);
|
||||
CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,
|
||||
const char *file);
|
||||
CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
|
||||
|
||||
631
lib/http.c
631
lib/http.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user