mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 22:30:07 -05:00
Merge topic 'update-curl' into release-4.0
0e1f3f175ccurl: Set build options the way we need for CMakeae94c2369dcurl: Clarify comments marking our local changes to the CMake code7f2b2375baMerge branch 'upstream-curl' into update-curl48b13baebccurl 2025-02-05 (34cf9d54)e8c41f4780curl: Update script to get curl 8.12.0 Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !10291
This commit is contained in:
@@ -8,7 +8,7 @@ readonly name="curl"
|
||||
readonly ownership="Curl Upstream <curl-library@lists.haxx.se>"
|
||||
readonly subtree="Utilities/cmcurl"
|
||||
readonly repo="https://github.com/curl/curl.git"
|
||||
readonly tag="curl-8_11_1"
|
||||
readonly tag="curl-8_12_0"
|
||||
readonly shortlog=false
|
||||
readonly paths="
|
||||
CMake/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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@")
|
||||
|
||||
+22
-11
@@ -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)
|
||||
|
||||
+563
-424
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
#define LIBCURL_VERSION "8.12.0"
|
||||
|
||||
/* 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.
|
||||
@@ -47,7 +47,7 @@ if(USE_ARES)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# CMake-specific curl code.
|
||||
# XXX(cmake): begin cmake-specific curl code
|
||||
unset(LIBCURL_OUTPUT_NAME CACHE)
|
||||
|
||||
add_library(cmcurl ${HHEADERS} ${CSOURCES})
|
||||
@@ -82,6 +82,7 @@ if(CURL_USE_OPENSSL AND OPENSSL_FOUND AND WIN32)
|
||||
endif()
|
||||
|
||||
return() # The rest of this file is not needed for building within CMake.
|
||||
# XXX(cmake): end cmake-specific curl code
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
if(CURL_BUILD_TESTING)
|
||||
@@ -143,9 +144,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
|
||||
@@ -176,9 +175,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
|
||||
@@ -215,9 +212,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
|
||||
@@ -246,7 +241,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 \
|
||||
|
||||
@@ -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!");
|
||||
|
||||
+151
-107
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -560,9 +560,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
|
||||
|
||||
@@ -620,8 +617,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
|
||||
@@ -629,24 +626,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
|
||||
@@ -712,6 +691,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
|
||||
|
||||
@@ -751,6 +733,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
|
||||
|
||||
@@ -797,12 +782,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}
|
||||
|
||||
@@ -857,3 +842,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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
@@ -187,7 +172,7 @@
|
||||
|
||||
#ifdef NEED_THREAD_SAFE
|
||||
# ifndef _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -199,14 +184,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
|
||||
|
||||
@@ -294,14 +279,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. */
|
||||
@@ -397,17 +374,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
|
||||
|
||||
@@ -460,9 +443,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! */
|
||||
@@ -509,11 +492,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>
|
||||
@@ -533,11 +524,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
|
||||
@@ -608,8 +599,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
|
||||
@@ -708,9 +699,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
|
||||
@@ -728,15 +719,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
|
||||
@@ -753,14 +744,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
|
||||
@@ -791,10 +791,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
|
||||
@@ -827,7 +823,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
|
||||
@@ -858,7 +854,7 @@
|
||||
*/
|
||||
|
||||
#ifndef Curl_nop_stmt
|
||||
# define Curl_nop_stmt do { } while(0)
|
||||
#define Curl_nop_stmt do { } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -897,6 +893,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
|
||||
*/
|
||||
@@ -926,6 +930,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
|
||||
@@ -942,8 +948,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);
|
||||
@@ -955,8 +962,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
|
||||
|
||||
@@ -965,7 +971,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
|
||||
@@ -985,7 +991,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
|
||||
@@ -998,26 +1004,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) */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+54
-138
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+19
-19
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -4098,8 +4109,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
|
||||
|
||||
/***********************************************************************
|
||||
@@ -4245,7 +4256,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;
|
||||
}
|
||||
@@ -4256,6 +4267,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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+36
-27
@@ -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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user