Merge branch 'upstream-curl' into update-curl

* upstream-curl:
  curl 2023-02-20 (046209e5)
This commit is contained in:
Brad King
2023-02-21 10:01:04 -05:00
360 changed files with 14421 additions and 9892 deletions

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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
@@ -28,7 +28,7 @@ find_path(BROTLI_INCLUDE_DIR "brotli/decode.h")
find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon)
find_library(BROTLIDEC_LIBRARY NAMES brotlidec)
find_package_handle_standard_args(BROTLI
find_package_handle_standard_args(Brotli
FOUND_VAR
BROTLI_FOUND
REQUIRED_VARS
@@ -36,7 +36,7 @@ find_package_handle_standard_args(BROTLI
BROTLICOMMON_LIBRARY
BROTLI_INCLUDE_DIR
FAIL_MESSAGE
"Could NOT find BROTLI"
"Could NOT find Brotli"
)
set(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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
@@ -181,14 +181,14 @@ if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approac
set(GSS_FLAVOUR "MIT")
else()
# prevent compiling the header - just check if we can include it
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__)
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
set(GSS_FLAVOUR "Heimdal")
endif()
set(CMAKE_REQUIRED_DEFINITIONS "")
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D__ROKEN_H__)
endif()
else()
# I'm not convinced if this is the right way but this is what autotools do at the moment

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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

View File

@@ -150,7 +150,7 @@ endif()
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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
@@ -253,7 +253,7 @@ if(WIN32)
set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
if(CURL_TARGET_WINDOWS_VERSION)
add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
endif()
endif()
@@ -488,7 +488,7 @@ include(CheckCSourceCompiles)
# On windows preload settings
if(WIN32)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_=")
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WINSOCKAPI_=)
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
endif()
@@ -514,24 +514,6 @@ if(WIN32)
endif()
if(0) # This code not needed for building within CMake.
# This check below for use of deprecated symbols is only temporary and is to
# be removed again after a year's service. Remove after November 25, 2022.
set(CURL_RECONFIG_REQUIRED 0)
foreach(_LIB GSSAPI OPENLDAP LIBSSH LIBSSH2 BEARSSL MBEDTLS NSS OPENSSL
SCHANNEL SECTRANSP WOLFSSL)
if(CMAKE_USE_${_LIB})
set(CURL_RECONFIG_REQUIRED 1)
message(SEND_ERROR "The option CMAKE_USE_${_LIB} was renamed to CURL_USE_${_LIB}.")
endif()
endforeach()
if(CMAKE_USE_WINSSL)
set(CURL_RECONFIG_REQUIRED 1)
message(SEND_ERROR "The option CMAKE_USE_WINSSL was renamed to CURL_USE_SCHANNEL.")
endif()
if(CURL_RECONFIG_REQUIRED)
message(FATAL_ERROR "Reconfig required")
endif()
# check SSL libraries
# TODO support GnuTLS
option(CURL_ENABLE_SSL "Enable SSL support" ON)
@@ -577,7 +559,6 @@ if(CURL_USE_SCHANNEL)
endif()
if(CURL_WINDOWS_SSPI)
set(USE_WINDOWS_SSPI ON)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
endif()
if(CURL_USE_SECTRANSP)
@@ -630,8 +611,6 @@ if(CURL_USE_OPENSSL)
if(CURL_CA_PATH)
add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
endif()
add_definitions(-DOPENSSL_SUPPRESS_DEPRECATED)
endif()
if(CURL_USE_MBEDTLS)
@@ -826,7 +805,7 @@ if(NOT CURL_DISABLE_LDAP)
return 0;
}"
)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DLDAP_DEPRECATED=1")
list(APPEND CMAKE_REQUIRED_DEFINITIONS -DLDAP_DEPRECATED=1)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
if(HAVE_LIBLBER)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
@@ -1204,6 +1183,7 @@ check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
check_symbol_exists(socketpair "${CURL_INCLUDES}" HAVE_SOCKETPAIR)
check_symbol_exists(recv "${CURL_INCLUDES}" HAVE_RECV)
check_symbol_exists(send "${CURL_INCLUDES}" HAVE_SEND)
check_symbol_exists(sendmsg "${CURL_INCLUDES}" HAVE_SENDMSG)
check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT)
check_symbol_exists(strdup "${CURL_INCLUDES}" HAVE_STRDUP)
check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R)
@@ -1248,7 +1228,7 @@ check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900))
# earlier MSVC compilers had faulty snprintf implementations
check_symbol_exists(snprintf "${CURL_INCLUDES}" HAVE_SNPRINTF)
check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF)
endif()
check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
check_symbol_exists(inet_ntop "${CURL_INCLUDES}" HAVE_INET_NTOP)
@@ -1451,7 +1431,7 @@ if(WIN32)
# Check if crypto functions in wincrypt.h are actually available
if(HAVE_WINCRYPT_H)
check_symbol_exists(CryptAcquireContext "${CURL_INCLUDES}" USE_WINCRYPT)
check_symbol_exists(CryptAcquireContext "windows.h;wincrypt.h" USE_WINCRYPT)
endif()
if(USE_WINCRYPT)
set(USE_WIN32_CRYPTO ON)

View File

@@ -1,6 +1,6 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2022, Daniel Stenberg, <daniel@haxx.se>, and many
Copyright (c) 1996 - 2023, Daniel Stenberg, <daniel@haxx.se>, and many
contributors, see the THANKS file.
All rights reserved.

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -167,7 +167,7 @@ typedef enum {
CURLSSLBACKEND_SECURETRANSPORT = 9,
CURLSSLBACKEND_AXTLS CURL_DEPRECATED(7.61.0, "") = 10,
CURLSSLBACKEND_MBEDTLS = 11,
CURLSSLBACKEND_MESALINK = 12,
CURLSSLBACKEND_MESALINK CURL_DEPRECATED(7.82.0, "") = 12,
CURLSSLBACKEND_BEARSSL = 13,
CURLSSLBACKEND_RUSTLS = 14
} curl_sslbackend;
@@ -248,7 +248,7 @@ typedef int (*curl_xferinfo_callback)(void *clientp,
#ifndef CURL_MAX_READ_SIZE
/* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
#define CURL_MAX_READ_SIZE 524288
#define CURL_MAX_READ_SIZE (10*1024*1024)
#endif
#ifndef CURL_MAX_WRITE_SIZE
@@ -2259,8 +2259,13 @@ enum {
CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1
Upgrade */
CURL_HTTP_VERSION_3 = 30, /* Makes use of explicit HTTP/3 without fallback.
Use CURLOPT_ALTSVC to enable HTTP/3 upgrade */
CURL_HTTP_VERSION_3 = 30, /* Use HTTP/3, fallback to HTTP/2 or HTTP/1 if
needed. For HTTPS only. For HTTP, this option
makes libcurl return error. */
CURL_HTTP_VERSION_3ONLY = 31, /* Use HTTP/3 without fallback. For HTTPS
only. For HTTP, this makes libcurl
return error. */
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
};
@@ -2953,6 +2958,7 @@ typedef enum {
CURL_LOCK_DATA_SSL_SESSION,
CURL_LOCK_DATA_CONNECT,
CURL_LOCK_DATA_PSL,
CURL_LOCK_DATA_HSTS,
CURL_LOCK_DATA_LAST
} curl_lock_data;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -28,17 +28,17 @@
a script at release-time. This was made its own header file in 7.11.2 */
/* This is the global package copyright */
#define LIBCURL_COPYRIGHT "1996 - 2022 Daniel Stenberg, <daniel@haxx.se>."
#define LIBCURL_COPYRIGHT "Daniel Stenberg, <daniel@haxx.se>."
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.87.0"
#define LIBCURL_VERSION "7.88.1"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 87
#define LIBCURL_VERSION_PATCH 0
#define LIBCURL_VERSION_MINOR 88
#define LIBCURL_VERSION_PATCH 1
/* 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 0x075700
#define LIBCURL_VERSION_NUM 0x075801
/*
* This is the date and time when the full source package was created. The

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -227,16 +227,14 @@
# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
#elif defined(__OS400__)
# if defined(__ILEC400__)
# 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 socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
# endif
# 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 socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__MVS__)
# if defined(__IBMC__) || defined(__IBMCPP__)

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -42,9 +42,8 @@
*/
#define curl_easy_setopt(handle, option, value) \
__extension__({ \
CURL_IGNORE_DEPRECATION(__typeof__(option) _curl_opt = option;) \
CURLoption _curl_opt = (option); \
if(__builtin_constant_p(_curl_opt)) { \
(void) option; \
CURL_IGNORE_DEPRECATION( \
if(curlcheck_long_option(_curl_opt)) \
if(!curlcheck_long(value)) \
@@ -120,9 +119,8 @@
/* wraps curl_easy_getinfo() with typechecking */
#define curl_easy_getinfo(handle, info, arg) \
__extension__({ \
CURL_IGNORE_DEPRECATION(__typeof__(info) _curl_info = info;) \
CURLINFO _curl_info = (info); \
if(__builtin_constant_p(_curl_info)) { \
(void) info; \
CURL_IGNORE_DEPRECATION( \
if(curlcheck_string_info(_curl_info)) \
if(!curlcheck_arr((arg), char *)) \

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2018 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -62,6 +62,7 @@ typedef enum {
CURLUE_BAD_SCHEME, /* 27 */
CURLUE_BAD_SLASHES, /* 28 */
CURLUE_BAD_USER, /* 29 */
CURLUE_LACKS_IDN, /* 30 */
CURLUE_LAST
} CURLUcode;
@@ -95,6 +96,7 @@ typedef enum {
#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the
scheme is unknown. */
#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */
#define CURLU_PUNYCODE (1<<12) /* get the host name in pynycode */
typedef struct Curl_URL CURLU;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -33,6 +33,7 @@ struct curl_ws_frame {
int flags; /* See the CURLWS_* defines */
curl_off_t offset; /* the offset of this data into the frame */
curl_off_t bytesleft; /* number of pending bytes left of the payload */
size_t len; /* size of the current data chunk */
};
/* flag bits */

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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
@@ -136,11 +136,12 @@ set_target_properties(${LIB_NAME} PROPERTIES
if(0) # This code not needed for building within CMake.
if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD" OR
# FreeBSD comes with the a.out and elf flavours
# but a.out was supported up to version 3.x and
# elf from 3.x. I cannot imagine someone runnig
# elf from 3.x. I cannot imagine someone running
# CMake on those ancient systems
CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
# 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
@@ -79,16 +79,17 @@ LIB_VTLS_HFILES = \
vtls/x509asn1.h
LIB_VQUIC_CFILES = \
vquic/msh3.c \
vquic/ngtcp2.c \
vquic/quiche.c \
vquic/curl_msh3.c \
vquic/curl_ngtcp2.c \
vquic/curl_quiche.c \
vquic/vquic.c
LIB_VQUIC_HFILES = \
vquic/msh3.h \
vquic/ngtcp2.h \
vquic/quiche.h \
vquic/vquic.h
vquic/curl_msh3.h \
vquic/curl_ngtcp2.h \
vquic/curl_quiche.h \
vquic/vquic.h \
vquic/vquic_int.h
LIB_VSSH_CFILES = \
vssh/libssh.c \
@@ -106,6 +107,8 @@ LIB_CFILES = \
base64.c \
bufref.c \
c-hyper.c \
cf-http.c \
cf-socket.c \
cfilters.c \
conncache.c \
connect.c \
@@ -118,6 +121,7 @@ LIB_CFILES = \
curl_get_line.c \
curl_gethostname.c \
curl_gssapi.c \
curl_log.c \
curl_memrchr.c \
curl_multibyte.c \
curl_ntlm_core.c \
@@ -229,6 +233,8 @@ LIB_HFILES = \
asyn.h \
bufref.h \
c-hyper.h \
cf-http.h \
cf-socket.h \
cfilters.h \
conncache.h \
connect.h \
@@ -246,6 +252,7 @@ LIB_HFILES = \
curl_hmac.h \
curl_krb5.h \
curl_ldap.h \
curl_log.h \
curl_md4.h \
curl_md5.h \
curl_memory.h \
@@ -312,7 +319,6 @@ LIB_HFILES = \
pop3.h \
progress.h \
psl.h \
quic.h \
rand.h \
rename.h \
rtsp.h \

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2019 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2021 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2021 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -485,7 +485,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
if(k->upgr101 == UPGR101_WS) {
if(http_status == 101) {
/* verify the response */
result = Curl_ws_accept(data);
result = Curl_ws_accept(data, NULL, 0);
if(result)
return result;
}
@@ -1128,6 +1128,16 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
goto error;
}
#ifdef HAVE_LIBZ
/* we only consider transfer-encoding magic if libz support is built-in */
result = Curl_transferencode(data);
if(result)
goto error;
result = Curl_hyper_header(data, headers, data->state.aptr.te);
if(result)
goto error;
#endif
if(!Curl_checkheaders(data, STRCONST("Accept-Encoding")) &&
data->set.str[STRING_ENCODING]) {
Curl_safefree(data->state.aptr.accept_encoding);
@@ -1144,16 +1154,6 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
else
Curl_safefree(data->state.aptr.accept_encoding);
#ifdef HAVE_LIBZ
/* we only consider transfer-encoding magic if libz support is built-in */
result = Curl_transferencode(data);
if(result)
goto error;
result = Curl_hyper_header(data, headers, data->state.aptr.te);
if(result)
goto error;
#endif
result = cookies(data, conn, headers);
if(result)
goto error;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -0,0 +1,518 @@
/***************************************************************************
* _ _ ____ _
* 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
*
***************************************************************************/
#include "curl_setup.h"
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
#include "urldata.h"
#include <curl/curl.h>
#include "curl_log.h"
#include "cfilters.h"
#include "connect.h"
#include "multiif.h"
#include "cf-http.h"
#include "http2.h"
#include "vquic/vquic.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
typedef enum {
CF_HC_INIT,
CF_HC_CONNECT,
CF_HC_SUCCESS,
CF_HC_FAILURE
} cf_hc_state;
struct cf_hc_baller {
const char *name;
struct Curl_cfilter *cf;
CURLcode result;
struct curltime started;
int reply_ms;
bool enabled;
};
static void cf_hc_baller_reset(struct cf_hc_baller *b,
struct Curl_easy *data)
{
if(b->cf) {
Curl_conn_cf_close(b->cf, data);
Curl_conn_cf_discard_chain(&b->cf, data);
b->cf = NULL;
}
b->result = CURLE_OK;
b->reply_ms = -1;
}
static bool cf_hc_baller_is_active(struct cf_hc_baller *b)
{
return b->enabled && b->cf && !b->result;
}
static bool cf_hc_baller_has_started(struct cf_hc_baller *b)
{
return !!b->cf;
}
static int cf_hc_baller_reply_ms(struct cf_hc_baller *b,
struct Curl_easy *data)
{
if(b->reply_ms < 0)
b->cf->cft->query(b->cf, data, CF_QUERY_CONNECT_REPLY_MS,
&b->reply_ms, NULL);
return b->reply_ms;
}
static bool cf_hc_baller_data_pending(struct cf_hc_baller *b,
const struct Curl_easy *data)
{
return b->cf && !b->result && b->cf->cft->has_data_pending(b->cf, data);
}
struct cf_hc_ctx {
cf_hc_state state;
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;
int soft_eyeballs_timeout_ms;
int hard_eyeballs_timeout_ms;
};
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);
b->cf = cf->next;
cf->next = save;
}
static CURLcode cf_hc_baller_connect(struct cf_hc_baller *b,
struct Curl_cfilter *cf,
struct Curl_easy *data,
bool *done)
{
struct Curl_cfilter *save = cf->next;
cf->next = b->cf;
b->result = Curl_conn_cf_connect(cf->next, data, FALSE, done);
b->cf = cf->next; /* it might mutate */
cf->next = save;
return b->result;
}
static void cf_hc_reset(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct cf_hc_ctx *ctx = cf->ctx;
if(ctx) {
cf_hc_baller_reset(&ctx->h3_baller, data);
cf_hc_baller_reset(&ctx->h21_baller, data);
ctx->state = CF_HC_INIT;
ctx->result = CURLE_OK;
ctx->hard_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout;
ctx->soft_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout / 2;
}
}
static CURLcode baller_connected(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct cf_hc_baller *winner)
{
struct cf_hc_ctx *ctx = cf->ctx;
CURLcode result = CURLE_OK;
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);
DEBUGF(LOG_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
winner->name, (int)Curl_timediff(Curl_now(), winner->started),
cf_hc_baller_reply_ms(winner, data)));
cf->next = winner->cf;
winner->cf = NULL;
switch(cf->conn->alpn) {
case CURL_HTTP_VERSION_3:
infof(data, "using HTTP/3");
break;
case CURL_HTTP_VERSION_2:
#ifdef USE_NGHTTP2
/* Using nghttp2, we add the filter "below" us, so when the conn
* closes, we tear it down for a fresh reconnect */
result = Curl_http2_switch_at(cf, data);
if(result) {
ctx->state = CF_HC_FAILURE;
ctx->result = result;
return result;
}
#endif
infof(data, "using HTTP/2");
break;
case CURL_HTTP_VERSION_1_1:
infof(data, "using HTTP/1.1");
break;
default:
infof(data, "using HTTP/1.x");
break;
}
ctx->state = CF_HC_SUCCESS;
cf->connected = TRUE;
Curl_conn_cf_cntrl(cf->next, data, TRUE,
CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
return result;
}
static bool time_to_start_h21(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct curltime now)
{
struct cf_hc_ctx *ctx = cf->ctx;
timediff_t elapsed_ms;
if(!ctx->h21_baller.enabled || cf_hc_baller_has_started(&ctx->h21_baller))
return FALSE;
if(!ctx->h3_baller.enabled || !cf_hc_baller_is_active(&ctx->h3_baller))
return TRUE;
elapsed_ms = Curl_timediff(now, ctx->started);
if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
DEBUGF(LOG_CF(data, cf, "hard timeout of %dms reached, starting h21",
ctx->hard_eyeballs_timeout_ms));
return TRUE;
}
if(elapsed_ms >= ctx->soft_eyeballs_timeout_ms) {
if(cf_hc_baller_reply_ms(&ctx->h3_baller, data) < 0) {
DEBUGF(LOG_CF(data, cf, "soft timeout of %dms reached, h3 has not "
"seen any data, starting h21",
ctx->soft_eyeballs_timeout_ms));
return TRUE;
}
/* set the effective hard timeout again */
Curl_expire(data, ctx->hard_eyeballs_timeout_ms - elapsed_ms,
EXPIRE_ALPN_EYEBALLS);
}
return FALSE;
}
static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done)
{
struct cf_hc_ctx *ctx = cf->ctx;
struct curltime now;
CURLcode result = CURLE_OK;
(void)blocking;
if(cf->connected) {
*done = TRUE;
return CURLE_OK;
}
*done = FALSE;
now = Curl_now();
switch(ctx->state) {
case CF_HC_INIT:
DEBUGASSERT(!ctx->h3_baller.cf);
DEBUGASSERT(!ctx->h21_baller.cf);
DEBUGASSERT(!cf->next);
DEBUGF(LOG_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);
}
else if(ctx->h21_baller.enabled)
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21", TRNSPRT_TCP);
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(!result && *done) {
result = baller_connected(cf, data, &ctx->h3_baller);
goto out;
}
}
if(time_to_start_h21(cf, data, now)) {
cf_hc_baller_init(&ctx->h21_baller, cf, data, "h21", TRNSPRT_TCP);
}
if(cf_hc_baller_is_active(&ctx->h21_baller)) {
DEBUGF(LOG_CF(data, cf, "connect, check h21"));
result = cf_hc_baller_connect(&ctx->h21_baller, cf, data, done);
if(!result && *done) {
result = baller_connected(cf, data, &ctx->h21_baller);
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 */
DEBUGF(LOG_CF(data, cf, "connect, all failed"));
result = ctx->result = ctx->h3_baller.enabled?
ctx->h3_baller.result : ctx->h21_baller.result;
ctx->state = CF_HC_FAILURE;
goto out;
}
result = CURLE_OK;
*done = FALSE;
break;
case CF_HC_FAILURE:
result = ctx->result;
cf->connected = FALSE;
*done = FALSE;
break;
case CF_HC_SUCCESS:
result = CURLE_OK;
cf->connected = TRUE;
*done = TRUE;
break;
}
out:
DEBUGF(LOG_CF(data, cf, "connect -> %d, done=%d", result, *done));
return result;
}
static int cf_hc_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
{
struct cf_hc_ctx *ctx = cf->ctx;
size_t i, j, s;
int brc, rc = GETSOCK_BLANK;
curl_socket_t bsocks[MAX_SOCKSPEREASYHANDLE];
struct cf_hc_baller *ballers[2];
if(cf->connected)
return cf->next->cft->get_select_socks(cf->next, data, socks);
ballers[0] = &ctx->h3_baller;
ballers[1] = &ctx->h21_baller;
for(i = s = 0; i < sizeof(ballers)/sizeof(ballers[0]); i++) {
struct cf_hc_baller *b = ballers[i];
if(!cf_hc_baller_is_active(b))
continue;
brc = Curl_conn_cf_get_select_socks(b->cf, data, bsocks);
DEBUGF(LOG_CF(data, cf, "get_selected_socks(%s) -> %x", b->name, brc));
if(!brc)
continue;
for(j = 0; j < MAX_SOCKSPEREASYHANDLE && s < MAX_SOCKSPEREASYHANDLE; ++j) {
if((brc & GETSOCK_WRITESOCK(j)) || (brc & GETSOCK_READSOCK(j))) {
socks[s] = bsocks[j];
if(brc & GETSOCK_WRITESOCK(j))
rc |= GETSOCK_WRITESOCK(s);
if(brc & GETSOCK_READSOCK(j))
rc |= GETSOCK_READSOCK(s);
s++;
}
}
}
DEBUGF(LOG_CF(data, cf, "get_selected_socks -> %x", rc));
return rc;
}
static bool cf_hc_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
struct cf_hc_ctx *ctx = cf->ctx;
if(cf->connected)
return cf->next->cft->has_data_pending(cf->next, data);
DEBUGF(LOG_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);
}
static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
DEBUGF(LOG_CF(data, cf, "close"));
cf_hc_reset(cf, data);
cf->connected = FALSE;
if(cf->next) {
cf->next->cft->close(cf->next, data);
Curl_conn_cf_discard_chain(&cf->next, data);
}
}
static void cf_hc_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
{
struct cf_hc_ctx *ctx = cf->ctx;
(void)data;
DEBUGF(LOG_CF(data, cf, "destroy"));
cf_hc_reset(cf, data);
Curl_safefree(ctx);
}
struct Curl_cftype Curl_cft_http_connect = {
"HTTPS-CONNECT",
0,
CURL_LOG_DEFAULT,
cf_hc_destroy,
cf_hc_connect,
cf_hc_close,
Curl_cf_def_get_host,
cf_hc_get_select_socks,
cf_hc_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
Curl_cf_def_cntrl,
Curl_cf_def_conn_is_alive,
Curl_cf_def_conn_keep_alive,
Curl_cf_def_query,
};
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)
{
struct Curl_cfilter *cf = NULL;
struct cf_hc_ctx *ctx;
CURLcode result = CURLE_OK;
(void)data;
ctx = calloc(sizeof(*ctx), 1);
if(!ctx) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
ctx->remotehost = remotehost;
ctx->h3_baller.enabled = try_h3;
ctx->h21_baller.enabled = try_h21;
result = Curl_cf_create(&cf, &Curl_cft_http_connect, ctx);
if(result)
goto out;
ctx = NULL;
cf_hc_reset(cf, data);
out:
*pcf = result? NULL : cf;
free(ctx);
return result;
}
CURLcode Curl_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)
{
struct Curl_cfilter *cf;
CURLcode result = CURLE_OK;
DEBUGASSERT(data);
result = cf_hc_create(&cf, data, remotehost, try_h3, try_h21);
if(result)
goto out;
Curl_conn_cf_add(data, conn, sockindex, cf);
out:
return result;
}
CURLcode
Curl_cf_http_connect_insert_after(struct Curl_cfilter *cf_at,
struct Curl_easy *data,
const struct Curl_dns_entry *remotehost,
bool try_h3, bool try_h21)
{
struct Curl_cfilter *cf;
CURLcode result;
DEBUGASSERT(data);
result = cf_hc_create(&cf, data, remotehost, try_h3, try_h21);
if(result)
goto out;
Curl_conn_cf_insert_after(cf_at, cf);
out:
return result;
}
CURLcode Curl_cf_https_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost)
{
bool try_h3 = FALSE, try_h21 = TRUE; /* defaults, for now */
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) /* can't 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;
}
result = Curl_cf_http_connect_add(data, conn, sockindex, remotehost,
try_h3, try_h21);
out:
return result;
}
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */

View File

@@ -0,0 +1,58 @@
#ifndef HEADER_CURL_CF_HTTP_H
#define HEADER_CURL_CF_HTTP_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.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)
struct Curl_cfilter;
struct Curl_easy;
struct connectdata;
struct Curl_cftype;
struct Curl_dns_entry;
extern struct Curl_cftype Curl_cft_http_connect;
CURLcode Curl_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);
CURLcode
Curl_cf_http_connect_insert_after(struct Curl_cfilter *cf_at,
struct Curl_easy *data,
const struct Curl_dns_entry *remotehost,
bool try_h3, bool try_h21);
CURLcode Curl_cf_https_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost);
#endif /* !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER) */
#endif /* HEADER_CURL_CF_HTTP_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,192 @@
#ifndef HEADER_CURL_CF_SOCKET_H
#define HEADER_CURL_CF_SOCKET_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.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"
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
#include "sockaddr.h"
struct Curl_addrinfo;
struct Curl_cfilter;
struct Curl_easy;
struct connectdata;
struct Curl_sockaddr_ex;
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold any
* protocol-specific address structures. The variable declared here will be
* used to pass / receive data to/from the fopensocket callback if this has
* been set, before that, it is initialized from parameters.
*/
struct Curl_sockaddr_ex {
int family;
int socktype;
int protocol;
unsigned int addrlen;
union {
struct sockaddr addr;
struct Curl_sockaddr_storage buff;
} _sa_ex_u;
};
#define sa_addr _sa_ex_u.addr
/*
* Create a socket based on info from 'conn' and 'ai'.
*
* Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
* socket callback is set, used that!
*
*/
CURLcode Curl_socket_open(struct Curl_easy *data,
const struct Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
int transport,
curl_socket_t *sockfd);
int Curl_socket_close(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sock);
/*
* This function should return TRUE if the socket is to be assumed to
* be dead. Most commonly this happens when the server has closed the
* connection due to inactivity.
*/
bool Curl_socket_is_dead(curl_socket_t sock);
/**
* Determine the curl code for a socket connect() == -1 with errno.
*/
CURLcode Curl_socket_connect_result(struct Curl_easy *data,
const char *ipaddress, int error);
#ifdef USE_WINSOCK
/* When you run a program that uses the Windows Sockets API, you may
experience slow performance when you copy data to a TCP server.
https://support.microsoft.com/kb/823764
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
Buffer Size
*/
void Curl_sndbufset(curl_socket_t sockfd);
#else
#define Curl_sndbufset(y) Curl_nop_stmt
#endif
/**
* 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);
/**
* Creates a cfilter that opens a TCP socket to the given address
* when calling its `connect` implementation.
* The filter will not touch any connection/data flags and can be
* used in happy eyeballing. Once selected for use, its `_active()`
* method needs to be called.
*/
CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
struct Curl_easy *data,
struct connectdata *conn,
const struct Curl_addrinfo *ai,
int transport);
/**
* Creates a cfilter that opens a UDP socket to the given address
* when calling its `connect` implementation.
* The filter will not touch any connection/data flags and can be
* used in happy eyeballing. Once selected for use, its `_active()`
* method needs to be called.
*/
CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
struct Curl_easy *data,
struct connectdata *conn,
const struct Curl_addrinfo *ai,
int transport);
/**
* Creates a cfilter that opens a UNIX socket to the given address
* when calling its `connect` implementation.
* The filter will not touch any connection/data flags and can be
* used in happy eyeballing. Once selected for use, its `_active()`
* method needs to be called.
*/
CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
struct Curl_easy *data,
struct connectdata *conn,
const struct Curl_addrinfo *ai,
int transport);
/**
* Creates a cfilter that keeps a listening socket.
*/
CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
curl_socket_t *s);
/**
* Replace the listen socket with the accept()ed one.
*/
CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
curl_socket_t *s);
/**
* Return TRUE iff `cf` is a socket filter.
*/
bool Curl_cf_is_socket(struct Curl_cfilter *cf);
/**
* Peek at the socket and remote ip/port the socket filter is using.
* The filter owns all returned values.
* @param psock pointer to hold socket descriptor or NULL
* @param paddr pointer to hold addr reference or NULL
* @param pr_ip_str pointer to hold remote addr as string or NULL
* @param pr_port pointer to hold remote port number or NULL
* @param pl_ip_str pointer to hold local addr as string or NULL
* @param pl_port pointer to hold local port number or NULL
* Returns error if the filter is of invalid type.
*/
CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *psock,
const struct Curl_sockaddr_ex **paddr,
const char **pr_ip_str, int *pr_port,
const char **pl_ip_str, int *pl_port);
extern struct Curl_cftype Curl_cft_tcp;
extern struct Curl_cftype Curl_cft_udp;
extern struct Curl_cftype Curl_cft_unix;
extern struct Curl_cftype Curl_cft_tcp_accept;
#endif /* HEADER_CURL_CF_SOCKET_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -34,9 +34,6 @@
#include "multiif.h"
#include "progress.h"
#include "warnless.h"
#include "http_proxy.h"
#include "socks.h"
#include "vtls/vtls.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -54,89 +51,116 @@ void Curl_cf_def_destroy_this(struct Curl_cfilter *cf, struct Curl_easy *data)
(void)data;
}
CURLcode Curl_cf_def_setup(struct Curl_cfilter *cf,
struct Curl_easy *data,
const struct Curl_dns_entry *remotehost)
{
DEBUGASSERT(cf->next);
return cf->next->cft->setup(cf->next, data, remotehost);
}
void Curl_cf_def_attach_data(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
(void)cf;
(void)data;
}
void Curl_cf_def_detach_data(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
(void)cf;
(void)data;
}
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
DEBUGASSERT(cf->next);
cf->connected = FALSE;
cf->next->cft->close(cf->next, data);
if(cf->next)
cf->next->cft->close(cf->next, data);
}
CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done)
{
DEBUGASSERT(cf->next);
return cf->next->cft->connect(cf->next, data, blocking, done);
CURLcode result;
if(cf->connected) {
*done = TRUE;
return CURLE_OK;
}
if(cf->next) {
result = cf->next->cft->connect(cf->next, data, blocking, done);
if(!result && *done) {
cf->connected = TRUE;
}
return result;
}
*done = FALSE;
return CURLE_FAILED_INIT;
}
void Curl_cf_def_get_host(struct Curl_cfilter *cf, struct Curl_easy *data,
const char **phost, const char **pdisplay_host,
int *pport)
{
DEBUGASSERT(cf->next);
cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
if(cf->next)
cf->next->cft->get_host(cf->next, data, phost, pdisplay_host, pport);
else {
*phost = cf->conn->host.name;
*pdisplay_host = cf->conn->host.dispname;
*pport = cf->conn->port;
}
}
int Curl_cf_def_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
{
DEBUGASSERT(cf->next);
return cf->next->cft->get_select_socks(cf->next, data, socks);
return cf->next?
cf->next->cft->get_select_socks(cf->next, data, socks) : 0;
}
bool Curl_cf_def_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
DEBUGASSERT(cf->next);
return cf->next->cft->has_data_pending(cf->next, data);
return cf->next?
cf->next->cft->has_data_pending(cf->next, data) : FALSE;
}
ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
DEBUGASSERT(cf->next);
return cf->next->cft->do_send(cf->next, data, buf, len, err);
return cf->next?
cf->next->cft->do_send(cf->next, data, buf, len, err) :
CURLE_RECV_ERROR;
}
ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
DEBUGASSERT(cf->next);
return cf->next->cft->do_recv(cf->next, data, buf, len, err);
return cf->next?
cf->next->cft->do_recv(cf->next, data, buf, len, err) :
CURLE_SEND_ERROR;
}
void Curl_conn_cf_discard_all(struct Curl_easy *data,
struct connectdata *conn, int index)
bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
struct Curl_cfilter *cfn, *cf = conn->cfilter[index];
return cf->next?
cf->next->cft->is_alive(cf->next, data) :
FALSE; /* pessimistic in absence of data */
}
CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
return cf->next?
cf->next->cft->keep_alive(cf->next, data) :
CURLE_OK;
}
CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
struct Curl_easy *data,
int query, int *pres1, void *pres2)
{
return cf->next?
cf->next->cft->query(cf->next, data, query, pres1, pres2) :
CURLE_UNKNOWN_OPTION;
}
void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
struct Curl_easy *data)
{
struct Curl_cfilter *cfn, *cf = *pcf;
if(cf) {
conn->cfilter[index] = NULL;
*pcf = NULL;
while(cf) {
cfn = cf->next;
/* prevent destroying filter to mess with its sub-chain, since
* we have the reference now and will call destroy on it.
*/
cf->next = NULL;
cf->cft->destroy(cf, data);
free(cf);
cf = cfn;
@@ -144,6 +168,12 @@ void Curl_conn_cf_discard_all(struct Curl_easy *data,
}
}
void Curl_conn_cf_discard_all(struct Curl_easy *data,
struct connectdata *conn, int index)
{
Curl_conn_cf_discard_chain(&conn->cfilter[index], data);
}
void Curl_conn_close(struct Curl_easy *data, int index)
{
struct Curl_cfilter *cf;
@@ -160,7 +190,6 @@ ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
size_t len, CURLcode *code)
{
struct Curl_cfilter *cf;
ssize_t nread;
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
@@ -169,13 +198,9 @@ ssize_t Curl_conn_recv(struct Curl_easy *data, int num, char *buf,
cf = cf->next;
}
if(cf) {
nread = cf->cft->do_recv(cf, data, buf, len, code);
/* DEBUGF(infof(data, "Curl_conn_recv(handle=%p, index=%d)"
"-> %ld, err=%d", data, num, nread, *code));*/
return nread;
return cf->cft->do_recv(cf, data, buf, len, code);
}
failf(data, "no filter connected, conn=%ld, sockindex=%d",
data->conn->connection_id, num);
failf(data, CMSGI(data->conn, num, "recv: no filter connected"));
*code = CURLE_FAILED_INIT;
return -1;
}
@@ -184,7 +209,6 @@ ssize_t Curl_conn_send(struct Curl_easy *data, int num,
const void *mem, size_t len, CURLcode *code)
{
struct Curl_cfilter *cf;
ssize_t nwritten;
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
@@ -193,13 +217,10 @@ ssize_t Curl_conn_send(struct Curl_easy *data, int num,
cf = cf->next;
}
if(cf) {
nwritten = cf->cft->do_send(cf, data, mem, len, code);
/* DEBUGF(infof(data, "Curl_conn_send(handle=%p, index=%d, len=%ld)"
" -> %ld, err=%d", data, num, len, nwritten, *code));*/
return nwritten;
return cf->cft->do_send(cf, data, mem, len, code);
}
failf(data, "no filter connected, conn=%ld, sockindex=%d",
data->conn->connection_id, num);
failf(data, CMSGI(data->conn, num, "send: no filter connected"));
DEBUGASSERT(0);
*code = CURLE_FAILED_INIT;
return -1;
}
@@ -234,12 +255,31 @@ void Curl_conn_cf_add(struct Curl_easy *data,
DEBUGASSERT(!cf->conn);
DEBUGASSERT(!cf->next);
DEBUGF(infof(data, CMSGI(conn, index, "cf_add(filter=%s)"),
cf->cft->name));
cf->next = conn->cfilter[index];
cf->conn = conn;
cf->sockindex = index;
conn->cfilter[index] = cf;
DEBUGF(LOG_CF(data, cf, "added"));
}
void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
struct Curl_cfilter *cf_new)
{
struct Curl_cfilter *tail, **pnext;
DEBUGASSERT(cf_at);
DEBUGASSERT(cf_new);
DEBUGASSERT(!cf_new->conn);
tail = cf_at->next;
cf_at->next = cf_new;
do {
cf_new->conn = cf_at->conn;
cf_new->sockindex = cf_at->sockindex;
pnext = &cf_new->next;
cf_new = cf_new->next;
} while(cf_new);
*pnext = tail;
}
void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
@@ -259,97 +299,54 @@ void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data)
free(cf);
}
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done)
{
if(cf)
return cf->cft->connect(cf, data, blocking, done);
return CURLE_FAILED_INIT;
}
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
if(cf)
cf->cft->close(cf, data);
}
int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks)
{
if(cf)
return cf->cft->get_select_socks(cf, data, socks);
return 0;
}
bool Curl_conn_cf_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data)
{
if(cf)
return cf->cft->has_data_pending(cf, data);
return FALSE;
}
ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err)
{
return cf->cft->do_send(cf, data, buf, len, err);
if(cf)
return cf->cft->do_send(cf, data, buf, len, err);
*err = CURLE_SEND_ERROR;
return -1;
}
ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err)
{
return cf->cft->do_recv(cf, data, buf, len, err);
}
CURLcode Curl_conn_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost,
int ssl_mode)
{
struct Curl_cfilter *cf;
CURLcode result;
DEBUGASSERT(data);
/* If no filter is set, we have the "default" setup of connection filters.
* The filter chain from botton to top will be:
* - SOCKET socket filter for outgoing connection to remotehost
* if http_proxy tunneling is engaged:
* - SSL if proxytype is CURLPROXY_HTTPS
* - HTTP_PROXY_TUNNEL
* otherwise, if socks_proxy is engaged:
* - SOCKS_PROXY_TUNNEL
* - SSL if conn->handler has PROTOPT_SSL
*/
if(!conn->cfilter[sockindex]) {
DEBUGF(infof(data, DMSGI(data, sockindex, "setup, init filter chain")));
result = Curl_conn_socket_set(data, conn, sockindex);
if(result)
goto out;
#ifndef CURL_DISABLE_PROXY
if(conn->bits.socksproxy) {
result = Curl_conn_socks_proxy_add(data, conn, sockindex);
if(result)
goto out;
}
if(conn->bits.httpproxy) {
#ifdef USE_SSL
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
result = Curl_ssl_cfilter_proxy_add(data, conn, sockindex);
if(result)
goto out;
}
#endif /* USE_SSL */
#if !defined(CURL_DISABLE_HTTP)
if(conn->bits.tunnel_proxy) {
result = Curl_conn_http_proxy_add(data, conn, sockindex);
if(result)
goto out;
}
#endif /* !CURL_DISABLE_HTTP */
}
#endif /* !CURL_DISABLE_PROXY */
#ifdef USE_SSL
if(ssl_mode == CURL_CF_SSL_ENABLE
|| (ssl_mode != CURL_CF_SSL_DISABLE
&& conn->handler->flags & PROTOPT_SSL)) {
result = Curl_ssl_cfilter_add(data, conn, sockindex);
if(result)
goto out;
}
#else
(void)ssl_mode;
#endif /* USE_SSL */
#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
if(data->set.haproxyprotocol) {
result = Curl_conn_haproxy_add(data, conn, sockindex);
if(result)
goto out;
}
#endif /* !CURL_DISABLE_PROXY && !CURL_DISABLE_HTTP */
}
DEBUGASSERT(conn->cfilter[sockindex]);
cf = data->conn->cfilter[sockindex];
result = cf->cft->setup(cf, data, remotehost);
out:
return result;
if(cf)
return cf->cft->do_recv(cf, data, buf, len, err);
*err = CURLE_RECV_ERROR;
return -1;
}
CURLcode Curl_conn_connect(struct Curl_easy *data,
@@ -358,16 +355,26 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
bool *done)
{
struct Curl_cfilter *cf;
CURLcode result;
CURLcode result = CURLE_OK;
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
cf = data->conn->cfilter[sockindex];
DEBUGASSERT(cf);
result = cf->cft->connect(cf, data, blocking, done);
if(!cf)
return CURLE_FAILED_INIT;
*done = cf->connected;
if(!*done) {
result = cf->cft->connect(cf, data, blocking, done);
if(!result && *done) {
Curl_conn_ev_update_info(data, data->conn);
Curl_conn_ev_report_stats(data, data->conn);
data->conn->keepalive = Curl_now();
}
}
DEBUGF(infof(data, DMSGI(data, sockindex, "connect(block=%d)-> %d, done=%d"),
blocking, result, *done));
return result;
}
@@ -394,11 +401,10 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex)
return FALSE;
}
bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex)
bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex)
{
struct Curl_cfilter *cf = data->conn? data->conn->cfilter[sockindex] : NULL;
struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
(void)data;
for(; cf; cf = cf->next) {
if(cf->cft->flags & CF_TYPE_SSL)
return TRUE;
@@ -408,6 +414,19 @@ bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex)
return FALSE;
}
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex)
{
struct Curl_cfilter *cf = conn? conn->cfilter[sockindex] : NULL;
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)
return FALSE;
}
return FALSE;
}
bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
{
@@ -416,8 +435,6 @@ bool Curl_conn_data_pending(struct Curl_easy *data, int sockindex)
(void)data;
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
if(Curl_recv_has_postponed_data(data->conn, sockindex))
return TRUE;
cf = data->conn->cfilter[sockindex];
while(cf && !cf->connected) {
@@ -437,46 +454,16 @@ int Curl_conn_get_select_socks(struct Curl_easy *data, int sockindex,
DEBUGASSERT(data);
DEBUGASSERT(data->conn);
cf = data->conn->cfilter[sockindex];
/* if the next one is not yet connected, that's the one we want */
while(cf && cf->next && !cf->next->connected)
cf = cf->next;
if(cf) {
return cf->cft->get_select_socks(cf, data, socks);
}
return GETSOCK_BLANK;
}
void Curl_conn_attach_data(struct connectdata *conn,
struct Curl_easy *data)
{
size_t i;
struct Curl_cfilter *cf;
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
cf = conn->cfilter[i];
if(cf) {
while(cf) {
cf->cft->attach_data(cf, data);
cf = cf->next;
}
}
}
}
void Curl_conn_detach_data(struct connectdata *conn,
struct Curl_easy *data)
{
size_t i;
struct Curl_cfilter *cf;
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
cf = conn->cfilter[i];
if(cf) {
while(cf) {
cf->cft->detach_data(cf, data);
cf = cf->next;
}
}
}
}
void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
const char **phost, const char **pdisplay_host,
int *pport)
@@ -491,7 +478,7 @@ void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
else {
/* Some filter ask during shutdown for this, mainly for debugging
* purposes. We hand out the defaults, however this is not always
* accurate, as the connction might be tunneled, etc. But all that
* accurate, as the connection might be tunneled, etc. But all that
* state is already gone here. */
*phost = data->conn->host.name;
*pdisplay_host = data->conn->host.dispname;
@@ -499,4 +486,158 @@ void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
}
}
CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
int event, int arg1, void *arg2)
{
(void)cf;
(void)data;
(void)event;
(void)arg1;
(void)arg2;
return CURLE_OK;
}
CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool ignore_result,
int event, int arg1, void *arg2)
{
CURLcode result = CURLE_OK;
for(; cf; cf = cf->next) {
if(Curl_cf_def_cntrl == cf->cft->cntrl)
continue;
result = cf->cft->cntrl(cf, data, event, arg1, arg2);
if(!ignore_result && result)
break;
}
return result;
}
curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
struct Curl_easy *data)
{
curl_socket_t sock;
if(cf && !cf->cft->query(cf, data, CF_QUERY_SOCKET, NULL, &sock))
return sock;
return CURL_SOCKET_BAD;
}
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex)
{
struct Curl_cfilter *cf;
cf = data->conn? data->conn->cfilter[sockindex] : NULL;
/* if the top filter has not connected, ask it (and its sub-filters)
* for the socket. Otherwise conn->sock[sockindex] should have it.
*/
if(cf && !cf->connected)
return Curl_conn_cf_get_socket(cf, data);
return data->conn? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
}
static CURLcode cf_cntrl_all(struct connectdata *conn,
struct Curl_easy *data,
bool ignore_result,
int event, int arg1, void *arg2)
{
CURLcode result = CURLE_OK;
size_t i;
for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) {
result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result,
event, arg1, arg2);
if(!ignore_result && result)
break;
}
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,
CF_CTRL_DATA_SETUP, 0, NULL);
}
CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data)
{
return cf_cntrl_all(data->conn, data, FALSE,
CF_CTRL_DATA_IDLE, 0, NULL);
}
/**
* Notify connection filters that the transfer represented by `data`
* is donw with sending data (e.g. has uploaded everything).
*/
void Curl_conn_ev_data_done_send(struct Curl_easy *data)
{
cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE_SEND, 0, NULL);
}
/**
* Notify connection filters that the transfer represented by `data`
* is finished - eventually premature, e.g. before being complete.
*/
void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature)
{
cf_cntrl_all(data->conn, data, TRUE, CF_CTRL_DATA_DONE, premature, NULL);
}
CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause)
{
return cf_cntrl_all(data->conn, data, FALSE,
CF_CTRL_DATA_PAUSE, do_pause, NULL);
}
void Curl_conn_ev_update_info(struct Curl_easy *data,
struct connectdata *conn)
{
cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_INFO_UPDATE, 0, NULL);
}
void Curl_conn_ev_report_stats(struct Curl_easy *data,
struct connectdata *conn)
{
cf_cntrl_all(conn, data, TRUE, CF_CTRL_CONN_REPORT_STATS, 0, NULL);
}
bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn)
{
struct Curl_cfilter *cf = conn->cfilter[FIRSTSOCKET];
return cf && !cf->conn->bits.close && cf->cft->is_alive(cf, data);
}
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf = conn->cfilter[sockindex];
return cf? cf->cft->keep_alive(cf, data) : CURLE_OK;
}
size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
struct connectdata *conn,
int sockindex)
{
CURLcode result;
int n = 0;
struct Curl_cfilter *cf = conn->cfilter[sockindex];
result = cf? cf->cft->query(cf, data, CF_QUERY_MAX_CONCURRENT,
&n, NULL) : CURLE_UNKNOWN_OPTION;
return (result || n <= 0)? 1 : (size_t)n;
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -36,11 +36,6 @@ struct connectdata;
typedef void Curl_cft_destroy_this(struct Curl_cfilter *cf,
struct Curl_easy *data);
/* Setup the connection for `data`, using destination `remotehost`.
*/
typedef CURLcode Curl_cft_setup(struct Curl_cfilter *cf,
struct Curl_easy *data,
const struct Curl_dns_entry *remotehost);
typedef void Curl_cft_close(struct Curl_cfilter *cf,
struct Curl_easy *data);
@@ -89,29 +84,89 @@ typedef ssize_t Curl_cft_recv(struct Curl_cfilter *cf,
size_t len, /* amount to read */
CURLcode *err); /* error to return */
typedef void Curl_cft_attach_data(struct Curl_cfilter *cf,
struct Curl_easy *data);
typedef void Curl_cft_detach_data(struct Curl_cfilter *cf,
struct Curl_easy *data);
typedef bool Curl_cft_conn_is_alive(struct Curl_cfilter *cf,
struct Curl_easy *data);
typedef CURLcode Curl_cft_conn_keep_alive(struct Curl_cfilter *cf,
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.
* Events/controls for connection filters, their arguments and
* return code handling. Filter callbacks are invoked "top down".
* Return code handling:
* "first fail" meaning that the first filter returning != CURLE_OK, will
* abort further event distribution and determine the result.
* "ignored" meaning return values are ignored and the event is distributed
* to all filters in the chain. Overall result is always CURLE_OK.
*/
void Curl_conn_detach(struct connectdata *conn, struct Curl_easy *data);
/* 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 */
#define CF_CTRL_DATA_DONE 7 /* premature NULL ignored */
#define CF_CTRL_DATA_DONE_SEND 8 /* 0 NULL ignored */
/* update conn info at connection and data */
#define CF_CTRL_CONN_INFO_UPDATE (256+0) /* 0 NULL ignored */
/* report conn statistics (timers) for connection and data */
#define CF_CTRL_CONN_REPORT_STATS (256+1) /* 0 NULL ignored */
/**
* Handle event/control for the filter.
* Implementations MUST NOT chain calls to cf->next.
*/
typedef CURLcode Curl_cft_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
int event, int arg1, void *arg2);
/**
* Queries to ask via a `Curl_cft_query *query` method on a cfilter chain.
* - MAX_CONCURRENT: the maximum number of parallel transfers the filter
* chain expects to handle at the same time.
* default: 1 if no filter overrides.
* - CONNECT_REPLY_MS: milliseconds until the first indication of a server
* response was received on a connect. For TCP, this
* reflects the time until the socket connected. On UDP
* this gives the time the first bytes from the server
* were received.
* -1 if not determined yet.
* - CF_QUERY_SOCKET: the socket used by the filter chain
*/
/* query res1 res2 */
#define CF_QUERY_MAX_CONCURRENT 1 /* number - */
#define CF_QUERY_CONNECT_REPLY_MS 2 /* number - */
#define CF_QUERY_SOCKET 3 /* - curl_socket_t */
/**
* Query the cfilter for properties. Filters ignorant of a query will
* pass it "down" the filter chain.
*/
typedef CURLcode Curl_cft_query(struct Curl_cfilter *cf,
struct Curl_easy *data,
int query, int *pres1, void *pres2);
/**
* Type flags for connection filters. A filter can have none, one or
* many of those. Use to evaluate state/capabilities of a filter chain.
*
* CF_TYPE_IP_CONNECT: provides an IP connection or sth equivalent, like
* a CONNECT tunnel, a UNIX domain socket, a QUIC
* connection, etc.
* CF_TYPE_SSL: provide SSL/TLS
* CF_TYPE_MULTIPLEX: provides multiplexing of easy handles
*/
#define CF_TYPE_IP_CONNECT (1 << 0)
#define CF_TYPE_SSL (1 << 1)
#define CF_TYPE_MULTIPLEX (1 << 2)
/* A connection filter type, e.g. specific implementation. */
struct Curl_cftype {
const char *name; /* name of the filter type */
long flags; /* flags of filter type */
int flags; /* flags of filter type */
int log_level; /* log level for such filters */
Curl_cft_destroy_this *destroy; /* destroy resources of this cf */
Curl_cft_setup *setup; /* setup for a connection */
Curl_cft_connect *connect; /* establish connection */
Curl_cft_close *close; /* close conn */
Curl_cft_get_host *get_host; /* host filter talks to */
@@ -119,8 +174,10 @@ struct Curl_cftype {
Curl_cft_data_pending *has_data_pending;/* conn has data pending */
Curl_cft_send *do_send; /* send data */
Curl_cft_recv *do_recv; /* receive data */
Curl_cft_attach_data *attach_data; /* data is being handled here */
Curl_cft_detach_data *detach_data; /* data is no longer handled here */
Curl_cft_cntrl *cntrl; /* events/control */
Curl_cft_conn_is_alive *is_alive; /* FALSE if conn is dead, Jim! */
Curl_cft_conn_keep_alive *keep_alive; /* try to keep it alive */
Curl_cft_query *query; /* query filter chain */
};
/* A connection filter instance, e.g. registered at a connection */
@@ -129,7 +186,7 @@ struct Curl_cfilter {
struct Curl_cfilter *next; /* next filter in chain */
void *ctx; /* filter type specific settings */
struct connectdata *conn; /* the connection this filter belongs to */
int sockindex; /* TODO: like to get rid off this */
int sockindex; /* the index the filter is installed at */
BIT(connected); /* != 0 iff this filter is connected */
};
@@ -139,9 +196,6 @@ void Curl_cf_def_destroy_this(struct Curl_cfilter *cf,
/* Default implementations for the type functions, implementing pass-through
* the filter chain. */
CURLcode Curl_cf_def_setup(struct Curl_cfilter *cf,
struct Curl_easy *data,
const struct Curl_dns_entry *remotehost);
void Curl_cf_def_close(struct Curl_cfilter *cf, struct Curl_easy *data);
CURLcode Curl_cf_def_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
@@ -158,16 +212,22 @@ ssize_t Curl_cf_def_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err);
ssize_t Curl_cf_def_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err);
void Curl_cf_def_attach_data(struct Curl_cfilter *cf,
struct Curl_easy *data);
void Curl_cf_def_detach_data(struct Curl_cfilter *cf,
struct Curl_easy *data);
CURLcode Curl_cf_def_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
int event, int arg1, void *arg2);
bool Curl_cf_def_conn_is_alive(struct Curl_cfilter *cf,
struct Curl_easy *data);
CURLcode Curl_cf_def_conn_keep_alive(struct Curl_cfilter *cf,
struct Curl_easy *data);
CURLcode Curl_cf_def_query(struct Curl_cfilter *cf,
struct Curl_easy *data,
int query, int *pres1, void *pres2);
/**
* Create a new filter instance, unattached to the filter chain.
* Use Curl_conn_cf_add() to add it to the chain.
* @param pcf on success holds the created instance
* @parm cft the filter type
* @param cft the filter type
* @param ctx the type specific context to use
*/
CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
@@ -176,7 +236,7 @@ CURLcode Curl_cf_create(struct Curl_cfilter **pcf,
/**
* Add a filter instance to the `sockindex` filter chain at connection
* `data->conn`. The filter must not already be attached. It is inserted at
* `conn`. The filter must not already be attached. It is inserted at
* the start of the chain (top).
*/
void Curl_conn_cf_add(struct Curl_easy *data,
@@ -185,11 +245,11 @@ void Curl_conn_cf_add(struct Curl_easy *data,
struct Curl_cfilter *cf);
/**
* Remove and destroy all filters at chain `sockindex` on connection `conn`.
* Insert a filter (chain) after `cf_at`.
* `cf_new` must not already be attached.
*/
void Curl_conn_cf_discard_all(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
void Curl_conn_cf_insert_after(struct Curl_cfilter *cf_at,
struct Curl_cfilter *cf_new);
/**
* Discard, e.g. remove and destroy a specific filter instance.
@@ -198,28 +258,50 @@ void Curl_conn_cf_discard_all(struct Curl_easy *data,
*/
void Curl_conn_cf_discard(struct Curl_cfilter *cf, struct Curl_easy *data);
/**
* Discard all cfilters starting with `*pcf` and clearing it afterwards.
*/
void Curl_conn_cf_discard_chain(struct Curl_cfilter **pcf,
struct Curl_easy *data);
/**
* Remove and destroy all filters at chain `sockindex` on connection `conn`.
*/
void Curl_conn_cf_discard_all(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
CURLcode Curl_conn_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done);
void Curl_conn_cf_close(struct Curl_cfilter *cf, struct Curl_easy *data);
int Curl_conn_cf_get_select_socks(struct Curl_cfilter *cf,
struct Curl_easy *data,
curl_socket_t *socks);
bool Curl_conn_cf_data_pending(struct Curl_cfilter *cf,
const struct Curl_easy *data);
ssize_t Curl_conn_cf_send(struct Curl_cfilter *cf, struct Curl_easy *data,
const void *buf, size_t len, CURLcode *err);
ssize_t Curl_conn_cf_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
char *buf, size_t len, CURLcode *err);
CURLcode Curl_conn_cf_cntrl(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool ignore_result,
int event, int arg1, void *arg2);
/**
* Get the socket used by the filter chain starting at `cf`.
* Returns CURL_SOCKET_BAD if not available.
*/
curl_socket_t Curl_conn_cf_get_socket(struct Curl_cfilter *cf,
struct Curl_easy *data);
#define CURL_CF_SSL_DEFAULT -1
#define CURL_CF_SSL_DISABLE 0
#define CURL_CF_SSL_ENABLE 1
/**
* Setup the filter chain at `sockindex` in connection `conn`, invoking
* the instance `setup(remotehost)` methods. If no filter chain is
* installed yet, inspects the configuration in `data` to install a
* suitable filter chain.
*/
CURLcode Curl_conn_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost,
int ssl_mode);
/**
* Bring the filter chain at `sockindex` for connection `data->conn` into
* connected state. Which will set `*done` to TRUE.
@@ -248,7 +330,12 @@ bool Curl_conn_is_ip_connected(struct Curl_easy *data, int sockindex);
* (or will be once connected). This will return FALSE, if SSL
* is only used in proxying and not for the tunnel itself.
*/
bool Curl_conn_is_ssl(struct Curl_easy *data, int sockindex);
bool Curl_conn_is_ssl(struct connectdata *conn, int sockindex);
/**
* Connection provides multiplexing of easy handles at `socketindex`.
*/
bool Curl_conn_is_multiplex(struct connectdata *conn, int sockindex);
/**
* Close the filter chain at `sockindex` for connection `data->conn`.
@@ -263,6 +350,12 @@ void Curl_conn_close(struct Curl_easy *data, int sockindex);
bool Curl_conn_data_pending(struct Curl_easy *data,
int sockindex);
/**
* Return the socket used on data's connection for the index.
* Returns CURL_SOCKET_BAD if not available.
*/
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
/**
* Get any select fd flags and the socket filters at chain `sockindex`
* at connection `conn` might be waiting for.
@@ -289,13 +382,12 @@ ssize_t Curl_conn_send(struct Curl_easy *data, int sockindex,
const void *buf, size_t len, CURLcode *code);
/**
* The easy handle `data` is being attached (served) by connection `conn`.
* All filters are informed to adapt to handling `data`.
* Note: there may be several `data` attached to a connection at the same
* time.
* 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_attach_data(struct connectdata *conn,
struct Curl_easy *data);
void Curl_conn_ev_data_attach(struct connectdata *conn,
struct Curl_easy *data);
/**
* The easy handle `data` is being detached (no longer served)
@@ -304,12 +396,141 @@ void Curl_conn_attach_data(struct connectdata *conn,
* Note: there may be several `data` attached to a connection at the same
* time.
*/
void Curl_conn_detach_data(struct connectdata *conn,
struct Curl_easy *data);
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.
*/
CURLcode Curl_conn_ev_data_setup(struct Curl_easy *data);
/**
* Notify connection filters that now would be a good time to
* perform any idle, e.g. time related, actions.
*/
CURLcode Curl_conn_ev_data_idle(struct Curl_easy *data);
/**
* Notify connection filters that the transfer represented by `data`
* is donw with sending data (e.g. has uploaded everything).
*/
void Curl_conn_ev_data_done_send(struct Curl_easy *data);
/**
* Notify connection filters that the transfer represented by `data`
* is finished - eventually premature, e.g. before being complete.
*/
void Curl_conn_ev_data_done(struct Curl_easy *data, bool premature);
/**
* Notify connection filters that the transfer of data is paused/unpaused.
*/
CURLcode Curl_conn_ev_data_pause(struct Curl_easy *data, bool do_pause);
/**
* Inform connection filters to update their info in `conn`.
*/
void Curl_conn_ev_update_info(struct Curl_easy *data,
struct connectdata *conn);
/**
* Inform connection filters to report statistics.
*/
void Curl_conn_ev_report_stats(struct Curl_easy *data,
struct connectdata *conn);
/**
* Check if FIRSTSOCKET's cfilter chain deems connection alive.
*/
bool Curl_conn_is_alive(struct Curl_easy *data, struct connectdata *conn);
/**
* Try to upkeep the connection filters at sockindex.
*/
CURLcode Curl_conn_keep_alive(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
void Curl_conn_get_host(struct Curl_easy *data, int sockindex,
const char **phost, const char **pdisplay_host,
int *pport);
/**
* Get the maximum number of parallel transfers the connection
* expects to be able to handle at `sockindex`.
*/
size_t Curl_conn_get_max_concurrent(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
/**
* Types and macros used to keep the current easy handle in filter calls,
* allowing for nested invocations. See #10336.
*
* `cf_call_data` is intended to be a member of the cfilter's `ctx` type.
* A filter defines the macro `CF_CTX_CALL_DATA` to give access to that.
*
* With all values 0, the default, this indicates that there is no cfilter
* call with `data` ongoing.
* Macro `CF_DATA_SAVE` preserves the current `cf_call_data` in a local
* variable and sets the `data` given, incrementing the `depth` counter.
*
* Macro `CF_DATA_RESTORE` restores the old values from the local variable,
* while checking that `depth` values are as expected (debug build), catching
* cases where a "lower" RESTORE was not called.
*
* Finally, macro `CF_DATA_CURRENT` gives the easy handle of the current
* invocation.
*/
struct cf_call_data {
struct Curl_easy *data;
#ifdef DEBUGBUILD
int depth;
#endif
};
/**
* define to access the `struct cf_call_data for a cfilter. Normally
* a member in the cfilter's `ctx`.
*
* #define CF_CTX_CALL_DATA(cf) -> struct cf_call_data instance
*/
#ifdef DEBUGBUILD
#define CF_DATA_SAVE(save, cf, data) \
do { \
(save) = CF_CTX_CALL_DATA(cf); \
DEBUGASSERT((save).data == NULL || (save).depth > 0); \
CF_CTX_CALL_DATA(cf).depth++; \
CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
} while(0)
#define CF_DATA_RESTORE(cf, save) \
do { \
DEBUGASSERT(CF_CTX_CALL_DATA(cf).depth == (save).depth + 1); \
DEBUGASSERT((save).data == NULL || (save).depth > 0); \
CF_CTX_CALL_DATA(cf) = (save); \
} while(0)
#else /* DEBUGBUILD */
#define CF_DATA_SAVE(save, cf, data) \
do { \
(save) = CF_CTX_CALL_DATA(cf); \
CF_CTX_CALL_DATA(cf).data = (struct Curl_easy *)data; \
} while(0)
#define CF_DATA_RESTORE(cf, save) \
do { \
CF_CTX_CALL_DATA(cf) = (save); \
} while(0)
#endif /* !DEBUGBUILD */
#define CF_DATA_CURRENT(cf) \
((cf)? (CF_CTX_CALL_DATA(cf).data) : NULL)
#endif /* HEADER_CURL_CFILTERS_H */

View File

@@ -5,8 +5,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) Linus Nielsen Feltzing, <linus@haxx.se>
* 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

View File

@@ -7,8 +7,8 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2015 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) Linus Nielsen Feltzing, <linus@haxx.se>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -29,9 +29,7 @@
#include "sockaddr.h"
#include "timeval.h"
CURLcode Curl_connecthost(struct Curl_easy *data,
struct connectdata *conn,
const struct Curl_dns_entry *host);
struct Curl_dns_entry;
/* generic function that returns how much time there's left to run, according
to the timeouts set */
@@ -53,67 +51,8 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen,
char *addr, int *port);
/*
* Check if a connection seems to be alive.
*/
bool Curl_connalive(struct Curl_easy *data, struct connectdata *conn);
#ifdef USE_WINSOCK
/* When you run a program that uses the Windows Sockets API, you may
experience slow performance when you copy data to a TCP server.
https://support.microsoft.com/kb/823764
Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
Buffer Size
*/
void Curl_sndbufset(curl_socket_t sockfd);
#else
#define Curl_sndbufset(y) Curl_nop_stmt
#endif
void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sockfd);
void Curl_conninfo_remote(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sockfd);
void Curl_conninfo_local(struct Curl_easy *data, curl_socket_t sockfd,
char *local_ip, int *local_port);
void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn,
char *local_ip, int local_port);
int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn,
curl_socket_t sock);
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold any
* protocol-specific address structures. The variable declared here will be
* used to pass / receive data to/from the fopensocket callback if this has
* been set, before that, it is initialized from parameters.
*/
struct Curl_sockaddr_ex {
int family;
int socktype;
int protocol;
unsigned int addrlen;
union {
struct sockaddr addr;
struct Curl_sockaddr_storage buff;
} _sa_ex_u;
};
#define sa_addr _sa_ex_u.addr
/*
* Create a socket based on info from 'conn' and 'ai'.
*
* Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
* socket callback is set, used that!
*
*/
CURLcode Curl_socket(struct Curl_easy *data,
const struct Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
/*
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
@@ -148,13 +87,71 @@ void Curl_conncontrol(struct connectdata *conn,
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
#endif
CURLcode Curl_conn_socket_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
/**
* Create a cfilter for making an "ip" connection to the
* given address, using parameters from `conn`. The "ip" connection
* can be a TCP socket, a UDP socket or even a QUIC connection.
*
* It MUST use only the supplied `ai` for its connection attempt.
*
* Such a filter may be used in "happy eyeball" scenarios, and its
* `connect` implementation needs to support non-blocking. Once connected,
* it MAY be installed in the connection filter chain to serve transfers.
*/
typedef CURLcode cf_ip_connect_create(struct Curl_cfilter **pcf,
struct Curl_easy *data,
struct connectdata *conn,
const struct Curl_addrinfo *ai,
int transport);
CURLcode Curl_conn_socket_accepted_set(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
curl_socket_t *s);
/**
* Create a happy eyeball connection filter that uses the, once resolved,
* address information to connect on ip families based on connection
* configuration.
* @param pcf output, the created cfilter
* @param data easy handle used in creation
* @param conn connection the filter is created for
* @param cf_create method to create the sub-filters performing the
* actual connects.
*/
CURLcode
Curl_cf_happy_eyeballs_create(struct Curl_cfilter **pcf,
struct Curl_easy *data,
struct connectdata *conn,
cf_ip_connect_create *cf_create,
const struct Curl_dns_entry *remotehost,
int transport);
CURLcode Curl_cf_setup_add(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost,
int transport,
int ssl_mode);
CURLcode Curl_cf_setup_insert_after(struct Curl_cfilter *cf_at,
struct Curl_easy *data,
const struct Curl_dns_entry *remotehost,
int transport,
int ssl_mode);
/**
* Setup the cfilters at `sockindex` in connection `conn`.
* If no filter chain is installed yet, inspects the configuration
* in `data` and `conn? to install a suitable filter chain.
*/
CURLcode Curl_conn_setup(struct Curl_easy *data,
struct connectdata *conn,
int sockindex,
const struct Curl_dns_entry *remotehost,
int ssl_mode);
extern struct Curl_cftype Curl_cft_happy_eyeballs;
extern struct Curl_cftype Curl_cft_setup;
#ifdef DEBUGBUILD
void Curl_debug_set_transport_provider(int transport,
cf_ip_connect_create *cf_create);
#endif
#endif /* HEADER_CURL_CONNECT_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -977,7 +977,8 @@ static const struct content_encoding error_encoding = {
static struct contenc_writer *
new_unencoding_writer(struct Curl_easy *data,
const struct content_encoding *handler,
struct contenc_writer *downstream)
struct contenc_writer *downstream,
int order)
{
struct contenc_writer *writer;
@@ -987,6 +988,7 @@ new_unencoding_writer(struct Curl_easy *data,
if(writer) {
writer->handler = handler;
writer->downstream = downstream;
writer->order = order;
if(handler->init_writer(data, writer)) {
free(writer);
writer = NULL;
@@ -1042,10 +1044,10 @@ static const struct content_encoding *find_encoding(const char *name,
/* Set-up the unencoding stack from the Content-Encoding header value.
* See RFC 7231 section 3.1.2.2. */
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
const char *enclist, int maybechunked)
const char *enclist, int is_transfer)
{
struct SingleRequest *k = &data->req;
int counter = 0;
unsigned int order = is_transfer? 2: 1;
do {
const char *name;
@@ -1062,7 +1064,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
namelen = enclist - name + 1;
/* Special case: chunked encoding is handled at the reader level. */
if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) {
if(is_transfer && namelen == 7 && strncasecompare(name, "chunked", 7)) {
k->chunk = TRUE; /* chunks coming our way. */
Curl_httpchunk_init(data); /* init our chunky engine. */
}
@@ -1071,7 +1073,8 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
struct contenc_writer *writer;
if(!k->writer_stack) {
k->writer_stack = new_unencoding_writer(data, &client_encoding, NULL);
k->writer_stack = new_unencoding_writer(data, &client_encoding,
NULL, 0);
if(!k->writer_stack)
return CURLE_OUT_OF_MEMORY;
@@ -1080,16 +1083,29 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
if(!encoding)
encoding = &error_encoding; /* Defer error at stack use. */
if(++counter >= MAX_ENCODE_STACK) {
failf(data, "Reject response due to %u content encodings",
counter);
if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) {
failf(data, "Reject response due to more than %u content encodings",
MAX_ENCODE_STACK);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Stack the unencoding stage. */
writer = new_unencoding_writer(data, encoding, k->writer_stack);
if(!writer)
return CURLE_OUT_OF_MEMORY;
k->writer_stack = writer;
if(order >= k->writer_stack->order) {
writer = new_unencoding_writer(data, encoding,
k->writer_stack, order);
if(!writer)
return CURLE_OUT_OF_MEMORY;
k->writer_stack = writer;
}
else {
struct contenc_writer *w = k->writer_stack;
while(w->downstream && order < w->downstream->order)
w = w->downstream;
writer = new_unencoding_writer(data, encoding,
w->downstream, order);
if(!writer)
return CURLE_OUT_OF_MEMORY;
w->downstream = writer;
}
}
} while(*enclist);
@@ -1099,11 +1115,11 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
#else
/* Stubs for builds without HTTP. */
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
const char *enclist, int maybechunked)
const char *enclist, int is_transfer)
{
(void) data;
(void) enclist;
(void) maybechunked;
(void) is_transfer;
return CURLE_NOT_BUILT_IN;
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -28,6 +28,7 @@
struct contenc_writer {
const struct content_encoding *handler; /* Encoding handler. */
struct contenc_writer *downstream; /* Downstream writer. */
unsigned int order; /* Ordering within writer stack. */
};
/* Content encoding writer. */
@@ -46,7 +47,7 @@ struct content_encoding {
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
const char *enclist, int maybechunked);
const char *enclist, int is_transfer);
CURLcode Curl_unencode_write(struct Curl_easy *data,
struct contenc_writer *writer,
const char *buf, size_t nbytes);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -329,7 +329,7 @@ static char *sanitize_cookie_path(const char *cookie_path)
*/
void Curl_cookie_loadfiles(struct Curl_easy *data)
{
struct curl_slist *list = data->state.cookielist;
struct curl_slist *list = data->set.cookielist;
if(list) {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
while(list) {
@@ -347,8 +347,6 @@ void Curl_cookie_loadfiles(struct Curl_easy *data)
data->cookies = newcookies;
list = list->next;
}
curl_slist_free_all(data->state.cookielist); /* clean up list */
data->state.cookielist = NULL; /* don't do this again! */
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
}
}
@@ -1301,7 +1299,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
*/
remove_expired(c);
if(fromfile && fp)
if(fromfile)
fclose(fp);
}
@@ -1800,12 +1798,10 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
CURLcode res;
if(data->set.str[STRING_COOKIEJAR]) {
if(data->state.cookielist) {
/* If there is a list of cookie files to read, do it first so that
we have all the told files read before we write the new jar.
Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
Curl_cookie_loadfiles(data);
}
/* If there is a list of cookie files to read, do it first so that
we have all the told files read before we write the new jar.
Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
Curl_cookie_loadfiles(data);
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
@@ -1816,12 +1812,6 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup)
data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res));
}
else {
if(cleanup && data->state.cookielist) {
/* since nothing is written, we can just free the list of cookie file
names */
curl_slist_free_all(data->state.cookielist); /* clean up list */
data->state.cookielist = NULL;
}
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -27,7 +27,7 @@
#define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f'))
#define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F'))
#define ISLOWCNTRL(x) ((x) >= 0 && ((x) <= 0x1f))
#define ISLOWCNTRL(x) ((unsigned char)(x) <= 0x1f)
#define IS7F(x) ((x) == 0x7f)
#define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d))

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2015 - 2022, Steve Holme, <steve_holme@hotmail.com>.
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2015 - 2022, Steve Holme, <steve_holme@hotmail.com>.
* Copyright (C) Steve Holme, <steve_holme@hotmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2011 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2011 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -0,0 +1,223 @@
/***************************************************************************
* _ _ ____ _
* 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
*
***************************************************************************/
#include "curl_setup.h"
#include <curl/curl.h>
#include "curl_log.h"
#include "urldata.h"
#include "easyif.h"
#include "cfilters.h"
#include "timeval.h"
#include "multiif.h"
#include "strcase.h"
#include "cf-socket.h"
#include "connect.h"
#include "http2.h"
#include "http_proxy.h"
#include "cf-http.h"
#include "socks.h"
#include "strtok.h"
#include "vtls/vtls.h"
#include "vquic/vquic.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
void Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size)
{
if(data->set.verbose) {
static const char s_infotype[CURLINFO_END][3] = {
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
if(data->set.fdebug) {
bool inCallback = Curl_is_in_callback(data);
Curl_set_in_callback(data, true);
(void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
Curl_set_in_callback(data, inCallback);
}
else {
switch(type) {
case CURLINFO_TEXT:
case CURLINFO_HEADER_OUT:
case CURLINFO_HEADER_IN:
fwrite(s_infotype[type], 2, 1, data->set.err);
fwrite(ptr, size, 1, data->set.err);
break;
default: /* nada */
break;
}
}
}
}
/* Curl_failf() is for messages stating why we failed.
* The message SHALL NOT include any LF or CR.
*/
void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
{
DEBUGASSERT(!strchr(fmt, '\n'));
if(data->set.verbose || data->set.errorbuffer) {
va_list ap;
int len;
char error[CURL_ERROR_SIZE + 2];
va_start(ap, fmt);
len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
if(data->set.errorbuffer && !data->state.errorbuf) {
strcpy(data->set.errorbuffer, error);
data->state.errorbuf = TRUE; /* wrote error string */
}
error[len++] = '\n';
error[len] = '\0';
Curl_debug(data, CURLINFO_TEXT, error, len);
va_end(ap);
}
}
/* Curl_infof() is for info message along the way */
#define MAXINFO 2048
void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
{
DEBUGASSERT(!strchr(fmt, '\n'));
if(data && data->set.verbose) {
va_list ap;
int len;
char buffer[MAXINFO + 2];
va_start(ap, fmt);
len = mvsnprintf(buffer, MAXINFO, fmt, ap);
va_end(ap);
buffer[len++] = '\n';
buffer[len] = '\0';
Curl_debug(data, CURLINFO_TEXT, buffer, len);
}
}
#ifdef DEBUGBUILD
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...)
{
DEBUGASSERT(cf);
if(data && Curl_log_cf_is_debug(cf)) {
va_list ap;
int len;
char buffer[MAXINFO + 2];
len = msnprintf(buffer, MAXINFO, "[CONN-%ld%s-%s] ",
cf->conn->connection_id, cf->sockindex? "/2" : "",
cf->cft->name);
va_start(ap, fmt);
len += mvsnprintf(buffer + len, MAXINFO - len, fmt, ap);
va_end(ap);
buffer[len++] = '\n';
buffer[len] = '\0';
Curl_debug(data, CURLINFO_TEXT, buffer, len);
}
}
static struct Curl_cftype *cf_types[] = {
&Curl_cft_tcp,
&Curl_cft_udp,
&Curl_cft_unix,
&Curl_cft_tcp_accept,
&Curl_cft_happy_eyeballs,
&Curl_cft_setup,
#ifdef USE_NGHTTP2
&Curl_cft_nghttp2,
#endif
#ifdef USE_SSL
&Curl_cft_ssl,
&Curl_cft_ssl_proxy,
#endif
#if !defined(CURL_DISABLE_PROXY)
#if !defined(CURL_DISABLE_HTTP)
&Curl_cft_http_proxy,
#endif /* !CURL_DISABLE_HTTP */
&Curl_cft_haproxy,
&Curl_cft_socks_proxy,
#endif /* !CURL_DISABLE_PROXY */
#ifdef ENABLE_QUIC
&Curl_cft_http3,
#endif
#if !defined(CURL_DISABLE_HTTP) && !defined(USE_HYPER)
&Curl_cft_http_connect,
#endif
NULL,
};
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
CURLcode Curl_log_init(void)
{
const char *setting = getenv("CURL_DEBUG");
if(setting) {
char *token, *tok_buf, *tmp;
size_t i;
tmp = strdup(setting);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
token = strtok_r(tmp, ", ", &tok_buf);
while(token) {
for(i = 0; cf_types[i]; ++i) {
if(strcasecompare(token, cf_types[i]->name)) {
cf_types[i]->log_level = CURL_LOG_DEBUG;
break;
}
}
token = strtok_r(NULL, ", ", &tok_buf);
}
free(tmp);
}
return CURLE_OK;
}
#else /* DEBUGBUILD */
CURLcode Curl_log_init(void)
{
return CURLE_OK;
}
#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...)
{
(void)data;
(void)cf;
(void)fmt;
}
#endif
#endif /* !DEBUGBUILD */

View File

@@ -0,0 +1,138 @@
#ifndef HEADER_CURL_LOG_H
#define HEADER_CURL_LOG_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.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
*
***************************************************************************/
struct Curl_easy;
struct Curl_cfilter;
/**
* Init logging, return != 0 on failure.
*/
CURLcode Curl_log_init(void);
void Curl_infof(struct Curl_easy *, const char *fmt, ...);
void Curl_failf(struct Curl_easy *, const char *fmt, ...);
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
#if defined(HAVE_VARIADIC_MACROS_C99)
#define infof(...) Curl_nop_stmt
#elif defined(HAVE_VARIADIC_MACROS_GCC)
#define infof(x...) Curl_nop_stmt
#else
#error "missing VARIADIC macro define, fix and rebuild!"
#endif
#else /* CURL_DISABLE_VERBOSE_STRINGS */
#define infof Curl_infof
#endif /* CURL_DISABLE_VERBOSE_STRINGS */
#define failf Curl_failf
#define CURL_LOG_DEFAULT 0
#define CURL_LOG_DEBUG 1
#define CURL_LOG_TRACE 2
/* the function used to output verbose information */
void Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size);
#ifdef DEBUGBUILD
/* explainer: we have some mix configuration and werror settings
* that define HAVE_VARIADIC_MACROS_C99 even though C89 is enforced
* on gnuc and some other compiler. Need to treat carefully.
*/
#if defined(HAVE_VARIADIC_MACROS_C99) && \
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define LOG_CF(data, cf, ...) \
do { if(Curl_log_cf_is_debug(cf)) \
Curl_log_cf_debug(data, cf, __VA_ARGS__); } while(0)
#else
#define LOG_CF Curl_log_cf_debug
#endif
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
#if defined(__GNUC__) && !defined(printf) && \
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(__MINGW32__)
const char *fmt, ...)
__attribute__((format(printf, 3, 4)));
#else
const char *fmt, ...);
#endif
#define Curl_log_cf_is_debug(cf) \
((cf) && (cf)->cft->log_level >= CURL_LOG_DEBUG)
#else /* !DEBUGBUILD */
#if defined(HAVE_VARIADIC_MACROS_C99) && \
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define LOG_CF(...) Curl_nop_stmt
#define Curl_log_cf_debug(...) Curl_nop_stmt
#elif defined(HAVE_VARIADIC_MACROS_GCC) && \
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define LOG_CF(x...) Curl_nop_stmt
#define Curl_log_cf_debug(x...) Curl_nop_stmt
#else
#define LOG_CF Curl_log_cf_debug
/* without c99, we seem unable to completely define away this function. */
void Curl_log_cf_debug(struct Curl_easy *data, struct Curl_cfilter *cf,
const char *fmt, ...);
#endif
#define Curl_log_cf_is_debug(x) ((void)(x), FALSE)
#endif /* !DEBUGBUILD */
#define LOG_CF_IS_DEBUG(x) Curl_log_cf_is_debug(x)
/* Macros intended for DEBUGF logging, use like:
* DEBUGF(infof(data, CFMSG(cf, "this filter %s rocks"), "very much"));
* and it will output:
* [CONN-1-0][CF-SSL] this filter very much rocks
* on connection #1 with sockindex 0 for filter of type "SSL". */
#define DMSG(d,msg) \
"[CONN-%ld] "msg, (d)->conn->connection_id
#define DMSGI(d,i,msg) \
"[CONN-%ld-%d] "msg, (d)->conn->connection_id, (i)
#define CMSG(c,msg) \
"[CONN-%ld] "msg, (c)->connection_id
#define CMSGI(c,i,msg) \
"[CONN-%ld-%d] "msg, (c)->connection_id, (i)
#define CFMSG(cf,msg) \
"[CONN-%ld-%d][CF-%s] "msg, (cf)->conn->connection_id, \
(cf)->sockindex, (cf)->cft->name
#endif /* HEADER_CURL_LOG_H */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -36,12 +36,13 @@
/* Please keep the SSL backend-specific #if branches in this order:
1. USE_OPENSSL
2. USE_GNUTLS
3. USE_NSS
4. USE_MBEDTLS
5. USE_SECTRANSP
6. USE_OS400CRYPTO
7. USE_WIN32_CRYPTO
2. USE_WOLFSSL
3. USE_GNUTLS
4. USE_NSS
5. USE_MBEDTLS
6. USE_SECTRANSP
7. USE_OS400CRYPTO
8. USE_WIN32_CRYPTO
This ensures that:
- the same SSL branch gets activated throughout this source

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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
@@ -37,11 +37,11 @@
#define NTLM_NEEDS_NSS_INIT
#endif
#ifdef USE_WOLFSSL
#if defined(USE_OPENSSL)
# include <openssl/ssl.h>
#elif defined(USE_WOLFSSL)
# include <wolfssl/options.h>
# include <wolfssl/openssl/ssl.h>
#elif defined(USE_OPENSSL)
# include <openssl/ssl.h>
#endif
/* Helpers to generate function byte arguments in little endian order */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
* 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

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