mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
curl 2020-08-19 (9d954e49)
Code extracted from:
https://github.com/curl/curl.git
at commit 9d954e49bce3706a9a2efb119ecd05767f0f2a9e (curl-7_72_0).
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindZstd
|
||||
----------
|
||||
|
||||
Find the zstd library
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
``Zstd_FOUND``
|
||||
System has zstd
|
||||
``Zstd_INCLUDE_DIRS``
|
||||
The zstd include directories.
|
||||
``Zstd_LIBRARIES``
|
||||
The libraries needed to use zstd
|
||||
#]=======================================================================]
|
||||
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(PC_Zstd libzstd)
|
||||
endif()
|
||||
|
||||
find_path(Zstd_INCLUDE_DIR zstd.h
|
||||
HINTS
|
||||
${PC_Zstd_INCLUDEDIR}
|
||||
${PC_Zstd_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(Zstd_LIBRARY NAMES zstd
|
||||
HINTS
|
||||
${PC_Zstd_LIBDIR}
|
||||
${PC_Zstd_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Zstd
|
||||
REQUIRED_VARS
|
||||
Zstd_LIBRARY
|
||||
Zstd_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if(Zstd_FOUND)
|
||||
set(Zstd_LIBRARIES ${Zstd_LIBRARY})
|
||||
set(Zstd_INCLUDE_DIRS ${Zstd_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(Zstd_INCLUDE_DIRS Zstd_LIBRARIES)
|
||||
+46
-10
@@ -82,12 +82,15 @@ 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}")
|
||||
elseif(ENABLE_INET_PTON)
|
||||
# _WIN32_WINNT_VISTA (0x0600)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=0x0600")
|
||||
else()
|
||||
# _WIN32_WINNT_WINXP (0x0501)
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WIN32_WINNT=0x0501")
|
||||
endif()
|
||||
endif()
|
||||
option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF)
|
||||
@@ -101,7 +104,7 @@ option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OF
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
|
||||
if(PICKY_COMPILER)
|
||||
foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers -Wno-pedantic-ms-format)
|
||||
foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wfloat-equal -Wsign-compare -Wundef -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wvla -Wdouble-promotion)
|
||||
# surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
|
||||
# test result in.
|
||||
string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
|
||||
@@ -110,6 +113,15 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(_CCOPT long-long multichar format-nonliteral sign-conversion system-headers pedantic-ms-format)
|
||||
# GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
|
||||
# so test for the positive form instead
|
||||
string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
|
||||
check_c_compiler_flag("-W${_CCOPT}" ${_optvarname})
|
||||
if(${_optvarname})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-${_CCOPT}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -213,7 +225,10 @@ if(ENABLE_IPV6 AND NOT WIN32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
curl_nroff_check()
|
||||
if(USE_MANUAL)
|
||||
#nroff is currently only used when USE_MANUAL is set, so we can prevent the warning of no *NROFF if USE_MANUAL is OFF (or not defined), by not even looking for NROFF..
|
||||
curl_nroff_check()
|
||||
endif()
|
||||
find_package(Perl)
|
||||
|
||||
cmake_dependent_option(ENABLE_MANUAL "to provide the built-in manual"
|
||||
@@ -297,14 +312,17 @@ endif()
|
||||
|
||||
# check SSL libraries
|
||||
# TODO support GnuTLS
|
||||
if(CMAKE_USE_WINSSL)
|
||||
message(FATAL_ERROR "The cmake option CMAKE_USE_WINSSL was renamed to CMAKE_USE_SCHANNEL.")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
option(CMAKE_USE_SECTRANSP "enable Apple OS native SSL/TLS" OFF)
|
||||
endif()
|
||||
if(WIN32)
|
||||
option(CMAKE_USE_WINSSL "enable Windows native SSL/TLS" OFF)
|
||||
option(CMAKE_USE_SCHANNEL "enable Windows native SSL/TLS" OFF)
|
||||
cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without openssl" ON
|
||||
CMAKE_USE_WINSSL OFF)
|
||||
CMAKE_USE_SCHANNEL OFF)
|
||||
endif()
|
||||
option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
|
||||
option(CMAKE_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF)
|
||||
@@ -312,13 +330,13 @@ option(CMAKE_USE_NSS "Enable NSS for SSL/TLS" OFF)
|
||||
option(CMAKE_USE_WOLFSSL "enable wolfSSL for SSL/TLS" OFF)
|
||||
|
||||
set(openssl_default ON)
|
||||
if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS OR CMAKE_USE_NSS OR CMAKE_USE_WOLFSSL)
|
||||
if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_SCHANNEL OR CMAKE_USE_MBEDTLS OR CMAKE_USE_NSS OR CMAKE_USE_WOLFSSL)
|
||||
set(openssl_default OFF)
|
||||
endif()
|
||||
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
|
||||
|
||||
count_true(enabled_ssl_options_count
|
||||
CMAKE_USE_WINSSL
|
||||
CMAKE_USE_SCHANNEL
|
||||
CMAKE_USE_SECTRANSP
|
||||
CMAKE_USE_OPENSSL
|
||||
CMAKE_USE_MBEDTLS
|
||||
@@ -330,10 +348,10 @@ if(enabled_ssl_options_count GREATER "1")
|
||||
set(CURL_WITH_MULTI_SSL ON)
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_WINSSL)
|
||||
if(CMAKE_USE_SCHANNEL)
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_SCHANNEL ON) # Windows native SSL/TLS support
|
||||
set(USE_WINDOWS_SSPI ON) # CMAKE_USE_WINSSL implies CURL_WINDOWS_SSPI
|
||||
set(USE_WINDOWS_SSPI ON) # CMAKE_USE_SCHANNEL implies CURL_WINDOWS_SSPI
|
||||
list(APPEND CURL_LIBS "crypt32")
|
||||
endif()
|
||||
if(CURL_WINDOWS_SSPI)
|
||||
@@ -638,6 +656,22 @@ if(CURL_BROTLI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CURL_ZSTD "Set to ON to enable building curl with zstd support." OFF)
|
||||
set(HAVE_ZSTD OFF)
|
||||
if(CURL_ZSTD)
|
||||
find_package(Zstd REQUIRED)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${Zstd_INCLUDE_DIRS})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${Zstd_LIBRARIES})
|
||||
check_symbol_exists(ZSTD_createDStream "zstd.h" HAVE_ZSTD_CREATEDSTREAM)
|
||||
cmake_pop_check_state()
|
||||
if(Zstd_FOUND AND HAVE_ZSTD_CREATEDSTREAM)
|
||||
set(HAVE_ZSTD ON)
|
||||
list(APPEND CURL_LIBS ${Zstd_LIBRARIES})
|
||||
include_directories(${Zstd_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#libSSH2
|
||||
option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON)
|
||||
mark_as_advanced(CMAKE_USE_LIBSSH2)
|
||||
@@ -1319,11 +1353,13 @@ _add_if("SSL" SSL_ENABLED)
|
||||
_add_if("IPv6" ENABLE_IPV6)
|
||||
_add_if("unix-sockets" USE_UNIX_SOCKETS)
|
||||
_add_if("libz" HAVE_LIBZ)
|
||||
_add_if("brotli" HAVE_BROTLI)
|
||||
_add_if("zstd" HAVE_ZSTD)
|
||||
_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
|
||||
_add_if("IDN" HAVE_LIBIDN2)
|
||||
_add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
|
||||
((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
|
||||
# TODO SSP1 (WinSSL) check is missing
|
||||
# TODO SSP1 (Schannel) check is missing
|
||||
_add_if("SSPI" USE_WINDOWS_SSPI)
|
||||
_add_if("GSS-API" HAVE_GSSAPI)
|
||||
_add_if("alt-svc" ENABLE_ALT_SVC)
|
||||
@@ -1385,7 +1421,7 @@ message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
|
||||
|
||||
# Clear list and collect SSL backends
|
||||
set(_items)
|
||||
_add_if("WinSSL" SSL_ENABLED AND USE_WINDOWS_SSPI)
|
||||
_add_if("Schannel" SSL_ENABLED AND USE_WINDOWS_SSPI)
|
||||
_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL)
|
||||
_add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
|
||||
_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS)
|
||||
|
||||
+11
-6
@@ -2634,10 +2634,6 @@ typedef enum {
|
||||
CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
|
||||
CURLINFO_PROTOCOL = CURLINFO_LONG + 48,
|
||||
CURLINFO_SCHEME = CURLINFO_STRING + 49,
|
||||
/* Fill in new entries below here! */
|
||||
|
||||
/* Preferably these would be defined conditionally based on the
|
||||
sizeof curl_off_t being 64-bits */
|
||||
CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50,
|
||||
CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51,
|
||||
CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52,
|
||||
@@ -2646,8 +2642,9 @@ typedef enum {
|
||||
CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55,
|
||||
CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
|
||||
CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57,
|
||||
CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58,
|
||||
|
||||
CURLINFO_LASTONE = 57
|
||||
CURLINFO_LASTONE = 58
|
||||
} CURLINFO;
|
||||
|
||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||
@@ -2748,6 +2745,7 @@ typedef enum {
|
||||
CURLVERSION_FIFTH,
|
||||
CURLVERSION_SIXTH,
|
||||
CURLVERSION_SEVENTH,
|
||||
CURLVERSION_EIGHTH,
|
||||
CURLVERSION_LAST /* never actually use this */
|
||||
} CURLversion;
|
||||
|
||||
@@ -2756,7 +2754,7 @@ typedef enum {
|
||||
meant to be a built-in version number for what kind of struct the caller
|
||||
expects. If the struct ever changes, we redefine the NOW to another enum
|
||||
from above. */
|
||||
#define CURLVERSION_NOW CURLVERSION_SEVENTH
|
||||
#define CURLVERSION_NOW CURLVERSION_EIGHTH
|
||||
|
||||
struct curl_version_info_data {
|
||||
CURLversion age; /* age of the returned struct */
|
||||
@@ -2802,6 +2800,11 @@ struct curl_version_info_data {
|
||||
const char *capath; /* the built-in default CURLOPT_CAPATH, might
|
||||
be NULL */
|
||||
|
||||
/* These fields were added in CURLVERSION_EIGHTH */
|
||||
unsigned int zstd_ver_num; /* Numeric Zstd version
|
||||
(MAJOR << 24) | (MINOR << 12) | PATCH */
|
||||
const char *zstd_version; /* human readable string. */
|
||||
|
||||
};
|
||||
typedef struct curl_version_info_data curl_version_info_data;
|
||||
|
||||
@@ -2836,6 +2839,8 @@ typedef struct curl_version_info_data curl_version_info_data;
|
||||
#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */
|
||||
#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
|
||||
#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */
|
||||
#define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */
|
||||
#define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.71.1-DEV"
|
||||
#define LIBCURL_VERSION "7.72.0-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 71
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
#define LIBCURL_VERSION_MINOR 72
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -57,7 +57,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 0x074701
|
||||
#define LIBCURL_VERSION_NUM 0x074800
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -427,12 +427,14 @@ CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
* Name: curl_push_callback
|
||||
*
|
||||
* Desc: This callback gets called when a new stream is being pushed by the
|
||||
* server. It approves or denies the new stream.
|
||||
* server. It approves or denies the new stream. It can also decide
|
||||
* to completely fail the connection.
|
||||
*
|
||||
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
|
||||
* Returns: CURL_PUSH_OK, CURL_PUSH_DENY or CURL_PUSH_ERROROUT
|
||||
*/
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
#define CURL_PUSH_ERROROUT 2 /* added in 7.72.0 */
|
||||
|
||||
struct curl_pushheaders; /* forward declaration only */
|
||||
|
||||
|
||||
+3
-2
@@ -60,7 +60,8 @@ LIB_CFILES = altsvc.c amigaos.c asyn-ares.c asyn-thread.c base64.c \
|
||||
sendf.c setopt.c sha256.c share.c slist.c smb.c smtp.c socketpair.c socks.c \
|
||||
socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c strdup.c \
|
||||
strerror.c strtok.c strtoofft.c system_win32.c telnet.c tftp.c timeval.c \
|
||||
transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c
|
||||
transfer.c urlapi.c version.c warnless.c wildcard.c x509asn1.c dynbuf.c \
|
||||
version_win32.c
|
||||
|
||||
LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
|
||||
content_encoding.h cookie.h curl_addrinfo.h curl_base64.h curl_ctype.h \
|
||||
@@ -79,7 +80,7 @@ LIB_HFILES = altsvc.h amigaos.h arpa_telnet.h asyn.h conncache.h connect.h \
|
||||
smb.h smtp.h sockaddr.h socketpair.h socks.h speedcheck.h splay.h strcase.h \
|
||||
strdup.h strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \
|
||||
timeval.h transfer.h urlapi-int.h urldata.h warnless.h wildcard.h \
|
||||
x509asn1.h dynbuf.h
|
||||
x509asn1.h dynbuf.h version_win32.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
|
||||
+4
-4
@@ -633,7 +633,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
#ifdef ENABLE_IPV6
|
||||
switch(conn->ip_version) {
|
||||
default:
|
||||
#if ARES_VERSION >= 0x010601
|
||||
@@ -649,7 +649,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
family = PF_INET6;
|
||||
break;
|
||||
}
|
||||
#endif /* CURLRES_IPV6 */
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
||||
bufp = strdup(hostname);
|
||||
if(bufp) {
|
||||
@@ -670,7 +670,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
/* initial status - failed */
|
||||
res->last_status = ARES_ENOTFOUND;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
#ifdef ENABLE_IPV6
|
||||
if(family == PF_UNSPEC) {
|
||||
if(Curl_ipv6works(conn)) {
|
||||
res->num_pending = 2;
|
||||
@@ -690,7 +690,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
#endif /* ENABLE_IPV6 */
|
||||
{
|
||||
res->num_pending = 1;
|
||||
|
||||
|
||||
@@ -164,7 +164,6 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
#define Curl_resolver_kill(x) Curl_nop_stmt
|
||||
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_getsock(x,y,z) 0
|
||||
#define Curl_resolver_duphandle(x,y,z) CURLE_OK
|
||||
#define Curl_resolver_init(x,y) CURLE_OK
|
||||
#define Curl_resolver_global_init() CURLE_OK
|
||||
|
||||
+15
-14
@@ -74,7 +74,7 @@
|
||||
#include "warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "system_win32.h"
|
||||
#include "version_win32.h"
|
||||
#include "quic.h"
|
||||
#include "socks.h"
|
||||
|
||||
@@ -934,10 +934,10 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
infof(data, "Connection failed\n");
|
||||
}
|
||||
else if(rc & CURL_CSELECT_ERR)
|
||||
else if(rc & CURL_CSELECT_ERR) {
|
||||
(void)verifyconnect(conn->tempsock[i], &error);
|
||||
}
|
||||
|
||||
/*
|
||||
* The connection failed here, we should attempt to connect to the "next
|
||||
@@ -1085,8 +1085,8 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
static int detectOsState = DETECT_OS_NONE;
|
||||
|
||||
if(detectOsState == DETECT_OS_NONE) {
|
||||
if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL))
|
||||
if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL))
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
else
|
||||
detectOsState = DETECT_OS_PREVISTA;
|
||||
@@ -1363,15 +1363,15 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
|
||||
struct connfind {
|
||||
struct connectdata *tofind;
|
||||
bool found;
|
||||
long id_tofind;
|
||||
struct connectdata *found;
|
||||
};
|
||||
|
||||
static int conn_is_conn(struct connectdata *conn, void *param)
|
||||
{
|
||||
struct connfind *f = (struct connfind *)param;
|
||||
if(conn == f->tofind) {
|
||||
f->found = TRUE;
|
||||
if(conn->connection_id == f->id_tofind) {
|
||||
f->found = conn;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1393,21 +1393,22 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
||||
* - that is associated with a multi handle, and whose connection
|
||||
* was detached with CURLOPT_CONNECT_ONLY
|
||||
*/
|
||||
if(data->state.lastconnect && (data->multi_easy || data->multi)) {
|
||||
struct connectdata *c = data->state.lastconnect;
|
||||
if((data->state.lastconnect_id != -1) && (data->multi_easy || data->multi)) {
|
||||
struct connectdata *c;
|
||||
struct connfind find;
|
||||
find.tofind = data->state.lastconnect;
|
||||
find.found = FALSE;
|
||||
find.id_tofind = data->state.lastconnect_id;
|
||||
find.found = NULL;
|
||||
|
||||
Curl_conncache_foreach(data, data->multi_easy?
|
||||
&data->multi_easy->conn_cache:
|
||||
&data->multi->conn_cache, &find, conn_is_conn);
|
||||
|
||||
if(!find.found) {
|
||||
data->state.lastconnect = NULL;
|
||||
data->state.lastconnect_id = -1;
|
||||
return CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
c = find.found;
|
||||
if(connp) {
|
||||
/* only store this if the caller cares for it */
|
||||
*connp = c;
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include <brotli/decode.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
#include "sendf.h"
|
||||
#include "http.h"
|
||||
#include "content_encoding.h"
|
||||
@@ -710,6 +714,95 @@ static const struct content_encoding brotli_encoding = {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
/* Writer parameters. */
|
||||
struct zstd_params {
|
||||
ZSTD_DStream *zds; /* State structure for zstd. */
|
||||
void *decomp;
|
||||
};
|
||||
|
||||
static CURLcode zstd_init_writer(struct connectdata *conn,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
struct zstd_params *zp = (struct zstd_params *)&writer->params;
|
||||
(void)conn;
|
||||
|
||||
if(!writer->downstream)
|
||||
return CURLE_WRITE_ERROR;
|
||||
|
||||
zp->zds = ZSTD_createDStream();
|
||||
zp->decomp = NULL;
|
||||
return zp->zds ? CURLE_OK : CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
static CURLcode zstd_unencode_write(struct connectdata *conn,
|
||||
struct contenc_writer *writer,
|
||||
const char *buf, size_t nbytes)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct zstd_params *zp = (struct zstd_params *)&writer->params;
|
||||
ZSTD_inBuffer in;
|
||||
ZSTD_outBuffer out;
|
||||
size_t errorCode;
|
||||
|
||||
if(!zp->decomp) {
|
||||
zp->decomp = malloc(DSIZ);
|
||||
if(!zp->decomp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
in.pos = 0;
|
||||
in.src = buf;
|
||||
in.size = nbytes;
|
||||
|
||||
for(;;) {
|
||||
out.pos = 0;
|
||||
out.dst = zp->decomp;
|
||||
out.size = DSIZ;
|
||||
|
||||
errorCode = ZSTD_decompressStream(zp->zds, &out, &in);
|
||||
if(ZSTD_isError(errorCode)) {
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
if(out.pos > 0) {
|
||||
result = Curl_unencode_write(conn, writer->downstream,
|
||||
zp->decomp, out.pos);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
if((in.pos == nbytes) && (out.pos < out.size))
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void zstd_close_writer(struct connectdata *conn,
|
||||
struct contenc_writer *writer)
|
||||
{
|
||||
struct zstd_params *zp = (struct zstd_params *)&writer->params;
|
||||
(void)conn;
|
||||
|
||||
if(zp->decomp) {
|
||||
free(zp->decomp);
|
||||
zp->decomp = NULL;
|
||||
}
|
||||
if(zp->zds) {
|
||||
ZSTD_freeDStream(zp->zds);
|
||||
zp->zds = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct content_encoding zstd_encoding = {
|
||||
"zstd",
|
||||
NULL,
|
||||
zstd_init_writer,
|
||||
zstd_unencode_write,
|
||||
zstd_close_writer,
|
||||
sizeof(struct zstd_params)
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* Identity handler. */
|
||||
static CURLcode identity_init_writer(struct connectdata *conn,
|
||||
struct contenc_writer *writer)
|
||||
@@ -751,6 +844,9 @@ static const struct content_encoding * const encodings[] = {
|
||||
#endif
|
||||
#ifdef HAVE_BROTLI
|
||||
&brotli_encoding,
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD
|
||||
&zstd_encoding,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -437,6 +437,9 @@
|
||||
/* if brotli is available */
|
||||
#cmakedefine HAVE_BROTLI 1
|
||||
|
||||
/* if zstd is available */
|
||||
#cmakedefine HAVE_ZSTD 1
|
||||
|
||||
/* if your compiler supports LL */
|
||||
#cmakedefine HAVE_LL 1
|
||||
|
||||
|
||||
+1
-1
@@ -641,7 +641,7 @@ int netware_init(void);
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
defined(USE_MBEDTLS) || \
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_SET_ODD_PARITY))
|
||||
(defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT))
|
||||
|
||||
#define USE_NTLM
|
||||
|
||||
|
||||
+2
-1
@@ -28,6 +28,7 @@
|
||||
#include "curl_sspi.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "system_win32.h"
|
||||
#include "version_win32.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
@@ -82,7 +83,7 @@ CURLcode Curl_sspi_global_init(void)
|
||||
* have both these DLLs (security.dll forwards calls to secur32.dll) */
|
||||
|
||||
/* Load SSPI dll into the address space of the calling process */
|
||||
if(Curl_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL))
|
||||
if(curlx_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL))
|
||||
s_hSecDll = Curl_load_library(TEXT("security.dll"));
|
||||
else
|
||||
s_hSecDll = Curl_load_library(TEXT("secur32.dll"));
|
||||
|
||||
@@ -63,6 +63,9 @@
|
||||
curlx_unicodefree()
|
||||
*/
|
||||
|
||||
#include "version_win32.h"
|
||||
/* "version_win32.h" provides curlx_verify_windows_version() */
|
||||
|
||||
/* Now setup curlx_ * names for the functions that are to become curlx_ and
|
||||
be removed from a future libcurl official API:
|
||||
curlx_getenv
|
||||
|
||||
@@ -858,7 +858,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
|
||||
addr = (void *)ai->ai_addr; /* storage area for this info */
|
||||
DEBUGASSERT(sizeof(struct in_addr) == sizeof(de->addr[i].ip.v4));
|
||||
memcpy(&addr->sin_addr, &de->addr[i].ip.v4, sizeof(struct in_addr));
|
||||
addr->sin_family = (CURL_SA_FAMILY_T)addrtype;
|
||||
addr->sin_family = addrtype;
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
@@ -867,7 +867,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port)
|
||||
addr6 = (void *)ai->ai_addr; /* storage area for this info */
|
||||
DEBUGASSERT(sizeof(struct in6_addr) == sizeof(de->addr[i].ip.v6));
|
||||
memcpy(&addr6->sin6_addr, &de->addr[i].ip.v6, sizeof(struct in6_addr));
|
||||
addr6->sin6_family = (CURL_SA_FAMILY_T)addrtype;
|
||||
addr6->sin6_family = addrtype;
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -53,11 +53,11 @@ size_t Curl_dyn_len(const struct dynbuf *s);
|
||||
#define DYN_HAXPROXY 2048
|
||||
#define DYN_HTTP_REQUEST (128*1024)
|
||||
#define DYN_H2_HEADERS (128*1024)
|
||||
#define DYN_H2_TRAILER 4096
|
||||
#define DYN_H2_TRAILERS (128*1024)
|
||||
#define DYN_APRINTF 8000000
|
||||
#define DYN_RTSP_REQ_HEADER (64*1024)
|
||||
#define DYN_TRAILERS (64*1024)
|
||||
#define DYN_PROXY_CONNECT_HEADERS 16384
|
||||
#define DYN_QLOG_NAME 1024
|
||||
#define DYN_H1_TRAILER DYN_H2_TRAILER
|
||||
#define DYN_H1_TRAILER 4096
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -838,8 +838,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
|
||||
/* the connection cache is setup on demand */
|
||||
outcurl->state.conn_cache = NULL;
|
||||
|
||||
outcurl->state.lastconnect = NULL;
|
||||
outcurl->state.lastconnect_id = -1;
|
||||
|
||||
outcurl->progress.flags = data->progress.flags;
|
||||
outcurl->progress.callback = data->progress.callback;
|
||||
|
||||
@@ -3251,9 +3251,9 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
}
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* The secondary socket used SSL so we must close down that part first
|
||||
before we close the socket for real */
|
||||
result = Curl_ssl_shutdown(conn, SECONDARYSOCKET);
|
||||
/* The secondary socket is using SSL so we must close down that part
|
||||
first before we close the socket for real */
|
||||
Curl_ssl_close(conn, SECONDARYSOCKET);
|
||||
|
||||
/* Note that we keep "use" set to TRUE since that (next) connection is
|
||||
still requested to use SSL */
|
||||
|
||||
@@ -78,6 +78,7 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
|
||||
info->conn_local_ip[0] = '\0';
|
||||
info->conn_primary_port = 0;
|
||||
info->conn_local_port = 0;
|
||||
info->retry_after = 0;
|
||||
|
||||
info->conn_scheme = 0;
|
||||
info->conn_protocol = 0;
|
||||
@@ -95,6 +96,34 @@ static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
|
||||
case CURLINFO_EFFECTIVE_URL:
|
||||
*param_charp = data->change.url?data->change.url:(char *)"";
|
||||
break;
|
||||
case CURLINFO_EFFECTIVE_METHOD: {
|
||||
const char *m = data->set.str[STRING_CUSTOMREQUEST];
|
||||
if(!m) {
|
||||
if(data->set.opt_no_body)
|
||||
m = "HEAD";
|
||||
else {
|
||||
switch(data->state.httpreq) {
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
case HTTPREQ_POST_MIME:
|
||||
m = "POST";
|
||||
break;
|
||||
case HTTPREQ_PUT:
|
||||
m = "PUT";
|
||||
break;
|
||||
default: /* this should never happen */
|
||||
case HTTPREQ_GET:
|
||||
m = "GET";
|
||||
break;
|
||||
case HTTPREQ_HEAD:
|
||||
m = "HEAD";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*param_charp = m;
|
||||
}
|
||||
break;
|
||||
case CURLINFO_CONTENT_TYPE:
|
||||
*param_charp = data->info.contenttype;
|
||||
break;
|
||||
|
||||
@@ -2014,9 +2014,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
case HTTPREQ_PUT:
|
||||
request = "PUT";
|
||||
break;
|
||||
case HTTPREQ_OPTIONS:
|
||||
request = "OPTIONS";
|
||||
break;
|
||||
default: /* this should never happen */
|
||||
case HTTPREQ_GET:
|
||||
request = "GET";
|
||||
|
||||
@@ -148,6 +148,7 @@ struct HTTP {
|
||||
struct dynbuf header_recvbuf;
|
||||
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
|
||||
upper layer */
|
||||
struct dynbuf trailer_recvbuf;
|
||||
int status_code; /* HTTP status code */
|
||||
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
|
||||
size_t pauselen; /* the number of bytes left in data */
|
||||
|
||||
+60
-20
@@ -514,7 +514,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const nghttp2_push_promise *frame)
|
||||
{
|
||||
int rv;
|
||||
int rv; /* one of the CURL_PUSH_* defines */
|
||||
H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
|
||||
frame->promised_stream_id));
|
||||
if(data->multi->push_cb) {
|
||||
@@ -528,7 +528,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
struct Curl_easy *newhandle = duphandle(data);
|
||||
if(!newhandle) {
|
||||
infof(data, "failed to duplicate handle\n");
|
||||
rv = 1; /* FAIL HARD */
|
||||
rv = CURL_PUSH_DENY; /* FAIL HARD */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -541,13 +541,15 @@ static int push_promise(struct Curl_easy *data,
|
||||
if(!stream) {
|
||||
failf(data, "Internal NULL stream!\n");
|
||||
(void)Curl_close(&newhandle);
|
||||
rv = 1;
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rv = set_transfer_url(newhandle, &heads);
|
||||
if(rv)
|
||||
if(rv) {
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
Curl_set_in_callback(data, true);
|
||||
rv = data->multi->push_cb(data, newhandle,
|
||||
@@ -563,6 +565,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
stream->push_headers_used = 0;
|
||||
|
||||
if(rv) {
|
||||
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
|
||||
/* denied, kill off the new handle again */
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
newhandle->req.protop = NULL;
|
||||
@@ -583,7 +586,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
newhandle->req.protop = NULL;
|
||||
Curl_close(&newhandle);
|
||||
rv = 1;
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -595,12 +598,13 @@ static int push_promise(struct Curl_easy *data,
|
||||
infof(data, "failed to set user_data for stream %d\n",
|
||||
frame->promised_stream_id);
|
||||
DEBUGASSERT(0);
|
||||
rv = CURL_PUSH_DENY;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else {
|
||||
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
|
||||
rv = 1;
|
||||
rv = CURL_PUSH_DENY;
|
||||
}
|
||||
fail:
|
||||
return rv;
|
||||
@@ -737,11 +741,16 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
rv = push_promise(data_s, conn, &frame->push_promise);
|
||||
if(rv) { /* deny! */
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
int h2;
|
||||
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
|
||||
h2 = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_CANCEL);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
if(nghttp2_is_fatal(h2))
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
else if(rv == CURL_PUSH_ERROROUT) {
|
||||
DEBUGF(infof(data_s, "Fail the parent stream (too)\n"));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -839,7 +848,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
|
||||
nghttp2_strerror(error_code), error_code, stream_id));
|
||||
nghttp2_http2_strerror(error_code), error_code, stream_id));
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
@@ -1006,18 +1015,11 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
if(stream->bodystarted) {
|
||||
/* This is a trailer */
|
||||
struct dynbuf trail;
|
||||
H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
|
||||
value));
|
||||
Curl_dyn_init(&trail, DYN_H2_TRAILER);
|
||||
result = Curl_dyn_addf(&trail,
|
||||
result = Curl_dyn_addf(&stream->trailer_recvbuf,
|
||||
"%.*s: %.*s\r\n", namelen, name,
|
||||
valuelen, value);
|
||||
if(!result)
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
|
||||
Curl_dyn_ptr(&trail),
|
||||
Curl_dyn_len(&trail));
|
||||
Curl_dyn_free(&trail);
|
||||
if(result)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
@@ -1165,6 +1167,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
/* there might be allocated resources done before this got the 'h2' pointer
|
||||
setup */
|
||||
Curl_dyn_free(&http->header_recvbuf);
|
||||
Curl_dyn_free(&http->trailer_recvbuf);
|
||||
if(http->push_headers) {
|
||||
/* if they weren't used and then freed before */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
@@ -1174,7 +1177,8 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
|
||||
if(!httpc->h2) /* not HTTP/2 ? */
|
||||
if(!(data->conn->handler->protocol&PROTO_FAMILY_HTTP) ||
|
||||
!httpc->h2) /* not HTTP/2 ? */
|
||||
return;
|
||||
|
||||
if(premature) {
|
||||
@@ -1203,6 +1207,13 @@ void Curl_http2_done(struct Curl_easy *data, bool premature)
|
||||
}
|
||||
http->stream_id = 0;
|
||||
}
|
||||
|
||||
if(0 == nghttp2_session_check_request_allowed(httpc->h2)) {
|
||||
/* No more requests are allowed in the current session, so the connection
|
||||
may not be reused. This is set when a GOAWAY frame has been received or
|
||||
when the limit of stream identifiers has been reached. */
|
||||
connclose(data->conn, "http/2: No new requests allowed");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1456,7 +1467,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
}
|
||||
else if(httpc->error_code != NGHTTP2_NO_ERROR) {
|
||||
failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
|
||||
stream->stream_id, nghttp2_strerror(httpc->error_code),
|
||||
stream->stream_id, nghttp2_http2_strerror(httpc->error_code),
|
||||
httpc->error_code);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
@@ -1470,6 +1481,31 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(Curl_dyn_len(&stream->trailer_recvbuf)) {
|
||||
char *trailp = Curl_dyn_ptr(&stream->trailer_recvbuf);
|
||||
char *lf;
|
||||
|
||||
do {
|
||||
size_t len = 0;
|
||||
CURLcode result;
|
||||
/* each trailer line ends with a newline */
|
||||
lf = strchr(trailp, '\n');
|
||||
if(!lf)
|
||||
break;
|
||||
len = lf + 1 - trailp;
|
||||
|
||||
if(data->set.verbose)
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, trailp, len);
|
||||
/* pass the trailers one by one to the callback */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailp, len);
|
||||
if(result) {
|
||||
*err = result;
|
||||
return -1;
|
||||
}
|
||||
trailp = ++lf;
|
||||
} while(lf);
|
||||
}
|
||||
|
||||
stream->close_handled = TRUE;
|
||||
|
||||
H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
|
||||
@@ -2075,6 +2111,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
h2_pri_spec(conn->data, &pri_spec);
|
||||
|
||||
H2BUGF(infof(conn->data, "http2_send request allowed %d (easy handle %p)\n",
|
||||
nghttp2_session_check_request_allowed(h2), (void *)conn->data));
|
||||
|
||||
switch(conn->data->state.httpreq) {
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
@@ -2151,6 +2190,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
stream->stream_id = -1;
|
||||
|
||||
Curl_dyn_init(&stream->header_recvbuf, DYN_H2_HEADERS);
|
||||
Curl_dyn_init(&stream->trailer_recvbuf, DYN_H2_TRAILERS);
|
||||
|
||||
if((conn->handler == &Curl_handler_http2_ssl) ||
|
||||
(conn->handler == &Curl_handler_http2))
|
||||
|
||||
@@ -102,7 +102,9 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
|
||||
#include <openssl/md4.h>
|
||||
|
||||
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
|
||||
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
|
||||
defined(__MAC_OS_X_VERSION_MIN_ALLOWED) && \
|
||||
(__MAC_OS_X_VERSION_MIN_ALLOWED < 101500)) || \
|
||||
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
|
||||
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
|
||||
|
||||
|
||||
@@ -139,7 +139,9 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
|
||||
}
|
||||
|
||||
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
|
||||
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
|
||||
defined(__MAC_OS_X_VERSION_MIN_ALLOWED) && \
|
||||
(__MAC_OS_X_VERSION_MIN_ALLOWED < 101500)) || \
|
||||
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
|
||||
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
|
||||
|
||||
|
||||
@@ -456,6 +456,16 @@ FILE *curl_dbg_fopen(const char *file, const char *mode,
|
||||
return res;
|
||||
}
|
||||
|
||||
FILE *curl_dbg_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source)
|
||||
{
|
||||
FILE *res = fdopen(filedes, mode);
|
||||
if(source)
|
||||
curl_dbg_log("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
|
||||
source, line, filedes, mode, (void *)res);
|
||||
return res;
|
||||
}
|
||||
|
||||
int curl_dbg_fclose(FILE *file, int line, const char *source)
|
||||
{
|
||||
int res;
|
||||
|
||||
+4
-1
@@ -8,7 +8,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, 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,6 +79,9 @@ CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd,
|
||||
/* FILE functions */
|
||||
CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN FILE *curl_dbg_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source);
|
||||
|
||||
CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
|
||||
|
||||
#ifndef MEMDEBUG_NODEFINES
|
||||
|
||||
+20
-6
@@ -178,12 +178,14 @@ static long dprintf_DollarString(char *input, char **end)
|
||||
{
|
||||
int number = 0;
|
||||
while(ISDIGIT(*input)) {
|
||||
number *= 10;
|
||||
number += *input-'0';
|
||||
if(number < MAX_PARAMETERS) {
|
||||
number *= 10;
|
||||
number += *input - '0';
|
||||
}
|
||||
input++;
|
||||
}
|
||||
if(number && ('$'==*input++)) {
|
||||
*end = input;
|
||||
if(number <= MAX_PARAMETERS && ('$' == *input)) {
|
||||
*end = ++input;
|
||||
return number;
|
||||
}
|
||||
return 0;
|
||||
@@ -377,6 +379,8 @@ static int dprintf_Pass1(const char *format, struct va_stack *vto,
|
||||
if(width > max_param)
|
||||
max_param = width;
|
||||
break;
|
||||
case '\0':
|
||||
fmt--;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -458,6 +462,9 @@ static int dprintf_Pass1(const char *format, struct va_stack *vto,
|
||||
/* we have the width specified from a parameter, so we make that
|
||||
parameter's info setup properly */
|
||||
long k = width - 1;
|
||||
if((k < 0) || (k >= MAX_PARAMETERS))
|
||||
/* out of allowed range */
|
||||
return 1;
|
||||
vto[i].width = k;
|
||||
vto[k].type = FORMAT_WIDTH;
|
||||
vto[k].flags = FLAGS_NEW;
|
||||
@@ -469,6 +476,9 @@ static int dprintf_Pass1(const char *format, struct va_stack *vto,
|
||||
/* we have the precision specified from a parameter, so we make that
|
||||
parameter's info setup properly */
|
||||
long k = precision - 1;
|
||||
if((k < 0) || (k >= MAX_PARAMETERS))
|
||||
/* out of allowed range */
|
||||
return 1;
|
||||
vto[i].precision = k;
|
||||
vto[k].type = FORMAT_WIDTH;
|
||||
vto[k].flags = FLAGS_NEW;
|
||||
@@ -476,7 +486,7 @@ static int dprintf_Pass1(const char *format, struct va_stack *vto,
|
||||
vto[k].width = 0;
|
||||
vto[k].precision = 0;
|
||||
}
|
||||
*endpos++ = fmt + 1; /* end of this sequence */
|
||||
*endpos++ = fmt + ((*fmt == '\0') ? 0 : 1); /* end of this sequence */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,7 +764,7 @@ static int dprintf_formatf(
|
||||
|
||||
if(prec > 0) {
|
||||
width -= prec;
|
||||
while(prec-- > 0)
|
||||
while(prec-- > 0 && w >= work)
|
||||
*w-- = '0';
|
||||
}
|
||||
|
||||
@@ -918,6 +928,8 @@ static int dprintf_formatf(
|
||||
precision */
|
||||
size_t maxprec = sizeof(work) - 2;
|
||||
double val = p->data.dnum;
|
||||
if(width > 0 && prec <= width)
|
||||
maxprec -= width;
|
||||
while(val >= 10.0) {
|
||||
val /= 10;
|
||||
maxprec--;
|
||||
@@ -925,6 +937,8 @@ static int dprintf_formatf(
|
||||
|
||||
if(prec > (long)maxprec)
|
||||
prec = (long)maxprec-1;
|
||||
if(prec < 0)
|
||||
prec = 0;
|
||||
/* RECURSIVE USAGE */
|
||||
len = curl_msnprintf(fptr, left, ".%ld", prec);
|
||||
fptr += len;
|
||||
|
||||
+37
-25
@@ -455,6 +455,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
data->state.conn_cache = &data->share->conn_cache;
|
||||
else
|
||||
data->state.conn_cache = &multi->conn_cache;
|
||||
data->state.lastconnect_id = -1;
|
||||
|
||||
#ifdef USE_LIBPSL
|
||||
/* Do the same for PSL. */
|
||||
@@ -677,11 +678,11 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
CONNCACHE_UNLOCK(data);
|
||||
if(Curl_conncache_return_conn(data, conn)) {
|
||||
/* remember the most recently used connection */
|
||||
data->state.lastconnect = conn;
|
||||
data->state.lastconnect_id = conn->connection_id;
|
||||
infof(data, "%s\n", buffer);
|
||||
}
|
||||
else
|
||||
data->state.lastconnect = NULL;
|
||||
data->state.lastconnect_id = -1;
|
||||
}
|
||||
|
||||
Curl_safefree(data->state.buffer);
|
||||
@@ -689,6 +690,26 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int close_connect_only(struct connectdata *conn, void *param)
|
||||
{
|
||||
struct Curl_easy *data = param;
|
||||
|
||||
if(data->state.lastconnect_id != conn->connection_id)
|
||||
return 0;
|
||||
|
||||
if(conn->data != data)
|
||||
return 1;
|
||||
conn->data = NULL;
|
||||
|
||||
if(!conn->bits.connect_only)
|
||||
return 1;
|
||||
|
||||
connclose(conn, "Removing connect-only easy handle");
|
||||
conn->bits.connect_only = FALSE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
@@ -776,10 +797,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
multi_done() as that may actually call Curl_expire that uses this */
|
||||
Curl_llist_destroy(&data->state.timeoutlist, NULL);
|
||||
|
||||
/* as this was using a shared connection cache we clear the pointer to that
|
||||
since we're not part of that multi handle anymore */
|
||||
data->state.conn_cache = NULL;
|
||||
|
||||
/* change state without using multistate(), only to make singlesocket() do
|
||||
what we want */
|
||||
data->mstate = CURLM_STATE_COMPLETED;
|
||||
@@ -789,12 +806,22 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
/* Remove the association between the connection and the handle */
|
||||
Curl_detach_connnection(data);
|
||||
|
||||
if(data->state.lastconnect_id != -1) {
|
||||
/* Mark any connect-only connection for closure */
|
||||
Curl_conncache_foreach(data, data->state.conn_cache,
|
||||
data, &close_connect_only);
|
||||
}
|
||||
|
||||
#ifdef USE_LIBPSL
|
||||
/* Remove the PSL association. */
|
||||
if(data->psl == &multi->psl)
|
||||
data->psl = NULL;
|
||||
#endif
|
||||
|
||||
/* as this was using a shared connection cache we clear the pointer to that
|
||||
since we're not part of that multi handle anymore */
|
||||
data->state.conn_cache = NULL;
|
||||
|
||||
data->multi = NULL; /* clear the association to this multi handle */
|
||||
|
||||
/* make sure there's no pending message in the queue sent from this easy
|
||||
@@ -958,19 +985,6 @@ static int multi_getsock(struct Curl_easy *data,
|
||||
|
||||
switch(data->mstate) {
|
||||
default:
|
||||
#if 0 /* switch back on these cases to get the compiler to check for all enums
|
||||
to be present */
|
||||
case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */
|
||||
case CURLM_STATE_COMPLETED:
|
||||
case CURLM_STATE_MSGSENT:
|
||||
case CURLM_STATE_INIT:
|
||||
case CURLM_STATE_CONNECT:
|
||||
case CURLM_STATE_WAITDO:
|
||||
case CURLM_STATE_DONE:
|
||||
case CURLM_STATE_LAST:
|
||||
/* this will get called with CURLM_STATE_COMPLETED when a handle is
|
||||
removed */
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
case CURLM_STATE_WAITRESOLVE:
|
||||
@@ -1255,7 +1269,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi,
|
||||
sleep_ms = timeout_ms;
|
||||
/* when there are no easy handles in the multi, this holds a -1
|
||||
timeout */
|
||||
else if((sleep_ms < 0) && extrawait)
|
||||
else if(sleep_ms < 0)
|
||||
sleep_ms = timeout_ms;
|
||||
Curl_wait_ms(sleep_ms);
|
||||
}
|
||||
@@ -1808,7 +1822,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
|
||||
}
|
||||
}
|
||||
else if(result)
|
||||
else
|
||||
stream_error = TRUE;
|
||||
break;
|
||||
#endif
|
||||
@@ -1858,7 +1872,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
multistate(data, CURLM_STATE_DO);
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
else if(result) {
|
||||
else {
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(data, result, TRUE);
|
||||
@@ -2962,9 +2976,7 @@ CURLMcode curl_multi_setopt(struct Curl_multi *multi,
|
||||
long streams = va_arg(param, long);
|
||||
if(streams < 1)
|
||||
streams = 100;
|
||||
multi->max_concurrent_streams =
|
||||
(streams > (long)INITIAL_MAX_CONCURRENT_STREAMS)?
|
||||
INITIAL_MAX_CONCURRENT_STREAMS : (unsigned int)streams;
|
||||
multi->max_concurrent_streams = curlx_sltoui(streams);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ struct Curl_multi {
|
||||
this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
|
||||
long type;
|
||||
|
||||
/* We have a doubly-linked circular list with easy handles */
|
||||
/* We have a doubly-linked list with easy handles */
|
||||
struct Curl_easy *easyp;
|
||||
struct Curl_easy *easylp; /* last node */
|
||||
|
||||
|
||||
+2
-1
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, 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
|
||||
@@ -624,6 +624,7 @@ CURLcode Curl_gmtime(time_t intime, struct tm *store)
|
||||
/* thread-safe version */
|
||||
tm = (struct tm *)gmtime_r(&intime, store);
|
||||
#else
|
||||
/* !checksrc! disable BANNEDFUNC 1 */
|
||||
tm = gmtime(&intime);
|
||||
if(tm)
|
||||
*store = *tm; /* copy the pointed struct to the local copy */
|
||||
|
||||
+12
-3
@@ -27,6 +27,7 @@
|
||||
#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)) || \
|
||||
defined(USE_ALTSVC)
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
#include "timeval.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -39,17 +40,25 @@ int Curl_rename(const char *oldpath, const char *newpath)
|
||||
{
|
||||
#ifdef WIN32
|
||||
/* rename() on Windows doesn't overwrite, so we can't use it here.
|
||||
MoveFileExA() will overwrite and is usually atomic, however it fails
|
||||
MoveFileEx() will overwrite and is usually atomic, however it fails
|
||||
when there are open handles to the file. */
|
||||
const int max_wait_ms = 1000;
|
||||
struct curltime start = Curl_now();
|
||||
TCHAR *tchar_oldpath = curlx_convert_UTF8_to_tchar((char *)oldpath);
|
||||
TCHAR *tchar_newpath = curlx_convert_UTF8_to_tchar((char *)newpath);
|
||||
for(;;) {
|
||||
timediff_t diff;
|
||||
if(MoveFileExA(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
||||
if(MoveFileEx(tchar_oldpath, tchar_newpath, MOVEFILE_REPLACE_EXISTING)) {
|
||||
curlx_unicodefree(tchar_oldpath);
|
||||
curlx_unicodefree(tchar_newpath);
|
||||
break;
|
||||
}
|
||||
diff = Curl_timediff(Curl_now(), start);
|
||||
if(diff < 0 || diff > max_wait_ms)
|
||||
if(diff < 0 || diff > max_wait_ms) {
|
||||
curlx_unicodefree(tchar_oldpath);
|
||||
curlx_unicodefree(tchar_newpath);
|
||||
return 1;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -274,6 +274,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
if(data->set.opt_no_body)
|
||||
/* in HTTP lingo, no body means using the HEAD request... */
|
||||
data->set.method = HTTPREQ_HEAD;
|
||||
else if(data->set.method == HTTPREQ_HEAD)
|
||||
data->set.method = HTTPREQ_GET;
|
||||
break;
|
||||
case CURLOPT_FAILONERROR:
|
||||
/*
|
||||
|
||||
+4
-2
@@ -1760,8 +1760,10 @@ static CURLcode smtp_parse_address(struct connectdata *conn, const char *fqma,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
length = strlen(dup);
|
||||
if(dup[length - 1] == '>')
|
||||
dup[length - 1] = '\0';
|
||||
if(length) {
|
||||
if(dup[length - 1] == '>')
|
||||
dup[length - 1] = '\0';
|
||||
}
|
||||
|
||||
/* Extract the host name from the address (if we can) */
|
||||
host->name = strpbrk(dup, "@");
|
||||
|
||||
+3
-3
@@ -327,18 +327,18 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
|
||||
* Make connection
|
||||
*/
|
||||
{
|
||||
ssize_t packetsize = 9 +
|
||||
size_t packetsize = 9 +
|
||||
strlen((char *)socksreq + 8); /* size including NUL */
|
||||
|
||||
/* If SOCKS4a, set special invalid IP address 0.0.0.x */
|
||||
if(protocol4a) {
|
||||
ssize_t hostnamelen = 0;
|
||||
size_t hostnamelen = 0;
|
||||
socksreq[4] = 0;
|
||||
socksreq[5] = 0;
|
||||
socksreq[6] = 0;
|
||||
socksreq[7] = 1;
|
||||
/* append hostname */
|
||||
hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
|
||||
hostnamelen = strlen(hostname) + 1; /* length including NUL */
|
||||
if(hostnamelen <= 255)
|
||||
strcpy((char *)socksreq + packetsize, hostname);
|
||||
else {
|
||||
|
||||
+4
-9
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, 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
|
||||
@@ -39,19 +39,14 @@ char *curlx_strdup(const char *str)
|
||||
if(!str)
|
||||
return (char *)NULL;
|
||||
|
||||
len = strlen(str);
|
||||
len = strlen(str) + 1;
|
||||
|
||||
if(len >= ((size_t)-1) / sizeof(char))
|
||||
return (char *)NULL;
|
||||
|
||||
newstr = malloc((len + 1)*sizeof(char));
|
||||
newstr = malloc(len);
|
||||
if(!newstr)
|
||||
return (char *)NULL;
|
||||
|
||||
memcpy(newstr, str, (len + 1)*sizeof(char));
|
||||
|
||||
memcpy(newstr, str, len);
|
||||
return newstr;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+3
-194
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "system_win32.h"
|
||||
#include "version_win32.h"
|
||||
#include "curl_sspi.h"
|
||||
#include "warnless.h"
|
||||
|
||||
@@ -106,8 +107,8 @@ CURLcode Curl_win32_init(long flags)
|
||||
Curl_if_nametoindex = pIfNameToIndex;
|
||||
}
|
||||
|
||||
if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
if(curlx_verify_windows_version(6, 0, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
Curl_isVistaOrGreater = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -159,198 +160,6 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
|
||||
# define LOADLIBARYEX "LoadLibraryExA"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_verify_windows_version()
|
||||
*
|
||||
* This is used to verify if we are running on a specific windows version.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* majorVersion [in] - The major version number.
|
||||
* minorVersion [in] - The minor version number.
|
||||
* platform [in] - The optional platform identifier.
|
||||
* condition [in] - The test condition used to specifier whether we are
|
||||
* checking a version less then, equal to or greater than
|
||||
* what is specified in the major and minor version
|
||||
* numbers.
|
||||
*
|
||||
* Returns TRUE if matched; otherwise FALSE.
|
||||
*/
|
||||
bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
const PlatformIdentifier platform,
|
||||
const VersionCondition condition)
|
||||
{
|
||||
bool matched = FALSE;
|
||||
|
||||
#if defined(CURL_WINDOWS_APP)
|
||||
/* We have no way to determine the Windows version from Windows apps,
|
||||
so let's assume we're running on the target Windows version. */
|
||||
const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
|
||||
const WORD targetVersion = (WORD)_WIN32_WINNT;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
matched = targetVersion < fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
matched = targetVersion <= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
matched = targetVersion == fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
matched = targetVersion >= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
matched = targetVersion > fullVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
if(matched && (platform == PLATFORM_WINDOWS)) {
|
||||
/* we're always running on PLATFORM_WINNT */
|
||||
matched = FALSE;
|
||||
}
|
||||
#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
|
||||
/* Find out Windows version */
|
||||
if(GetVersionEx(&osver)) {
|
||||
/* Verify the Operating System version number */
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
if(osver.dwMajorVersion < majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion < minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
if(osver.dwMajorVersion < majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion <= minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
if(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion == minorVersion)
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
if(osver.dwMajorVersion > majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion >= minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
if(osver.dwMajorVersion > majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion > minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify the platform identifier (if necessary) */
|
||||
if(matched) {
|
||||
switch(platform) {
|
||||
case PLATFORM_WINDOWS:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
|
||||
matched = FALSE;
|
||||
break;
|
||||
|
||||
case PLATFORM_WINNT:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
matched = FALSE;
|
||||
|
||||
default: /* like platform == PLATFORM_DONT_CARE */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ULONGLONG cm = 0;
|
||||
OSVERSIONINFOEX osver;
|
||||
BYTE majorCondition;
|
||||
BYTE minorCondition;
|
||||
BYTE spMajorCondition;
|
||||
BYTE spMinorCondition;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
majorCondition = VER_LESS;
|
||||
minorCondition = VER_LESS;
|
||||
spMajorCondition = VER_LESS_EQUAL;
|
||||
spMinorCondition = VER_LESS_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
majorCondition = VER_LESS_EQUAL;
|
||||
minorCondition = VER_LESS_EQUAL;
|
||||
spMajorCondition = VER_LESS_EQUAL;
|
||||
spMinorCondition = VER_LESS_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
majorCondition = VER_EQUAL;
|
||||
minorCondition = VER_EQUAL;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
majorCondition = VER_GREATER_EQUAL;
|
||||
minorCondition = VER_GREATER_EQUAL;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
majorCondition = VER_GREATER;
|
||||
minorCondition = VER_GREATER;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
osver.dwMinorVersion = minorVersion;
|
||||
if(platform == PLATFORM_WINDOWS)
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
|
||||
else if(platform == PLATFORM_WINNT)
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
|
||||
|
||||
cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
|
||||
if(platform != PLATFORM_DONT_CARE)
|
||||
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
matched = TRUE;
|
||||
#endif
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_load_library()
|
||||
*
|
||||
|
||||
+1
-23
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016 - 2019, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2016 - 2020, 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
|
||||
@@ -32,34 +32,12 @@ extern bool Curl_isVistaOrGreater;
|
||||
CURLcode Curl_win32_init(long flags);
|
||||
void Curl_win32_cleanup(long init_flags);
|
||||
|
||||
/* Version condition */
|
||||
typedef enum {
|
||||
VERSION_LESS_THAN,
|
||||
VERSION_LESS_THAN_EQUAL,
|
||||
VERSION_EQUAL,
|
||||
VERSION_GREATER_THAN_EQUAL,
|
||||
VERSION_GREATER_THAN
|
||||
} VersionCondition;
|
||||
|
||||
/* Platform identifier */
|
||||
typedef enum {
|
||||
PLATFORM_DONT_CARE,
|
||||
PLATFORM_WINDOWS,
|
||||
PLATFORM_WINNT
|
||||
} PlatformIdentifier;
|
||||
|
||||
/* We use our own typedef here since some headers might lack this */
|
||||
typedef unsigned int(WINAPI *IF_NAMETOINDEX_FN)(const char *);
|
||||
|
||||
/* This is used instead of if_nametoindex if available on Windows */
|
||||
extern IF_NAMETOINDEX_FN Curl_if_nametoindex;
|
||||
|
||||
/* This is used to verify if we are running on a specific windows version */
|
||||
bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
const PlatformIdentifier platform,
|
||||
const VersionCondition condition);
|
||||
|
||||
/* This is used to dynamically load DLLs */
|
||||
HMODULE Curl_load_library(LPCTSTR filename);
|
||||
|
||||
|
||||
+12
-5
@@ -487,6 +487,12 @@ CURLcode Curl_readrewind(struct connectdata *conn)
|
||||
static int data_pending(const struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
|
||||
#ifdef ENABLE_QUIC
|
||||
if(conn->transport == TRNSPRT_QUIC)
|
||||
return Curl_quic_data_pending(data);
|
||||
#endif
|
||||
|
||||
/* in the case of libssh2, we can never be really sure that we have emptied
|
||||
its internal buffers so we MUST always try until we get EAGAIN back */
|
||||
return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
|
||||
@@ -500,8 +506,6 @@ static int data_pending(const struct Curl_easy *data)
|
||||
be called and we cannot signal the HTTP/2 stream has closed. As
|
||||
a workaround, we return nonzero here to call http2_recv. */
|
||||
((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20);
|
||||
#elif defined(ENABLE_QUIC)
|
||||
Curl_ssl_data_pending(conn, FIRSTSOCKET) || Curl_quic_data_pending(data);
|
||||
#else
|
||||
Curl_ssl_data_pending(conn, FIRSTSOCKET);
|
||||
#endif
|
||||
@@ -1441,8 +1445,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
||||
|
||||
if(!data->change.url && data->set.uh) {
|
||||
CURLUcode uc;
|
||||
free(data->set.str[STRING_SET_URL]);
|
||||
uc = curl_url_get(data->set.uh,
|
||||
CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
|
||||
CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
|
||||
if(uc) {
|
||||
failf(data, "No URL set!");
|
||||
return CURLE_URL_MALFORMAT;
|
||||
@@ -1799,12 +1804,14 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
||||
}
|
||||
if(retry) {
|
||||
#define CONN_MAX_RETRIES 5
|
||||
if(conn->retrycount++ >= CONN_MAX_RETRIES) {
|
||||
if(data->state.retrycount++ >= CONN_MAX_RETRIES) {
|
||||
failf(data, "Connection died, tried %d times before giving up",
|
||||
CONN_MAX_RETRIES);
|
||||
data->state.retrycount = 0;
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
infof(conn->data, "Connection died, retrying a fresh connect\n");
|
||||
infof(conn->data, "Connection died, retrying a fresh connect\
|
||||
(retry count: %d)\n", data->state.retrycount);
|
||||
*url = strdup(conn->data->change.url);
|
||||
if(!*url)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -630,7 +630,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
|
||||
Curl_initinfo(data);
|
||||
|
||||
/* most recent connection is not yet defined */
|
||||
data->state.lastconnect = NULL;
|
||||
data->state.lastconnect_id = -1;
|
||||
|
||||
data->progress.flags |= PGRS_HIDE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
@@ -1836,11 +1836,12 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
CURLU *uh;
|
||||
CURLUcode uc;
|
||||
char *hostname;
|
||||
bool use_set_uh = (data->set.uh && !data->state.this_is_a_follow);
|
||||
|
||||
up_free(data); /* cleanup previous leftovers first */
|
||||
|
||||
/* parse the URL */
|
||||
if(data->set.uh) {
|
||||
if(use_set_uh) {
|
||||
uh = data->state.uh = curl_url_dup(data->set.uh);
|
||||
}
|
||||
else {
|
||||
@@ -1863,7 +1864,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
data->change.url_alloc = TRUE;
|
||||
}
|
||||
|
||||
if(!data->set.uh) {
|
||||
if(!use_set_uh) {
|
||||
char *newurl;
|
||||
uc = curl_url_set(uh, CURLUPART_URL, data->change.url,
|
||||
CURLU_GUESS_SCHEME |
|
||||
@@ -3170,7 +3171,7 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
||||
else {
|
||||
/* this is a fresh connect */
|
||||
int rc;
|
||||
struct Curl_dns_entry *hostaddr;
|
||||
struct Curl_dns_entry *hostaddr = NULL;
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(conn->unix_domain_socket) {
|
||||
|
||||
+3
-3
@@ -1090,7 +1090,6 @@ struct connectdata {
|
||||
struct http_connect_state *connect_state; /* for HTTP CONNECT */
|
||||
struct connectbundle *bundle; /* The bundle we are member of */
|
||||
int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
|
||||
int retrycount; /* number of retries on a new connection */
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
char *unix_domain_socket;
|
||||
#endif
|
||||
@@ -1195,7 +1194,6 @@ typedef enum {
|
||||
HTTPREQ_POST_MIME, /* we make a difference internally */
|
||||
HTTPREQ_PUT,
|
||||
HTTPREQ_HEAD,
|
||||
HTTPREQ_OPTIONS,
|
||||
HTTPREQ_LAST /* last in list */
|
||||
} Curl_HttpReq;
|
||||
|
||||
@@ -1297,10 +1295,12 @@ struct UrlState {
|
||||
/* Points to the connection cache */
|
||||
struct conncache *conn_cache;
|
||||
|
||||
int retrycount; /* number of retries on a new connection */
|
||||
|
||||
/* buffers to store authentication data in, as parsed from input options */
|
||||
struct curltime keeps_speed; /* for the progress meter really */
|
||||
|
||||
struct connectdata *lastconnect; /* The last connection, NULL if undefined */
|
||||
long lastconnect_id; /* The last connection, -1 if undefined */
|
||||
struct dynbuf headerb; /* buffer to store headers in */
|
||||
|
||||
char *buffer; /* download buffer */
|
||||
|
||||
@@ -191,6 +191,7 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
free(ntlm->target_info); /* replace any previous data */
|
||||
ntlm->target_info = malloc(target_info_len);
|
||||
if(!ntlm->target_info)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
+45
-2
@@ -66,6 +66,10 @@
|
||||
#include <brotli/decode.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BROTLI
|
||||
static size_t brotli_version(char *buf, size_t bufsz)
|
||||
{
|
||||
@@ -78,6 +82,20 @@ static size_t brotli_version(char *buf, size_t bufsz)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
static size_t zstd_version(char *buf, size_t bufsz)
|
||||
{
|
||||
unsigned long zstd_version = (unsigned long)ZSTD_versionNumber();
|
||||
unsigned int major = (unsigned int)(zstd_version / (100 * 100));
|
||||
unsigned int minor = (unsigned int)((zstd_version -
|
||||
(major * 100 * 100)) / 100);
|
||||
unsigned int patch = (unsigned int)(zstd_version -
|
||||
(major * 100 * 100) - (minor * 100));
|
||||
|
||||
return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* curl_version() returns a pointer to a static buffer.
|
||||
*
|
||||
@@ -103,6 +121,9 @@ char *curl_version(void)
|
||||
#ifdef HAVE_BROTLI
|
||||
char br_version[40] = "brotli/";
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD
|
||||
char zst_version[40] = "zstd/";
|
||||
#endif
|
||||
#ifdef USE_ARES
|
||||
char cares_version[40];
|
||||
#endif
|
||||
@@ -153,6 +174,10 @@ char *curl_version(void)
|
||||
brotli_version(&br_version[7], sizeof(br_version) - 7);
|
||||
src[i++] = br_version;
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD
|
||||
zstd_version(&zst_version[5], sizeof(zst_version) - 5);
|
||||
src[i++] = zst_version;
|
||||
#endif
|
||||
#ifdef USE_ARES
|
||||
msnprintf(cares_version, sizeof(cares_version),
|
||||
"c-ares/%s", ares_version(NULL));
|
||||
@@ -365,6 +390,9 @@ static curl_version_info_data version_info = {
|
||||
( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) )
|
||||
| CURL_VERSION_LARGEFILE
|
||||
#endif
|
||||
#if defined(WIN32) && defined(UNICODE) && defined(_UNICODE)
|
||||
| CURL_VERSION_UNICODE
|
||||
#endif
|
||||
#if defined(CURL_DOES_CONVERSIONS)
|
||||
| CURL_VERSION_CONV
|
||||
#endif
|
||||
@@ -389,6 +417,9 @@ static curl_version_info_data version_info = {
|
||||
#if defined(HAVE_BROTLI)
|
||||
| CURL_VERSION_BROTLI
|
||||
#endif
|
||||
#if defined(HAVE_ZSTD)
|
||||
| CURL_VERSION_ZSTD
|
||||
#endif
|
||||
#if defined(USE_ALTSVC)
|
||||
| CURL_VERSION_ALTSVC
|
||||
#endif
|
||||
@@ -413,10 +444,12 @@ static curl_version_info_data version_info = {
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef CURL_CA_PATH
|
||||
CURL_CA_PATH /* capath */
|
||||
CURL_CA_PATH, /* capath */
|
||||
#else
|
||||
NULL
|
||||
NULL,
|
||||
#endif
|
||||
0, /* zstd_ver_num */
|
||||
NULL /* zstd version */
|
||||
};
|
||||
|
||||
curl_version_info_data *curl_version_info(CURLversion stamp)
|
||||
@@ -434,6 +467,10 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
|
||||
#ifdef HAVE_BROTLI
|
||||
static char brotli_buffer[80];
|
||||
#endif
|
||||
#ifdef HAVE_ZSTD
|
||||
static char zstd_buffer[80];
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
|
||||
@@ -485,6 +522,12 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
|
||||
version_info.brotli_version = brotli_buffer;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
version_info.zstd_ver_num = (unsigned int)ZSTD_versionNumber();
|
||||
zstd_version(zstd_buffer, sizeof(zstd_buffer));
|
||||
version_info.zstd_version = zstd_buffer;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
{
|
||||
nghttp2_info *h2 = nghttp2_version(0);
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016 - 2020, 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
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "version_win32.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* curlx_verify_windows_version()
|
||||
*
|
||||
* This is used to verify if we are running on a specific windows version.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* majorVersion [in] - The major version number.
|
||||
* minorVersion [in] - The minor version number.
|
||||
* platform [in] - The optional platform identifier.
|
||||
* condition [in] - The test condition used to specifier whether we are
|
||||
* checking a version less then, equal to or greater than
|
||||
* what is specified in the major and minor version
|
||||
* numbers.
|
||||
*
|
||||
* Returns TRUE if matched; otherwise FALSE.
|
||||
*/
|
||||
bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
const PlatformIdentifier platform,
|
||||
const VersionCondition condition)
|
||||
{
|
||||
bool matched = FALSE;
|
||||
|
||||
#if defined(CURL_WINDOWS_APP)
|
||||
/* We have no way to determine the Windows version from Windows apps,
|
||||
so let's assume we're running on the target Windows version. */
|
||||
const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
|
||||
const WORD targetVersion = (WORD)_WIN32_WINNT;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
matched = targetVersion < fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
matched = targetVersion <= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
matched = targetVersion == fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
matched = targetVersion >= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
matched = targetVersion > fullVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
if(matched && (platform == PLATFORM_WINDOWS)) {
|
||||
/* we're always running on PLATFORM_WINNT */
|
||||
matched = FALSE;
|
||||
}
|
||||
#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
|
||||
/* Find out Windows version */
|
||||
if(GetVersionEx(&osver)) {
|
||||
/* Verify the Operating System version number */
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
if(osver.dwMajorVersion < majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion < minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
if(osver.dwMajorVersion < majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion <= minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
if(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion == minorVersion)
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
if(osver.dwMajorVersion > majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion >= minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
if(osver.dwMajorVersion > majorVersion ||
|
||||
(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwMinorVersion > minorVersion))
|
||||
matched = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify the platform identifier (if necessary) */
|
||||
if(matched) {
|
||||
switch(platform) {
|
||||
case PLATFORM_WINDOWS:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
|
||||
matched = FALSE;
|
||||
break;
|
||||
|
||||
case PLATFORM_WINNT:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
matched = FALSE;
|
||||
|
||||
default: /* like platform == PLATFORM_DONT_CARE */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ULONGLONG cm = 0;
|
||||
OSVERSIONINFOEX osver;
|
||||
BYTE majorCondition;
|
||||
BYTE minorCondition;
|
||||
BYTE spMajorCondition;
|
||||
BYTE spMinorCondition;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
majorCondition = VER_LESS;
|
||||
minorCondition = VER_LESS;
|
||||
spMajorCondition = VER_LESS_EQUAL;
|
||||
spMinorCondition = VER_LESS_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
majorCondition = VER_LESS_EQUAL;
|
||||
minorCondition = VER_LESS_EQUAL;
|
||||
spMajorCondition = VER_LESS_EQUAL;
|
||||
spMinorCondition = VER_LESS_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
majorCondition = VER_EQUAL;
|
||||
minorCondition = VER_EQUAL;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
majorCondition = VER_GREATER_EQUAL;
|
||||
minorCondition = VER_GREATER_EQUAL;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
majorCondition = VER_GREATER;
|
||||
minorCondition = VER_GREATER;
|
||||
spMajorCondition = VER_GREATER_EQUAL;
|
||||
spMinorCondition = VER_GREATER_EQUAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
osver.dwMinorVersion = minorVersion;
|
||||
if(platform == PLATFORM_WINDOWS)
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
|
||||
else if(platform == PLATFORM_WINNT)
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
|
||||
|
||||
cm = VerSetConditionMask(cm, VER_MAJORVERSION, majorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, minorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, spMajorCondition);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, spMinorCondition);
|
||||
if(platform != PLATFORM_DONT_CARE)
|
||||
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
matched = TRUE;
|
||||
#endif
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef HEADER_CURL_VERSION_WIN32_H
|
||||
#define HEADER_CURL_VERSION_WIN32_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016 - 2020, 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
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
/* Version condition */
|
||||
typedef enum {
|
||||
VERSION_LESS_THAN,
|
||||
VERSION_LESS_THAN_EQUAL,
|
||||
VERSION_EQUAL,
|
||||
VERSION_GREATER_THAN_EQUAL,
|
||||
VERSION_GREATER_THAN
|
||||
} VersionCondition;
|
||||
|
||||
/* Platform identifier */
|
||||
typedef enum {
|
||||
PLATFORM_DONT_CARE,
|
||||
PLATFORM_WINDOWS,
|
||||
PLATFORM_WINNT
|
||||
} PlatformIdentifier;
|
||||
|
||||
/* This is used to verify if we are running on a specific windows version */
|
||||
bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
const PlatformIdentifier platform,
|
||||
const VersionCondition condition);
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif /* HEADER_CURL_VERSION_WIN32_H */
|
||||
+10
-9
@@ -150,9 +150,11 @@ quic_from_gtls_level(gnutls_record_encryption_level_t gtls_level)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void qlog_callback(void *user_data, const void *data, size_t datalen)
|
||||
static void qlog_callback(void *user_data, uint32_t flags,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
struct quicsocket *qs = (struct quicsocket *)user_data;
|
||||
(void)flags;
|
||||
if(qs->qlogfd != -1) {
|
||||
ssize_t rc = write(qs->qlogfd, data, datalen);
|
||||
if(rc == -1) {
|
||||
@@ -826,9 +828,8 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
|
||||
if(rv == -1)
|
||||
return CURLE_QUIC_CONNECT_ERROR;
|
||||
|
||||
ngtcp2_addr_init(&path.local, (uint8_t *)&qs->local_addr, qs->local_addrlen,
|
||||
NULL);
|
||||
ngtcp2_addr_init(&path.remote, (uint8_t*)addr, addrlen, NULL);
|
||||
ngtcp2_addr_init(&path.local, &qs->local_addr, qs->local_addrlen, NULL);
|
||||
ngtcp2_addr_init(&path.remote, addr, addrlen, NULL);
|
||||
|
||||
#ifdef NGTCP2_PROTO_VER
|
||||
#define QUICVER NGTCP2_PROTO_VER
|
||||
@@ -1744,10 +1745,10 @@ static CURLcode ng_process_ingress(struct connectdata *conn, int sockfd,
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
ngtcp2_addr_init(&path.local, (uint8_t *)&qs->local_addr,
|
||||
ngtcp2_addr_init(&path.local, &qs->local_addr,
|
||||
qs->local_addrlen, NULL);
|
||||
ngtcp2_addr_init(&path.remote, (uint8_t *)&remote_addr, remote_addrlen,
|
||||
NULL);
|
||||
ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr,
|
||||
remote_addrlen, NULL);
|
||||
|
||||
rv = ngtcp2_conn_read_pkt(qs->qconn, &path, buf, recvd, ts);
|
||||
if(rv != 0) {
|
||||
@@ -1778,7 +1779,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
nghttp3_vec vec[16];
|
||||
ssize_t ndatalen;
|
||||
|
||||
switch(qs->local_addr.ss_family) {
|
||||
switch(qs->local_addr.sa_family) {
|
||||
case AF_INET:
|
||||
pktlen = NGTCP2_MAX_PKTLEN_IPV4;
|
||||
break;
|
||||
@@ -1834,7 +1835,7 @@ static CURLcode ng_flush_egress(struct connectdata *conn, int sockfd,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if(outlen == NGTCP2_ERR_WRITE_STREAM_MORE) {
|
||||
else if(outlen == NGTCP2_ERR_WRITE_MORE) {
|
||||
assert(ndatalen > 0);
|
||||
rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id,
|
||||
ndatalen);
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ struct quicsocket {
|
||||
struct quic_handshake crypto_data[3];
|
||||
/* the last TLS alert description generated by the local endpoint */
|
||||
uint8_t tls_alert;
|
||||
struct sockaddr_storage local_addr;
|
||||
struct sockaddr local_addr;
|
||||
socklen_t local_addrlen;
|
||||
|
||||
nghttp3_conn *h3conn;
|
||||
|
||||
+8
-2
@@ -95,8 +95,14 @@ static CURLcode qs_disconnect(struct quicsocket *qs)
|
||||
quiche_h3_config_free(qs->h3config);
|
||||
if(qs->h3c)
|
||||
quiche_h3_conn_free(qs->h3c);
|
||||
quiche_config_free(qs->cfg);
|
||||
quiche_conn_free(qs->conn);
|
||||
if(qs->cfg) {
|
||||
quiche_config_free(qs->cfg);
|
||||
qs->cfg = NULL;
|
||||
}
|
||||
if(qs->conn) {
|
||||
quiche_conn_free(qs->conn);
|
||||
qs->conn = NULL;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1256,7 +1256,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
result = CURLE_SSH;
|
||||
sshc->actualcode = result;
|
||||
DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
|
||||
ssherr, (int)result));
|
||||
sftperr, (int)result));
|
||||
state(conn, SSH_STOP);
|
||||
break;
|
||||
}
|
||||
|
||||
+9
-2
@@ -300,8 +300,12 @@ static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
#else
|
||||
const char *hostname = conn->host.name;
|
||||
#endif
|
||||
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
|
||||
const bool verifyhost = SSL_CONN_CONFIG(verifyhost);
|
||||
CURLcode ret;
|
||||
@@ -386,8 +390,11 @@ static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
(!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
|
||||
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
|
||||
}
|
||||
|
||||
+41
-13
@@ -399,10 +399,15 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
#endif
|
||||
const char *prioritylist;
|
||||
const char *err = NULL;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
long * const certverifyresult = SSL_IS_PROXY() ?
|
||||
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
|
||||
#else
|
||||
const char * const hostname = conn->host.name;
|
||||
long * const certverifyresult = &data->set.ssl.certverifyresult;
|
||||
#endif
|
||||
|
||||
if(connssl->state == ssl_connection_complete)
|
||||
/* to make us tolerant against being called more than once for the
|
||||
@@ -620,8 +625,11 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
gnutls_datum_t protocols[2];
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
(!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
|
||||
protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||
cur++;
|
||||
@@ -694,12 +702,15 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
transport_ptr = conn->proxy_ssl[sockindex].backend->session;
|
||||
gnutls_transport_push = Curl_gtls_push_ssl;
|
||||
gnutls_transport_pull = Curl_gtls_pull_ssl;
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* file descriptor for the socket */
|
||||
transport_ptr = &conn->sock[sockindex];
|
||||
gnutls_transport_push = Curl_gtls_push;
|
||||
@@ -828,10 +839,15 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
unsigned int bits;
|
||||
gnutls_protocol_t version = gnutls_protocol_get_version(session);
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
long * const certverifyresult = SSL_IS_PROXY() ?
|
||||
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
|
||||
#else
|
||||
const char * const hostname = conn->host.name;
|
||||
long * const certverifyresult = &data->set.ssl.certverifyresult;
|
||||
#endif
|
||||
|
||||
/* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
|
||||
ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
|
||||
@@ -1112,8 +1128,12 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
if(!rc) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char * const dispname = SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.dispname : conn->host.dispname;
|
||||
#else
|
||||
const char * const dispname = conn->host.dispname;
|
||||
#endif
|
||||
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
failf(data, "SSL: certificate subject name (%s) does not match "
|
||||
@@ -1216,20 +1236,23 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
|
||||
|
||||
rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields);
|
||||
if(rc != 0)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
infof(data, "\t subject: %s\n", certfields.data);
|
||||
if(rc)
|
||||
infof(data, "Failed to get certificate name\n");
|
||||
else {
|
||||
infof(data, "\t subject: %s\n", certfields.data);
|
||||
|
||||
certclock = gnutls_x509_crt_get_activation_time(x509_cert);
|
||||
showtime(data, "start date", certclock);
|
||||
certclock = gnutls_x509_crt_get_activation_time(x509_cert);
|
||||
showtime(data, "start date", certclock);
|
||||
|
||||
certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
|
||||
showtime(data, "expire date", certclock);
|
||||
certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
|
||||
showtime(data, "expire date", certclock);
|
||||
}
|
||||
|
||||
rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields);
|
||||
if(rc != 0)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
infof(data, "\t issuer: %s\n", certfields.data);
|
||||
if(rc)
|
||||
infof(data, "Failed to get certificate issuer\n");
|
||||
else
|
||||
infof(data, "\t issuer: %s\n", certfields.data);
|
||||
#endif
|
||||
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
@@ -1381,10 +1404,13 @@ static bool Curl_gtls_data_pending(const struct connectdata *conn,
|
||||
0 != gnutls_record_check_pending(backend->session))
|
||||
res = TRUE;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
connssl = &conn->proxy_ssl[connindex];
|
||||
backend = connssl->backend;
|
||||
if(backend->session &&
|
||||
0 != gnutls_record_check_pending(backend->session))
|
||||
res = TRUE;
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1433,7 +1459,9 @@ static void close_one(struct ssl_connect_data *connssl)
|
||||
static void Curl_gtls_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
close_one(&conn->ssl[sockindex]);
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
close_one(&conn->proxy_ssl[sockindex]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+35
-9
@@ -1027,9 +1027,11 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
|
||||
CERTCertificate *cert;
|
||||
|
||||
/* remember the cert verification result */
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(SSL_IS_PROXY())
|
||||
data->set.proxy_ssl.certverifyresult = err;
|
||||
else
|
||||
#endif
|
||||
data->set.ssl.certverifyresult = err;
|
||||
|
||||
if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
|
||||
@@ -1553,24 +1555,32 @@ static void nss_close(struct ssl_connect_data *connssl)
|
||||
static void Curl_nss_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
|
||||
#endif
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
|
||||
if(backend->handle || connssl_proxy->backend->handle) {
|
||||
if(backend->handle
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
|| connssl_proxy->backend->handle
|
||||
#endif
|
||||
) {
|
||||
/* NSS closes the socket we previously handed to it, so we must mark it
|
||||
as closed to avoid double close */
|
||||
fake_sclose(conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(backend->handle)
|
||||
/* nss_close(connssl) will transitively close also
|
||||
connssl_proxy->backend->handle if both are used. Clear it to avoid
|
||||
a double close leading to crash. */
|
||||
connssl_proxy->backend->handle = NULL;
|
||||
|
||||
nss_close(connssl);
|
||||
nss_close(connssl_proxy);
|
||||
#endif
|
||||
nss_close(connssl);
|
||||
}
|
||||
|
||||
/* return true if NSS can provide error code (and possibly msg) for the
|
||||
@@ -1828,6 +1838,12 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
CURLcode result;
|
||||
bool second_layer = FALSE;
|
||||
SSLVersionRange sslver_supported;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
#else
|
||||
const char *hostname = conn->host.name;
|
||||
#endif
|
||||
|
||||
SSLVersionRange sslver = {
|
||||
SSL_LIBRARY_VERSION_TLS_1_0, /* min */
|
||||
@@ -1932,9 +1948,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
|
||||
/* not checked yet */
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(SSL_IS_PROXY())
|
||||
data->set.proxy_ssl.certverifyresult = 0;
|
||||
else
|
||||
#endif
|
||||
data->set.ssl.certverifyresult = 0;
|
||||
|
||||
if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
|
||||
@@ -1991,12 +2009,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
|
||||
DEBUGASSERT(conn->proxy_ssl[sockindex].backend->handle != NULL);
|
||||
nspr_io = conn->proxy_ssl[sockindex].backend->handle;
|
||||
second_layer = TRUE;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
/* wrap OS file descriptor by NSPR's file descriptor abstraction */
|
||||
nspr_io = PR_ImportTCPSocket(sockfd);
|
||||
@@ -2077,8 +2097,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
unsigned char protocols[128];
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
(!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
) {
|
||||
protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||
memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN);
|
||||
@@ -2101,14 +2124,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
|
||||
/* propagate hostname to the TLS layer */
|
||||
if(SSL_SetURL(backend->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name) != SECSuccess)
|
||||
if(SSL_SetURL(backend->handle, hostname) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
/* prevent NSS from re-using the session for a different hostname */
|
||||
if(SSL_SetSockPeerID(backend->handle, SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.name : conn->host.name)
|
||||
!= SECSuccess)
|
||||
if(SSL_SetSockPeerID(backend->handle, hostname) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -2127,11 +2147,17 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_SSL_CONNECT_ERROR;
|
||||
PRUint32 timeout;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
long * const certverifyresult = SSL_IS_PROXY() ?
|
||||
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
|
||||
const char * const pinnedpubkey = SSL_IS_PROXY() ?
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
|
||||
#else
|
||||
long * const certverifyresult = &data->set.ssl.certverifyresult;
|
||||
const char * const pinnedpubkey =
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
|
||||
#endif
|
||||
|
||||
|
||||
/* check timeout situation */
|
||||
|
||||
+5
-2
@@ -619,7 +619,9 @@ SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO* in,
|
||||
const char *key_passwd)
|
||||
{
|
||||
/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) /* 1.0.2 or later */
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \
|
||||
!(defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
(LIBRESSL_VERSION_NUMBER < 0x2090100fL)) /* LibreSSL 2.9.1 or later */
|
||||
int ret = 0;
|
||||
X509 *x = NULL;
|
||||
void *passwd_callback_userdata = (void *)key_passwd;
|
||||
@@ -2825,7 +2827,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) &&
|
||||
(SSL_SET_OPTION(native_ca_store))) {
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx);
|
||||
HCERTSTORE hStore = CertOpenSystemStoreA((HCRYPTPROV_LEGACY)NULL, "ROOT");
|
||||
HCERTSTORE hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL,
|
||||
TEXT("ROOT"));
|
||||
|
||||
if(hStore) {
|
||||
PCCERT_CONTEXT pContext = NULL;
|
||||
|
||||
+10
-10
@@ -50,7 +50,7 @@
|
||||
#include "x509asn1.h"
|
||||
#include "curl_printf.h"
|
||||
#include "multiif.h"
|
||||
#include "system_win32.h"
|
||||
#include "version_win32.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "curl_memory.h"
|
||||
@@ -436,8 +436,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
"schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
|
||||
hostname, conn->remote_port));
|
||||
|
||||
if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
|
||||
VERSION_LESS_THAN_EQUAL)) {
|
||||
if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT,
|
||||
VERSION_LESS_THAN_EQUAL)) {
|
||||
/* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
|
||||
algorithms that may not be supported by all servers. */
|
||||
infof(data, "schannel: Windows version is old and may not be able to "
|
||||
@@ -448,10 +448,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
/* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
|
||||
Also it doesn't seem to be supported for Wine, see curl bug #983. */
|
||||
BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
|
||||
!GetProcAddress(GetModuleHandleA("ntdll"),
|
||||
!GetProcAddress(GetModuleHandle(TEXT("ntdll")),
|
||||
"wine_get_version") &&
|
||||
Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL);
|
||||
curlx_verify_windows_version(6, 3, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL);
|
||||
#else
|
||||
BACKEND->use_alpn = false;
|
||||
#endif
|
||||
@@ -467,8 +467,8 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
#else
|
||||
#ifdef HAS_MANUAL_VERIFY_API
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
BACKEND->use_manual_cred_validation = true;
|
||||
}
|
||||
else {
|
||||
@@ -2015,8 +2015,8 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
*/
|
||||
if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
|
||||
!BACKEND->recv_sspi_close_notify) {
|
||||
bool isWin2k = Curl_verify_windows_version(5, 0, PLATFORM_WINNT,
|
||||
VERSION_EQUAL);
|
||||
bool isWin2k = curlx_verify_windows_version(5, 0, PLATFORM_WINNT,
|
||||
VERSION_EQUAL);
|
||||
|
||||
if(isWin2k && sspi_status == SEC_E_OK)
|
||||
BACKEND->recv_sspi_close_notify = true;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_printf.h"
|
||||
#include "hostcheck.h"
|
||||
#include "system_win32.h"
|
||||
#include "version_win32.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "curl_memory.h"
|
||||
@@ -317,8 +317,8 @@ static DWORD cert_get_name_string(struct Curl_easy *data,
|
||||
DWORD i;
|
||||
|
||||
/* CERT_NAME_SEARCH_ALL_NAMES_FLAG is available from Windows 8 onwards. */
|
||||
if(Curl_verify_windows_version(6, 2, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
if(curlx_verify_windows_version(6, 2, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL)) {
|
||||
#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
|
||||
/* CertGetNameString will provide the 8-bit character string without
|
||||
* any decoding */
|
||||
@@ -564,7 +564,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex)
|
||||
* trusted certificates. This is only supported on Windows 7+.
|
||||
*/
|
||||
|
||||
if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
|
||||
if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
|
||||
failf(data, "schannel: this version of Windows is too old to support "
|
||||
"certificate verification via CA bundle file.");
|
||||
result = CURLE_SSL_CACERT_BADFILE;
|
||||
|
||||
@@ -621,6 +621,7 @@ void Curl_ssl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
|
||||
Curl_ssl->close_one(conn, sockindex);
|
||||
conn->ssl[sockindex].state = ssl_connection_none;
|
||||
}
|
||||
|
||||
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
Reference in New Issue
Block a user