mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-08 15:19:51 -05:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2017-04-19 (d957e218) Resolve conflicts in `CMakeLists.txt` in favor of the upstream version. We will re-apply our logic as needed in following commits.
This commit is contained in:
@@ -533,3 +533,19 @@ main () {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FSETXATTR_6
|
||||
#include <sys/xattr.h> /* header from libc, not from libattr */
|
||||
int
|
||||
main() {
|
||||
fsetxattr(0, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_FSETXATTR_5
|
||||
#include <sys/xattr.h> /* header from libc, not from libattr */
|
||||
int
|
||||
main() {
|
||||
fsetxattr(0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# GSS_LINKER_FLAGS - Additional linker flags
|
||||
# GSS_COMPILER_FLAGS - Additional compiler flags
|
||||
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
|
||||
# In case the library is found but no version info availabe it'll be set to "unknown"
|
||||
# In case the library is found but no version info available it'll be set to "unknown"
|
||||
|
||||
set(_MIT_MODNAME mit-krb5-gssapi)
|
||||
set(_HEIMDAL_MODNAME heimdal-gssapi)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
|
||||
|
||||
find_library(MBEDTLS_LIBRARY mbedtls)
|
||||
find_library(MBEDX509_LIBRARY mbedx509)
|
||||
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
|
||||
|
||||
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
|
||||
MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
||||
|
||||
mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
||||
@@ -29,3 +29,16 @@ function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
|
||||
set(${RETVAL} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Returns a list of arguments that evaluate to true
|
||||
function(collect_true output_var output_count_var)
|
||||
set(${output_var})
|
||||
foreach(option_var IN LISTS ARGN)
|
||||
if(${option_var})
|
||||
list(APPEND ${output_var} ${option_var})
|
||||
endif()
|
||||
endforeach()
|
||||
set(${output_var} ${${output_var}} PARENT_SCOPE)
|
||||
list(LENGTH ${output_var} ${output_count_var})
|
||||
set(${output_count_var} ${${output_count_var}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
+101
-80
@@ -290,6 +290,8 @@ if(ENABLE_MANUAL)
|
||||
message(WARNING "Found no *nroff program")
|
||||
endif()
|
||||
endif()
|
||||
# Required for building manual, docs, tests
|
||||
find_package(Perl REQUIRED)
|
||||
|
||||
# We need ansi c-flags, especially on HP
|
||||
set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}")
|
||||
@@ -367,60 +369,91 @@ if(WIN32)
|
||||
check_library_exists_concat("winmm" getch HAVE_LIBWINMM)
|
||||
endif()
|
||||
|
||||
set(USE_OPENSSL OFF)
|
||||
set(HAVE_LIBCRYPTO OFF)
|
||||
set(HAVE_LIBSSL OFF)
|
||||
# check SSL libraries
|
||||
# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL
|
||||
|
||||
if(APPLE)
|
||||
option(CMAKE_USE_DARWINSSL "enable Apple OS native SSL/TLS" OFF)
|
||||
endif()
|
||||
if(WIN32)
|
||||
option(CMAKE_USE_WINSSL "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)
|
||||
endif()
|
||||
option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
|
||||
|
||||
set(openssl_default ON)
|
||||
if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
|
||||
set(openssl_default OFF)
|
||||
endif()
|
||||
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
|
||||
|
||||
collect_true(enabled_ssl_options enabled_ssl_options_count
|
||||
CMAKE_USE_WINSSL
|
||||
CMAKE_USE_DARWINSSL
|
||||
CMAKE_USE_OPENSSL
|
||||
CMAKE_USE_MBEDTLS
|
||||
)
|
||||
if(enabled_ssl_options_count GREATER 1)
|
||||
message(FATAL_ERROR "Multiple SSL options specified: ${enabled_ssl_options}. Please pick at most one and disable the rest.")
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_WINSSL)
|
||||
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
|
||||
list(APPEND CURL_LIBS "crypt32")
|
||||
endif()
|
||||
if(CURL_WINDOWS_SSPI)
|
||||
set(USE_WINDOWS_SSPI ON)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_DARWINSSL)
|
||||
find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
|
||||
if(NOT COREFOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "CoreFoundation framework not found")
|
||||
endif()
|
||||
|
||||
find_library(SECURITY_FRAMEWORK "Security")
|
||||
if(NOT SECURITY_FRAMEWORK)
|
||||
message(FATAL_ERROR "Security framework not found")
|
||||
endif()
|
||||
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_DARWINSSL ON)
|
||||
list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_OPENSSL)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
|
||||
set(USE_OPENSSL ON)
|
||||
set(HAVE_LIBCRYPTO ON)
|
||||
set(HAVE_LIBSSL ON)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
|
||||
check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
|
||||
check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H)
|
||||
check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H)
|
||||
check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
|
||||
check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
|
||||
check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
|
||||
check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H)
|
||||
check_include_file("openssl/rand.h" HAVE_OPENSSL_RAND_H)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_OPENSSL ON)
|
||||
set(HAVE_LIBCRYPTO ON)
|
||||
set(HAVE_LIBSSL ON)
|
||||
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
check_include_file("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
|
||||
check_include_file("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
|
||||
check_include_file("openssl/err.h" HAVE_OPENSSL_ERR_H)
|
||||
check_include_file("openssl/pem.h" HAVE_OPENSSL_PEM_H)
|
||||
check_include_file("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
|
||||
check_include_file("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
|
||||
check_include_file("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
|
||||
check_include_file("openssl/x509.h" HAVE_OPENSSL_X509_H)
|
||||
check_include_file("openssl/rand.h" HAVE_OPENSSL_RAND_H)
|
||||
check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
|
||||
check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
|
||||
check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
|
||||
endif()
|
||||
|
||||
# Optionally build with a specific CA cert bundle.
|
||||
if(CURL_CA_BUNDLE)
|
||||
add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}")
|
||||
endif()
|
||||
# Optionally build with a specific CA cert dir.
|
||||
if(CURL_CA_PATH)
|
||||
add_definitions(-DCURL_CA_PATH="${CURL_CA_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
# Use Windows SSL/TLS native implementation.
|
||||
set(CURL_WINDOWS_SSPI ON)
|
||||
elseif(APPLE)
|
||||
# Use OS X SSL/TLS native implementation if available on target version.
|
||||
if(CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND sw_vers -productVersion
|
||||
OUTPUT_VARIABLE OSX_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif()
|
||||
if(NOT OSX_VERSION VERSION_LESS 10.6 AND
|
||||
CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
||||
add_definitions(-DUSE_DARWINSSL)
|
||||
list(APPEND CURL_LIBS
|
||||
"-framework CoreFoundation"
|
||||
"-framework Security"
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_USE_MBEDTLS)
|
||||
find_package(MbedTLS REQUIRED)
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_MBEDTLS ON)
|
||||
list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
|
||||
include_directories(${MBEDTLS_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
|
||||
@@ -681,18 +714,8 @@ if(NOT UNIX)
|
||||
check_include_file_concat("winsock.h" HAVE_WINSOCK_H)
|
||||
check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H)
|
||||
check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H)
|
||||
if(CURL_WINDOWS_SSPI)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -DSECURITY_WIN32")
|
||||
check_include_file_concat("sspi.h" HAVE_SSPI_H)
|
||||
if(HAVE_SSPI_H)
|
||||
check_include_file_concat("schannel.h" HAVE_SCHANNEL_H)
|
||||
set(USE_WINDOWS_SSPI ON)
|
||||
if(HAVE_SCHANNEL_H)
|
||||
set(USE_SCHANNEL ON)
|
||||
set(SSL_ENABLED ON)
|
||||
set(CURL_LIBS ${CURL_LIBS} "crypt32")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL)
|
||||
set(CURL_LIBS ${CURL_LIBS} "crypt32")
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_WINDOWS_H 0)
|
||||
@@ -717,6 +740,7 @@ check_include_file_concat("sys/types.h" HAVE_SYS_TYPES_H)
|
||||
check_include_file_concat("sys/uio.h" HAVE_SYS_UIO_H)
|
||||
check_include_file_concat("sys/un.h" HAVE_SYS_UN_H)
|
||||
check_include_file_concat("sys/utime.h" HAVE_SYS_UTIME_H)
|
||||
check_include_file_concat("sys/xattr.h" HAVE_SYS_XATTR_H)
|
||||
check_include_file_concat("alloca.h" HAVE_ALLOCA_H)
|
||||
check_include_file_concat("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||
check_include_file_concat("arpa/tftp.h" HAVE_ARPA_TFTP_H)
|
||||
@@ -837,14 +861,6 @@ check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT)
|
||||
check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
|
||||
check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
|
||||
check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME)
|
||||
if(CMAKE_USE_OPENSSL)
|
||||
check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
|
||||
check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
|
||||
check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
|
||||
if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
|
||||
set(USE_OPENSSL 1)
|
||||
endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
|
||||
endif(CMAKE_USE_OPENSSL)
|
||||
check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
|
||||
check_symbol_exists(localtime_r "${CURL_INCLUDES}" HAVE_LOCALTIME_R)
|
||||
|
||||
@@ -879,6 +895,13 @@ check_symbol_exists(setsockopt "${CURL_INCLUDES}" HAVE_SETSOCKOPT)
|
||||
# symbol exists in win32, but function does not.
|
||||
check_function_exists(inet_pton HAVE_INET_PTON)
|
||||
|
||||
check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
|
||||
if(HAVE_FSETXATTR)
|
||||
foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
|
||||
curl_internal_test_run(${CURL_TEST})
|
||||
endforeach(CURL_TEST)
|
||||
endif(HAVE_FSETXATTR)
|
||||
|
||||
# sigaction and sigsetjmp are special. Use special mechanism for
|
||||
# detecting those, but only if previous attempt failed.
|
||||
if(HAVE_SIGNAL_H)
|
||||
@@ -1092,9 +1115,9 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
|
||||
string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
|
||||
string(REGEX REPLACE "\\\\\n" "§!§" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
string(REPLACE "§!§" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
|
||||
string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${}
|
||||
string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts.
|
||||
@@ -1102,6 +1125,7 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
|
||||
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(docs)
|
||||
add_subdirectory(lib)
|
||||
if(BUILD_CURL_EXE)
|
||||
add_subdirectory(src)
|
||||
@@ -1125,11 +1149,6 @@ if(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL, WINSSL, DARWINSSL
|
||||
if(USE_OPENSSL)
|
||||
set(SSL_ENABLED 1)
|
||||
endif()
|
||||
|
||||
# Helper to populate a list (_items) with a label when conditions (the remaining
|
||||
# args) are satisfied
|
||||
function(_add_if label)
|
||||
@@ -1143,6 +1162,8 @@ endfunction()
|
||||
set(_items)
|
||||
_add_if("WinSSL" SSL_ENABLED AND USE_WINDOWS_SSPI)
|
||||
_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL)
|
||||
_add_if("DarwinSSL" SSL_ENABLED AND USE_DARWINSSL)
|
||||
_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS)
|
||||
_add_if("IPv6" ENABLE_IPV6)
|
||||
_add_if("unix-sockets" USE_UNIX_SOCKETS)
|
||||
_add_if("libz" HAVE_LIBZ)
|
||||
@@ -1159,9 +1180,9 @@ _add_if("SPNEGO" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
_add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
|
||||
# NTLM support requires crypto function adaptions from various SSL libs
|
||||
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS, DARWINSSL
|
||||
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
|
||||
if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR
|
||||
USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR DARWINSSL_ENABLED))
|
||||
USE_WINDOWS_SSPI OR GNUTLS_ENABLED OR NSS_ENABLED OR USE_DARWINSSL OR USE_MBEDTLS))
|
||||
_add_if("NTLM" 1)
|
||||
# TODO missing option (autoconf: --enable-ntlm-wb)
|
||||
_add_if("NTLM_WB" NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2016, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
Copyright (c) 1996 - 2017, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
contributors, see the THANKS file.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -35,6 +35,7 @@
|
||||
#endif
|
||||
|
||||
#include "curlver.h" /* libcurl version defines */
|
||||
#include "system.h" /* determine things run-time */
|
||||
#include "cmcurl/include/curl/curlbuild.h" /* libcurl build definitions */
|
||||
#include "curlrules.h" /* libcurl rules enforcement */
|
||||
|
||||
@@ -193,6 +194,11 @@ typedef int (*curl_xferinfo_callback)(void *clientp,
|
||||
curl_off_t ultotal,
|
||||
curl_off_t ulnow);
|
||||
|
||||
#ifndef CURL_MAX_READ_SIZE
|
||||
/* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
|
||||
#define CURL_MAX_READ_SIZE 524288
|
||||
#endif
|
||||
|
||||
#ifndef CURL_MAX_WRITE_SIZE
|
||||
/* Tests have proven that 20K is a very bad buffer size for uploads on
|
||||
Windows, while 16K for some odd reason performed a lot better.
|
||||
@@ -479,7 +485,7 @@ typedef enum {
|
||||
CURLE_LDAP_CANNOT_BIND, /* 38 */
|
||||
CURLE_LDAP_SEARCH_FAILED, /* 39 */
|
||||
CURLE_OBSOLETE40, /* 40 - NOT USED */
|
||||
CURLE_FUNCTION_NOT_FOUND, /* 41 */
|
||||
CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */
|
||||
CURLE_ABORTED_BY_CALLBACK, /* 42 */
|
||||
CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
|
||||
CURLE_OBSOLETE44, /* 44 - NOT USED */
|
||||
@@ -1595,7 +1601,7 @@ typedef enum {
|
||||
CINIT(DNS_SERVERS, STRINGPOINT, 211),
|
||||
|
||||
/* Time-out accept operations (currently for FTP only) after this amount
|
||||
of miliseconds. */
|
||||
of milliseconds. */
|
||||
CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
|
||||
|
||||
/* Set TCP keepalive */
|
||||
@@ -1770,6 +1776,12 @@ typedef enum {
|
||||
this option is used only if PROXY_SSL_VERIFYPEER is true */
|
||||
CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
|
||||
|
||||
/* Path to an abstract Unix domain socket */
|
||||
CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
|
||||
|
||||
/* Suppress proxy CONNECT response headers from user callbacks */
|
||||
CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -1876,6 +1888,18 @@ enum {
|
||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||
};
|
||||
|
||||
enum {
|
||||
CURL_SSLVERSION_MAX_NONE = 0,
|
||||
CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16),
|
||||
CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16),
|
||||
CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16),
|
||||
CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16),
|
||||
CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16),
|
||||
|
||||
/* never use, keep last */
|
||||
CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16)
|
||||
};
|
||||
|
||||
enum CURL_TLSAUTH {
|
||||
CURL_TLSAUTH_NONE,
|
||||
CURL_TLSAUTH_SRP,
|
||||
@@ -2438,7 +2462,7 @@ typedef struct {
|
||||
#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */
|
||||
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
|
||||
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper
|
||||
is suported */
|
||||
is supported */
|
||||
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
|
||||
#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */
|
||||
#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -105,11 +105,6 @@
|
||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_FORMAT_OFF_T
|
||||
# error "CURL_FORMAT_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
|
||||
#endif
|
||||
|
||||
#ifndef CURL_SIZEOF_CURL_OFF_T
|
||||
# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
|
||||
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
|
||||
@@ -241,22 +236,4 @@ typedef char
|
||||
#undef CurlchkszEQ
|
||||
#undef CurlchkszGE
|
||||
|
||||
/*
|
||||
* Get rid of macros not intended to exist beyond this point.
|
||||
*/
|
||||
|
||||
#undef CURL_PULL_WS2TCPIP_H
|
||||
#undef CURL_PULL_SYS_TYPES_H
|
||||
#undef CURL_PULL_SYS_SOCKET_H
|
||||
#undef CURL_PULL_SYS_POLL_H
|
||||
#undef CURL_PULL_STDINT_H
|
||||
#undef CURL_PULL_INTTYPES_H
|
||||
|
||||
#undef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||
#undef CURL_TYPEOF_CURL_OFF_T
|
||||
|
||||
#ifdef CURL_NO_OLDIES
|
||||
#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
|
||||
#endif
|
||||
|
||||
#endif /* __CURL_CURLRULES_H */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -26,17 +26,17 @@
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, <daniel@haxx.se>."
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.52.1"
|
||||
#define LIBCURL_VERSION "7.54.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 52
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
#define LIBCURL_VERSION_MINOR 54
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions 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 0x073401
|
||||
#define LIBCURL_VERSION_NUM 0x073600
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -0,0 +1,484 @@
|
||||
#ifndef __CURL_SYSTEM_H
|
||||
#define __CURL_SYSTEM_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This header is supposed to eventually replace curlbuild.h. This little one
|
||||
* is still learning. During the experimental phase, this header files
|
||||
* defines symbols using the prefixes CURLSYS_ or curlsys_. When we feel
|
||||
* confident enough, we replace curlbuild.h with this file and rename all
|
||||
* prefixes to CURL_ and curl_.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Try to keep one section per platform, compiler and architecture, otherwise,
|
||||
* if an existing section is reused for a different one and later on the
|
||||
* original is adjusted, probably the piggybacking one can be adversely
|
||||
* changed.
|
||||
*
|
||||
* In order to differentiate between platforms/compilers/architectures use
|
||||
* only compiler built in predefined preprocessor symbols.
|
||||
*
|
||||
* curl_off_t
|
||||
* ----------
|
||||
*
|
||||
* For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
|
||||
* wide signed integral data type. The width of this data type must remain
|
||||
* constant and independent of any possible large file support settings.
|
||||
*
|
||||
* As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
|
||||
* wide signed integral data type if there is no 64-bit type.
|
||||
*
|
||||
* As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
|
||||
* only be violated if off_t is the only 64-bit data type available and the
|
||||
* size of off_t is independent of large file support settings. Keep your
|
||||
* build on the safe side avoiding an off_t gating. If you have a 64-bit
|
||||
* off_t then take for sure that another 64-bit data type exists, dig deeper
|
||||
* and you will find it.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(__DJGPP__) || defined(__GO32__)
|
||||
# if defined(__DJGPP__) && (__DJGPP__ > 1)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# else
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__SALFORDC__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
# if (__BORLANDC__ < 0x520)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T i64
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ui64
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
# if defined(__386__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T i64
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__POCC__)
|
||||
# if (__POCC__ < 280)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# elif defined(_MSC_VER)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T i64
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__LCC__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
# if defined(__EABI__) /* Treat all ARM compilers equally */
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__CW32__)
|
||||
# pragma longlong on
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__VC32__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__MWERKS__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(_WIN32_WCE)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T i64
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ui64
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
# define CURLSYS_PULL_SYS_TYPES_H 1
|
||||
# define CURLSYS_PULL_WS2TCPIP_H 1
|
||||
|
||||
#elif defined(__VMS)
|
||||
# if defined(__VAX)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T unsigned int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__OS400__)
|
||||
# if defined(__ILEC400__)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
# define CURLSYS_PULL_SYS_TYPES_H 1
|
||||
# define CURLSYS_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(__MVS__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# elif defined(_LP64)
|
||||
# define CURLSYS_SIZEOF_LONG 8
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
# define CURLSYS_PULL_SYS_TYPES_H 1
|
||||
# define CURLSYS_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(__370__)
|
||||
# if defined(__IBMC__) || defined(__IBMCPP__)
|
||||
# if defined(_ILP32)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# elif defined(_LP64)
|
||||
# define CURLSYS_SIZEOF_LONG 8
|
||||
# endif
|
||||
# if defined(_LONG_LONG)
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(_LP64)
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# else
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
# define CURLSYS_PULL_SYS_TYPES_H 1
|
||||
# define CURLSYS_PULL_SYS_SOCKET_H 1
|
||||
# endif
|
||||
|
||||
#elif defined(TPF)
|
||||
# define CURLSYS_SIZEOF_LONG 8
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
#elif defined(__TINYC__) /* also known as tcc */
|
||||
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURLSYS_PULL_SYS_TYPES_H 1
|
||||
# define CURLSYS_PULL_SYS_SOCKET_H 1
|
||||
|
||||
/* ===================================== */
|
||||
/* KEEP MSVC THE PENULTIMATE ENTRY */
|
||||
/* ===================================== */
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T __int64
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "I64d"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "I64u"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T i64
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ui64
|
||||
# else
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
|
||||
/* ===================================== */
|
||||
/* KEEP GENERIC GCC THE LAST ENTRY */
|
||||
/* ===================================== */
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
# if !defined(__LP64__) && (defined(__ILP32__) || \
|
||||
defined(__i386__) || defined(__ppc__) || defined(__arm__) || \
|
||||
defined(__sparc__) || defined(__mips__) || defined(__sh__))
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "lld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "llu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T LL
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU ULL
|
||||
# elif defined(__LP64__) || \
|
||||
defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__)
|
||||
# define CURLSYS_SIZEOF_LONG 8
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 8
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# endif
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
# define CURLSYS_PULL_SYS_TYPES_H 1
|
||||
# define CURLSYS_PULL_SYS_SOCKET_H 1
|
||||
|
||||
#else
|
||||
/* generic "safe guess" on old 32 bit style */
|
||||
# define CURLSYS_SIZEOF_LONG 4
|
||||
# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4
|
||||
# define CURLSYS_SIZEOF_CURL_OFF_T 4
|
||||
# define CURLSYS_TYPEOF_CURL_OFF_T long
|
||||
# define CURLSYS_FORMAT_CURL_OFF_T "ld"
|
||||
# define CURLSYS_FORMAT_CURL_OFF_TU "lu"
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_T L
|
||||
# define CURLSYS_SUFFIX_CURL_OFF_TU UL
|
||||
# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int
|
||||
#endif
|
||||
|
||||
/* CURLSYS_PULL_WS2TCPIP_H is defined above when inclusion of header file */
|
||||
/* ws2tcpip.h is required here to properly make type definitions below. */
|
||||
#ifdef CURLSYS_PULL_WS2TCPIP_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
/* CURLSYS_PULL_SYS_TYPES_H is defined above when inclusion of header file */
|
||||
/* sys/types.h is required here to properly make type definitions below. */
|
||||
#ifdef CURLSYS_PULL_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* CURLSYS_PULL_SYS_SOCKET_H is defined above when inclusion of header file */
|
||||
/* sys/socket.h is required here to properly make type definitions below. */
|
||||
#ifdef CURLSYS_PULL_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* Data type definition of curl_socklen_t. */
|
||||
#ifdef CURLSYS_TYPEOF_CURL_SOCKLEN_T
|
||||
typedef CURLSYS_TYPEOF_CURL_SOCKLEN_T curlsys_socklen_t;
|
||||
#endif
|
||||
|
||||
/* Data type definition of curl_off_t. */
|
||||
|
||||
#ifdef CURLSYS_TYPEOF_CURL_OFF_T
|
||||
typedef CURLSYS_TYPEOF_CURL_OFF_T curlsys_off_t;
|
||||
#endif
|
||||
|
||||
#endif /* __CURL_SYSTEM_H */
|
||||
|
||||
@@ -219,7 +219,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
|
||||
/* evaluates to true if option takes a char* argument */
|
||||
#define _curl_is_string_option(option) \
|
||||
((option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
|
||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
(option) == CURLOPT_CAINFO || \
|
||||
(option) == CURLOPT_CAPATH || \
|
||||
(option) == CURLOPT_COOKIE || \
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -358,12 +358,20 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct timeval now = Curl_tvnow();
|
||||
struct Curl_dns_entry *temp_entry;
|
||||
|
||||
if(entry)
|
||||
*entry = NULL; /* clear on entry */
|
||||
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(timeout < 0) {
|
||||
/* already expired! */
|
||||
connclose(conn, "Timed out before name resolve started");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
if(!timeout)
|
||||
timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
|
||||
|
||||
/* Wait for the name resolve query to complete. */
|
||||
for(;;) {
|
||||
while(!result) {
|
||||
struct timeval *tvp, tv, store;
|
||||
long timediff;
|
||||
int itimeout;
|
||||
@@ -385,28 +393,25 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
timeout_ms = 1000;
|
||||
|
||||
waitperform(conn, timeout_ms);
|
||||
Curl_resolver_is_resolved(conn, &temp_entry);
|
||||
result = Curl_resolver_is_resolved(conn, &temp_entry);
|
||||
|
||||
if(conn->async.done)
|
||||
if(result || conn->async.done)
|
||||
break;
|
||||
|
||||
if(Curl_pgrsUpdate(conn)) {
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
timeout = -1; /* trigger the cancel below */
|
||||
}
|
||||
else {
|
||||
struct timeval now2 = Curl_tvnow();
|
||||
timediff = Curl_tvdiff(now2, now); /* spent time */
|
||||
timeout -= timediff?timediff:1; /* always deduct at least 1 */
|
||||
now = now2; /* for next loop */
|
||||
}
|
||||
|
||||
if(timeout < 0) {
|
||||
/* our timeout, so we cancel the ares operation */
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
break;
|
||||
}
|
||||
if(timeout < 0)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
if(result)
|
||||
/* failure, so we cancel the ares operation */
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
|
||||
/* Operation complete, if the lookup was successful we now have the entry
|
||||
in the cache. */
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012, 2016, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2017, 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
|
||||
@@ -56,11 +56,7 @@ static CURLcode bundle_create(struct Curl_easy *data,
|
||||
(*cb_ptr)->num_connections = 0;
|
||||
(*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
|
||||
|
||||
(*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
|
||||
if(!(*cb_ptr)->conn_list) {
|
||||
Curl_safefree(*cb_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -69,10 +65,8 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
|
||||
if(!cb_ptr)
|
||||
return;
|
||||
|
||||
if(cb_ptr->conn_list) {
|
||||
Curl_llist_destroy(cb_ptr->conn_list, NULL);
|
||||
cb_ptr->conn_list = NULL;
|
||||
}
|
||||
Curl_llist_destroy(&cb_ptr->conn_list, NULL);
|
||||
|
||||
free(cb_ptr);
|
||||
}
|
||||
|
||||
@@ -80,7 +74,7 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
|
||||
static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
|
||||
if(!Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->bundle = cb_ptr;
|
||||
@@ -95,10 +89,10 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr,
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = cb_ptr->conn_list->head;
|
||||
curr = cb_ptr->conn_list.head;
|
||||
while(curr) {
|
||||
if(curr->ptr == conn) {
|
||||
Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
|
||||
Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
|
||||
cb_ptr->num_connections--;
|
||||
conn->bundle = NULL;
|
||||
return 1; /* we removed a handle */
|
||||
@@ -127,8 +121,9 @@ void Curl_conncache_destroy(struct conncache *connc)
|
||||
Curl_hash_destroy(&connc->hash);
|
||||
}
|
||||
|
||||
/* returns an allocated key to find a bundle for this connection */
|
||||
static char *hashkey(struct connectdata *conn)
|
||||
/* creates a key to find a bundle for this connection */
|
||||
static void hashkey(struct connectdata *conn, char *buf,
|
||||
size_t len) /* something like 128 is fine */
|
||||
{
|
||||
const char *hostname;
|
||||
|
||||
@@ -141,7 +136,10 @@ static char *hashkey(struct connectdata *conn)
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
return aprintf("%s:%d", hostname, conn->port);
|
||||
DEBUGASSERT(len > 32);
|
||||
|
||||
/* put the number first so that the hostname gets cut off if too long */
|
||||
snprintf(buf, len, "%ld%s", conn->port, hostname);
|
||||
}
|
||||
|
||||
/* Look up the bundle with all the connections to the same host this
|
||||
@@ -151,11 +149,9 @@ struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
{
|
||||
struct connectbundle *bundle = NULL;
|
||||
if(connc) {
|
||||
char *key = hashkey(conn);
|
||||
if(key) {
|
||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
||||
free(key);
|
||||
}
|
||||
char key[128];
|
||||
hashkey(conn, key, sizeof(key));
|
||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
||||
}
|
||||
|
||||
return bundle;
|
||||
@@ -204,21 +200,16 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
|
||||
bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
|
||||
if(!bundle) {
|
||||
char *key;
|
||||
int rc;
|
||||
char key[128];
|
||||
|
||||
result = bundle_create(data, &new_bundle);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
key = hashkey(conn);
|
||||
if(!key) {
|
||||
bundle_destroy(new_bundle);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
hashkey(conn, key, sizeof(key));
|
||||
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
|
||||
free(key);
|
||||
|
||||
if(!rc) {
|
||||
bundle_destroy(new_bundle);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -292,7 +283,7 @@ void Curl_conncache_foreach(struct conncache *connc,
|
||||
bundle = he->ptr;
|
||||
he = Curl_hash_next_element(&iter);
|
||||
|
||||
curr = bundle->conn_list->head;
|
||||
curr = bundle->conn_list.head;
|
||||
while(curr) {
|
||||
/* Yes, we need to update curr before calling func(), because func()
|
||||
might decide to remove the connection */
|
||||
@@ -321,7 +312,7 @@ Curl_conncache_find_first_connection(struct conncache *connc)
|
||||
struct curl_llist_element *curr;
|
||||
bundle = he->ptr;
|
||||
|
||||
curr = bundle->conn_list->head;
|
||||
curr = bundle->conn_list.head;
|
||||
if(curr) {
|
||||
return curr->ptr;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -38,7 +38,7 @@ struct conncache {
|
||||
struct connectbundle {
|
||||
int multiuse; /* supports multi-use */
|
||||
size_t num_connections; /* Number of connections in the bundle */
|
||||
struct curl_llist *conn_list; /* The connectdata members of the bundle */
|
||||
struct curl_llist conn_list; /* The connectdata members of the bundle */
|
||||
};
|
||||
|
||||
int Curl_conncache_init(struct conncache *, int size);
|
||||
|
||||
@@ -810,8 +810,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
else
|
||||
infof(data, "Connection failed\n");
|
||||
infof(data, "Connection failed\n");
|
||||
}
|
||||
else if(rc & CURL_CSELECT_ERR)
|
||||
(void)verifyconnect(conn->tempsock[i], &error);
|
||||
@@ -1386,7 +1385,7 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
*/
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
int ctrl /* see defines in header */
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
, const char *reason
|
||||
#endif
|
||||
)
|
||||
|
||||
@@ -127,16 +127,16 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
|
||||
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
int closeit
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
, const char *reason
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
||||
#else /* if !CURLDEBUG */
|
||||
#else /* if !DEBUGBUILD || CURL_DISABLE_VERBOSE_STRINGS */
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
||||
|
||||
@@ -130,8 +130,7 @@ inflate_stream(struct connectdata *conn,
|
||||
free(decomp);
|
||||
if(inflateEnd(z) == Z_OK)
|
||||
return exit_zlib(z, &k->zlib_init, result);
|
||||
else
|
||||
return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
|
||||
return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
|
||||
}
|
||||
|
||||
/* Done with these bytes, exit */
|
||||
@@ -314,7 +313,7 @@ Curl_unencode_gzip_write(struct connectdata *conn,
|
||||
#ifndef OLD_ZLIB_SUPPORT
|
||||
/* Support for old zlib versions is compiled away and we are running with
|
||||
an old version, so return an error. */
|
||||
return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
|
||||
return exit_zlib(z, &k->zlib_init, CURLE_WRITE_ERROR);
|
||||
|
||||
#else
|
||||
/* This next mess is to get around the potential case where there isn't
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -492,7 +492,6 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
}
|
||||
else if(strcasecompare("domain", name)) {
|
||||
bool is_ip;
|
||||
const char *dotp;
|
||||
|
||||
/* Now, we make sure that our host is within the given domain,
|
||||
or the given domain is not valid and thus cannot be set. */
|
||||
@@ -500,12 +499,22 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if('.' == whatptr[0])
|
||||
whatptr++; /* ignore preceding dot */
|
||||
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
#ifndef USE_LIBPSL
|
||||
/*
|
||||
* Without PSL we don't know when the incoming cookie is set on a
|
||||
* TLD or otherwise "protected" suffix. To reduce risk, we require a
|
||||
* dot OR the exact host name being "localhost".
|
||||
*/
|
||||
{
|
||||
const char *dotp;
|
||||
/* check for more dots */
|
||||
dotp = strchr(whatptr, '.');
|
||||
if(!dotp && !strcasecompare("localhost", whatptr))
|
||||
domain=":";
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check for more dots */
|
||||
dotp = strchr(whatptr, '.');
|
||||
if(!dotp)
|
||||
domain=":";
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
|
||||
if(!domain
|
||||
|| (is_ip && !strcmp(whatptr, domain))
|
||||
@@ -920,9 +929,8 @@ static char *get_line(char *buf, int len, FILE *input)
|
||||
}
|
||||
return b;
|
||||
}
|
||||
else
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -1055,16 +1063,16 @@ static int cookie_sort(const void *p1, const void *p2)
|
||||
#define CLONE(field) \
|
||||
do { \
|
||||
if(src->field) { \
|
||||
dup->field = strdup(src->field); \
|
||||
if(!dup->field) \
|
||||
d->field = strdup(src->field); \
|
||||
if(!d->field) \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static struct Cookie *dup_cookie(struct Cookie *src)
|
||||
{
|
||||
struct Cookie *dup = calloc(sizeof(struct Cookie), 1);
|
||||
if(dup) {
|
||||
struct Cookie *d = calloc(sizeof(struct Cookie), 1);
|
||||
if(d) {
|
||||
CLONE(expirestr);
|
||||
CLONE(domain);
|
||||
CLONE(path);
|
||||
@@ -1073,16 +1081,16 @@ static struct Cookie *dup_cookie(struct Cookie *src)
|
||||
CLONE(value);
|
||||
CLONE(maxage);
|
||||
CLONE(version);
|
||||
dup->expires = src->expires;
|
||||
dup->tailmatch = src->tailmatch;
|
||||
dup->secure = src->secure;
|
||||
dup->livecookie = src->livecookie;
|
||||
dup->httponly = src->httponly;
|
||||
d->expires = src->expires;
|
||||
d->tailmatch = src->tailmatch;
|
||||
d->secure = src->secure;
|
||||
d->livecookie = src->livecookie;
|
||||
d->httponly = src->httponly;
|
||||
}
|
||||
return dup;
|
||||
return d;
|
||||
|
||||
fail:
|
||||
freecookie(dup);
|
||||
freecookie(d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -47,6 +47,8 @@
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "inet_pton.h"
|
||||
#include "warnless.h"
|
||||
@@ -467,7 +469,7 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, address, port);
|
||||
#ifdef ENABLE_IPV6
|
||||
else {
|
||||
{
|
||||
struct in6_addr in6;
|
||||
if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
|
||||
/* This is a dotted IPv6 address ::1-style */
|
||||
@@ -483,24 +485,29 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
* struct initialized with this path.
|
||||
* Set '*longpath' to TRUE if the error is a too long path.
|
||||
*/
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath)
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
struct sockaddr_un *sa_un;
|
||||
size_t path_len;
|
||||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
|
||||
if(!ai->ai_addr) {
|
||||
free(ai);
|
||||
*longpath = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
|
||||
/* sun_path must be able to store the NUL-terminated path */
|
||||
path_len = strlen(path);
|
||||
if(path_len >= sizeof(sa_un->sun_path)) {
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai->ai_addr);
|
||||
free(ai);
|
||||
*longpath = TRUE;
|
||||
@@ -509,10 +516,15 @@ Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath)
|
||||
|
||||
ai->ai_family = AF_UNIX;
|
||||
ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
|
||||
ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
|
||||
ai->ai_addrlen = (curl_socklen_t)
|
||||
((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF);
|
||||
|
||||
/* Abstract Unix domain socket have NULL prefix instead of suffix */
|
||||
if(abstract)
|
||||
memcpy(sa_un->sun_path + 1, path, path_len - 1);
|
||||
else
|
||||
memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */
|
||||
|
||||
return ai;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -80,7 +80,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, int *longpath);
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
|
||||
@@ -512,6 +512,15 @@
|
||||
/* Define to 1 if you have the send function. */
|
||||
#cmakedefine HAVE_SEND 1
|
||||
|
||||
/* Define to 1 if you have the 'fsetxattr' function. */
|
||||
#cmakedefine HAVE_FSETXATTR 1
|
||||
|
||||
/* fsetxattr() takes 5 args */
|
||||
#cmakedefine HAVE_FSETXATTR_5 1
|
||||
|
||||
/* fsetxattr() takes 6 args */
|
||||
#cmakedefine HAVE_FSETXATTR_6 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#cmakedefine HAVE_SETJMP_H 1
|
||||
|
||||
@@ -912,6 +921,9 @@
|
||||
/* if PolarSSL is enabled */
|
||||
#cmakedefine USE_POLARSSL 1
|
||||
|
||||
/* if DarwinSSL is enabled */
|
||||
#cmakedefine USE_DARWINSSL 1
|
||||
|
||||
/* if mbedTLS is enabled */
|
||||
#cmakedefine USE_MBEDTLS 1
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
|
||||
@@ -145,8 +145,7 @@ static int setcharset(unsigned char **p, unsigned char *charset)
|
||||
else if(c == ']') {
|
||||
if(something_found)
|
||||
return SETCHARSET_OK;
|
||||
else
|
||||
something_found = TRUE;
|
||||
something_found = TRUE;
|
||||
state = CURLFNM_SCHS_RIGHTBR;
|
||||
charset[c] = 1;
|
||||
(*p)++;
|
||||
@@ -244,7 +243,7 @@ static int setcharset(unsigned char **p, unsigned char *charset)
|
||||
if(c == ']') {
|
||||
return SETCHARSET_OK;
|
||||
}
|
||||
else if(c == '\\') {
|
||||
if(c == '\\') {
|
||||
c = *(++(*p));
|
||||
if(ISPRINT(c)) {
|
||||
charset[c] = 1;
|
||||
@@ -345,8 +344,7 @@ static int loop(const unsigned char *pattern, const unsigned char *string)
|
||||
else if(*p == '\0') {
|
||||
if(*s == '\0')
|
||||
return CURL_FNMATCH_MATCH;
|
||||
else
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
return CURL_FNMATCH_NOMATCH;
|
||||
}
|
||||
else if(*p == '\\') {
|
||||
state = CURLFNM_LOOP_BACKSLASH;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -70,7 +70,7 @@
|
||||
*
|
||||
* Programs and libraries in 'tests' subdirectories have specific
|
||||
* purposes and needs, and as such each one will use whatever fits
|
||||
* best, depending additionally wether it links with libcurl or not.
|
||||
* best, depending additionally whether it links with libcurl or not.
|
||||
*
|
||||
* Caveat emptor. Proper curlx_* separation is a work in progress
|
||||
* the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@@ -501,7 +501,7 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
size_t srclen)
|
||||
{
|
||||
@@ -512,7 +512,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
const char *src, size_t srclen)
|
||||
@@ -597,7 +597,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/* This returns the HMAC MD5 digest */
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
@@ -715,8 +715,10 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
|
||||
/* Create the BLOB structure */
|
||||
snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
|
||||
NTLMv2_BLOB_SIGNATURE
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c", /* Reserved = 0 */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0);
|
||||
|
||||
Curl_write64_le(tw, ptr + 24);
|
||||
|
||||
@@ -33,31 +33,26 @@
|
||||
!defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
|
||||
# error "curl_ntlm_core.h shall not be included before OpenSSL headers."
|
||||
# endif
|
||||
# ifdef OPENSSL_NO_MD4
|
||||
# define USE_NTRESPONSES 0
|
||||
# define USE_NTLM2SESSION 0
|
||||
# define USE_NTLM_V2 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
|
||||
/* Define USE_NTRESPONSES in order to make the type-3 message include
|
||||
* the NT response message. */
|
||||
#ifndef USE_NTRESPONSES
|
||||
#define USE_NTRESPONSES 1
|
||||
#if !defined(USE_OPENSSL) || !defined(OPENSSL_NO_MD4)
|
||||
#define USE_NTRESPONSES
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the
|
||||
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
|
||||
NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
|
||||
Crypto engine that we have curl_ssl_md5sum() for. */
|
||||
#if !defined(USE_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO)
|
||||
#define USE_NTLM2SESSION 1
|
||||
#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
|
||||
#define USE_NTLM2SESSION
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the
|
||||
/* Define USE_NTLM_V2 in order to allow the type-3 message to include the
|
||||
LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
|
||||
and support for 64-bit integers. */
|
||||
#if !defined(USE_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
#define USE_NTLM_V2 1
|
||||
#if defined(USE_NTRESPONSES) && (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
#define USE_NTLM_V2
|
||||
#endif
|
||||
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
@@ -68,12 +63,12 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Supported mechanisms */
|
||||
const struct {
|
||||
static const struct {
|
||||
const char *name; /* Name */
|
||||
size_t len; /* Name length */
|
||||
unsigned int bit; /* Flag bit */
|
||||
|
||||
@@ -128,18 +128,7 @@
|
||||
/* please, do it beyond the point further indicated in this file. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* libcurl's external interface definitions are also used internally,
|
||||
* and might also include required system header files to define them.
|
||||
*/
|
||||
|
||||
#include <curl/curlbuild.h>
|
||||
|
||||
/*
|
||||
* Compile time sanity checks must also be done when building the library.
|
||||
*/
|
||||
|
||||
#include <curl/curlrules.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Ensure that no one is using the old SIZEOF_CURL_OFF_T macro
|
||||
|
||||
@@ -92,7 +92,7 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
|
||||
static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
|
||||
{
|
||||
char *newp;
|
||||
char *newp = NULL;
|
||||
char *dictp;
|
||||
char *ptr;
|
||||
size_t len;
|
||||
|
||||
+38
-16
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -179,7 +179,7 @@ curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
|
||||
#endif
|
||||
#else
|
||||
/*
|
||||
* Symbian OS doesn't support initialization to code in writeable static data.
|
||||
* Symbian OS doesn't support initialization to code in writable static data.
|
||||
* Initialization will occur in the curl_global_init() call.
|
||||
*/
|
||||
curl_malloc_callback Curl_cmalloc;
|
||||
@@ -619,7 +619,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
/* If nothing updated the timeout, we decrease it by the spent time.
|
||||
* If it was updated, it has the new timeout time stored already.
|
||||
*/
|
||||
ev->ms += curlx_tvdiff(after, before);
|
||||
ev->ms += (long)curlx_tvdiff(after, before);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -773,8 +773,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
|
||||
curl_multi_cleanup(multi);
|
||||
if(mcode == CURLM_OUT_OF_MEMORY)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
return CURLE_FAILED_INIT;
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
@@ -870,6 +869,11 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
* get setup on-demand in the code, as that would probably decrease
|
||||
* the likeliness of us forgetting to init a buffer here in the future.
|
||||
*/
|
||||
outcurl->set.buffer_size = data->set.buffer_size;
|
||||
outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
|
||||
if(!outcurl->state.buffer)
|
||||
goto fail;
|
||||
|
||||
outcurl->state.headerbuff = malloc(HEADERSIZE);
|
||||
if(!outcurl->state.headerbuff)
|
||||
goto fail;
|
||||
@@ -940,6 +944,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
if(outcurl) {
|
||||
curl_slist_free_all(outcurl->change.cookielist);
|
||||
outcurl->change.cookielist = NULL;
|
||||
Curl_safefree(outcurl->state.buffer);
|
||||
Curl_safefree(outcurl->state.headerbuff);
|
||||
Curl_safefree(outcurl->change.url);
|
||||
Curl_safefree(outcurl->change.referer);
|
||||
@@ -975,6 +980,10 @@ void curl_easy_reset(struct Curl_easy *data)
|
||||
|
||||
data->progress.flags |= PGRS_HIDE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
|
||||
/* zero out authentication data: */
|
||||
memset(&data->state.authhost, 0, sizeof(struct auth));
|
||||
memset(&data->state.authproxy, 0, sizeof(struct auth));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1002,19 +1011,32 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
/* put it back in the keepon */
|
||||
k->keepon = newstate;
|
||||
|
||||
if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) {
|
||||
/* we have a buffer for sending that we now seem to be able to deliver
|
||||
since the receive pausing is lifted! */
|
||||
if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) {
|
||||
/* there are buffers for sending that can be delivered as the receive
|
||||
pausing is lifted! */
|
||||
unsigned int i;
|
||||
unsigned int count = data->state.tempcount;
|
||||
struct tempbuf writebuf[3]; /* there can only be three */
|
||||
|
||||
/* get the pointer in local copy since the function may return PAUSE
|
||||
again and then we'll get a new copy allocted and stored in
|
||||
the tempwrite variables */
|
||||
char *tempwrite = data->state.tempwrite;
|
||||
/* copy the structs to allow for immediate re-pausing */
|
||||
for(i=0; i < data->state.tempcount; i++) {
|
||||
writebuf[i] = data->state.tempwrite[i];
|
||||
data->state.tempwrite[i].buf = NULL;
|
||||
}
|
||||
data->state.tempcount = 0;
|
||||
|
||||
data->state.tempwrite = NULL;
|
||||
result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
|
||||
tempwrite, data->state.tempwritesize);
|
||||
free(tempwrite);
|
||||
for(i=0; i < count; i++) {
|
||||
/* even if one function returns error, this loops through and frees all
|
||||
buffers */
|
||||
if(!result)
|
||||
result = Curl_client_chop_write(data->easy_conn,
|
||||
writebuf[i].type,
|
||||
writebuf[i].buf,
|
||||
writebuf[i].len);
|
||||
free(writebuf[i].buf);
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* if there's no error and we're not pausing both directions, we want
|
||||
|
||||
@@ -113,9 +113,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
testing_ptr = Curl_saferealloc(ns, alloc);
|
||||
if(!testing_ptr)
|
||||
return NULL;
|
||||
else {
|
||||
ns = testing_ptr;
|
||||
}
|
||||
ns = testing_ptr;
|
||||
}
|
||||
|
||||
result = Curl_convert_to_network(data, &in, 1);
|
||||
|
||||
@@ -355,8 +355,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
failf(data, "Can't get the size of %s", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
data->state.resume_from = (curl_off_t)file_stat.st_size;
|
||||
data->state.resume_from = (curl_off_t)file_stat.st_size;
|
||||
}
|
||||
|
||||
while(!result) {
|
||||
@@ -476,7 +475,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
time_t filetime;
|
||||
struct tm buffer;
|
||||
const struct tm *tm = &buffer;
|
||||
snprintf(buf, sizeof(data->state.buffer),
|
||||
snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||||
if(result)
|
||||
@@ -519,8 +518,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
failf(data, "Can't get the size of file.");
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
else
|
||||
data->state.resume_from += (curl_off_t)statbuf.st_size;
|
||||
data->state.resume_from += (curl_off_t)statbuf.st_size;
|
||||
}
|
||||
|
||||
if(data->state.resume_from <= expected_size)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -342,6 +342,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
#else
|
||||
current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
|
||||
#endif
|
||||
/* FALLTHROUGH */
|
||||
case CURLFORM_COPYNAME:
|
||||
if(current_form->name)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
@@ -629,70 +630,68 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
return_value = CURL_FORMADD_INCOMPLETE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if(((form->flags & HTTPPOST_FILENAME) ||
|
||||
(form->flags & HTTPPOST_BUFFER)) &&
|
||||
!form->contenttype) {
|
||||
char *f = form->flags & HTTPPOST_BUFFER?
|
||||
form->showfilename : form->value;
|
||||
if(((form->flags & HTTPPOST_FILENAME) ||
|
||||
(form->flags & HTTPPOST_BUFFER)) &&
|
||||
!form->contenttype) {
|
||||
char *f = form->flags & HTTPPOST_BUFFER?
|
||||
form->showfilename : form->value;
|
||||
|
||||
/* our contenttype is missing */
|
||||
form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
|
||||
if(!form->contenttype) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
form->contenttype_alloc = TRUE;
|
||||
}
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) &&
|
||||
(form == first_form) ) {
|
||||
/* Note that there's small risk that form->name is NULL here if the
|
||||
app passed in a bad combo, so we better check for that first. */
|
||||
if(form->name) {
|
||||
/* copy name (without strdup; possibly contains null characters) */
|
||||
form->name = Curl_memdup(form->name, form->namelength?
|
||||
form->namelength:
|
||||
strlen(form->name)+1);
|
||||
}
|
||||
if(!form->name) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
form->name_alloc = TRUE;
|
||||
}
|
||||
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||
HTTPPOST_CALLBACK)) && form->value) {
|
||||
/* copy value (without strdup; possibly contains null characters) */
|
||||
size_t clen = (size_t) form->contentslength;
|
||||
if(!clen)
|
||||
clen = strlen(form->value)+1;
|
||||
|
||||
form->value = Curl_memdup(form->value, clen);
|
||||
|
||||
if(!form->value) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
form->value_alloc = TRUE;
|
||||
}
|
||||
post = AddHttpPost(form->name, form->namelength,
|
||||
form->value, form->contentslength,
|
||||
form->buffer, form->bufferlength,
|
||||
form->contenttype, form->flags,
|
||||
form->contentheader, form->showfilename,
|
||||
form->userp,
|
||||
post, httppost,
|
||||
last_post);
|
||||
|
||||
if(!post) {
|
||||
/* our contenttype is missing */
|
||||
form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
|
||||
if(!form->contenttype) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
if(form->contenttype)
|
||||
prevtype = form->contenttype;
|
||||
form->contenttype_alloc = TRUE;
|
||||
}
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) &&
|
||||
(form == first_form) ) {
|
||||
/* Note that there's small risk that form->name is NULL here if the
|
||||
app passed in a bad combo, so we better check for that first. */
|
||||
if(form->name) {
|
||||
/* copy name (without strdup; possibly contains null characters) */
|
||||
form->name = Curl_memdup(form->name, form->namelength?
|
||||
form->namelength:
|
||||
strlen(form->name)+1);
|
||||
}
|
||||
if(!form->name) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
form->name_alloc = TRUE;
|
||||
}
|
||||
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||
HTTPPOST_CALLBACK)) && form->value) {
|
||||
/* copy value (without strdup; possibly contains null characters) */
|
||||
size_t clen = (size_t) form->contentslength;
|
||||
if(!clen)
|
||||
clen = strlen(form->value)+1;
|
||||
|
||||
form->value = Curl_memdup(form->value, clen);
|
||||
|
||||
if(!form->value) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
form->value_alloc = TRUE;
|
||||
}
|
||||
post = AddHttpPost(form->name, form->namelength,
|
||||
form->value, form->contentslength,
|
||||
form->buffer, form->bufferlength,
|
||||
form->contenttype, form->flags,
|
||||
form->contentheader, form->showfilename,
|
||||
form->userp,
|
||||
post, httppost,
|
||||
last_post);
|
||||
|
||||
if(!post) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
if(form->contenttype)
|
||||
prevtype = form->contenttype;
|
||||
}
|
||||
if(CURL_FORMADD_OK != return_value) {
|
||||
/* On error, free allocated fields for nodes of the FormInfo linked
|
||||
@@ -1332,7 +1331,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
char buffer[512];
|
||||
while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
|
||||
result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
|
||||
if(result)
|
||||
if(result || feof(fileread) || ferror(fileread))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1462,8 +1461,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
||||
if(callback) {
|
||||
if(form->fread_func == ZERO_NULL)
|
||||
return 0;
|
||||
else
|
||||
nread = form->fread_func(buffer, 1, size, form->data->line);
|
||||
nread = form->fread_func(buffer, 1, size, form->data->line);
|
||||
}
|
||||
else {
|
||||
if(!form->fp) {
|
||||
@@ -1553,7 +1551,7 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
||||
struct Form *form=(struct Form *)formp;
|
||||
|
||||
if(!form->data)
|
||||
return 0; /* nothing, ERROR! */
|
||||
return NULL; /* nothing, ERROR! */
|
||||
|
||||
header = form->data->line;
|
||||
*len = form->data->length;
|
||||
|
||||
+54
-58
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -916,8 +916,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
|
||||
return bits;
|
||||
}
|
||||
else
|
||||
return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
|
||||
return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
|
||||
}
|
||||
|
||||
/* This is called after the FTP_QUOTE state is passed.
|
||||
@@ -1209,7 +1208,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
possibly_non_local = FALSE; /* don't try this again */
|
||||
continue;
|
||||
}
|
||||
else if(error != EADDRINUSE && error != EACCES) {
|
||||
if(error != EADDRINUSE && error != EACCES) {
|
||||
failf(data, "bind(port=%hu) failed: %s", port,
|
||||
Curl_strerror(conn, error) );
|
||||
Curl_closesocket(conn, portsock);
|
||||
@@ -1307,7 +1306,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if(PORT == fcmd) {
|
||||
if(PORT == fcmd) {
|
||||
char *source = myhost;
|
||||
char *dest = tmp;
|
||||
|
||||
@@ -1674,31 +1673,29 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(seekerr != CURL_SEEKFUNC_OK) {
|
||||
curl_off_t passed=0;
|
||||
if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
|
||||
failf(data, "Could not seek stream");
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
/* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
|
||||
else {
|
||||
curl_off_t passed=0;
|
||||
do {
|
||||
size_t readthisamountnow =
|
||||
(data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
do {
|
||||
size_t readthisamountnow =
|
||||
(data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
|
||||
size_t actuallyread =
|
||||
data->state.fread_func(data->state.buffer, 1, readthisamountnow,
|
||||
data->state.in);
|
||||
size_t actuallyread =
|
||||
data->state.fread_func(data->state.buffer, 1, readthisamountnow,
|
||||
data->state.in);
|
||||
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
/* this checks for greater-than only to make sure that the
|
||||
CURL_READFUNC_ABORT return code still aborts */
|
||||
failf(data, "Failed to read data");
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
} while(passed < data->state.resume_from);
|
||||
}
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
/* this checks for greater-than only to make sure that the
|
||||
CURL_READFUNC_ABORT return code still aborts */
|
||||
failf(data, "Failed to read data");
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
} while(passed < data->state.resume_from);
|
||||
}
|
||||
/* now, decrease the size of the read */
|
||||
if(data->state.infilesize>0) {
|
||||
@@ -1757,7 +1754,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
|
||||
/*
|
||||
* This state uses:
|
||||
* 'count1' to iterate over the commands to send
|
||||
* 'count2' to store wether to allow commands to fail
|
||||
* 'count2' to store whether to allow commands to fail
|
||||
*/
|
||||
|
||||
if(init)
|
||||
@@ -2000,7 +1997,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
|
||||
if(!addr) {
|
||||
failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2040,11 +2037,14 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
|
||||
|
||||
Curl_safefree(conn->secondaryhostname);
|
||||
conn->secondaryhostname = strdup(ftpc->newhost);
|
||||
conn->secondary_port = ftpc->newport;
|
||||
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
|
||||
Curl_safefree(conn->secondaryhostname);
|
||||
conn->secondary_port = ftpc->newport;
|
||||
conn->secondaryhostname = strdup(ftpc->newhost);
|
||||
if(!conn->secondaryhostname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->bits.do_more = TRUE;
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
|
||||
@@ -2107,7 +2107,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
/* we have a time, reformat it */
|
||||
time_t secs=time(NULL);
|
||||
/* using the good old yacc/bison yuck */
|
||||
snprintf(buf, sizeof(conn->data->state.buffer),
|
||||
snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
/* now, convert this into a time() value: */
|
||||
@@ -2318,7 +2318,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||||
if(instate == FTP_SIZE) {
|
||||
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||||
if(-1 != filesize) {
|
||||
snprintf(buf, sizeof(data->state.buffer),
|
||||
snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||||
if(result)
|
||||
@@ -2409,8 +2409,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
else
|
||||
return InitiateTransfer(conn);
|
||||
return InitiateTransfer(conn);
|
||||
}
|
||||
|
||||
/* for LIST and RETR responses */
|
||||
@@ -2823,6 +2822,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
case FTP_PWD:
|
||||
if(ftpcode == 257) {
|
||||
char *ptr=&data->state.buffer[4]; /* start on the first letter */
|
||||
const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
|
||||
char *dir;
|
||||
char *store;
|
||||
|
||||
@@ -2840,7 +2840,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
*/
|
||||
|
||||
/* scan for the first double-quote for non-standard responses */
|
||||
while(ptr < &data->state.buffer[sizeof(data->state.buffer)]
|
||||
while(ptr < &data->state.buffer[buf_size]
|
||||
&& *ptr != '\n' && *ptr != '\0' && *ptr != '"')
|
||||
ptr++;
|
||||
|
||||
@@ -2870,7 +2870,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
does not start with a '/'), we probably need some server-dependent
|
||||
adjustments. For example, this is the case when connecting to
|
||||
an OS400 FTP server: this server supports two name syntaxes,
|
||||
the default one being incompatible with standard pathes. In
|
||||
the default one being incompatible with standard paths. In
|
||||
addition, this server switches automatically to the regular path
|
||||
syntax when one is encountered in a command: this results in
|
||||
having an entrypath in the wrong syntax when later used in CWD.
|
||||
@@ -2944,12 +2944,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
state(conn, FTP_NAMEFMT);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Nothing special for the target server. */
|
||||
/* remember target server OS */
|
||||
Curl_safefree(ftpc->server_os);
|
||||
ftpc->server_os = os;
|
||||
}
|
||||
/* Nothing special for the target server. */
|
||||
/* remember target server OS */
|
||||
Curl_safefree(ftpc->server_os);
|
||||
ftpc->server_os = os;
|
||||
}
|
||||
else {
|
||||
/* Cannot identify server OS. Continue anyway and cross fingers. */
|
||||
@@ -3210,6 +3208,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
|
||||
/* until we cope better with prematurely ended requests, let them
|
||||
* fallback as if in complete failure */
|
||||
/* FALLTHROUGH */
|
||||
default: /* by default, an error means the control connection is
|
||||
wedged and should not be used anymore */
|
||||
ftpc->ctl_valid = FALSE;
|
||||
@@ -3553,7 +3552,7 @@ static CURLcode ftp_range(struct connectdata *conn)
|
||||
" to %" CURL_FORMAT_CURL_OFF_T ", totally %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
from, to, data->req.maxdownload));
|
||||
ftpc->dont_check = TRUE; /* dont check for successful transfer */
|
||||
ftpc->dont_check = TRUE; /* don't check for successful transfer */
|
||||
}
|
||||
else
|
||||
data->req.maxdownload = -1;
|
||||
@@ -3796,12 +3795,10 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
result = ftp_parse_url_path(conn);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
wildcard->pattern = strdup(last_slash);
|
||||
if(!wildcard->pattern)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
last_slash[0] = '\0'; /* cut file from path */
|
||||
}
|
||||
wildcard->pattern = strdup(last_slash);
|
||||
if(!wildcard->pattern)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
last_slash[0] = '\0'; /* cut file from path */
|
||||
}
|
||||
else { /* there is only 'wildcard pattern' or nothing */
|
||||
if(path[0]) {
|
||||
@@ -3886,8 +3883,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
if(wildcard->state == CURLWC_CLEAN)
|
||||
/* only listing! */
|
||||
break;
|
||||
else
|
||||
wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||
wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||
break;
|
||||
|
||||
case CURLWC_MATCHING: {
|
||||
@@ -3905,7 +3901,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
wildcard->state = CURLWC_CLEAN;
|
||||
return wc_statemach(conn);
|
||||
}
|
||||
else if(wildcard->filelist->size == 0) {
|
||||
if(wildcard->filelist.size == 0) {
|
||||
/* no corresponding file */
|
||||
wildcard->state = CURLWC_CLEAN;
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
@@ -3916,7 +3912,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
case CURLWC_DOWNLOADING: {
|
||||
/* filelist has at least one file, lets get first one */
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
struct curl_fileinfo *finfo = wildcard->filelist->head->ptr;
|
||||
struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
|
||||
|
||||
char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
|
||||
if(!tmp_path)
|
||||
@@ -3931,7 +3927,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
||||
if(conn->data->set.chunk_bgn) {
|
||||
long userresponse = conn->data->set.chunk_bgn(
|
||||
finfo, wildcard->customptr, (int)wildcard->filelist->size);
|
||||
finfo, wildcard->customptr, (int)wildcard->filelist.size);
|
||||
switch(userresponse) {
|
||||
case CURL_CHUNK_BGN_FUNC_SKIP:
|
||||
infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
|
||||
@@ -3956,9 +3952,9 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
return result;
|
||||
|
||||
/* we don't need the Curl_fileinfo of first file anymore */
|
||||
Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
|
||||
Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||
|
||||
if(wildcard->filelist->size == 0) { /* remains only one file to down. */
|
||||
if(wildcard->filelist.size == 0) { /* remains only one file to down. */
|
||||
wildcard->state = CURLWC_CLEAN;
|
||||
/* after that will be ftp_do called once again and no transfer
|
||||
will be done because of CURLWC_CLEAN state */
|
||||
@@ -3969,8 +3965,8 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
case CURLWC_SKIP: {
|
||||
if(conn->data->set.chunk_end)
|
||||
conn->data->set.chunk_end(conn->data->wildcard.customptr);
|
||||
Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
|
||||
wildcard->state = (wildcard->filelist->size == 0) ?
|
||||
Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||
wildcard->state = (wildcard->filelist.size == 0) ?
|
||||
CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
||||
return wc_statemach(conn);
|
||||
}
|
||||
@@ -3986,6 +3982,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
|
||||
case CURLWC_DONE:
|
||||
case CURLWC_ERROR:
|
||||
case CURLWC_CLEAR:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4283,7 +4280,6 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
&ftpc->dirs[ftpc->dirdepth], NULL,
|
||||
TRUE);
|
||||
if(result) {
|
||||
free(ftpc->dirs[ftpc->dirdepth]);
|
||||
freedirs(ftpc);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -280,7 +280,7 @@ static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
|
||||
curl_fnmatch_callback compare;
|
||||
struct WildcardData *wc = &conn->data->wildcard;
|
||||
struct ftp_wc_tmpdata *tmpdata = wc->tmp;
|
||||
struct curl_llist *llist = wc->filelist;
|
||||
struct curl_llist *llist = &wc->filelist;
|
||||
struct ftp_parselist_data *parser = tmpdata->parser;
|
||||
bool add = TRUE;
|
||||
|
||||
@@ -433,10 +433,8 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
||||
return bufflen;
|
||||
}
|
||||
else {
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
finfo->b_used = 0;
|
||||
}
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
finfo->b_used = 0;
|
||||
}
|
||||
else {
|
||||
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
||||
|
||||
@@ -78,7 +78,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
|
||||
curl_off_t *bytecount = &data->req.bytecount;
|
||||
char *path = data->state.path;
|
||||
char *sel;
|
||||
char *sel = NULL;
|
||||
char *sel_org = NULL;
|
||||
ssize_t amount, k;
|
||||
size_t len;
|
||||
@@ -106,8 +106,8 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
|
||||
/* ... and finally unescape */
|
||||
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
|
||||
if(!sel)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(result)
|
||||
return result;
|
||||
sel_org = sel;
|
||||
}
|
||||
|
||||
|
||||
+20
-48
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -37,8 +37,6 @@ hash_element_dtor(void *user, void *element)
|
||||
struct curl_hash *h = (struct curl_hash *) user;
|
||||
struct curl_hash_element *e = (struct curl_hash_element *) element;
|
||||
|
||||
Curl_safefree(e->key);
|
||||
|
||||
if(e->ptr) {
|
||||
h->dtor(e->ptr);
|
||||
e->ptr = NULL;
|
||||
@@ -74,54 +72,32 @@ Curl_hash_init(struct curl_hash *h,
|
||||
h->size = 0;
|
||||
h->slots = slots;
|
||||
|
||||
h->table = malloc(slots * sizeof(struct curl_llist *));
|
||||
h->table = malloc(slots * sizeof(struct curl_llist));
|
||||
if(h->table) {
|
||||
for(i = 0; i < slots; ++i) {
|
||||
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
|
||||
if(!h->table[i]) {
|
||||
while(i--) {
|
||||
Curl_llist_destroy(h->table[i], NULL);
|
||||
h->table[i] = NULL;
|
||||
}
|
||||
free(h->table);
|
||||
h->table = NULL;
|
||||
h->slots = 0;
|
||||
return 1; /* failure */
|
||||
}
|
||||
}
|
||||
for(i = 0; i < slots; ++i)
|
||||
Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
|
||||
return 0; /* fine */
|
||||
}
|
||||
else {
|
||||
h->slots = 0;
|
||||
return 1; /* failure */
|
||||
}
|
||||
h->slots = 0;
|
||||
return 1; /* failure */
|
||||
}
|
||||
|
||||
static struct curl_hash_element *
|
||||
mk_hash_element(const void *key, size_t key_len, const void *p)
|
||||
{
|
||||
struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element));
|
||||
|
||||
/* allocate the struct plus memory after it to store the key */
|
||||
struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) +
|
||||
key_len);
|
||||
if(he) {
|
||||
void *dupkey = malloc(key_len);
|
||||
if(dupkey) {
|
||||
/* copy the key */
|
||||
memcpy(dupkey, key, key_len);
|
||||
|
||||
he->key = dupkey;
|
||||
he->key_len = key_len;
|
||||
he->ptr = (void *) p;
|
||||
}
|
||||
else {
|
||||
/* failed to duplicate the key, free memory and fail */
|
||||
free(he);
|
||||
he = NULL;
|
||||
}
|
||||
/* copy the key */
|
||||
memcpy(he->key, key, key_len);
|
||||
he->key_len = key_len;
|
||||
he->ptr = (void *) p;
|
||||
}
|
||||
return he;
|
||||
}
|
||||
|
||||
#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)]
|
||||
#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
|
||||
|
||||
/* Insert the data in the hash. If there already was a match in the hash,
|
||||
* that data is replaced.
|
||||
@@ -158,7 +134,6 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
|
||||
* "destructor" for the actual data 'p'. When we fail, we shall not touch
|
||||
* that data.
|
||||
*/
|
||||
free(he->key);
|
||||
free(he);
|
||||
}
|
||||
|
||||
@@ -243,8 +218,7 @@ Curl_hash_destroy(struct curl_hash *h)
|
||||
int i;
|
||||
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
Curl_llist_destroy(h->table[i], (void *) h);
|
||||
h->table[i] = NULL;
|
||||
Curl_llist_destroy(&h->table[i], (void *) h);
|
||||
}
|
||||
|
||||
Curl_safefree(h->table);
|
||||
@@ -276,7 +250,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
return;
|
||||
|
||||
for(i = 0; i < h->slots; ++i) {
|
||||
list = h->table[i];
|
||||
list = &h->table[i];
|
||||
le = list->head; /* get first list entry */
|
||||
while(le) {
|
||||
struct curl_hash_element *he = le->ptr;
|
||||
@@ -335,8 +309,8 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
|
||||
/* If we have reached the end of the list, find the next one */
|
||||
if(!iter->current_element) {
|
||||
for(i = iter->slot_index;i < h->slots;i++) {
|
||||
if(h->table[i]->head) {
|
||||
iter->current_element = h->table[i]->head;
|
||||
if(h->table[i].head) {
|
||||
iter->current_element = h->table[i].head;
|
||||
iter->slot_index = i+1;
|
||||
break;
|
||||
}
|
||||
@@ -347,10 +321,8 @@ Curl_hash_next_element(struct curl_hash_iterator *iter)
|
||||
struct curl_hash_element *he = iter->current_element->ptr;
|
||||
return he;
|
||||
}
|
||||
else {
|
||||
iter->current_element = NULL;
|
||||
return NULL;
|
||||
}
|
||||
iter->current_element = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0 /* useful function for debugging hashes and their contents */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -44,7 +44,7 @@ typedef size_t (*comp_function) (void *key1,
|
||||
typedef void (*curl_hash_dtor)(void *);
|
||||
|
||||
struct curl_hash {
|
||||
struct curl_llist **table;
|
||||
struct curl_llist *table;
|
||||
|
||||
/* Hash function to be used for this hash table */
|
||||
hash_function hash_func;
|
||||
@@ -58,8 +58,8 @@ struct curl_hash {
|
||||
|
||||
struct curl_hash_element {
|
||||
void *ptr;
|
||||
char *key;
|
||||
size_t key_len;
|
||||
char key[1]; /* allocated memory following the struct */
|
||||
};
|
||||
|
||||
struct curl_hash_iterator {
|
||||
|
||||
@@ -87,7 +87,7 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
|
||||
return CURL_HOST_NOMATCH;
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
|
||||
if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
|
||||
return CURL_HOST_NOMATCH;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -143,7 +143,7 @@ void Curl_global_host_cache_dtor(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return # of adresses in a Curl_addrinfo struct
|
||||
* Return # of addresses in a Curl_addrinfo struct
|
||||
*/
|
||||
int Curl_num_addresses(const Curl_addrinfo *addr)
|
||||
{
|
||||
@@ -573,7 +573,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
#ifdef USE_ALARM_TIMEOUT
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction keep_sigact; /* store the old struct here */
|
||||
volatile bool keep_copysig = FALSE; /* wether old sigact has been saved */
|
||||
volatile bool keep_copysig = FALSE; /* whether old sigact has been saved */
|
||||
struct sigaction sigact;
|
||||
#else
|
||||
#ifdef HAVE_SIGNAL
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -130,7 +130,7 @@ int Curl_mk_dnscache(struct curl_hash *hash);
|
||||
/* prune old entries from the DNS cache */
|
||||
void Curl_hostcache_prune(struct Curl_easy *data);
|
||||
|
||||
/* Return # of adresses in a Curl_addrinfo struct */
|
||||
/* Return # of addresses in a Curl_addrinfo struct */
|
||||
int Curl_num_addresses(const Curl_addrinfo *addr);
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
|
||||
|
||||
+67
-52
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -297,7 +297,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
pwd = conn->passwd;
|
||||
}
|
||||
|
||||
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||||
snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"%s:%s", user, pwd);
|
||||
|
||||
result = Curl_base64_encode(data,
|
||||
data->state.buffer, strlen(data->state.buffer),
|
||||
@@ -644,10 +645,10 @@ output_auth_headers(struct connectdata *conn,
|
||||
proxy ? "Proxy" : "Server", auth,
|
||||
proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
|
||||
(conn->user ? conn->user : ""));
|
||||
authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
|
||||
authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
|
||||
}
|
||||
else
|
||||
authstatus->multi = FALSE;
|
||||
authstatus->multipass = FALSE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1196,8 +1197,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
This needs FIXing.
|
||||
*/
|
||||
return CURLE_SEND_ERROR;
|
||||
else
|
||||
Curl_pipeline_leave_write(conn);
|
||||
Curl_pipeline_leave_write(conn);
|
||||
}
|
||||
}
|
||||
Curl_add_buffer_free(in);
|
||||
@@ -1358,6 +1358,10 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->bits.proxy_connect_closed)
|
||||
/* this is not an error, just part of the connection negotiation */
|
||||
return CURLE_OK;
|
||||
|
||||
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
|
||||
return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
|
||||
|
||||
@@ -1365,7 +1369,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
/* nothing else to do except wait right now - we're not done here. */
|
||||
return CURLE_OK;
|
||||
|
||||
if(conn->given->flags & PROTOPT_SSL) {
|
||||
if(conn->given->protocol & CURLPROTO_HTTPS) {
|
||||
/* perform SSL initialization */
|
||||
result = https_connecting(conn, done);
|
||||
if(result)
|
||||
@@ -1425,7 +1429,10 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
|
||||
infof(data, "Curl_http_done: called premature == %d\n", premature);
|
||||
/* Clear multipass flag. If authentication isn't done yet, then it will get
|
||||
* a chance to be set back to true when we output the next auth header */
|
||||
data->state.authhost.multipass = FALSE;
|
||||
data->state.authproxy.multipass = FALSE;
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
@@ -1511,6 +1518,20 @@ static bool use_http_1_1plus(const struct Curl_easy *data,
|
||||
(data->set.httpversion >= CURL_HTTP_VERSION_1_1));
|
||||
}
|
||||
|
||||
static const char *get_http_string(const struct Curl_easy *data,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
#ifdef USE_NGHTTP2
|
||||
if(conn->proto.httpc.h2)
|
||||
return "2";
|
||||
#endif
|
||||
|
||||
if(use_http_1_1plus(data, conn))
|
||||
return "1.1";
|
||||
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
/* check and possibly add an Expect: header */
|
||||
static CURLcode expect100(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
@@ -1849,7 +1870,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if((data->state.authhost.multi || data->state.authproxy.multi) &&
|
||||
if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
|
||||
(httpreq != HTTPREQ_GET) &&
|
||||
(httpreq != HTTPREQ_HEAD)) {
|
||||
/* Auth is required and we are not authenticated yet. Make a PUT or POST
|
||||
@@ -2134,32 +2155,31 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
if(seekerr != CURL_SEEKFUNC_OK) {
|
||||
curl_off_t passed=0;
|
||||
|
||||
if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
|
||||
failf(data, "Could not seek stream");
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
/* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
|
||||
else {
|
||||
curl_off_t passed=0;
|
||||
do {
|
||||
size_t readthisamountnow =
|
||||
(data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
do {
|
||||
size_t readthisamountnow =
|
||||
(data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
|
||||
size_t actuallyread =
|
||||
data->state.fread_func(data->state.buffer, 1, readthisamountnow,
|
||||
data->state.in);
|
||||
size_t actuallyread =
|
||||
data->state.fread_func(data->state.buffer, 1, readthisamountnow,
|
||||
data->state.in);
|
||||
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
/* this checks for greater-than only to make sure that the
|
||||
CURL_READFUNC_ABORT return code still aborts */
|
||||
failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes from the input", passed);
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
} while(passed < data->state.resume_from);
|
||||
}
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
/* this checks for greater-than only to make sure that the
|
||||
CURL_READFUNC_ABORT return code still aborts */
|
||||
failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes from the input", passed);
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
} while(passed < data->state.resume_from);
|
||||
}
|
||||
|
||||
/* now, decrease the size of the read */
|
||||
@@ -2225,9 +2245,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
}
|
||||
|
||||
/* Use 1.1 unless the user specifically asked for 1.0 or the server only
|
||||
supports 1.0 */
|
||||
httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
|
||||
httpstring = get_http_string(data, conn);
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
req_buffer = Curl_add_buffer_init();
|
||||
@@ -2294,20 +2312,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
te
|
||||
);
|
||||
|
||||
/* clear userpwd to avoid re-using credentials from re-used connections */
|
||||
/* clear userpwd and proxyuserpwd to avoid re-using old credentials
|
||||
* from re-used connections */
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
|
||||
/*
|
||||
* Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
|
||||
* with the connection and shouldn't be repeated over it either.
|
||||
*/
|
||||
switch(data->state.authproxy.picked) {
|
||||
case CURLAUTH_NEGOTIATE:
|
||||
case CURLAUTH_NTLM:
|
||||
case CURLAUTH_NTLM_WB:
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
break;
|
||||
}
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2501,7 +2509,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
postsize = data->state.infilesize;
|
||||
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
@@ -2553,7 +2561,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
@@ -2807,8 +2815,7 @@ checkrtspprefix(struct Curl_easy *data,
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
if(checkprefix("RTSP/", s))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* CURL_DISABLE_RTSP */
|
||||
|
||||
@@ -3229,9 +3236,17 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
k->maxdownload = k->size;
|
||||
}
|
||||
|
||||
/* If max download size is *zero* (nothing) we already
|
||||
have nothing and can safely return ok now! */
|
||||
if(0 == k->maxdownload)
|
||||
/* If max download size is *zero* (nothing) we already have
|
||||
nothing and can safely return ok now! But for HTTP/2, we'd
|
||||
like to call http2_handle_stream_close to properly close a
|
||||
stream. In order to do this, we keep reading until we
|
||||
close the stream. */
|
||||
if(0 == k->maxdownload
|
||||
#if defined(USE_NGHTTP2)
|
||||
&& !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||
conn->httpversion == 20)
|
||||
#endif
|
||||
)
|
||||
*stop_reading = TRUE;
|
||||
|
||||
if(*stop_reading) {
|
||||
@@ -3288,7 +3303,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
/*
|
||||
* https://tools.ietf.org/html/rfc7230#section-3.1.2
|
||||
*
|
||||
* The reponse code is always a three-digit number in HTTP as the spec
|
||||
* The response code is always a three-digit number in HTTP as the spec
|
||||
* says. We try to allow any number here, but we cannot make
|
||||
* guarantees on future behaviors since it isn't within the protocol.
|
||||
*/
|
||||
|
||||
@@ -219,6 +219,10 @@ struct http_conn {
|
||||
|
||||
/* this is a hash of all individual streams (Curl_easy structs) */
|
||||
struct h2settings settings;
|
||||
|
||||
/* list of settings that will be sent */
|
||||
nghttp2_settings_entry local_settings[3];
|
||||
size_t local_settings_num;
|
||||
#else
|
||||
int unused; /* prevent a compiler warning */
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -116,18 +116,11 @@ static int http2_getsock(struct connectdata *conn,
|
||||
return http2_perform_getsock(conn, sock, numsocks);
|
||||
}
|
||||
|
||||
static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
/*
|
||||
* http2_stream_free() free HTTP2 stream related data
|
||||
*/
|
||||
static void http2_stream_free(struct HTTP *http)
|
||||
{
|
||||
struct HTTP *http = conn->data->req.protop;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
(void)dead_connection;
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
|
||||
if(http) {
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
@@ -139,6 +132,19 @@ static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
(void)dead_connection;
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
http2_stream_free(conn->data->req.protop);
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
|
||||
|
||||
@@ -402,6 +408,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
stream = data->req.protop;
|
||||
if(!stream) {
|
||||
failf(data, "Internal NULL stream!\n");
|
||||
(void)Curl_close(newhandle);
|
||||
rv = 1;
|
||||
goto fail;
|
||||
}
|
||||
@@ -415,9 +422,11 @@ static int push_promise(struct Curl_easy *data,
|
||||
free(stream->push_headers[i]);
|
||||
free(stream->push_headers);
|
||||
stream->push_headers = NULL;
|
||||
stream->push_headers_used = 0;
|
||||
|
||||
if(rv) {
|
||||
/* denied, kill off the new handle again */
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
(void)Curl_close(newhandle);
|
||||
goto fail;
|
||||
}
|
||||
@@ -432,6 +441,7 @@ static int push_promise(struct Curl_easy *data,
|
||||
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
|
||||
if(rc) {
|
||||
infof(data, "failed to add handle to multi\n");
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
Curl_close(newhandle);
|
||||
rv = 1;
|
||||
goto fail;
|
||||
@@ -587,6 +597,9 @@ static int on_invalid_frame_recv(nghttp2_session *session,
|
||||
{
|
||||
struct Curl_easy *data_s = NULL;
|
||||
(void)userp;
|
||||
#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void)lib_error_code;
|
||||
#endif
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
@@ -697,6 +710,9 @@ static int on_frame_not_send(nghttp2_session *session,
|
||||
{
|
||||
struct Curl_easy *data_s;
|
||||
(void)userp;
|
||||
#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void)lib_error_code;
|
||||
#endif
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
if(data_s) {
|
||||
@@ -967,14 +983,6 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
return nread;
|
||||
}
|
||||
|
||||
/*
|
||||
* The HTTP2 settings we send in the Upgrade request
|
||||
*/
|
||||
static nghttp2_settings_entry settings[] = {
|
||||
{ NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
|
||||
{ NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, HTTP2_HUGE_WINDOW_SIZE },
|
||||
};
|
||||
|
||||
#define H2_BUFSIZE 32768
|
||||
|
||||
#ifdef NGHTTP2_HAS_ERROR_CALLBACK
|
||||
@@ -990,6 +998,23 @@ static int error_callback(nghttp2_session *session,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void populate_settings(struct connectdata *conn,
|
||||
struct http_conn *httpc)
|
||||
{
|
||||
nghttp2_settings_entry *iv = httpc->local_settings;
|
||||
|
||||
iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||
iv[0].value = 100;
|
||||
|
||||
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
|
||||
|
||||
iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
|
||||
iv[2].value = conn->data->multi->push_cb != NULL;
|
||||
|
||||
httpc->local_settings_num = 3;
|
||||
}
|
||||
|
||||
void Curl_http2_done(struct connectdata *conn, bool premature)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
@@ -1103,16 +1128,14 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
size_t blen;
|
||||
struct SingleRequest *k = &conn->data->req;
|
||||
uint8_t *binsettings = conn->proto.httpc.binsettings;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
|
||||
/* As long as we have a fixed set of settings, we don't have to dynamically
|
||||
* figure out the base64 strings since it'll always be the same. However,
|
||||
* the settings will likely not be fixed every time in the future.
|
||||
*/
|
||||
populate_settings(conn, httpc);
|
||||
|
||||
/* this returns number of bytes it wrote */
|
||||
binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
|
||||
settings,
|
||||
sizeof(settings)/sizeof(settings[0]));
|
||||
httpc->local_settings,
|
||||
httpc->local_settings_num);
|
||||
if(!binlen) {
|
||||
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
|
||||
return CURLE_FAILED_INIT;
|
||||
@@ -1862,28 +1885,22 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* Warn stream may be rejected if cumulative length of headers is too large.
|
||||
It appears nghttp2 will not send a header frame larger than 64KB. */
|
||||
#define MAX_ACC 60000 /* <64KB to account for some overhead */
|
||||
{
|
||||
size_t acc = 0;
|
||||
const size_t max_acc = 60000; /* <64KB to account for some overhead */
|
||||
|
||||
for(i = 0; i < nheader; ++i) {
|
||||
if(nva[i].namelen > max_acc - acc)
|
||||
break;
|
||||
acc += nva[i].namelen;
|
||||
|
||||
if(nva[i].valuelen > max_acc - acc)
|
||||
break;
|
||||
acc += nva[i].valuelen;
|
||||
acc += nva[i].namelen + nva[i].valuelen;
|
||||
|
||||
DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
|
||||
nva[i].namelen, nva[i].name,
|
||||
nva[i].valuelen, nva[i].value));
|
||||
}
|
||||
|
||||
if(i != nheader) {
|
||||
if(acc > MAX_ACC) {
|
||||
infof(conn->data, "http2_send: Warning: The cumulative length of all "
|
||||
"headers exceeds %zu bytes and that could cause the "
|
||||
"stream to be rejected.\n", max_acc);
|
||||
"headers exceeds %zu bytes and that could cause the "
|
||||
"stream to be rejected.\n", MAX_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2037,10 +2054,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
conn->data);
|
||||
}
|
||||
else {
|
||||
populate_settings(conn, httpc);
|
||||
|
||||
/* stream ID is unknown at this point */
|
||||
stream->stream_id = -1;
|
||||
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, settings,
|
||||
sizeof(settings) / sizeof(settings[0]));
|
||||
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE,
|
||||
httpc->local_settings,
|
||||
httpc->local_settings_num);
|
||||
if(rv != 0) {
|
||||
failf(data, "nghttp2_submit_settings() failed: %s(%d)",
|
||||
nghttp2_strerror(rv), rv);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -98,16 +98,21 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
* original pointer
|
||||
*
|
||||
* This function might be called several times in the multi interface case
|
||||
* if the proxy's CONNTECT response is not instant.
|
||||
* if the proxy's CONNECT response is not instant.
|
||||
*/
|
||||
prot_save = conn->data->req.protop;
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
conn->data->req.protop = &http_proxy;
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
if(sockindex == SECONDARYSOCKET)
|
||||
hostname = conn->secondaryhostname;
|
||||
else if(conn->bits.conn_to_host)
|
||||
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
*/
|
||||
|
||||
if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else if(sockindex == SECONDARYSOCKET)
|
||||
hostname = conn->secondaryhostname;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
@@ -199,7 +204,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(host_port);
|
||||
|
||||
if(!result) {
|
||||
char *host=(char *)"";
|
||||
char *host = NULL;
|
||||
const char *proxyconn="";
|
||||
const char *useragent="";
|
||||
const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
@@ -242,13 +247,13 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
"%s", /* Proxy-Connection */
|
||||
hostheader,
|
||||
http,
|
||||
host,
|
||||
host?host:"",
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
useragent,
|
||||
proxyconn);
|
||||
|
||||
if(host && *host)
|
||||
if(host)
|
||||
free(host);
|
||||
free(hostheader);
|
||||
|
||||
@@ -288,10 +293,8 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
if(!Curl_conn_data_pending(conn, sockindex))
|
||||
/* return so we'll be called again polling-style */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
DEBUGF(infof(data,
|
||||
"Read response immediately from proxy CONNECT\n"));
|
||||
}
|
||||
DEBUGF(infof(data,
|
||||
"Read response immediately from proxy CONNECT\n"));
|
||||
}
|
||||
|
||||
/* at this point, the tunnel_connecting phase is over. */
|
||||
@@ -311,8 +314,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
perline = 0;
|
||||
|
||||
while(nread < BUFSIZE && keepon && !error) {
|
||||
int writetype;
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
@@ -339,7 +340,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if(result) {
|
||||
if(result) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -414,19 +415,20 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
Curl_debug(data, CURLINFO_HEADER_IN,
|
||||
line_start, (size_t)perline, conn);
|
||||
|
||||
/* send the header to the callback */
|
||||
writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
if(!data->set.suppress_connect_headers) {
|
||||
/* send the header to the callback */
|
||||
int writetype = CLIENTWRITE_HEADER;
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
result = Curl_client_write(conn, writetype, line_start, perline);
|
||||
result = Curl_client_write(conn, writetype, line_start, perline);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
data->info.header_size += (long)perline;
|
||||
data->req.headerbytecount += (long)perline;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Newlines are CRLF, so the CR is ignored as the line isn't
|
||||
really terminated until the LF comes. Treat a following CR
|
||||
as end-of-headers as well.*/
|
||||
@@ -510,33 +512,34 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
}
|
||||
else if(checkprefix("Content-Length:", line_start)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
/* A server MUST NOT send any Transfer-Encoding or
|
||||
Content-Length header fields in a 2xx (Successful)
|
||||
response to CONNECT. (RFC 7231 section 4.3.6) */
|
||||
failf(data, "Content-Length: in %03d response",
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
infof(data, "Ignoring Content-Length in CONNECT %03d response\n",
|
||||
k->httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
cl = curlx_strtoofft(line_start +
|
||||
strlen("Content-Length:"), NULL, 10);
|
||||
else {
|
||||
cl = curlx_strtoofft(line_start +
|
||||
strlen("Content-Length:"), NULL, 10);
|
||||
}
|
||||
}
|
||||
else if(Curl_compareheader(line_start, "Connection:", "close"))
|
||||
closeConnection = TRUE;
|
||||
else if(Curl_compareheader(line_start,
|
||||
"Transfer-Encoding:",
|
||||
"chunked")) {
|
||||
else if(checkprefix("Transfer-Encoding:", line_start)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
/* A server MUST NOT send any Transfer-Encoding or
|
||||
Content-Length header fields in a 2xx (Successful)
|
||||
response to CONNECT. (RFC 7231 section 4.3.6) */
|
||||
failf(data, "Transfer-Encoding: in %03d response", k->httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
/* A client MUST ignore any Content-Length or Transfer-Encoding
|
||||
header fields received in a successful response to CONNECT.
|
||||
"Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
|
||||
infof(data, "Ignoring Transfer-Encoding in "
|
||||
"CONNECT %03d response\n", k->httpcode);
|
||||
}
|
||||
else if(Curl_compareheader(line_start,
|
||||
"Transfer-Encoding:", "chunked")) {
|
||||
infof(data, "CONNECT responded chunked\n");
|
||||
chunked_encoding = TRUE;
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(conn);
|
||||
}
|
||||
infof(data, "CONNECT responded chunked\n");
|
||||
chunked_encoding = TRUE;
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(conn);
|
||||
}
|
||||
else if(Curl_compareheader(line_start, "Proxy-Connection:", "close"))
|
||||
closeConnection = TRUE;
|
||||
@@ -612,11 +615,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
if(conn->bits.proxy_connect_closed)
|
||||
/* this is not an error, just part of the connection negotiation */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||
data->req.httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||
data->req.httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -130,7 +130,8 @@ const struct Curl_handler Curl_handler_imap = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_IMAP, /* defport */
|
||||
CURLPROTO_IMAP, /* protocol */
|
||||
PROTOPT_CLOSEACTION /* flags */
|
||||
PROTOPT_CLOSEACTION| /* flags */
|
||||
PROTOPT_URLOPTIONS
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
@@ -952,7 +953,7 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
|
||||
|
||||
if(imapcode != 'O') {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied. %c", imapcode);
|
||||
failf(data, "STARTTLS denied");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
else
|
||||
@@ -1748,7 +1749,7 @@ static CURLcode imap_setup_connection(struct connectdata *conn)
|
||||
*
|
||||
* imap_sendf()
|
||||
*
|
||||
* Sends the formated string as an IMAP command to the server.
|
||||
* Sends the formatted string as an IMAP command to the server.
|
||||
*
|
||||
* Designed to never block.
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -51,7 +51,7 @@ BEGIN
|
||||
VALUE "OriginalFilename", "libcurl.dll\0"
|
||||
VALUE "ProductName", "The curl library\0"
|
||||
VALUE "ProductVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "LegalCopyright", "© " LIBCURL_COPYRIGHT "\0"
|
||||
VALUE "LegalCopyright", "\xa9 " LIBCURL_COPYRIGHT "\0" /* a9: Copyright symbol */
|
||||
VALUE "License", "https://curl.haxx.se/docs/copyright.html\0"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -33,8 +33,8 @@
|
||||
/*
|
||||
* @unittest: 1300
|
||||
*/
|
||||
static void
|
||||
llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
||||
void
|
||||
Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
||||
{
|
||||
l->size = 0;
|
||||
l->dtor = dtor;
|
||||
@@ -42,20 +42,6 @@ llist_init(struct curl_llist *l, curl_llist_dtor dtor)
|
||||
l->tail = NULL;
|
||||
}
|
||||
|
||||
struct curl_llist *
|
||||
Curl_llist_alloc(curl_llist_dtor dtor)
|
||||
{
|
||||
struct curl_llist *list;
|
||||
|
||||
list = malloc(sizeof(struct curl_llist));
|
||||
if(!list)
|
||||
return NULL;
|
||||
|
||||
llist_init(list, dtor);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_llist_insert_next()
|
||||
*
|
||||
@@ -149,8 +135,6 @@ Curl_llist_destroy(struct curl_llist *list, void *user)
|
||||
if(list) {
|
||||
while(list->size > 0)
|
||||
Curl_llist_remove(list, list->tail, user);
|
||||
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -43,7 +43,7 @@ struct curl_llist {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct curl_llist *Curl_llist_alloc(curl_llist_dtor);
|
||||
void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
|
||||
int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
|
||||
const void *);
|
||||
int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -458,7 +458,7 @@ int curl_fclose(FILE *file, int line, const char *source)
|
||||
|
||||
#define LOGLINE_BUFSIZE 1024
|
||||
|
||||
/* this does the writting to the memory tracking log file */
|
||||
/* this does the writing to the memory tracking log file */
|
||||
void curl_memlog(const char *format, ...)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
@@ -1092,8 +1092,7 @@ char *curl_maprintf(const char *format, ...)
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
return info.buffer;
|
||||
}
|
||||
else
|
||||
return strdup("");
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
char *curl_mvaprintf(const char *format, va_list ap_save)
|
||||
@@ -1117,8 +1116,7 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
|
||||
info.buffer[info.len] = 0; /* we terminate this with a zero byte */
|
||||
return info.buffer;
|
||||
}
|
||||
else
|
||||
return strdup("");
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
static int storebuffer(int output, FILE *data)
|
||||
|
||||
+133
-124
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -280,7 +280,7 @@ static int sh_init(struct curl_hash *hash, int hashsize)
|
||||
static CURLMcode multi_addmsg(struct Curl_multi *multi,
|
||||
struct Curl_message *msg)
|
||||
{
|
||||
if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg))
|
||||
if(!Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg))
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
|
||||
return CURLM_OK;
|
||||
@@ -316,13 +316,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
||||
if(Curl_conncache_init(&multi->conn_cache, chashsize))
|
||||
goto error;
|
||||
|
||||
multi->msglist = Curl_llist_alloc(multi_freeamsg);
|
||||
if(!multi->msglist)
|
||||
goto error;
|
||||
|
||||
multi->pending = Curl_llist_alloc(multi_freeamsg);
|
||||
if(!multi->pending)
|
||||
goto error;
|
||||
Curl_llist_init(&multi->msglist, multi_freeamsg);
|
||||
Curl_llist_init(&multi->pending, multi_freeamsg);
|
||||
|
||||
/* allocate a new easy handle to use when closing cached connections */
|
||||
multi->closure_handle = curl_easy_init();
|
||||
@@ -345,8 +340,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
||||
Curl_conncache_destroy(&multi->conn_cache);
|
||||
Curl_close(multi->closure_handle);
|
||||
multi->closure_handle = NULL;
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
Curl_llist_destroy(multi->pending, NULL);
|
||||
Curl_llist_destroy(&multi->msglist, NULL);
|
||||
Curl_llist_destroy(&multi->pending, NULL);
|
||||
|
||||
free(multi);
|
||||
return NULL;
|
||||
@@ -361,8 +356,6 @@ struct Curl_multi *curl_multi_init(void)
|
||||
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct curl_llist *timeoutlist;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
@@ -376,10 +369,8 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
if(data->multi)
|
||||
return CURLM_ADDED_ALREADY;
|
||||
|
||||
/* Allocate and initialize timeout list for easy handle */
|
||||
timeoutlist = Curl_llist_alloc(multi_freetimeout);
|
||||
if(!timeoutlist)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
/* Initialize timeout list for this handle */
|
||||
Curl_llist_init(&data->state.timeoutlist, multi_freetimeout);
|
||||
|
||||
/*
|
||||
* No failure allowed in this function beyond this point. And no
|
||||
@@ -388,10 +379,6 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
* function no matter what.
|
||||
*/
|
||||
|
||||
/* Make easy handle use timeout list initialized above */
|
||||
data->state.timeoutlist = timeoutlist;
|
||||
timeoutlist = NULL;
|
||||
|
||||
/* set the easy handle */
|
||||
multistate(data, CURLM_STATE_INIT);
|
||||
|
||||
@@ -532,6 +519,7 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
CURLcode result;
|
||||
struct connectdata *conn;
|
||||
struct Curl_easy *data;
|
||||
unsigned int i;
|
||||
|
||||
DEBUGASSERT(*connp);
|
||||
|
||||
@@ -579,7 +567,7 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||
if(conn->send_pipe.size + conn->recv_pipe.size != 0 &&
|
||||
!data->set.reuse_forbid &&
|
||||
!conn->bits.close) {
|
||||
/* Stop if pipeline is not empty and we do not have to close
|
||||
@@ -598,9 +586,11 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
}
|
||||
|
||||
/* if the transfer was completed in a paused state there can be buffered
|
||||
data left to write and then kill */
|
||||
free(data->state.tempwrite);
|
||||
data->state.tempwrite = NULL;
|
||||
data left to free */
|
||||
for(i=0; i < data->state.tempcount; i++) {
|
||||
free(data->state.tempwrite[i].buf);
|
||||
}
|
||||
data->state.tempcount = 0;
|
||||
|
||||
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
|
||||
forced us to close this connection. This is ignored for requests taking
|
||||
@@ -638,7 +628,10 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
|
||||
infof(data, "Connection #%ld to host %s left intact\n",
|
||||
conn->connection_id,
|
||||
conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
|
||||
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
|
||||
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
|
||||
conn->host.dispname);
|
||||
}
|
||||
else
|
||||
data->state.lastconnect = NULL;
|
||||
@@ -692,13 +685,13 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
if(data->easy_conn &&
|
||||
data->mstate > CURLM_STATE_DO &&
|
||||
data->mstate < CURLM_STATE_COMPLETED) {
|
||||
/* Set connection owner so that the DONE function closes it. We can
|
||||
safely do this here since connection is killed. */
|
||||
data->easy_conn->data = easy;
|
||||
/* If the handle is in a pipeline and has started sending off its
|
||||
request but not received its response yet, we need to close
|
||||
connection. */
|
||||
streamclose(data->easy_conn, "Removed with partial response");
|
||||
/* Set connection owner so that the DONE function closes it. We can
|
||||
safely do this here since connection is killed. */
|
||||
data->easy_conn->data = easy;
|
||||
easy_owns_conn = TRUE;
|
||||
}
|
||||
|
||||
@@ -735,10 +728,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
|
||||
/* destroy the timeout list that is held in the easy handle, do this *after*
|
||||
multi_done() as that may actually call Curl_expire that uses this */
|
||||
if(data->state.timeoutlist) {
|
||||
Curl_llist_destroy(data->state.timeoutlist, NULL);
|
||||
data->state.timeoutlist = NULL;
|
||||
}
|
||||
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 */
|
||||
@@ -761,11 +751,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
/* make sure there's no pending message in the queue sent from this easy
|
||||
handle */
|
||||
|
||||
for(e = multi->msglist->head; e; e = e->next) {
|
||||
for(e = multi->msglist.head; e; e = e->next) {
|
||||
struct Curl_message *msg = e->ptr;
|
||||
|
||||
if(msg->extmsg.easy_handle == easy) {
|
||||
Curl_llist_remove(multi->msglist, e, NULL);
|
||||
Curl_llist_remove(&multi->msglist, e, NULL);
|
||||
/* there can only be one from this specific handle */
|
||||
break;
|
||||
}
|
||||
@@ -956,10 +946,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
|
||||
if(s == CURL_SOCKET_BAD)
|
||||
/* this socket is unused, break out of loop */
|
||||
break;
|
||||
else {
|
||||
if((int)s > this_max_fd)
|
||||
this_max_fd = (int)s;
|
||||
}
|
||||
if((int)s > this_max_fd)
|
||||
this_max_fd = (int)s;
|
||||
}
|
||||
|
||||
data = data->next; /* check next handle */
|
||||
@@ -970,6 +958,8 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
#define NUM_POLLS_ON_STACK 10
|
||||
|
||||
CURLMcode curl_multi_wait(struct Curl_multi *multi,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
@@ -983,8 +973,10 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
|
||||
unsigned int nfds = 0;
|
||||
unsigned int curlfds;
|
||||
struct pollfd *ufds = NULL;
|
||||
bool ufds_malloc = FALSE;
|
||||
long timeout_internal;
|
||||
int retcode = 0;
|
||||
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
@@ -1024,9 +1016,14 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
|
||||
nfds += extra_nfds; /* add the externally provided ones */
|
||||
|
||||
if(nfds || extra_nfds) {
|
||||
ufds = malloc(nfds * sizeof(struct pollfd));
|
||||
if(!ufds)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
if(nfds > NUM_POLLS_ON_STACK) {
|
||||
ufds = malloc(nfds * sizeof(struct pollfd));
|
||||
if(!ufds)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
ufds_malloc = TRUE;
|
||||
}
|
||||
else
|
||||
ufds = &a_few_on_stack[0];
|
||||
}
|
||||
nfds = 0;
|
||||
|
||||
@@ -1104,7 +1101,8 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
|
||||
}
|
||||
}
|
||||
|
||||
free(ufds);
|
||||
if(ufds_malloc)
|
||||
free(ufds);
|
||||
if(ret)
|
||||
*ret = retcode;
|
||||
return CURLM_OK;
|
||||
@@ -1307,6 +1305,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SingleRequest *k;
|
||||
time_t timeout_ms;
|
||||
time_t recv_timeout_ms;
|
||||
time_t send_timeout_ms;
|
||||
int control;
|
||||
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
@@ -1432,7 +1432,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
multistate(data, CURLM_STATE_CONNECT_PEND);
|
||||
|
||||
/* add this handle to the list of connect-pending handles */
|
||||
if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
|
||||
if(!Curl_llist_insert_next(&multi->pending, multi->pending.tail, data))
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
result = CURLE_OK;
|
||||
@@ -1477,8 +1477,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
const char *hostname;
|
||||
|
||||
if(conn->bits.proxy)
|
||||
hostname = conn->proxy.name;
|
||||
if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
@@ -1826,19 +1826,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
else
|
||||
result = Curl_speedcheck(data, now);
|
||||
|
||||
if(( (data->set.max_send_speed == 0) ||
|
||||
(Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now) <= 0)) &&
|
||||
( (data->set.max_recv_speed == 0) ||
|
||||
(Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now) <= 0)))
|
||||
multistate(data, CURLM_STATE_PERFORM);
|
||||
if(!result) {
|
||||
send_timeout_ms = 0;
|
||||
if(data->set.max_send_speed > 0)
|
||||
send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now);
|
||||
|
||||
recv_timeout_ms = 0;
|
||||
if(data->set.max_recv_speed > 0)
|
||||
recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now);
|
||||
|
||||
if(send_timeout_ms <= 0 && recv_timeout_ms <= 0)
|
||||
multistate(data, CURLM_STATE_PERFORM);
|
||||
else if(send_timeout_ms >= recv_timeout_ms)
|
||||
Curl_expire_latest(data, send_timeout_ms);
|
||||
else
|
||||
Curl_expire_latest(data, recv_timeout_ms);
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLM_STATE_PERFORM:
|
||||
@@ -1848,31 +1859,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
bool comeback = FALSE;
|
||||
|
||||
/* check if over send speed */
|
||||
if(data->set.max_send_speed > 0) {
|
||||
timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now);
|
||||
if(timeout_ms > 0) {
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
}
|
||||
send_timeout_ms = 0;
|
||||
if(data->set.max_send_speed > 0)
|
||||
send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now);
|
||||
|
||||
/* check if over recv speed */
|
||||
if(data->set.max_recv_speed > 0) {
|
||||
timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now);
|
||||
if(timeout_ms > 0) {
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
recv_timeout_ms = 0;
|
||||
if(data->set.max_recv_speed > 0)
|
||||
recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now);
|
||||
|
||||
if(send_timeout_ms > 0 || recv_timeout_ms > 0) {
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
if(send_timeout_ms >= recv_timeout_ms)
|
||||
Curl_expire_latest(data, send_timeout_ms);
|
||||
else
|
||||
Curl_expire_latest(data, recv_timeout_ms);
|
||||
break;
|
||||
}
|
||||
|
||||
/* read/write data if it is ready to do so */
|
||||
@@ -1928,11 +1938,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
Curl_posttransfer(data);
|
||||
|
||||
/* we're no longer receiving */
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||
|
||||
/* expire the new receiving pipeline head */
|
||||
if(data->easy_conn->recv_pipe->head)
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
|
||||
if(data->easy_conn->recv_pipe.head)
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe.head->ptr, 0);
|
||||
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
@@ -1997,7 +2007,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
CURLcode res;
|
||||
|
||||
/* Remove ourselves from the receive pipeline, if we are there. */
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
|
||||
@@ -2073,8 +2083,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* if this has a connection, unsubscribe from the pipelines */
|
||||
Curl_pipeline_leave_write(data->easy_conn);
|
||||
Curl_pipeline_leave_read(data->easy_conn);
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
|
||||
Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
|
||||
|
||||
if(stream_error) {
|
||||
/* Don't attempt to send data over a connection that timed out */
|
||||
@@ -2229,8 +2239,8 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
||||
|
||||
Curl_hash_destroy(&multi->sockhash);
|
||||
Curl_conncache_destroy(&multi->conn_cache);
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
Curl_llist_destroy(multi->pending, NULL);
|
||||
Curl_llist_destroy(&multi->msglist, NULL);
|
||||
Curl_llist_destroy(&multi->pending, NULL);
|
||||
|
||||
/* remove all easy handles */
|
||||
data = multi->easyp;
|
||||
@@ -2262,8 +2272,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
else
|
||||
return CURLM_BAD_HANDLE;
|
||||
return CURLM_BAD_HANDLE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2282,24 +2291,23 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
|
||||
|
||||
*msgs_in_queue = 0; /* default to none */
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) {
|
||||
if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(&multi->msglist)) {
|
||||
/* there is one or more messages in the list */
|
||||
struct curl_llist_element *e;
|
||||
|
||||
/* extract the head of the list to return */
|
||||
e = multi->msglist->head;
|
||||
e = multi->msglist.head;
|
||||
|
||||
msg = e->ptr;
|
||||
|
||||
/* remove the extracted entry */
|
||||
Curl_llist_remove(multi->msglist, e, NULL);
|
||||
Curl_llist_remove(&multi->msglist, e, NULL);
|
||||
|
||||
*msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist));
|
||||
*msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
|
||||
|
||||
return &msg->extmsg;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2394,7 +2402,7 @@ static void singlesocket(struct Curl_multi *multi,
|
||||
removed. */
|
||||
struct connectdata *easy_conn = data->easy_conn;
|
||||
if(easy_conn) {
|
||||
if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) {
|
||||
if(easy_conn->recv_pipe.size > 1) {
|
||||
/* the handle should not be removed from the pipe yet */
|
||||
remove_sock_from_hash = FALSE;
|
||||
|
||||
@@ -2403,12 +2411,12 @@ static void singlesocket(struct Curl_multi *multi,
|
||||
isn't already) */
|
||||
if(entry->easy == data) {
|
||||
if(Curl_recvpipe_head(data, easy_conn))
|
||||
entry->easy = easy_conn->recv_pipe->head->next->ptr;
|
||||
entry->easy = easy_conn->recv_pipe.head->next->ptr;
|
||||
else
|
||||
entry->easy = easy_conn->recv_pipe->head->ptr;
|
||||
entry->easy = easy_conn->recv_pipe.head->ptr;
|
||||
}
|
||||
}
|
||||
if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) {
|
||||
if(easy_conn->send_pipe.size > 1) {
|
||||
/* the handle should not be removed from the pipe yet */
|
||||
remove_sock_from_hash = FALSE;
|
||||
|
||||
@@ -2417,9 +2425,9 @@ static void singlesocket(struct Curl_multi *multi,
|
||||
isn't already) */
|
||||
if(entry->easy == data) {
|
||||
if(Curl_sendpipe_head(data, easy_conn))
|
||||
entry->easy = easy_conn->send_pipe->head->next->ptr;
|
||||
entry->easy = easy_conn->send_pipe.head->next->ptr;
|
||||
else
|
||||
entry->easy = easy_conn->send_pipe->head->ptr;
|
||||
entry->easy = easy_conn->send_pipe.head->ptr;
|
||||
}
|
||||
}
|
||||
/* Don't worry about overwriting recv_pipe head with send_pipe_head,
|
||||
@@ -2494,7 +2502,7 @@ static CURLMcode add_next_timeout(struct timeval now,
|
||||
struct Curl_easy *d)
|
||||
{
|
||||
struct timeval *tv = &d->state.expiretime;
|
||||
struct curl_llist *list = d->state.timeoutlist;
|
||||
struct curl_llist *list = &d->state.timeoutlist;
|
||||
struct curl_llist_element *e;
|
||||
|
||||
/* move over the timeout list for this specific handle and remove all
|
||||
@@ -2560,7 +2568,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
/* or should we fall-through and do the timer-based stuff? */
|
||||
return result;
|
||||
}
|
||||
else if(s != CURL_SOCKET_TIMEOUT) {
|
||||
if(s != CURL_SOCKET_TIMEOUT) {
|
||||
|
||||
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
|
||||
|
||||
@@ -2585,13 +2593,11 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
head. If we should read from the socket, take the recv_pipe head. */
|
||||
if(data->easy_conn) {
|
||||
if((ev_bitmask & CURL_POLL_OUT) &&
|
||||
data->easy_conn->send_pipe &&
|
||||
data->easy_conn->send_pipe->head)
|
||||
data = data->easy_conn->send_pipe->head->ptr;
|
||||
data->easy_conn->send_pipe.head)
|
||||
data = data->easy_conn->send_pipe.head->ptr;
|
||||
else if((ev_bitmask & CURL_POLL_IN) &&
|
||||
data->easy_conn->recv_pipe &&
|
||||
data->easy_conn->recv_pipe->head)
|
||||
data = data->easy_conn->recv_pipe->head->ptr;
|
||||
data->easy_conn->recv_pipe.head)
|
||||
data = data->easy_conn->recv_pipe.head->ptr;
|
||||
}
|
||||
|
||||
if(data->easy_conn &&
|
||||
@@ -2928,7 +2934,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli)
|
||||
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += (long)(milli/1000);
|
||||
set.tv_usec += (milli%1000)*1000;
|
||||
set.tv_usec += (long)(milli%1000)*1000;
|
||||
|
||||
if(set.tv_usec >= 1000000) {
|
||||
set.tv_sec++;
|
||||
@@ -2943,13 +2949,13 @@ void Curl_expire(struct Curl_easy *data, time_t milli)
|
||||
if(diff > 0) {
|
||||
/* the new expire time was later so just add it to the queue
|
||||
and get out */
|
||||
multi_addtimeout(data->state.timeoutlist, &set);
|
||||
multi_addtimeout(&data->state.timeoutlist, &set);
|
||||
return;
|
||||
}
|
||||
|
||||
/* the new time is newer than the presently set one, so add the current
|
||||
to the queue and update the head */
|
||||
multi_addtimeout(data->state.timeoutlist, nowp);
|
||||
multi_addtimeout(&data->state.timeoutlist, nowp);
|
||||
|
||||
/* Since this is an updated time, we must remove the previous entry from
|
||||
the splay tree first and then re-add the new value */
|
||||
@@ -2985,7 +2991,7 @@ void Curl_expire_latest(struct Curl_easy *data, time_t milli)
|
||||
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += (long)(milli / 1000);
|
||||
set.tv_usec += (milli % 1000) * 1000;
|
||||
set.tv_usec += (long)(milli % 1000) * 1000;
|
||||
|
||||
if(set.tv_usec >= 1000000) {
|
||||
set.tv_sec++;
|
||||
@@ -2995,11 +3001,14 @@ void Curl_expire_latest(struct Curl_easy *data, time_t milli)
|
||||
if(expire->tv_sec || expire->tv_usec) {
|
||||
/* This means that the struct is added as a node in the splay tree.
|
||||
Compare if the new time is earlier, and only remove-old/add-new if it
|
||||
is. */
|
||||
is. */
|
||||
time_t diff = curlx_tvdiff(set, *expire);
|
||||
if(diff > 0)
|
||||
/* the new expire time was later than the top time, so just skip this */
|
||||
if((diff > 0) && (diff < milli)) {
|
||||
/* if the new expire time is later than the top time, skip it, but not
|
||||
if the diff is larger than the new offset since then the previous
|
||||
time is already expired! */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just add the timeout like normal */
|
||||
@@ -3026,7 +3035,7 @@ void Curl_expire_clear(struct Curl_easy *data)
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
the splay tree */
|
||||
struct curl_llist *list = data->state.timeoutlist;
|
||||
struct curl_llist *list = &data->state.timeoutlist;
|
||||
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
@@ -3086,17 +3095,17 @@ curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
|
||||
|
||||
struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
|
||||
{
|
||||
return multi->pipelining_site_bl;
|
||||
return &multi->pipelining_site_bl;
|
||||
}
|
||||
|
||||
struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
|
||||
{
|
||||
return multi->pipelining_server_bl;
|
||||
return &multi->pipelining_server_bl;
|
||||
}
|
||||
|
||||
void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
{
|
||||
struct curl_llist_element *e = multi->pending->head;
|
||||
struct curl_llist_element *e = multi->pending.head;
|
||||
|
||||
while(e) {
|
||||
struct Curl_easy *data = e->ptr;
|
||||
@@ -3106,7 +3115,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
multistate(data, CURLM_STATE_CONNECT);
|
||||
|
||||
/* Remove this node from the list */
|
||||
Curl_llist_remove(multi->pending, e, NULL);
|
||||
Curl_llist_remove(&multi->pending, e, NULL);
|
||||
|
||||
/* Make sure that the handle will be processed soonish. */
|
||||
Curl_expire_latest(data, 0);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -80,10 +80,10 @@ struct Curl_multi {
|
||||
int num_alive; /* amount of easy handles that are added but have not yet
|
||||
reached COMPLETE state */
|
||||
|
||||
struct curl_llist *msglist; /* a list of messages from completed transfers */
|
||||
struct curl_llist msglist; /* a list of messages from completed transfers */
|
||||
|
||||
struct curl_llist *pending; /* Curl_easys that are in the
|
||||
CURLM_STATE_CONNECT_PEND state */
|
||||
struct curl_llist pending; /* Curl_easys that are in the
|
||||
CURLM_STATE_CONNECT_PEND state */
|
||||
|
||||
/* callback function and user data pointer for the *socket() API */
|
||||
curl_socket_callback socket_cb;
|
||||
@@ -138,11 +138,11 @@ struct Curl_multi {
|
||||
bigger than this is not
|
||||
considered for pipelining */
|
||||
|
||||
struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted
|
||||
from pipelining */
|
||||
struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted
|
||||
from pipelining */
|
||||
|
||||
struct curl_llist *pipelining_server_bl; /* List of server types that are
|
||||
blacklisted from pipelining */
|
||||
struct curl_llist pipelining_server_bl; /* List of server types that are
|
||||
blacklisted from pipelining */
|
||||
|
||||
/* timer callback and user data pointer for the *socket() API */
|
||||
curl_multi_timer_callback timer_cb;
|
||||
|
||||
@@ -58,8 +58,7 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
flags = sfcntl(sockfd, F_GETFL, 0);
|
||||
if(nonblock)
|
||||
return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
else
|
||||
return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
|
||||
#elif defined(HAVE_IOCTL_FIONBIO)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -152,7 +152,7 @@ void Curl_pp_init(struct pingpong *pp)
|
||||
*
|
||||
* Curl_pp_vsendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* Send the formatted string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
@@ -239,7 +239,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
|
||||
*
|
||||
* Curl_pp_sendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* Send the formatted string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -95,7 +95,7 @@ time_t Curl_pp_state_timeout(struct pingpong *pp);
|
||||
*
|
||||
* Curl_pp_sendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* Send the formatted string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
@@ -108,7 +108,7 @@ CURLcode Curl_pp_sendf(struct pingpong *pp,
|
||||
*
|
||||
* Curl_pp_vsendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* Send the formatted string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
* append the necessary things itself.
|
||||
*
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2013-2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2013 - 2017, 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
|
||||
@@ -69,8 +69,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data,
|
||||
curl_off_t recv_size = -2; /* Make it easy to spot in the log */
|
||||
|
||||
/* Find the head of the recv pipe, if any */
|
||||
if(conn->recv_pipe && conn->recv_pipe->head) {
|
||||
struct Curl_easy *recv_handle = conn->recv_pipe->head->ptr;
|
||||
if(conn->recv_pipe.head) {
|
||||
struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr;
|
||||
|
||||
recv_size = recv_handle->req.size;
|
||||
|
||||
@@ -103,18 +103,18 @@ static CURLcode addHandleToPipeline(struct Curl_easy *data,
|
||||
CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *sendhead = conn->send_pipe->head;
|
||||
struct curl_llist_element *sendhead = conn->send_pipe.head;
|
||||
struct curl_llist *pipeline;
|
||||
CURLcode result;
|
||||
|
||||
pipeline = conn->send_pipe;
|
||||
pipeline = &conn->send_pipe;
|
||||
|
||||
result = addHandleToPipeline(handle, pipeline);
|
||||
|
||||
if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
|
||||
if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
|
||||
/* this is a new one as head, expire it */
|
||||
Curl_pipeline_leave_write(conn); /* not in use yet */
|
||||
Curl_expire(conn->send_pipe->head->ptr, 0);
|
||||
Curl_expire(conn->send_pipe.head->ptr, 0);
|
||||
}
|
||||
|
||||
#if 0 /* enable for pipeline debugging */
|
||||
@@ -135,21 +135,21 @@ void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = conn->send_pipe->head;
|
||||
curr = conn->send_pipe.head;
|
||||
while(curr) {
|
||||
if(curr->ptr == handle) {
|
||||
Curl_llist_move(conn->send_pipe, curr,
|
||||
conn->recv_pipe, conn->recv_pipe->tail);
|
||||
Curl_llist_move(&conn->send_pipe, curr,
|
||||
&conn->recv_pipe, conn->recv_pipe.tail);
|
||||
|
||||
if(conn->send_pipe->head) {
|
||||
if(conn->send_pipe.head) {
|
||||
/* Since there's a new easy handle at the start of the send pipeline,
|
||||
set its timeout value to 1ms to make it trigger instantly */
|
||||
Curl_pipeline_leave_write(conn); /* not used now */
|
||||
#ifdef DEBUGBUILD
|
||||
infof(conn->data, "%p is at send pipe head B!\n",
|
||||
(void *)conn->send_pipe->head->ptr);
|
||||
(void *)conn->send_pipe.head->ptr);
|
||||
#endif
|
||||
Curl_expire(conn->send_pipe->head->ptr, 0);
|
||||
Curl_expire(conn->send_pipe.head->ptr, 0);
|
||||
}
|
||||
|
||||
/* The receiver's list is not really interesting here since either this
|
||||
@@ -191,15 +191,14 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
|
||||
}
|
||||
|
||||
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
struct curl_llist **list_ptr)
|
||||
struct curl_llist *list)
|
||||
{
|
||||
struct curl_llist *old_list = *list_ptr;
|
||||
struct curl_llist *new_list = NULL;
|
||||
/* Free the old list */
|
||||
if(list->size)
|
||||
Curl_llist_destroy(list, NULL);
|
||||
|
||||
if(sites) {
|
||||
new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor);
|
||||
if(!new_list)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor);
|
||||
|
||||
/* Parse the URLs and populate the list */
|
||||
while(*sites) {
|
||||
@@ -209,14 +208,14 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
|
||||
hostname = strdup(*sites);
|
||||
if(!hostname) {
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
Curl_llist_destroy(list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
entry = malloc(sizeof(struct site_blacklist_entry));
|
||||
if(!entry) {
|
||||
free(hostname);
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
Curl_llist_destroy(list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -233,9 +232,9 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
|
||||
entry->hostname = hostname;
|
||||
|
||||
if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) {
|
||||
if(!Curl_llist_insert_next(list, list->tail, entry)) {
|
||||
site_blacklist_llist_dtor(NULL, entry);
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
Curl_llist_destroy(list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -243,14 +242,6 @@ CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the old list */
|
||||
if(old_list) {
|
||||
Curl_llist_destroy(old_list, NULL);
|
||||
}
|
||||
|
||||
/* This might be NULL if sites == NULL, i.e the blacklist is cleared */
|
||||
*list_ptr = new_list;
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
@@ -284,15 +275,14 @@ bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||
}
|
||||
|
||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||
struct curl_llist **list_ptr)
|
||||
struct curl_llist *list)
|
||||
{
|
||||
struct curl_llist *old_list = *list_ptr;
|
||||
struct curl_llist *new_list = NULL;
|
||||
/* Free the old list */
|
||||
if(list->size)
|
||||
Curl_llist_destroy(list, NULL);
|
||||
|
||||
if(servers) {
|
||||
new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor);
|
||||
if(!new_list)
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor);
|
||||
|
||||
/* Parse the URLs and populate the list */
|
||||
while(*servers) {
|
||||
@@ -300,12 +290,12 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||
|
||||
server_name = strdup(*servers);
|
||||
if(!server_name) {
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
Curl_llist_destroy(list, NULL);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) {
|
||||
Curl_llist_destroy(new_list, NULL);
|
||||
if(!Curl_llist_insert_next(list, list->tail, server_name)) {
|
||||
Curl_llist_destroy(list, NULL);
|
||||
Curl_safefree(server_name);
|
||||
return CURLM_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -314,13 +304,6 @@ CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the old list */
|
||||
if(old_list) {
|
||||
Curl_llist_destroy(old_list, NULL);
|
||||
}
|
||||
|
||||
/* This might be NULL if sites == NULL, i.e the blacklist is cleared */
|
||||
*list_ptr = new_list;
|
||||
|
||||
return CURLM_OK;
|
||||
}
|
||||
@@ -340,14 +323,14 @@ static bool pipe_head(struct Curl_easy *data,
|
||||
bool Curl_recvpipe_head(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
return pipe_head(data, conn->recv_pipe);
|
||||
return pipe_head(data, &conn->recv_pipe);
|
||||
}
|
||||
|
||||
/* returns TRUE if the given handle is head of the send pipe */
|
||||
bool Curl_sendpipe_head(struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
return pipe_head(data, conn->send_pipe);
|
||||
return pipe_head(data, &conn->send_pipe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -34,13 +34,13 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
|
||||
struct connectdata *conn);
|
||||
|
||||
CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
|
||||
struct curl_llist **list_ptr);
|
||||
struct curl_llist *list_ptr);
|
||||
|
||||
bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||
char *server_name);
|
||||
|
||||
CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
|
||||
struct curl_llist **list_ptr);
|
||||
struct curl_llist *list_ptr);
|
||||
|
||||
bool Curl_pipeline_checkget_write(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -127,7 +127,8 @@ const struct Curl_handler Curl_handler_pop3 = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_POP3, /* defport */
|
||||
CURLPROTO_POP3, /* protocol */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
|
||||
PROTOPT_URLOPTIONS
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
@@ -153,7 +154,7 @@ const struct Curl_handler Curl_handler_pop3s = {
|
||||
PORT_POP3S, /* defport */
|
||||
CURLPROTO_POP3S, /* protocol */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_SSL
|
||||
| PROTOPT_NOURLQUERY /* flags */
|
||||
| PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -799,7 +800,7 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
|
||||
|
||||
if(pop3code != '+') {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied. %c", pop3code);
|
||||
failf(data, "STARTTLS denied");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -229,16 +229,16 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
|
||||
* need to wait until we're back under the speed limit, if needed.
|
||||
*
|
||||
* The way it works is by having a "starting point" (time & amount of data
|
||||
* transfered by then) used in the speed computation, to be used instead of the
|
||||
* start of the transfer.
|
||||
* This starting point is regularly moved as transfer goes on, to keep getting
|
||||
* accurate values (instead of average over the entire tranfer).
|
||||
* transferred by then) used in the speed computation, to be used instead of
|
||||
* the start of the transfer. This starting point is regularly moved as
|
||||
* transfer goes on, to keep getting accurate values (instead of average over
|
||||
* the entire transfer).
|
||||
*
|
||||
* This function takes the current amount of data transfered, the amount at the
|
||||
* starting point, the limit (in bytes/s), the time of the starting point and
|
||||
* the current time.
|
||||
* This function takes the current amount of data transferred, the amount at
|
||||
* the starting point, the limit (in bytes/s), the time of the starting point
|
||||
* and the current time.
|
||||
*
|
||||
* Returns -1 if no waiting is needed (not enough data transfered since
|
||||
* Returns -1 if no waiting is needed (not enough data transferred since
|
||||
* starting point yet), 0 when no waiting is needed but the starting point
|
||||
* should be reset (to current), or the number of milliseconds to wait to get
|
||||
* back under the speed limit.
|
||||
@@ -267,8 +267,8 @@ long Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
||||
if(actual < minimum)
|
||||
/* this is a conversion on some systems (64bit time_t => 32bit long) */
|
||||
return (long)(minimum - actual);
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
|
||||
@@ -454,7 +454,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
||||
failf(data, "Callback aborted");
|
||||
return result;
|
||||
}
|
||||
else if(data->set.fprogress) {
|
||||
if(data->set.fprogress) {
|
||||
/* The older deprecated callback is set, call that */
|
||||
result= data->set.fprogress(data->set.progress_client,
|
||||
(double)data->progress.size_dl,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "vtls/vtls.h"
|
||||
@@ -61,7 +63,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
|
||||
/* data may be NULL! */
|
||||
result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd));
|
||||
if(result != CURLE_NOT_BUILT_IN)
|
||||
/* only if there is no random funtion in the TLS backend do the non crypto
|
||||
/* only if there is no random function in the TLS backend do the non crypto
|
||||
version, otherwise return result */
|
||||
return result;
|
||||
|
||||
|
||||
+33
-37
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -216,7 +216,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
|
||||
CSeq_sent, CSeq_recv);
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
else if(data->set.rtspreq == RTSPREQ_RECEIVE &&
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE &&
|
||||
(conn->proto.rtspc.rtp_channel == -1)) {
|
||||
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
|
||||
/* TODO CPC: Server -> Client logic here */
|
||||
@@ -648,31 +648,29 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
*readmore = TRUE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* We have the full RTP interleaved packet
|
||||
* Write out the header including the leading '$' */
|
||||
DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
|
||||
rtspc->rtp_channel, rtp_length));
|
||||
result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
|
||||
if(result) {
|
||||
failf(data, "Got an error writing an RTP packet");
|
||||
*readmore = FALSE;
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
rtspc->rtp_buf = NULL;
|
||||
rtspc->rtp_bufsize = 0;
|
||||
return result;
|
||||
}
|
||||
/* We have the full RTP interleaved packet
|
||||
* Write out the header including the leading '$' */
|
||||
DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
|
||||
rtspc->rtp_channel, rtp_length));
|
||||
result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
|
||||
if(result) {
|
||||
failf(data, "Got an error writing an RTP packet");
|
||||
*readmore = FALSE;
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
rtspc->rtp_buf = NULL;
|
||||
rtspc->rtp_bufsize = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Move forward in the buffer */
|
||||
rtp_dataleft -= rtp_length + 4;
|
||||
rtp += rtp_length + 4;
|
||||
/* Move forward in the buffer */
|
||||
rtp_dataleft -= rtp_length + 4;
|
||||
rtp += rtp_length + 4;
|
||||
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE) {
|
||||
/* If we are in a passive receive, give control back
|
||||
* to the app as often as we can.
|
||||
*/
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
}
|
||||
if(data->set.rtspreq == RTSPREQ_RECEIVE) {
|
||||
/* If we are in a passive receive, give control back
|
||||
* to the app as often as we can.
|
||||
*/
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -703,20 +701,18 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
|
||||
*nread = 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
else {
|
||||
/* Fix up k->str to point just after the last RTP packet */
|
||||
k->str += *nread - rtp_dataleft;
|
||||
/* Fix up k->str to point just after the last RTP packet */
|
||||
k->str += *nread - rtp_dataleft;
|
||||
|
||||
/* either all of the data has been read or...
|
||||
* rtp now points at the next byte to parse
|
||||
*/
|
||||
if(rtp_dataleft > 0)
|
||||
DEBUGASSERT(k->str[0] == rtp[0]);
|
||||
/* either all of the data has been read or...
|
||||
* rtp now points at the next byte to parse
|
||||
*/
|
||||
if(rtp_dataleft > 0)
|
||||
DEBUGASSERT(k->str[0] == rtp[0]);
|
||||
|
||||
DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
|
||||
DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
|
||||
|
||||
*nread = rtp_dataleft;
|
||||
}
|
||||
*nread = rtp_dataleft;
|
||||
|
||||
/* If we get here, we have finished with the leftover/merge buffer */
|
||||
Curl_safefree(rtspc->rtp_buf);
|
||||
@@ -797,7 +793,7 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
|
||||
/* If the Session ID is not set, and we find it in a response, then set
|
||||
* it.
|
||||
*
|
||||
* Allow any non whitespace content, up to the field seperator or end of
|
||||
* Allow any non whitespace content, up to the field separator or end of
|
||||
* line. RFC 2326 isn't 100% clear on the session ID and for example
|
||||
* gstreamer does url-encoded session ID's not covered by the standard.
|
||||
*/
|
||||
|
||||
@@ -367,6 +367,10 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
|
||||
size_t decoded_sz = 0;
|
||||
CURLcode error;
|
||||
|
||||
if(!conn->mech)
|
||||
/* not inititalized, return error */
|
||||
return -1;
|
||||
|
||||
DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
|
||||
|
||||
error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -129,7 +129,7 @@ int Curl_wait_ms(int timeout_ms)
|
||||
* and a file descriptor is too large for FD_SETSIZE.
|
||||
*
|
||||
* A negative timeout value makes this function wait indefinitely,
|
||||
* unles no valid file descriptor is given, when this happens the
|
||||
* unless no valid file descriptor is given, when this happens the
|
||||
* negative timeout is ignored and the function times out immediately.
|
||||
*
|
||||
* Return values:
|
||||
@@ -164,7 +164,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
int r;
|
||||
int ret;
|
||||
|
||||
#if SIZEOF_LONG != SIZEOF_INT
|
||||
#if SIZEOF_TIME_T != SIZEOF_INT
|
||||
/* wrap-around precaution */
|
||||
if(timeout_ms >= INT_MAX)
|
||||
timeout_ms = INT_MAX;
|
||||
@@ -380,7 +380,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
* select() is used instead. An error is returned if select() is
|
||||
* being used and a file descriptor is too large for FD_SETSIZE.
|
||||
* A negative timeout value makes this function wait indefinitely,
|
||||
* unles no valid file descriptor is given, when this happens the
|
||||
* unless no valid file descriptor is given, when this happens the
|
||||
* negative timeout is ignored and the function times out immediately.
|
||||
*
|
||||
* Return values:
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#elif defined(HAVE_POLL_H)
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#elif defined(HAVE_SYS_POLL_H)
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "non-ascii.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "strdup.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -262,7 +263,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Curl_sendf() sends formated data to the server */
|
||||
/* Curl_sendf() sends formatted data to the server */
|
||||
CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
@@ -474,21 +475,58 @@ static CURLcode pausewrite(struct Curl_easy *data,
|
||||
we want to send we need to dup it to save a copy for when the sending
|
||||
is again enabled */
|
||||
struct SingleRequest *k = &data->req;
|
||||
char *dupl = malloc(len);
|
||||
if(!dupl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
struct UrlState *s = &data->state;
|
||||
char *dupl;
|
||||
unsigned int i;
|
||||
bool newtype = TRUE;
|
||||
|
||||
memcpy(dupl, ptr, len);
|
||||
if(s->tempcount) {
|
||||
for(i=0; i< s->tempcount; i++) {
|
||||
if(s->tempwrite[i].type == type) {
|
||||
/* data for this type exists */
|
||||
newtype = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUGASSERT(i < 3);
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
/* store this information in the state struct for later use */
|
||||
data->state.tempwrite = dupl;
|
||||
data->state.tempwritesize = len;
|
||||
data->state.tempwritetype = type;
|
||||
if(!newtype) {
|
||||
/* append new data to old data */
|
||||
|
||||
/* figure out the new size of the data to save */
|
||||
size_t newlen = len + s->tempwrite[i].len;
|
||||
/* allocate the new memory area */
|
||||
char *newptr = realloc(s->tempwrite[i].buf, newlen);
|
||||
if(!newptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
/* copy the new data to the end of the new area */
|
||||
memcpy(newptr + s->tempwrite[i].len, ptr, len);
|
||||
|
||||
/* update the pointer and the size */
|
||||
s->tempwrite[i].buf = newptr;
|
||||
s->tempwrite[i].len = newlen;
|
||||
}
|
||||
else {
|
||||
dupl = Curl_memdup(ptr, len);
|
||||
if(!dupl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* store this information in the state struct for later use */
|
||||
s->tempwrite[i].buf = dupl;
|
||||
s->tempwrite[i].len = len;
|
||||
s->tempwrite[i].type = type;
|
||||
|
||||
if(newtype)
|
||||
s->tempcount++;
|
||||
}
|
||||
|
||||
/* mark the connection as RECV paused */
|
||||
k->keepon |= KEEP_RECV_PAUSE;
|
||||
|
||||
DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
|
||||
DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n",
|
||||
len, type));
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -511,31 +549,10 @@ CURLcode Curl_client_chop_write(struct connectdata *conn,
|
||||
if(!len)
|
||||
return CURLE_OK;
|
||||
|
||||
/* If reading is actually paused, we're forced to append this chunk of data
|
||||
to the already held data, but only if it is the same type as otherwise it
|
||||
can't work and it'll return error instead. */
|
||||
if(data->req.keepon & KEEP_RECV_PAUSE) {
|
||||
size_t newlen;
|
||||
char *newptr;
|
||||
if(type != data->state.tempwritetype)
|
||||
/* major internal confusion */
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
DEBUGASSERT(data->state.tempwrite);
|
||||
|
||||
/* figure out the new size of the data to save */
|
||||
newlen = len + data->state.tempwritesize;
|
||||
/* allocate the new memory area */
|
||||
newptr = realloc(data->state.tempwrite, newlen);
|
||||
if(!newptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
/* copy the new data to the end of the new area */
|
||||
memcpy(newptr + data->state.tempwritesize, ptr, len);
|
||||
/* update the pointer and the size */
|
||||
data->state.tempwrite = newptr;
|
||||
data->state.tempwritesize = newlen;
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* If reading is paused, append this data to the already held data for this
|
||||
type. */
|
||||
if(data->req.keepon & KEEP_RECV_PAUSE)
|
||||
return pausewrite(data, type, ptr, len);
|
||||
|
||||
/* Determine the callback(s) to use. */
|
||||
if(type & CLIENTWRITE_BODY)
|
||||
@@ -565,10 +582,9 @@ CURLcode Curl_client_chop_write(struct connectdata *conn,
|
||||
failf(data, "Write callback asked for PAUSE when not supported!");
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
else
|
||||
return pausewrite(data, type, ptr, len);
|
||||
return pausewrite(data, type, ptr, len);
|
||||
}
|
||||
else if(wrote != chunklen) {
|
||||
if(wrote != chunklen) {
|
||||
failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
@@ -616,6 +632,8 @@ CURLcode Curl_client_write(struct connectdata *conn,
|
||||
if(0 == len)
|
||||
len = strlen(ptr);
|
||||
|
||||
DEBUGASSERT(type <= 3);
|
||||
|
||||
/* FTP data may need conversion. */
|
||||
if((type & CLIENTWRITE_BODY) &&
|
||||
(conn->handler->protocol & PROTO_FAMILY_FTP) &&
|
||||
@@ -652,8 +670,7 @@ CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
#endif
|
||||
if(return_error)
|
||||
return CURLE_AGAIN;
|
||||
else
|
||||
return CURLE_RECV_ERROR;
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
/* we only return number of bytes read when we return OK */
|
||||
|
||||
+23
-18
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
|
||||
* Copyright (C) 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2016-2017, 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
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
|
||||
(CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
|
||||
(CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
@@ -32,8 +32,12 @@
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
#include <process.h>
|
||||
#ifdef CURL_WINDOWS_APP
|
||||
#define getpid GetCurrentProcessId
|
||||
#else
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "smb.h"
|
||||
#include "urldata.h"
|
||||
@@ -117,18 +121,18 @@ const struct Curl_handler Curl_handler_smbs = {
|
||||
#define SERVICENAME "?????"
|
||||
|
||||
/* Append a string to an SMB message */
|
||||
#define MSGCAT(str) \
|
||||
strcpy(p, (str)); \
|
||||
#define MSGCAT(str) \
|
||||
strcpy(p, (str)); \
|
||||
p += strlen(str);
|
||||
|
||||
/* Append a null-terminated string to an SMB message */
|
||||
#define MSGCATNULL(str) \
|
||||
strcpy(p, (str)); \
|
||||
#define MSGCATNULL(str) \
|
||||
strcpy(p, (str)); \
|
||||
p += strlen(str) + 1;
|
||||
|
||||
/* SMB is mostly little endian */
|
||||
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
|
||||
defined(__OS400__)
|
||||
defined(__OS400__)
|
||||
static unsigned short smb_swap16(unsigned short x)
|
||||
{
|
||||
return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
|
||||
@@ -137,20 +141,20 @@ static unsigned short smb_swap16(unsigned short x)
|
||||
static unsigned int smb_swap32(unsigned int x)
|
||||
{
|
||||
return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
|
||||
((x >> 24) & 0xff);
|
||||
((x >> 24) & 0xff);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LONGLONG
|
||||
static unsigned long long smb_swap64(unsigned long long x)
|
||||
{
|
||||
return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
}
|
||||
#else
|
||||
static unsigned __int64 smb_swap64(unsigned __int64 x)
|
||||
{
|
||||
return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
@@ -197,7 +201,7 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
|
||||
|
||||
if(smb->state != newstate)
|
||||
infof(conn->data, "SMB conn %p state change from %s to %s\n",
|
||||
(void *)smb, names[smb->state], names[newstate]);
|
||||
(void *)smb, names[smb->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
smb->state = newstate;
|
||||
@@ -223,7 +227,7 @@ static void request_state(struct connectdata *conn,
|
||||
|
||||
if(req->state != newstate)
|
||||
infof(conn->data, "SMB request %p state change from %s to %s\n",
|
||||
(void *)req, names[req->state], names[newstate]);
|
||||
(void *)req, names[req->state], names[newstate]);
|
||||
#endif
|
||||
|
||||
req->state = newstate;
|
||||
@@ -308,8 +312,9 @@ static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
|
||||
if(smbc->got < sizeof(unsigned int))
|
||||
return CURLE_OK;
|
||||
|
||||
nbt_size = Curl_read16_be((const unsigned char *)(buf +
|
||||
sizeof(unsigned short))) + sizeof(unsigned int);
|
||||
nbt_size = Curl_read16_be((const unsigned char *)
|
||||
(buf + sizeof(unsigned short))) +
|
||||
sizeof(unsigned int);
|
||||
if(smbc->got < nbt_size)
|
||||
return CURLE_OK;
|
||||
|
||||
@@ -320,7 +325,7 @@ static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
|
||||
if(nbt_size >= msg_size + sizeof(unsigned short)) {
|
||||
/* Add the byte count */
|
||||
msg_size += sizeof(unsigned short) +
|
||||
Curl_read16_le((const unsigned char *)&buf[msg_size]);
|
||||
Curl_read16_le((const unsigned char *)&buf[msg_size]);
|
||||
if(nbt_size < msg_size)
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
@@ -441,7 +446,7 @@ static CURLcode smb_send_setup(struct connectdata *conn)
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
|
||||
Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
|
||||
Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
|
||||
#else
|
||||
@@ -603,7 +608,7 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
||||
/* Check if there is data in the transfer buffer */
|
||||
if(!smbc->send_size && smbc->upload_size) {
|
||||
int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
|
||||
(int) smbc->upload_size;
|
||||
(int) smbc->upload_size;
|
||||
conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
|
||||
result = Curl_fillreadbuffer(conn, nread, &nread);
|
||||
if(result && result != CURLE_AGAIN)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -126,7 +126,8 @@ const struct Curl_handler Curl_handler_smtp = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_SMTP, /* defport */
|
||||
CURLPROTO_SMTP, /* protocol */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
|
||||
PROTOPT_URLOPTIONS
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
@@ -152,7 +153,7 @@ const struct Curl_handler Curl_handler_smtps = {
|
||||
PORT_SMTPS, /* defport */
|
||||
CURLPROTO_SMTPS, /* protocol */
|
||||
PROTOPT_CLOSEACTION | PROTOPT_SSL
|
||||
| PROTOPT_NOURLQUERY /* flags */
|
||||
| PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -692,7 +693,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
|
||||
|
||||
if(smtpcode != 220) {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied. %c", smtpcode);
|
||||
failf(data, "STARTTLS denied, code %d", smtpcode);
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -73,7 +73,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
|
||||
result = Curl_read_plain(sockfd, buf, buffersize, &nread);
|
||||
if(CURLE_AGAIN == result)
|
||||
continue;
|
||||
else if(result)
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(buffersize == nread) {
|
||||
@@ -416,7 +416,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
failf(conn->data, "SOCKS5: no connection here");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(0 == result) {
|
||||
if(0 == result) {
|
||||
failf(conn->data, "SOCKS5: connection timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
@@ -457,7 +457,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
failf(conn->data, "SOCKS5 nothing to read");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(0 == result) {
|
||||
if(0 == result) {
|
||||
failf(conn->data, "SOCKS5 read timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
@@ -553,7 +553,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
"SOCKS5 GSSAPI per-message authentication is not supported.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(socksreq[1] == 255) {
|
||||
if(socksreq[1] == 255) {
|
||||
#endif
|
||||
if(!proxy_name || !*proxy_name) {
|
||||
failf(data,
|
||||
@@ -772,9 +772,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else {
|
||||
infof(data, "SOCKS5 request granted.\n");
|
||||
}
|
||||
infof(data, "SOCKS5 request granted.\n");
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
return CURLE_OK; /* Proxy was successful! */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -33,42 +33,41 @@ void Curl_speedinit(struct Curl_easy *data)
|
||||
memset(&data->state.keeps_speed, 0, sizeof(struct timeval));
|
||||
}
|
||||
|
||||
/*
|
||||
* @unittest: 1606
|
||||
*/
|
||||
CURLcode Curl_speedcheck(struct Curl_easy *data,
|
||||
struct timeval now)
|
||||
{
|
||||
if((data->progress.current_speed >= 0) &&
|
||||
data->set.low_speed_time &&
|
||||
(Curl_tvlong(data->state.keeps_speed) != 0) &&
|
||||
(data->progress.current_speed < data->set.low_speed_limit)) {
|
||||
time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
|
||||
time_t nextcheck = (data->set.low_speed_time * 1000) - howlong;
|
||||
if((data->progress.current_speed >= 0) && data->set.low_speed_time) {
|
||||
if(data->progress.current_speed < data->set.low_speed_limit) {
|
||||
if(!data->state.keeps_speed.tv_sec)
|
||||
/* under the limit at this very moment */
|
||||
data->state.keeps_speed = now;
|
||||
else {
|
||||
/* how long has it been under the limit */
|
||||
time_t howlong = Curl_tvdiff(now, data->state.keeps_speed);
|
||||
|
||||
/* We are now below the "low speed limit". If we are below it
|
||||
for "low speed time" seconds we consider that enough reason
|
||||
to abort the download. */
|
||||
if(nextcheck <= 0) {
|
||||
/* we have been this slow for long enough, now die */
|
||||
failf(data,
|
||||
"Operation too slow. "
|
||||
"Less than %ld bytes/sec transferred the last %ld seconds",
|
||||
data->set.low_speed_limit,
|
||||
data->set.low_speed_time);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else {
|
||||
/* wait complete low_speed_time */
|
||||
Curl_expire_latest(data, nextcheck);
|
||||
if(howlong >= data->set.low_speed_time * 1000) {
|
||||
/* too long */
|
||||
failf(data,
|
||||
"Operation too slow. "
|
||||
"Less than %ld bytes/sec transferred the last %ld seconds",
|
||||
data->set.low_speed_limit,
|
||||
data->set.low_speed_time);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
/* faster right now */
|
||||
data->state.keeps_speed.tv_sec = 0;
|
||||
}
|
||||
else {
|
||||
/* we keep up the required speed all right */
|
||||
data->state.keeps_speed = now;
|
||||
|
||||
if(data->set.low_speed_limit)
|
||||
/* if there is a low speed limit enabled, we set the expire timer to
|
||||
make this connection's speed get checked again no later than when
|
||||
this time is up */
|
||||
Curl_expire_latest(data, data->set.low_speed_time*1000);
|
||||
}
|
||||
if(data->set.low_speed_limit)
|
||||
/* if low speed limit is enabled, set the expire timer to make this
|
||||
connection's speed get checked again in a second */
|
||||
Curl_expire_latest(data, 1000);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -110,22 +110,17 @@ struct Curl_tree *Curl_splayinsert(struct timeval i,
|
||||
t = Curl_splay(i, t);
|
||||
if(compare(i, t->key)==0) {
|
||||
/* There already exists a node in the tree with the very same key. Build
|
||||
a linked list of nodes. We make the new 'node' struct the new master
|
||||
node and make the previous node the first one in the 'same' list. */
|
||||
a doubly-linked circular list of nodes. We add the new 'node' struct
|
||||
to the end of this list. */
|
||||
|
||||
node->same = t;
|
||||
node->key = i;
|
||||
node->smaller = t->smaller;
|
||||
node->larger = t->larger;
|
||||
|
||||
t->smaller = node; /* in the sub node for this same key, we use the
|
||||
smaller pointer to point back to the master
|
||||
node */
|
||||
|
||||
t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED
|
||||
node->key = KEY_NOTUSED; /* we set the key in the sub node to NOTUSED
|
||||
to quickly identify this node as a subnode */
|
||||
node->samen = t;
|
||||
node->samep = t->samep;
|
||||
t->samep->samen = node;
|
||||
t->samep = node;
|
||||
|
||||
return node; /* new root node */
|
||||
return t; /* the root node always stays the same */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,16 +140,20 @@ struct Curl_tree *Curl_splayinsert(struct timeval i,
|
||||
}
|
||||
node->key = i;
|
||||
|
||||
node->same = NULL; /* no identical node (yet) */
|
||||
/* no identical nodes (yet), we are the only one in the list of nodes */
|
||||
node->samen = node;
|
||||
node->samep = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Finds and deletes the best-fit node from the tree. Return a pointer to the
|
||||
resulting tree. best-fit means the node with the given or lower key */
|
||||
resulting tree. best-fit means the smallest node if it is not larger than
|
||||
the key */
|
||||
struct Curl_tree *Curl_splaygetbest(struct timeval i,
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree **removed)
|
||||
struct Curl_tree *t,
|
||||
struct Curl_tree **removed)
|
||||
{
|
||||
static struct timeval tv_zero = {0, 0};
|
||||
struct Curl_tree *x;
|
||||
|
||||
if(!t) {
|
||||
@@ -162,49 +161,36 @@ struct Curl_tree *Curl_splaygetbest(struct timeval i,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t = Curl_splay(i, t);
|
||||
/* find smallest */
|
||||
t = Curl_splay(tv_zero, t);
|
||||
if(compare(i, t->key) < 0) {
|
||||
/* too big node, try the smaller chain */
|
||||
if(t->smaller)
|
||||
t=Curl_splay(t->smaller->key, t);
|
||||
else {
|
||||
/* fail */
|
||||
*removed = NULL;
|
||||
return t;
|
||||
}
|
||||
/* even the smallest is too big */
|
||||
*removed = NULL;
|
||||
return t;
|
||||
}
|
||||
|
||||
if(compare(i, t->key) >= 0) { /* found it */
|
||||
/* FIRST! Check if there is a list with identical keys */
|
||||
x = t->same;
|
||||
if(x) {
|
||||
/* there is, pick one from the list */
|
||||
/* FIRST! Check if there is a list with identical keys */
|
||||
x = t->samen;
|
||||
if(x != t) {
|
||||
/* there is, pick one from the list */
|
||||
|
||||
/* 'x' is the new root node */
|
||||
/* 'x' is the new root node */
|
||||
|
||||
x->key = t->key;
|
||||
x->larger = t->larger;
|
||||
x->smaller = t->smaller;
|
||||
x->key = t->key;
|
||||
x->larger = t->larger;
|
||||
x->smaller = t->smaller;
|
||||
x->samep = t->samep;
|
||||
t->samep->samen = x;
|
||||
|
||||
*removed = t;
|
||||
return x; /* new root */
|
||||
}
|
||||
|
||||
if(t->smaller == NULL) {
|
||||
x = t->larger;
|
||||
}
|
||||
else {
|
||||
x = Curl_splay(i, t->smaller);
|
||||
x->larger = t->larger;
|
||||
}
|
||||
*removed = t;
|
||||
return x; /* new root */
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
else {
|
||||
*removed = NULL; /* no match */
|
||||
return t; /* It wasn't there */
|
||||
}
|
||||
/* we splayed the tree to the smallest element, there is no smaller */
|
||||
x = t->larger;
|
||||
*removed = t;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,19 +217,17 @@ int Curl_splayremovebyaddr(struct Curl_tree *t,
|
||||
|
||||
if(compare(KEY_NOTUSED, removenode->key) == 0) {
|
||||
/* Key set to NOTUSED means it is a subnode within a 'same' linked list
|
||||
and thus we can unlink it easily. The 'smaller' link of a subnode
|
||||
links to the parent node. */
|
||||
if(removenode->smaller == NULL)
|
||||
and thus we can unlink it easily. */
|
||||
if(removenode->samen == removenode)
|
||||
/* A non-subnode should never be set to KEY_NOTUSED */
|
||||
return 3;
|
||||
|
||||
removenode->smaller->same = removenode->same;
|
||||
if(removenode->same)
|
||||
removenode->same->smaller = removenode->smaller;
|
||||
removenode->samep->samen = removenode->samen;
|
||||
removenode->samen->samep = removenode->samep;
|
||||
|
||||
/* Ensures that double-remove gets caught. */
|
||||
removenode->smaller = NULL;
|
||||
removenode->samen = removenode;
|
||||
|
||||
/* voila, we're done! */
|
||||
*newroot = t; /* return the same root */
|
||||
return 0;
|
||||
}
|
||||
@@ -262,14 +246,16 @@ int Curl_splayremovebyaddr(struct Curl_tree *t,
|
||||
|
||||
/* Check if there is a list with identical sizes, as then we're trying to
|
||||
remove the root node of a list of nodes with identical keys. */
|
||||
x = t->same;
|
||||
if(x) {
|
||||
x = t->samen;
|
||||
if(x != t) {
|
||||
/* 'x' is the new root node, we just make it use the root node's
|
||||
smaller/larger links */
|
||||
|
||||
x->key = t->key;
|
||||
x->larger = t->larger;
|
||||
x->smaller = t->smaller;
|
||||
x->samep = t->samep;
|
||||
t->samep->samen = x;
|
||||
}
|
||||
else {
|
||||
/* Remove the root node */
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
struct Curl_tree {
|
||||
struct Curl_tree *smaller; /* smaller node */
|
||||
struct Curl_tree *larger; /* larger node */
|
||||
struct Curl_tree *same; /* points to a node with identical key */
|
||||
struct Curl_tree *samen; /* points to the next node with identical key */
|
||||
struct Curl_tree *samep; /* points to the prev node with identical key */
|
||||
struct timeval key; /* this node's "sort" key */
|
||||
void *payload; /* data the splay code doesn't care about */
|
||||
};
|
||||
|
||||
+151
-164
@@ -688,14 +688,11 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn)
|
||||
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
|
||||
return sshc->actualcode;
|
||||
}
|
||||
else {
|
||||
infof(data, "MD5 checksum match!\n");
|
||||
/* as we already matched, we skip the check for known hosts */
|
||||
return CURLE_OK;
|
||||
}
|
||||
infof(data, "MD5 checksum match!\n");
|
||||
/* as we already matched, we skip the check for known hosts */
|
||||
return CURLE_OK;
|
||||
}
|
||||
else
|
||||
return ssh_knownhost(conn);
|
||||
return ssh_knownhost(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -738,7 +735,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc) {
|
||||
if(rc) {
|
||||
failf(data, "Failure establishing ssh session");
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualcode = CURLE_FAILED_INIT;
|
||||
@@ -782,16 +779,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
break;
|
||||
}
|
||||
err = libssh2_session_last_errno(sshc->ssh_session);
|
||||
if(err == LIBSSH2_ERROR_EAGAIN)
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
else {
|
||||
err = libssh2_session_last_errno(sshc->ssh_session);
|
||||
if(err == LIBSSH2_ERROR_EAGAIN)
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
else {
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(err);
|
||||
}
|
||||
break;
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(err);
|
||||
}
|
||||
break;
|
||||
}
|
||||
infof(data, "SSH authentication methods available: %s\n",
|
||||
sshc->authlist);
|
||||
@@ -918,6 +913,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
&err_msg, NULL, 0);
|
||||
infof(data, "SSH public key authentication failed: %s\n", err_msg);
|
||||
state(conn, SSH_AUTH_PASS_INIT);
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -928,6 +924,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_HOST_INIT);
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -940,7 +937,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc == 0) {
|
||||
if(rc == 0) {
|
||||
sshc->authed = TRUE;
|
||||
infof(data, "Initialized password authentication\n");
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
@@ -989,6 +986,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc < 0) {
|
||||
infof(data, "Failure connecting to agent\n");
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_AGENT_LIST);
|
||||
@@ -1008,6 +1006,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc < 0) {
|
||||
infof(data, "Failure requesting identities to agent\n");
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_AGENT);
|
||||
@@ -1077,7 +1076,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc == 0) {
|
||||
if(rc == 0) {
|
||||
sshc->authed = TRUE;
|
||||
infof(data, "Initialized keyboard interactive authentication\n");
|
||||
}
|
||||
@@ -1116,21 +1115,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
*/
|
||||
sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
|
||||
if(!sshc->sftp_session) {
|
||||
char *err_msg;
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
char *err_msg;
|
||||
|
||||
(void)libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0);
|
||||
failf(data, "Failure initializing sftp session: %s", err_msg);
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualcode = CURLE_FAILED_INIT;
|
||||
break;
|
||||
}
|
||||
(void)libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0);
|
||||
failf(data, "Failure initializing sftp session: %s", err_msg);
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualcode = CURLE_FAILED_INIT;
|
||||
break;
|
||||
}
|
||||
state(conn, SSH_SFTP_REALPATH);
|
||||
break;
|
||||
@@ -1147,7 +1144,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc > 0) {
|
||||
if(rc > 0) {
|
||||
/* It seems that this string is not always NULL terminated */
|
||||
tempHome[rc] = '\0';
|
||||
sshc->homedir = strdup(tempHome);
|
||||
@@ -1261,7 +1258,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_SFTP_NEXT_QUOTE);
|
||||
break;
|
||||
}
|
||||
else if(cmd) {
|
||||
if(cmd) {
|
||||
/*
|
||||
* the arguments following the command must be separated from the
|
||||
* command with a space so we can check for it unconditionally
|
||||
@@ -1321,7 +1318,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_SFTP_QUOTE_STAT);
|
||||
break;
|
||||
}
|
||||
else if(strncasecompare(cmd, "ln ", 3) ||
|
||||
if(strncasecompare(cmd, "ln ", 3) ||
|
||||
strncasecompare(cmd, "symlink ", 8)) {
|
||||
/* symbolic linking */
|
||||
/* sshc->quote_path1 is the source */
|
||||
@@ -1443,7 +1440,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
|
||||
if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@@ -1514,7 +1511,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@@ -1537,7 +1534,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@@ -1558,7 +1555,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
|
||||
@@ -1582,7 +1579,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
@@ -1601,7 +1598,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
|
||||
@@ -1619,7 +1616,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
|
||||
@@ -1642,7 +1639,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc != 0 && !sshc->acceptfail) {
|
||||
if(rc != 0 && !sshc->acceptfail) {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
|
||||
@@ -1705,7 +1702,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc == 0) {
|
||||
if(rc == 0) {
|
||||
data->info.filetime = (long)attrs.mtime;
|
||||
}
|
||||
|
||||
@@ -1743,7 +1740,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc) {
|
||||
if(rc) {
|
||||
data->state.resume_from = 0;
|
||||
}
|
||||
else {
|
||||
@@ -1778,47 +1775,47 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
if(LIBSSH2_ERROR_EAGAIN == rc)
|
||||
break;
|
||||
else {
|
||||
if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
|
||||
/* only when there was an SFTP protocol error can we extract
|
||||
the sftp error! */
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
else
|
||||
err = -1; /* not an sftp error at all */
|
||||
|
||||
if(sshc->secondCreateDirs) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
sshc->actualcode = err>= LIBSSH2_FX_OK?
|
||||
sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
|
||||
failf(data, "Creating the dir/file failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
break;
|
||||
}
|
||||
else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
|
||||
(err == LIBSSH2_FX_FAILURE) ||
|
||||
(err == LIBSSH2_FX_NO_SUCH_PATH)) &&
|
||||
(data->set.ftp_create_missing_dirs &&
|
||||
(strlen(sftp_scp->path) > 1))) {
|
||||
/* try to create the path remotely */
|
||||
sshc->secondCreateDirs = 1;
|
||||
state(conn, SSH_SFTP_CREATE_DIRS_INIT);
|
||||
break;
|
||||
}
|
||||
if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
|
||||
/* only when there was an SFTP protocol error can we extract
|
||||
the sftp error! */
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
else
|
||||
err = -1; /* not an sftp error at all */
|
||||
|
||||
if(sshc->secondCreateDirs) {
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
sshc->actualcode = err>= LIBSSH2_FX_OK?
|
||||
sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
|
||||
if(!sshc->actualcode) {
|
||||
/* Sometimes, for some reason libssh2_sftp_last_error() returns
|
||||
zero even though libssh2_sftp_open() failed previously! We need
|
||||
to work around that! */
|
||||
sshc->actualcode = CURLE_SSH;
|
||||
err=-1;
|
||||
}
|
||||
failf(data, "Upload failed: %s (%d/%d)",
|
||||
err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
|
||||
err, rc);
|
||||
failf(data, "Creating the dir/file failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
break;
|
||||
}
|
||||
if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
|
||||
(err == LIBSSH2_FX_FAILURE) ||
|
||||
(err == LIBSSH2_FX_NO_SUCH_PATH)) &&
|
||||
(data->set.ftp_create_missing_dirs &&
|
||||
(strlen(sftp_scp->path) > 1))) {
|
||||
/* try to create the path remotely */
|
||||
rc = 0; /* clear rc and continue */
|
||||
sshc->secondCreateDirs = 1;
|
||||
state(conn, SSH_SFTP_CREATE_DIRS_INIT);
|
||||
break;
|
||||
}
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
sshc->actualcode = err>= LIBSSH2_FX_OK?
|
||||
sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
|
||||
if(!sshc->actualcode) {
|
||||
/* Sometimes, for some reason libssh2_sftp_last_error() returns
|
||||
zero even though libssh2_sftp_open() failed previously! We need
|
||||
to work around that! */
|
||||
sshc->actualcode = CURLE_SSH;
|
||||
err=-1;
|
||||
}
|
||||
failf(data, "Upload failed: %s (%d/%d)",
|
||||
err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
|
||||
err, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have a restart point then we need to seek to the correct
|
||||
@@ -1831,32 +1828,30 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
|
||||
if(seekerr != CURL_SEEKFUNC_OK) {
|
||||
curl_off_t passed=0;
|
||||
|
||||
if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
|
||||
failf(data, "Could not seek stream");
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
/* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
|
||||
else {
|
||||
curl_off_t passed=0;
|
||||
do {
|
||||
size_t readthisamountnow =
|
||||
(data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
do {
|
||||
size_t readthisamountnow =
|
||||
(data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
|
||||
size_t actuallyread =
|
||||
data->state.fread_func(data->state.buffer, 1,
|
||||
readthisamountnow, data->state.in);
|
||||
size_t actuallyread =
|
||||
data->state.fread_func(data->state.buffer, 1,
|
||||
readthisamountnow, data->state.in);
|
||||
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
/* this checks for greater-than only to make sure that the
|
||||
CURL_READFUNC_ABORT return code still aborts */
|
||||
failf(data, "Failed to read data");
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
} while(passed < data->state.resume_from);
|
||||
}
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
/* this checks for greater-than only to make sure that the
|
||||
CURL_READFUNC_ABORT return code still aborts */
|
||||
failf(data, "Failed to read data");
|
||||
return CURLE_FTP_COULDNT_USE_REST;
|
||||
}
|
||||
} while(passed < data->state.resume_from);
|
||||
}
|
||||
|
||||
/* now, decrease the size of the read */
|
||||
@@ -1921,9 +1916,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_SFTP_UPLOAD_INIT);
|
||||
}
|
||||
state(conn, SSH_SFTP_UPLOAD_INIT);
|
||||
break;
|
||||
|
||||
case SSH_SFTP_CREATE_DIRS_MKDIR:
|
||||
@@ -1936,7 +1929,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
*sshc->slash_pos = '/';
|
||||
++sshc->slash_pos;
|
||||
if(rc == -1) {
|
||||
if(rc < 0) {
|
||||
/*
|
||||
* Abort if failure wasn't that the dir already exists or the
|
||||
* permission was denied (creation might succeed further down the
|
||||
@@ -1951,6 +1944,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->actualcode = result?result:CURLE_SSH;
|
||||
break;
|
||||
}
|
||||
rc = 0; /* clear rc and continue */
|
||||
}
|
||||
state(conn, SSH_SFTP_CREATE_DIRS);
|
||||
break;
|
||||
@@ -1977,15 +1971,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
failf(data, "Could not open directory for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
result = sftp_libssh2_error_to_CURLE(err);
|
||||
sshc->actualcode = result?result:CURLE_SSH;
|
||||
break;
|
||||
}
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
failf(data, "Could not open directory for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
result = sftp_libssh2_error_to_CURLE(err);
|
||||
sshc->actualcode = result?result:CURLE_SSH;
|
||||
break;
|
||||
}
|
||||
sshc->readdir_filename = malloc(PATH_MAX+1);
|
||||
if(!sshc->readdir_filename) {
|
||||
@@ -2192,15 +2184,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
failf(data, "Could not open remote file for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
result = sftp_libssh2_error_to_CURLE(err);
|
||||
sshc->actualcode = result?result:CURLE_SSH;
|
||||
break;
|
||||
}
|
||||
err = sftp_libssh2_last_error(sshc->sftp_session);
|
||||
failf(data, "Could not open remote file for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
result = sftp_libssh2_error_to_CURLE(err);
|
||||
sshc->actualcode = result?result:CURLE_SSH;
|
||||
break;
|
||||
}
|
||||
state(conn, SSH_SFTP_DOWNLOAD_STAT);
|
||||
break;
|
||||
@@ -2215,7 +2205,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc ||
|
||||
if(rc ||
|
||||
!(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
|
||||
(attrs.filesize == 0)) {
|
||||
/*
|
||||
@@ -2313,18 +2303,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_STOP);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
|
||||
FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
|
||||
FALSE, NULL, -1, NULL);
|
||||
|
||||
/* not set by Curl_setup_transfer to preserve keepon bits */
|
||||
conn->writesockfd = conn->sockfd;
|
||||
/* not set by Curl_setup_transfer to preserve keepon bits */
|
||||
conn->writesockfd = conn->sockfd;
|
||||
|
||||
/* we want to use the _receiving_ function even when the socket turns
|
||||
out writableable as the underlying libssh2 recv function will deal
|
||||
with both accordingly */
|
||||
conn->cselect_bits = CURL_CSELECT_IN;
|
||||
|
||||
/* we want to use the _receiving_ function even when the socket turns
|
||||
out writableable as the underlying libssh2 recv function will deal
|
||||
with both accordingly */
|
||||
conn->cselect_bits = CURL_CSELECT_IN;
|
||||
}
|
||||
if(result) {
|
||||
/* this should never occur; the close state should be entered
|
||||
at the time the error occurs */
|
||||
@@ -2342,7 +2331,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to close libssh2 file\n");
|
||||
}
|
||||
sshc->sftp_handle = NULL;
|
||||
@@ -2376,7 +2365,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to close libssh2 file\n");
|
||||
}
|
||||
sshc->sftp_handle = NULL;
|
||||
@@ -2386,7 +2375,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to stop libssh2 sftp subsystem\n");
|
||||
}
|
||||
sshc->sftp_session = NULL;
|
||||
@@ -2431,22 +2420,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
|
||||
data->state.infilesize);
|
||||
if(!sshc->ssh_channel) {
|
||||
int ssh_err;
|
||||
char *err_msg;
|
||||
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
int ssh_err;
|
||||
char *err_msg;
|
||||
|
||||
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0));
|
||||
failf(conn->data, "%s", err_msg);
|
||||
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
|
||||
break;
|
||||
}
|
||||
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0));
|
||||
failf(conn->data, "%s", err_msg);
|
||||
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
|
||||
break;
|
||||
}
|
||||
|
||||
/* upload data */
|
||||
@@ -2501,22 +2489,22 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
#endif
|
||||
|
||||
if(!sshc->ssh_channel) {
|
||||
int ssh_err;
|
||||
char *err_msg;
|
||||
|
||||
if(libssh2_session_last_errno(sshc->ssh_session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = LIBSSH2_ERROR_EAGAIN;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
int ssh_err;
|
||||
char *err_msg;
|
||||
|
||||
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0));
|
||||
failf(conn->data, "%s", err_msg);
|
||||
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
|
||||
break;
|
||||
}
|
||||
|
||||
ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
|
||||
&err_msg, NULL, 0));
|
||||
failf(conn->data, "%s", err_msg);
|
||||
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||
sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
|
||||
break;
|
||||
}
|
||||
|
||||
/* download data */
|
||||
@@ -2554,7 +2542,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc) {
|
||||
if(rc) {
|
||||
infof(data, "Failed to send libssh2 channel EOF\n");
|
||||
}
|
||||
}
|
||||
@@ -2567,7 +2555,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc) {
|
||||
if(rc) {
|
||||
infof(data, "Failed to get channel EOF: %d\n", rc);
|
||||
}
|
||||
}
|
||||
@@ -2580,7 +2568,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc) {
|
||||
if(rc) {
|
||||
infof(data, "Channel failed to close: %d\n", rc);
|
||||
}
|
||||
}
|
||||
@@ -2593,7 +2581,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to free libssh2 scp subsystem\n");
|
||||
}
|
||||
sshc->ssh_channel = NULL;
|
||||
@@ -2615,7 +2603,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to free libssh2 scp subsystem\n");
|
||||
}
|
||||
sshc->ssh_channel = NULL;
|
||||
@@ -2626,7 +2614,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to disconnect libssh2 session\n");
|
||||
}
|
||||
}
|
||||
@@ -2651,7 +2639,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to disconnect from libssh2 agent\n");
|
||||
}
|
||||
libssh2_agent_free(sshc->ssh_agent);
|
||||
@@ -2669,7 +2657,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
if(rc < 0) {
|
||||
infof(data, "Failed to free libssh2 session\n");
|
||||
}
|
||||
sshc->ssh_session = NULL;
|
||||
@@ -2834,7 +2822,8 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
|
||||
|
||||
while((sshc->state != SSH_STOP) && !result) {
|
||||
bool block;
|
||||
long left;
|
||||
time_t left;
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
result = ssh_statemach_act(conn, &block);
|
||||
if(result)
|
||||
@@ -2842,12 +2831,10 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
else {
|
||||
struct timeval now = Curl_tvnow();
|
||||
result = Curl_speedcheck(data, now);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
|
||||
result = Curl_speedcheck(data, now);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
left = Curl_timeleft(data, NULL, duringconnect);
|
||||
if(left < 0) {
|
||||
|
||||
@@ -125,9 +125,9 @@ int Curl_safe_strcasecompare(const char *first, const char *second)
|
||||
if(first && second)
|
||||
/* both pointers point to something then compare them */
|
||||
return Curl_strcasecompare(first, second);
|
||||
else
|
||||
/* if both pointers are NULL then treat them as equal */
|
||||
return (NULL == first && NULL == second);
|
||||
|
||||
/* if both pointers are NULL then treat them as equal */
|
||||
return (NULL == first && NULL == second);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2016, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2016 - 2017, 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
|
||||
@@ -68,7 +68,7 @@ typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);
|
||||
*
|
||||
* majorVersion [in] - The major version number.
|
||||
* minorVersion [in] - The minor version number.
|
||||
* platform [in] - The optional platform identifer.
|
||||
* 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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -872,7 +872,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Window Size */
|
||||
/* Window Size */
|
||||
if(strcasecompare(option_keyword, "WS")) {
|
||||
if(sscanf(option_arg, "%hu%*[xX]%hu",
|
||||
&tn->subopt_wsx, &tn->subopt_wsy) == 2)
|
||||
@@ -899,11 +899,9 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
result = CURLE_UNKNOWN_TELNET_OPTION;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
failf(data, "Syntax error in telnet option: %s", head->data);
|
||||
result = CURLE_TELNET_OPTION_SYNTAX;
|
||||
break;
|
||||
}
|
||||
failf(data, "Syntax error in telnet option: %s", head->data);
|
||||
result = CURLE_TELNET_OPTION_SYNTAX;
|
||||
break;
|
||||
}
|
||||
|
||||
if(result) {
|
||||
@@ -1016,7 +1014,7 @@ static void sendsuboption(struct connectdata *conn, int option)
|
||||
CURL_SB_ACCUM(tn, CURL_IAC);
|
||||
CURL_SB_ACCUM(tn, CURL_SB);
|
||||
CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
|
||||
/* We must deal either with litte or big endien processors */
|
||||
/* We must deal either with litte or big endian processors */
|
||||
/* Window size must be sent according to the 'network order' */
|
||||
x=htons(tn->subopt_wsx);
|
||||
y=htons(tn->subopt_wsy);
|
||||
@@ -1186,7 +1184,7 @@ CURLcode telrcv(struct connectdata *conn,
|
||||
* IAC SE was left off, or another option got inserted into the
|
||||
* suboption are all possibilities. If we assume that the IAC was
|
||||
* not doubled, and really the IAC SE was left off, we could get
|
||||
* into an infinate loop here. So, instead, we terminate the
|
||||
* into an infinite loop here. So, instead, we terminate the
|
||||
* suboption, and process the partial suboption if we can.
|
||||
*/
|
||||
CURL_SB_ACCUM(tn, CURL_IAC);
|
||||
@@ -1326,7 +1324,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
#ifdef USE_WINSOCK
|
||||
/*
|
||||
** This functionality only works with WinSock >= 2.0. So,
|
||||
** make sure have it.
|
||||
** make sure we have it.
|
||||
*/
|
||||
result = check_wsock2(data);
|
||||
if(result)
|
||||
@@ -1416,28 +1414,29 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
|
||||
/* Keep on listening and act on events */
|
||||
while(keepon) {
|
||||
const DWORD buf_size = (DWORD)CURL_BUFSIZE(data->set.buffer_size);
|
||||
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
|
||||
switch(waitret) {
|
||||
case WAIT_TIMEOUT:
|
||||
{
|
||||
for(;;) {
|
||||
if(data->set.is_fread_set) {
|
||||
size_t n;
|
||||
/* read from user-supplied method */
|
||||
result = (int)data->state.fread_func(buf, 1, BUFSIZE - 1,
|
||||
data->state.in);
|
||||
if(result == CURL_READFUNC_ABORT) {
|
||||
n = data->state.fread_func(buf, 1, BUFSIZE - 1, data->state.in);
|
||||
if(n == CURL_READFUNC_ABORT) {
|
||||
keepon = FALSE;
|
||||
result = CURLE_READ_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if(result == CURL_READFUNC_PAUSE)
|
||||
if(n == CURL_READFUNC_PAUSE)
|
||||
break;
|
||||
|
||||
if(result == 0) /* no bytes */
|
||||
if(n == 0) /* no bytes */
|
||||
break;
|
||||
|
||||
readfile_read = result; /* fall thru with number of bytes read */
|
||||
readfile_read = (DWORD)n; /* fall thru with number of bytes read */
|
||||
}
|
||||
else {
|
||||
/* read from stdin */
|
||||
@@ -1451,7 +1450,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
if(!readfile_read)
|
||||
break;
|
||||
|
||||
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||||
if(!ReadFile(stdin_handle, buf, buf_size,
|
||||
&readfile_read, NULL)) {
|
||||
keepon = FALSE;
|
||||
result = CURLE_READ_ERROR;
|
||||
@@ -1470,7 +1469,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
{
|
||||
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||||
if(!ReadFile(stdin_handle, buf, buf_size,
|
||||
&readfile_read, NULL)) {
|
||||
keepon = FALSE;
|
||||
result = CURLE_READ_ERROR;
|
||||
@@ -1593,7 +1592,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||||
if(result == CURLE_AGAIN)
|
||||
break;
|
||||
/* returned not-zero, this an error */
|
||||
else if(result) {
|
||||
if(result) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
|
||||
failf(data, "invalid blocksize value in OACK packet");
|
||||
return CURLE_TFTP_ILLEGAL;
|
||||
}
|
||||
else if(blksize > TFTP_BLKSIZE_MAX) {
|
||||
if(blksize > TFTP_BLKSIZE_MAX) {
|
||||
failf(data, "%s (%d)", "blksize is larger than max supported",
|
||||
TFTP_BLKSIZE_MAX);
|
||||
return CURLE_TFTP_ILLEGAL;
|
||||
@@ -1189,7 +1189,7 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
|
||||
state->state = TFTP_STATE_FIN;
|
||||
return 0;
|
||||
}
|
||||
else if(current > state->rx_time+state->retry_time) {
|
||||
if(current > state->rx_time+state->retry_time) {
|
||||
if(event)
|
||||
*event = TFTP_EVENT_TIMEOUT;
|
||||
time(&state->rx_time); /* update even though we received nothing */
|
||||
@@ -1223,7 +1223,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
|
||||
failf(data, "TFTP response timeout");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else if(event != TFTP_EVENT_NONE) {
|
||||
if(event != TFTP_EVENT_NONE) {
|
||||
result = tftp_state_machine(state, event);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -139,8 +139,7 @@ double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
|
||||
if(newer.tv_sec != older.tv_sec)
|
||||
return (double)(newer.tv_sec-older.tv_sec)+
|
||||
(double)(newer.tv_usec-older.tv_usec)/1000000.0;
|
||||
else
|
||||
return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
|
||||
return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
|
||||
}
|
||||
|
||||
/* return the number of seconds in the given input timeval struct */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -117,7 +117,8 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
|
||||
*nreadp = 0;
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
else if(nread == CURL_READFUNC_PAUSE) {
|
||||
if(nread == CURL_READFUNC_PAUSE) {
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
if(conn->handler->flags & PROTOPT_NONETWORK) {
|
||||
/* protocols that work without network cannot be paused. This is
|
||||
@@ -126,16 +127,15 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
|
||||
failf(data, "Read callback asked for PAUSE when not supported!");
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
else {
|
||||
struct SingleRequest *k = &data->req;
|
||||
/* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
|
||||
k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
|
||||
if(data->req.upload_chunky) {
|
||||
|
||||
/* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
|
||||
k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
|
||||
if(data->req.upload_chunky) {
|
||||
/* Back out the preallocation done above */
|
||||
data->req.upload_fromhere -= (8 + 2);
|
||||
}
|
||||
*nreadp = 0;
|
||||
data->req.upload_fromhere -= (8 + 2);
|
||||
}
|
||||
*nreadp = 0;
|
||||
|
||||
return CURLE_OK; /* nothing was read */
|
||||
}
|
||||
else if((size_t)nread > buffersize) {
|
||||
@@ -642,7 +642,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
else if(CHUNKE_STOP == res) {
|
||||
if(CHUNKE_STOP == res) {
|
||||
size_t dataleft;
|
||||
/* we're done reading chunks! */
|
||||
k->keepon &= ~KEEP_RECV; /* read no more */
|
||||
@@ -918,7 +918,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
/* this is a paused transfer */
|
||||
break;
|
||||
}
|
||||
else if(nread<=0) {
|
||||
if(nread<=0) {
|
||||
result = done_sending(conn, k);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -1192,7 +1192,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
k->size - k->bytecount);
|
||||
return CURLE_PARTIAL_FILE;
|
||||
}
|
||||
else if(!(data->set.opt_no_body) &&
|
||||
if(!(data->set.opt_no_body) &&
|
||||
k->chunk &&
|
||||
(conn->chunk.state != CHUNK_STOP)) {
|
||||
/*
|
||||
@@ -1356,13 +1356,12 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
||||
|
||||
if(data->set.wildcardmatch) {
|
||||
struct WildcardData *wc = &data->wildcard;
|
||||
if(!wc->filelist) {
|
||||
if(wc->state < CURLWC_INIT) {
|
||||
result = Curl_wildcard_init(wc); /* init wildcard structures */
|
||||
if(result)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1795,7 +1794,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
||||
break;
|
||||
|
||||
case 303: /* See Other */
|
||||
/* Disable both types of POSTs, unless the user explicitely
|
||||
/* Disable both types of POSTs, unless the user explicitly
|
||||
asks for POST after POST */
|
||||
if(data->set.httpreq != HTTPREQ_GET
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_303)) {
|
||||
@@ -1843,12 +1842,17 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
|
||||
if((data->req.bytecount + data->req.headerbytecount == 0) &&
|
||||
conn->bits.reuse &&
|
||||
(data->set.rtspreq != RTSPREQ_RECEIVE)) {
|
||||
/* We didn't get a single byte when we attempted to re-use a
|
||||
connection. This might happen if the connection was left alive when we
|
||||
were done using it before, but that was closed when we wanted to use it
|
||||
again. Bad luck. Retry the same request on a fresh connect! */
|
||||
conn->bits.reuse &&
|
||||
(!data->set.opt_no_body
|
||||
|| (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
|
||||
(data->set.rtspreq != RTSPREQ_RECEIVE)) {
|
||||
/* We got no data, we attempted to re-use a connection. For HTTP this
|
||||
can be a retry so we try again regardless if we expected a body.
|
||||
For other protocols we only try again only if we expected a body.
|
||||
|
||||
This might happen if the connection was left alive when we were
|
||||
done using it before, but that was closed when we wanted to read from
|
||||
it again. Bad luck. Retry the same request on a fresh connect! */
|
||||
infof(conn->data, "Connection died, retrying a fresh connect\n");
|
||||
*url = strdup(conn->data->change.url);
|
||||
if(!*url)
|
||||
|
||||
+422
-297
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -136,8 +136,10 @@
|
||||
#undef realloc
|
||||
#endif /* USE_AXTLS */
|
||||
|
||||
#ifdef USE_SCHANNEL
|
||||
#if defined(USE_SCHANNEL) || defined(USE_WINDOWS_SSPI)
|
||||
#include "curl_sspi.h"
|
||||
#endif
|
||||
#ifdef USE_SCHANNEL
|
||||
#include <schnlsp.h>
|
||||
#include <schannel.h>
|
||||
#endif
|
||||
@@ -201,6 +203,9 @@
|
||||
/* Download buffer size, keep it fairly big for speed reasons */
|
||||
#undef BUFSIZE
|
||||
#define BUFSIZE CURL_MAX_WRITE_SIZE
|
||||
#undef MAX_BUFSIZE
|
||||
#define MAX_BUFSIZE CURL_MAX_READ_SIZE
|
||||
#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
|
||||
|
||||
/* Initial size of the buffer to store headers in, it'll be enlarged in case
|
||||
of need. */
|
||||
@@ -311,7 +316,7 @@ struct ssl_connect_data {
|
||||
PRFileDesc *handle;
|
||||
char *client_nickname;
|
||||
struct Curl_easy *data;
|
||||
struct curl_llist *obj_list;
|
||||
struct curl_llist obj_list;
|
||||
PK11GenericObject *obj_clicert;
|
||||
#elif defined(USE_GSKIT)
|
||||
gsk_handle handle;
|
||||
@@ -345,6 +350,7 @@ struct ssl_connect_data {
|
||||
|
||||
struct ssl_primary_config {
|
||||
long version; /* what version the client wants to use */
|
||||
long version_max; /* max supported version the client wants to use*/
|
||||
bool verifypeer; /* set TRUE if this is desired */
|
||||
bool verifyhost; /* set TRUE if CN/SAN must match hostname */
|
||||
bool verifystatus; /* set TRUE if certificate status must be checked */
|
||||
@@ -354,6 +360,7 @@ struct ssl_primary_config {
|
||||
char *random_file; /* path to file containing "random" data */
|
||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||
char *cipher_list; /* list of ciphers to use */
|
||||
bool sessionid; /* cache session IDs or not */
|
||||
};
|
||||
|
||||
struct ssl_config_data {
|
||||
@@ -383,7 +390,6 @@ struct ssl_config_data {
|
||||
};
|
||||
|
||||
struct ssl_general_config {
|
||||
bool sessionid; /* cache session IDs or not */
|
||||
size_t max_ssl_sessions; /* SSL session id cache size */
|
||||
};
|
||||
|
||||
@@ -405,6 +411,7 @@ struct digestdata {
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
BYTE *input_token;
|
||||
size_t input_token_len;
|
||||
CtxtHandle *http_context;
|
||||
#else
|
||||
char *nonce;
|
||||
char *cnonce;
|
||||
@@ -842,6 +849,8 @@ struct Curl_handler {
|
||||
request instead of per connection */
|
||||
#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
|
||||
#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */
|
||||
#define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field
|
||||
of the URL */
|
||||
|
||||
/* return the count of bytes sent, or -1 on error */
|
||||
typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
|
||||
@@ -931,7 +940,6 @@ struct connectdata {
|
||||
char *secondaryhostname; /* secondary socket host name (ftp) */
|
||||
struct hostname conn_to_host; /* the host to connect to. valid only if
|
||||
bits.conn_to_host is set */
|
||||
struct hostname proxy;
|
||||
|
||||
struct proxy_info socks_proxy;
|
||||
struct proxy_info http_proxy;
|
||||
@@ -1050,10 +1058,10 @@ struct connectdata {
|
||||
handle */
|
||||
bool writechannel_inuse; /* whether the write channel is in use by an easy
|
||||
handle */
|
||||
struct curl_llist *send_pipe; /* List of handles waiting to
|
||||
send on this pipeline */
|
||||
struct curl_llist *recv_pipe; /* List of handles waiting to read
|
||||
their responses on this pipeline */
|
||||
struct curl_llist send_pipe; /* List of handles waiting to send on this
|
||||
pipeline */
|
||||
struct curl_llist recv_pipe; /* List of handles waiting to read their
|
||||
responses on this pipeline */
|
||||
char *master_buffer; /* The master buffer allocated on-demand;
|
||||
used for pipelining. */
|
||||
size_t read_pos; /* Current read position in the master buffer */
|
||||
@@ -1133,6 +1141,7 @@ struct connectdata {
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
char *unix_domain_socket;
|
||||
bool abstract_unix_socket;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1274,8 +1283,8 @@ struct auth {
|
||||
this resource */
|
||||
bool done; /* TRUE when the auth phase is done and ready to do the *actual*
|
||||
request */
|
||||
bool multi; /* TRUE if this is not yet authenticated but within the auth
|
||||
multipass negotiation */
|
||||
bool multipass; /* TRUE if this is not yet authenticated but within the
|
||||
auth multipass negotiation */
|
||||
bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
|
||||
be RFC compliant */
|
||||
};
|
||||
@@ -1285,6 +1294,19 @@ struct Curl_http2_dep {
|
||||
struct Curl_easy *data;
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct is for holding data that was attemped to get sent to the user's
|
||||
* callback but is held due to pausing. One instance per type (BOTH, HEADER,
|
||||
* BODY).
|
||||
*/
|
||||
struct tempbuf {
|
||||
char *buf; /* allocated buffer to keep data in when a write callback
|
||||
returns to make the connection paused */
|
||||
size_t len; /* size of the 'tempwrite' allocated buffer */
|
||||
int type; /* type of the 'tempwrite' buffer as a bitmask that is used with
|
||||
Curl_client_write() */
|
||||
};
|
||||
|
||||
struct UrlState {
|
||||
|
||||
/* Points to the connection cache */
|
||||
@@ -1303,9 +1325,9 @@ struct UrlState {
|
||||
char *headerbuff; /* allocated buffer to store headers in */
|
||||
size_t headersize; /* size of the allocation */
|
||||
|
||||
char buffer[BUFSIZE+1]; /* download buffer */
|
||||
char *buffer; /* download buffer */
|
||||
char uploadbuffer[BUFSIZE+1]; /* upload buffer */
|
||||
curl_off_t current_speed; /* the ProgressShow() funcion sets this,
|
||||
curl_off_t current_speed; /* the ProgressShow() function sets this,
|
||||
bytes / second */
|
||||
bool this_is_a_follow; /* this is a followed Location: request */
|
||||
|
||||
@@ -1318,11 +1340,8 @@ struct UrlState {
|
||||
int first_remote_port; /* remote port of the first (not followed) request */
|
||||
struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
|
||||
long sessionage; /* number of the most recent session */
|
||||
char *tempwrite; /* allocated buffer to keep data in when a write
|
||||
callback returns to make the connection paused */
|
||||
size_t tempwritesize; /* size of the 'tempwrite' allocated buffer */
|
||||
int tempwritetype; /* type of the 'tempwrite' buffer as a bitmask that is
|
||||
used with Curl_client_write() */
|
||||
unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
|
||||
struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */
|
||||
char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */
|
||||
bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
|
||||
This must be set to FALSE every time _easy_perform() is
|
||||
@@ -1355,7 +1374,7 @@ struct UrlState {
|
||||
#endif /* USE_OPENSSL */
|
||||
struct timeval expiretime; /* set this with Curl_expire() only */
|
||||
struct Curl_tree timenode; /* for the splay stuff */
|
||||
struct curl_llist *timeoutlist; /* list of pending timeouts */
|
||||
struct curl_llist timeoutlist; /* list of pending timeouts */
|
||||
|
||||
/* a place to store the most recently set FTP entrypath */
|
||||
char *most_recent_ftp_entrypath;
|
||||
@@ -1638,7 +1657,6 @@ struct UserDefined {
|
||||
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
|
||||
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
|
||||
curl_proxytype proxytype; /* what kind of proxy that is in use */
|
||||
curl_proxytype socks_proxytype; /* what kind of socks proxy that is in use */
|
||||
long dns_cache_timeout; /* DNS cache timeout */
|
||||
long buffer_size; /* size of receive buffer to use */
|
||||
void *private_data; /* application-private data */
|
||||
@@ -1748,12 +1766,16 @@ struct UserDefined {
|
||||
bool pipewait; /* wait for pipe/multiplex status before starting a
|
||||
new connection */
|
||||
long expect_100_timeout; /* in milliseconds */
|
||||
bool suppress_connect_headers; /* suppress proxy CONNECT response headers
|
||||
from user callbacks */
|
||||
|
||||
struct Curl_easy *stream_depends_on;
|
||||
bool stream_depends_e; /* set or don't set the Exclusive bit */
|
||||
int stream_weight;
|
||||
|
||||
struct Curl_http2_dep *stream_dependents;
|
||||
|
||||
bool abstract_unix_socket;
|
||||
};
|
||||
|
||||
struct Names {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -237,7 +237,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
|
||||
* auth_decode_digest_md5_message()
|
||||
*
|
||||
* This is used internally to decode an already encoded DIGEST-MD5 challenge
|
||||
* message into the seperate attributes.
|
||||
* message into the separate attributes.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
@@ -366,7 +366,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
|
||||
char *spn = NULL;
|
||||
|
||||
/* Decode the challange message */
|
||||
/* Decode the challenge message */
|
||||
result = auth_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
||||
realm, sizeof(realm),
|
||||
algorithm, sizeof(algorithm),
|
||||
@@ -502,7 +502,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
/*
|
||||
* Curl_auth_decode_digest_http_message()
|
||||
*
|
||||
* This is used to decode a HTTP DIGEST challenge message into the seperate
|
||||
* This is used to decode a HTTP DIGEST challenge message into the separate
|
||||
* attributes.
|
||||
*
|
||||
* Parameters:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2015 - 2017, 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
|
||||
@@ -320,7 +320,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
/*
|
||||
* Curl_auth_decode_digest_http_message()
|
||||
*
|
||||
* This is used to decode a HTTP DIGEST challenge message into the seperate
|
||||
* This is used to decode a HTTP DIGEST challenge message into the separate
|
||||
* attributes.
|
||||
*
|
||||
* Parameters:
|
||||
@@ -335,13 +335,44 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
||||
{
|
||||
size_t chlglen = strlen(chlg);
|
||||
|
||||
/* We had an input token before and we got another one now. This means we
|
||||
provided bad credentials in the previous request. */
|
||||
if(digest->input_token)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
/* We had an input token before so if there's another one now that means we
|
||||
provided bad credentials in the previous request or it's stale. */
|
||||
if(digest->input_token) {
|
||||
bool stale = false;
|
||||
const char *p = chlg;
|
||||
|
||||
/* Simply store the challenge for use later */
|
||||
digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen);
|
||||
/* Check for the 'stale' directive */
|
||||
for(;;) {
|
||||
char value[DIGEST_MAX_VALUE_LENGTH];
|
||||
char content[DIGEST_MAX_CONTENT_LENGTH];
|
||||
|
||||
while(*p && ISSPACE(*p))
|
||||
p++;
|
||||
|
||||
if(!Curl_auth_digest_get_pair(p, value, content, &p))
|
||||
break;
|
||||
|
||||
if(Curl_strcasecompare(value, "stale")
|
||||
&& Curl_strcasecompare(content, "true")) {
|
||||
stale = true;
|
||||
break;
|
||||
}
|
||||
|
||||
while(*p && ISSPACE(*p))
|
||||
p++;
|
||||
|
||||
if(',' == *p)
|
||||
p++;
|
||||
}
|
||||
|
||||
if(stale)
|
||||
Curl_auth_digest_cleanup(digest);
|
||||
else
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
/* Store the challenge for use later */
|
||||
digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen + 1);
|
||||
if(!digest->input_token)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -379,21 +410,13 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
size_t token_max;
|
||||
CredHandle credentials;
|
||||
CtxtHandle context;
|
||||
char *resp;
|
||||
BYTE *output_token;
|
||||
size_t output_token_len = 0;
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SecBuffer chlg_buf[3];
|
||||
SecBuffer resp_buf;
|
||||
SecBuffer chlg_buf[5];
|
||||
SecBufferDesc chlg_desc;
|
||||
SecBufferDesc resp_desc;
|
||||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
|
||||
TCHAR *spn;
|
||||
|
||||
(void) data;
|
||||
|
||||
@@ -408,123 +431,168 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
/* Release the package buffer as it is not required anymore */
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
|
||||
if(userp && *userp) {
|
||||
/* Populate our identity structure */
|
||||
if(Curl_create_sspi_identity(userp, passwdp, &identity))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Populate our identity domain */
|
||||
if(Curl_override_sspi_http_realm((const char *) digest->input_token,
|
||||
&identity))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
p_identity = &identity;
|
||||
}
|
||||
else
|
||||
/* Use the current Windows user */
|
||||
p_identity = NULL;
|
||||
|
||||
/* Acquire our credentials handle */
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT(SP_NAME_DIGEST),
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
p_identity, NULL, NULL,
|
||||
&credentials, &expiry);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
/* Allocate the output buffer according to the max token size as indicated
|
||||
by the security package */
|
||||
output_token = malloc(token_max);
|
||||
if(!output_token) {
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Setup the challenge "input" security buffer if present */
|
||||
chlg_desc.ulVersion = SECBUFFER_VERSION;
|
||||
chlg_desc.cBuffers = 3;
|
||||
chlg_desc.pBuffers = chlg_buf;
|
||||
chlg_buf[0].BufferType = SECBUFFER_TOKEN;
|
||||
chlg_buf[0].pvBuffer = digest->input_token;
|
||||
chlg_buf[0].cbBuffer = curlx_uztoul(digest->input_token_len);
|
||||
chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[1].pvBuffer = (void *) request;
|
||||
chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request));
|
||||
chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[2].pvBuffer = NULL;
|
||||
chlg_buf[2].cbBuffer = 0;
|
||||
if(digest->http_context) {
|
||||
chlg_desc.ulVersion = SECBUFFER_VERSION;
|
||||
chlg_desc.cBuffers = 5;
|
||||
chlg_desc.pBuffers = chlg_buf;
|
||||
chlg_buf[0].BufferType = SECBUFFER_TOKEN;
|
||||
chlg_buf[0].pvBuffer = NULL;
|
||||
chlg_buf[0].cbBuffer = 0;
|
||||
chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[1].pvBuffer = (void *) request;
|
||||
chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request));
|
||||
chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[2].pvBuffer = (void *) uripath;
|
||||
chlg_buf[2].cbBuffer = curlx_uztoul(strlen((const char *) uripath));
|
||||
chlg_buf[3].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[3].pvBuffer = NULL;
|
||||
chlg_buf[3].cbBuffer = 0;
|
||||
chlg_buf[4].BufferType = SECBUFFER_PADDING;
|
||||
chlg_buf[4].pvBuffer = output_token;
|
||||
chlg_buf[4].cbBuffer = curlx_uztoul(token_max);
|
||||
|
||||
/* Setup the response "output" security buffer */
|
||||
resp_desc.ulVersion = SECBUFFER_VERSION;
|
||||
resp_desc.cBuffers = 1;
|
||||
resp_desc.pBuffers = &resp_buf;
|
||||
resp_buf.BufferType = SECBUFFER_TOKEN;
|
||||
resp_buf.pvBuffer = output_token;
|
||||
resp_buf.cbBuffer = curlx_uztoul(token_max);
|
||||
|
||||
spn = Curl_convert_UTF8_to_tchar((char *) uripath);
|
||||
if(!spn) {
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
free(output_token);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
status = s_pSecFn->MakeSignature(digest->http_context, 0, &chlg_desc, 0);
|
||||
if(status == SEC_E_OK)
|
||||
output_token_len = chlg_buf[4].cbBuffer;
|
||||
else { /* delete the context so a new one can be made */
|
||||
infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx\n",
|
||||
(long)status);
|
||||
s_pSecFn->DeleteSecurityContext(digest->http_context);
|
||||
Curl_safefree(digest->http_context);
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate our reponse message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
|
||||
spn,
|
||||
ISC_REQ_USE_HTTP_STYLE, 0, 0,
|
||||
&chlg_desc, 0, &context,
|
||||
&resp_desc, &attrs, &expiry);
|
||||
Curl_unicodefree(spn);
|
||||
if(!digest->http_context) {
|
||||
CredHandle credentials;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SEC_WINNT_AUTH_IDENTITY *p_identity;
|
||||
SecBuffer resp_buf;
|
||||
SecBufferDesc resp_desc;
|
||||
unsigned long attrs;
|
||||
TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
|
||||
TCHAR *spn;
|
||||
|
||||
if(userp && *userp) {
|
||||
/* Populate our identity structure */
|
||||
if(Curl_create_sspi_identity(userp, passwdp, &identity)) {
|
||||
free(output_token);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate our identity domain */
|
||||
if(Curl_override_sspi_http_realm((const char *) digest->input_token,
|
||||
&identity)) {
|
||||
free(output_token);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
p_identity = &identity;
|
||||
}
|
||||
else
|
||||
/* Use the current Windows user */
|
||||
p_identity = NULL;
|
||||
|
||||
/* Acquire our credentials handle */
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT(SP_NAME_DIGEST),
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
p_identity, NULL, NULL,
|
||||
&credentials, &expiry);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
free(output_token);
|
||||
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
/* Setup the challenge "input" security buffer if present */
|
||||
chlg_desc.ulVersion = SECBUFFER_VERSION;
|
||||
chlg_desc.cBuffers = 3;
|
||||
chlg_desc.pBuffers = chlg_buf;
|
||||
chlg_buf[0].BufferType = SECBUFFER_TOKEN;
|
||||
chlg_buf[0].pvBuffer = digest->input_token;
|
||||
chlg_buf[0].cbBuffer = curlx_uztoul(digest->input_token_len);
|
||||
chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[1].pvBuffer = (void *) request;
|
||||
chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request));
|
||||
chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS;
|
||||
chlg_buf[2].pvBuffer = NULL;
|
||||
chlg_buf[2].cbBuffer = 0;
|
||||
|
||||
/* Setup the response "output" security buffer */
|
||||
resp_desc.ulVersion = SECBUFFER_VERSION;
|
||||
resp_desc.cBuffers = 1;
|
||||
resp_desc.pBuffers = &resp_buf;
|
||||
resp_buf.BufferType = SECBUFFER_TOKEN;
|
||||
resp_buf.pvBuffer = output_token;
|
||||
resp_buf.cbBuffer = curlx_uztoul(token_max);
|
||||
|
||||
spn = Curl_convert_UTF8_to_tchar((char *) uripath);
|
||||
if(!spn) {
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
free(output_token);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Allocate our new context handle */
|
||||
digest->http_context = calloc(1, sizeof(CtxtHandle));
|
||||
if(!digest->http_context)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Generate our response message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&credentials, NULL,
|
||||
spn,
|
||||
ISC_REQ_USE_HTTP_STYLE, 0, 0,
|
||||
&chlg_desc, 0,
|
||||
digest->http_context,
|
||||
&resp_desc, &attrs, &expiry);
|
||||
Curl_unicodefree(spn);
|
||||
|
||||
if(status == SEC_I_COMPLETE_NEEDED ||
|
||||
status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
|
||||
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
free(output_token);
|
||||
|
||||
Curl_safefree(digest->http_context);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
output_token_len = resp_buf.cbBuffer;
|
||||
|
||||
if(status == SEC_I_COMPLETE_NEEDED ||
|
||||
status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
s_pSecFn->CompleteAuthToken(&credentials, &resp_desc);
|
||||
else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
free(output_token);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
resp = malloc(resp_buf.cbBuffer + 1);
|
||||
resp = malloc(output_token_len + 1);
|
||||
if(!resp) {
|
||||
s_pSecFn->DeleteSecurityContext(&context);
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
free(output_token);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Copy the generated reponse */
|
||||
memcpy(resp, resp_buf.pvBuffer, resp_buf.cbBuffer);
|
||||
resp[resp_buf.cbBuffer] = 0x00;
|
||||
/* Copy the generated response */
|
||||
memcpy(resp, output_token, output_token_len);
|
||||
resp[output_token_len] = 0;
|
||||
|
||||
/* Return the response */
|
||||
*outptr = resp;
|
||||
*outlen = resp_buf.cbBuffer;
|
||||
|
||||
/* Free our handles */
|
||||
s_pSecFn->DeleteSecurityContext(&context);
|
||||
s_pSecFn->FreeCredentialsHandle(&credentials);
|
||||
|
||||
/* Free the identity structure */
|
||||
Curl_sspi_free_identity(p_identity);
|
||||
*outlen = output_token_len;
|
||||
|
||||
/* Free the response buffer */
|
||||
free(output_token);
|
||||
@@ -549,6 +617,12 @@ void Curl_auth_digest_cleanup(struct digestdata *digest)
|
||||
|
||||
/* Reset any variables */
|
||||
digest->input_token_len = 0;
|
||||
|
||||
/* Delete security context */
|
||||
if(digest->http_context) {
|
||||
s_pSecFn->DeleteSecurityContext(digest->http_context);
|
||||
Curl_safefree(digest->http_context);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2014 - 2017, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -68,7 +68,7 @@ bool Curl_auth_is_gssapi_supported(void)
|
||||
* passdwp [in] - The user's password.
|
||||
* service [in] - The service type such as http, smtp, pop or imap.
|
||||
* host [in[ - The host name.
|
||||
* mutual_auth [in] - Flag specifing whether or not mutual authentication
|
||||
* mutual_auth [in] - Flag specifying whether or not mutual authentication
|
||||
* is enabled.
|
||||
* chlg64 [in] - Pointer to the optional base64 encoded challenge
|
||||
* message.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2014 - 2017, 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
|
||||
@@ -74,7 +74,7 @@ bool Curl_auth_is_gssapi_supported(void)
|
||||
* passdwp [in] - The user's password.
|
||||
* service [in] - The service type such as http, smtp, pop or imap.
|
||||
* host [in] - The host name.
|
||||
* mutual_auth [in] - Flag specifing whether or not mutual authentication
|
||||
* mutual_auth [in] - Flag specifying whether or not mutual authentication
|
||||
* is enabled.
|
||||
* chlg64 [in] - The optional base64 encoded challenge message.
|
||||
* krb5 [in/out] - The Kerberos 5 data struct being used and modified.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@@ -394,7 +394,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(const char *userp,
|
||||
/* Clean up any former leftovers and initialise to defaults */
|
||||
Curl_auth_ntlm_cleanup(ntlm);
|
||||
|
||||
#if USE_NTRESPONSES && USE_NTLM2SESSION
|
||||
#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
|
||||
#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
|
||||
#else
|
||||
#define NTLM2FLAG 0
|
||||
@@ -509,7 +509,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
int lmrespoff;
|
||||
unsigned char lmresp[24]; /* fixed-size */
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
int ntrespoff;
|
||||
unsigned int ntresplen = 24;
|
||||
unsigned char ntresp[24]; /* fixed-size */
|
||||
@@ -552,7 +552,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
hostlen = strlen(host);
|
||||
}
|
||||
|
||||
#if USE_NTRESPONSES && USE_NTLM_V2
|
||||
#if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2)
|
||||
if(ntlm->target_info_len) {
|
||||
unsigned char ntbuffer[0x18];
|
||||
unsigned int entropy[2];
|
||||
@@ -590,7 +590,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
else
|
||||
#endif
|
||||
|
||||
#if USE_NTRESPONSES && USE_NTLM2SESSION
|
||||
#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
|
||||
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
||||
unsigned char ntbuffer[0x18];
|
||||
@@ -630,12 +630,12 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
#endif
|
||||
{
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
unsigned char ntbuffer[0x18];
|
||||
#endif
|
||||
unsigned char lmbuffer[0x18];
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -651,7 +651,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
|
||||
/* A safer but less compatible alternative is:
|
||||
* Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
|
||||
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
|
||||
* See https://davenport.sourceforge.io/ntlm.html#ntlmVersion2 */
|
||||
}
|
||||
|
||||
if(unicode) {
|
||||
@@ -661,7 +661,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
lmrespoff = 64; /* size of the message header */
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
ntrespoff = lmrespoff + 0x18;
|
||||
domoff = ntrespoff + ntresplen;
|
||||
#else
|
||||
@@ -721,7 +721,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
SHORTPAIR(ntresplen), /* NT-response length, twice */
|
||||
SHORTPAIR(ntresplen),
|
||||
SHORTPAIR(ntrespoff),
|
||||
@@ -768,7 +768,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
|
||||
});
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#ifdef USE_NTRESPONSES
|
||||
if(size < (NTLM_BUFSIZE - ntresplen)) {
|
||||
DEBUGASSERT(size == (size_t)ntrespoff);
|
||||
memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/* Stuff only required for curl_ntlm_msgs.c */
|
||||
#ifdef BUILDING_CURL_NTLM_MSGS_C
|
||||
|
||||
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
|
||||
/* Flag bits definitions based on https://davenport.sourceforge.io/ntlm.html */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
|
||||
/* Indicates that Unicode strings are supported for use in security buffer
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "warnless.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "sendf.h"
|
||||
#include "strerror.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
@@ -224,6 +225,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
free(chlg);
|
||||
|
||||
if(GSS_ERROR(nego->status)) {
|
||||
failf(data, "InitializeSecurityContext failed: %s",
|
||||
Curl_sspi_strerror(data->easy_conn, nego->status));
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
|
||||
* Copyright (C) 2010 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2017, 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
|
||||
@@ -156,6 +156,12 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
same connection */
|
||||
return CURLE_OK;
|
||||
|
||||
if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
|
||||
failf(data, "axtls does not support CURL_SSLVERSION_MAX");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* axTLS only supports TLSv1 */
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
@@ -256,7 +262,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
* 2) setting up callbacks. these seem gnutls specific
|
||||
*/
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
const uint8_t *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
|
||||
@@ -267,13 +273,13 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
/* we got a session id, use it! */
|
||||
infof(data, "SSL re-using session ID\n");
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
|
||||
ssl_sessionid, (uint8_t)ssl_idsize);
|
||||
ssl_sessionid, (uint8_t)ssl_idsize, NULL);
|
||||
}
|
||||
Curl_ssl_sessionid_unlock(conn);
|
||||
}
|
||||
|
||||
if(!ssl)
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
|
||||
|
||||
conn->ssl[sockindex].ssl = ssl;
|
||||
return CURLE_OK;
|
||||
@@ -386,9 +392,9 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
conn->send[sockindex] = axtls_send;
|
||||
|
||||
/* Put our freshly minted SSL session in cache */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
|
||||
size_t ssl_idsize = ssl_get_session_id(ssl);
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
|
||||
size_t ssl_idsize = ssl_get_session_id_size(ssl);
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
|
||||
sockindex) != CURLE_OK)
|
||||
@@ -680,9 +686,9 @@ size_t Curl_axtls_version(char *buffer, size_t size)
|
||||
return snprintf(buffer, size, "axTLS/%s", ssl_version());
|
||||
}
|
||||
|
||||
int Curl_axtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length)
|
||||
CURLcode Curl_axtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length)
|
||||
{
|
||||
static bool ssl_seeded = FALSE;
|
||||
(void)data;
|
||||
@@ -694,7 +700,7 @@ int Curl_axtls_random(struct Curl_easy *data,
|
||||
RNG_initialize();
|
||||
}
|
||||
get_random((int)length, entropy);
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* USE_AXTLS */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
|
||||
* Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -42,9 +42,9 @@ void Curl_axtls_session_free(void *ptr);
|
||||
size_t Curl_axtls_version(char *buffer, size_t size);
|
||||
int Curl_axtls_shutdown(struct connectdata *conn, int sockindex);
|
||||
int Curl_axtls_check_cxn(struct connectdata *conn);
|
||||
int Curl_axtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
CURLcode Curl_axtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
|
||||
/* Set the API backend definition to axTLS */
|
||||
#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -134,6 +134,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
char error_buffer[CYASSL_MAX_ERROR_SZ];
|
||||
char *ciphers;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data* conssl = &conn->ssl[sockindex];
|
||||
SSL_METHOD* req_method = NULL;
|
||||
@@ -148,6 +149,11 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
if(conssl->state == ssl_connection_complete)
|
||||
return CURLE_OK;
|
||||
|
||||
if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
|
||||
failf(data, "CyaSSL does not support to set maximum SSL/TLS version");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
@@ -229,6 +235,15 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
ciphers = SSL_CONN_CONFIG(cipher_list);
|
||||
if(ciphers) {
|
||||
if(!SSL_CTX_set_cipher_list(conssl->ctx, ciphers)) {
|
||||
failf(data, "failed setting cipher list: %s", ciphers);
|
||||
return CURLE_SSL_CIPHER;
|
||||
}
|
||||
infof(data, "Cipher selection: %s\n", ciphers);
|
||||
}
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* load trusted cacert */
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
@@ -383,7 +398,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *ssl_sessionid = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
@@ -581,7 +596,13 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
conssl->connecting_state = ssl_connect_3;
|
||||
#if (LIBCYASSL_VERSION_HEX >= 0x03009010)
|
||||
infof(data, "SSL connection using %s / %s\n",
|
||||
wolfSSL_get_version(conssl->handle),
|
||||
wolfSSL_get_cipher_name(conssl->handle));
|
||||
#else
|
||||
infof(data, "SSL connected\n");
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -597,7 +618,7 @@ cyassl_connect_step3(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
bool incache;
|
||||
SSL_SESSION *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
@@ -720,7 +741,9 @@ void Curl_cyassl_session_free(void *ptr)
|
||||
|
||||
size_t Curl_cyassl_version(char *buffer, size_t size)
|
||||
{
|
||||
#ifdef WOLFSSL_VERSION
|
||||
#if LIBCYASSL_VERSION_HEX >= 0x03006000
|
||||
return snprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
|
||||
#elif defined(WOLFSSL_VERSION)
|
||||
return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
|
||||
#elif defined(CYASSL_VERSION)
|
||||
return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
|
||||
@@ -772,7 +795,7 @@ cyassl_connect_common(struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
long timeout_ms;
|
||||
time_t timeout_ms;
|
||||
int what;
|
||||
|
||||
/* check if the connection has already been established */
|
||||
@@ -901,19 +924,19 @@ Curl_cyassl_connect(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
int Curl_cyassl_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length)
|
||||
CURLcode Curl_cyassl_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length)
|
||||
{
|
||||
RNG rng;
|
||||
(void)data;
|
||||
if(InitRng(&rng))
|
||||
return 1;
|
||||
return CURLE_FAILED_INIT;
|
||||
if(length > UINT_MAX)
|
||||
return 1;
|
||||
return CURLE_FAILED_INIT;
|
||||
if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
|
||||
return 1;
|
||||
return 0;
|
||||
return CURLE_FAILED_INIT;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -51,15 +51,15 @@ int Curl_cyassl_init(void);
|
||||
CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *done);
|
||||
int Curl_cyassl_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
CURLcode Curl_cyassl_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *sha256sum, /* output */
|
||||
size_t unused);
|
||||
|
||||
/* Set the API backend definition to Schannel */
|
||||
/* Set the API backend definition to CyaSSL */
|
||||
#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL
|
||||
|
||||
/* this backend supports CURLOPT_SSL_CTX_* */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
|
||||
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2017, 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
|
||||
@@ -219,6 +219,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
|
||||
return ortn;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
|
||||
{
|
||||
switch(cipher) {
|
||||
@@ -776,6 +777,7 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
|
||||
}
|
||||
return "TLS_NULL_WITH_NULL_NULL";
|
||||
}
|
||||
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
#if CURL_BUILD_MAC
|
||||
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
|
||||
@@ -885,12 +887,13 @@ static OSStatus CopyIdentityWithLabel(char *label,
|
||||
SecIdentityRef *out_cert_and_key)
|
||||
{
|
||||
OSStatus status = errSecItemNotFound;
|
||||
|
||||
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||
CFArrayRef keys_list;
|
||||
CFIndex keys_list_count;
|
||||
CFIndex i;
|
||||
CFStringRef common_name;
|
||||
|
||||
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
|
||||
kSecClassIdentity was introduced in Lion. If both exist, let's use them
|
||||
to find the certificate. */
|
||||
@@ -929,28 +932,35 @@ static OSStatus CopyIdentityWithLabel(char *label,
|
||||
if(status == noErr) {
|
||||
keys_list_count = CFArrayGetCount(keys_list);
|
||||
*out_cert_and_key = NULL;
|
||||
status = 1;
|
||||
for(i=0; i<keys_list_count; i++) {
|
||||
OSStatus err = noErr;
|
||||
SecCertificateRef cert = NULL;
|
||||
*out_cert_and_key =
|
||||
SecIdentityRef identity =
|
||||
(SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
|
||||
err = SecIdentityCopyCertificate(*out_cert_and_key, &cert);
|
||||
err = SecIdentityCopyCertificate(identity, &cert);
|
||||
if(err == noErr) {
|
||||
#if CURL_BUILD_IOS
|
||||
common_name = SecCertificateCopySubjectSummary(cert);
|
||||
#elif CURL_BUILD_MAC_10_7
|
||||
SecCertificateCopyCommonName(cert, &common_name);
|
||||
#endif
|
||||
if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
|
||||
CFRelease(cert);
|
||||
CFRelease(common_name);
|
||||
CFRetain(identity);
|
||||
*out_cert_and_key = identity;
|
||||
status = noErr;
|
||||
break;
|
||||
}
|
||||
CFRelease(common_name);
|
||||
}
|
||||
*out_cert_and_key = NULL;
|
||||
status = 1;
|
||||
CFRelease(cert);
|
||||
}
|
||||
}
|
||||
|
||||
if(keys_list)
|
||||
CFRelease(keys_list);
|
||||
CFRelease(query_dict);
|
||||
CFRelease(label_cf);
|
||||
}
|
||||
@@ -1034,6 +1044,109 @@ CF_INLINE bool is_file(const char *filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||
static CURLcode darwinssl_version_from_curl(long *darwinver, long ssl_version)
|
||||
{
|
||||
switch(ssl_version) {
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
*darwinver = kTLSProtocol1;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
*darwinver = kTLSProtocol11;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
*darwinver = kTLSProtocol12;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
break;
|
||||
}
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
long ssl_version = SSL_CONN_CONFIG(version);
|
||||
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||
|
||||
switch(ssl_version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ssl_version_max) {
|
||||
case CURL_SSLVERSION_MAX_NONE:
|
||||
ssl_version_max = ssl_version << 16;
|
||||
break;
|
||||
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
break;
|
||||
}
|
||||
|
||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||
if(SSLSetProtocolVersionMax != NULL) {
|
||||
SSLProtocol darwin_ver_min = kTLSProtocol1;
|
||||
SSLProtocol darwin_ver_max = kTLSProtocol1;
|
||||
CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
|
||||
ssl_version);
|
||||
if(result) {
|
||||
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
|
||||
return result;
|
||||
}
|
||||
result = darwinssl_version_from_curl(&darwin_ver_max,
|
||||
ssl_version_max >> 16);
|
||||
if(result) {
|
||||
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
|
||||
return result;
|
||||
}
|
||||
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, darwin_ver_min);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, darwin_ver_max);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
long i = ssl_version;
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocolAll,
|
||||
false);
|
||||
for(; i <= (ssl_version_max >> 16); i++) {
|
||||
switch(i) {
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol11,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol12,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||
}
|
||||
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
|
||||
failf(data, "DarwinSSL: cannot set SSL protocol");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
@@ -1103,20 +1216,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
{
|
||||
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||
if(err != noErr) {
|
||||
@@ -1157,23 +1265,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol11,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol12,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
{
|
||||
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocol3,
|
||||
@@ -1199,6 +1299,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
#endif /* CURL_SUPPORT_MAC_10_8 */
|
||||
}
|
||||
#else
|
||||
if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
|
||||
failf(data, "Your version of the OS does not support to set maximum"
|
||||
" SSL/TLS version");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||
switch(conn->ssl_config.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
@@ -1385,18 +1490,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
|
||||
|
||||
if(ssl_cafile) {
|
||||
if(ssl_cafile && verifypeer) {
|
||||
bool is_cert_file = is_file(ssl_cafile);
|
||||
|
||||
if(!is_cert_file) {
|
||||
failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
if(!verifypeer) {
|
||||
failf(data, "SSL: CA certificate set, but certificate verification "
|
||||
"is disabled");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure hostname check. SNI is used if available.
|
||||
@@ -1420,6 +1520,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
"the OS.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
|
||||
}
|
||||
|
||||
/* Disable cipher suites that ST supports but are not safe. These ciphers
|
||||
are unlikely to be used in any case since ST gives other ciphers a much
|
||||
@@ -1541,7 +1644,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
char *ssl_sessionid;
|
||||
size_t ssl_sessionid_len;
|
||||
|
||||
@@ -1921,7 +2024,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
/* The below is errSSLServerAuthCompleted; it's not defined in
|
||||
Leopard's headers */
|
||||
case -9841:
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
|
||||
int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
|
||||
connssl->ssl_ctx);
|
||||
if(res != CURLE_OK)
|
||||
@@ -2034,9 +2137,11 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
darwinssl_connect_step3(struct connectdata *conn,
|
||||
int sockindex)
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
/* This should be called during step3 of the connection at the earliest */
|
||||
static void
|
||||
show_verbose_server_cert(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
@@ -2048,9 +2153,9 @@ darwinssl_connect_step3(struct connectdata *conn,
|
||||
CFIndex i, count;
|
||||
SecTrustRef trust = NULL;
|
||||
|
||||
/* There is no step 3!
|
||||
* Well, okay, if verbose mode is on, let's print the details of the
|
||||
* server certificates. */
|
||||
if(!connssl->ssl_ctx)
|
||||
return;
|
||||
|
||||
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||
#if CURL_BUILD_IOS
|
||||
#pragma unused(server_certs)
|
||||
@@ -2147,6 +2252,23 @@ darwinssl_connect_step3(struct connectdata *conn,
|
||||
CFRelease(server_certs);
|
||||
}
|
||||
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
|
||||
}
|
||||
#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
static CURLcode
|
||||
darwinssl_connect_step3(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
/* There is no step 3!
|
||||
* Well, okay, if verbose mode is on, let's print the details of the
|
||||
* server certificates. */
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
if(data->set.verbose)
|
||||
show_verbose_server_cert(conn, sockindex);
|
||||
#endif
|
||||
|
||||
connssl->connecting_state = ssl_connect_done;
|
||||
return CURLE_OK;
|
||||
@@ -2424,8 +2546,8 @@ bool Curl_darwinssl_data_pending(const struct connectdata *conn,
|
||||
return false;
|
||||
}
|
||||
|
||||
int Curl_darwinssl_random(unsigned char *entropy,
|
||||
size_t length)
|
||||
CURLcode Curl_darwinssl_random(unsigned char *entropy,
|
||||
size_t length)
|
||||
{
|
||||
/* arc4random_buf() isn't available on cats older than Lion, so let's
|
||||
do this manually for the benefit of the older cats. */
|
||||
@@ -2439,7 +2561,7 @@ int Curl_darwinssl_random(unsigned char *entropy,
|
||||
random_number >>= 8;
|
||||
}
|
||||
i = random_number = 0;
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -42,8 +42,8 @@ int Curl_darwinssl_check_cxn(struct connectdata *conn);
|
||||
bool Curl_darwinssl_data_pending(const struct connectdata *conn,
|
||||
int connindex);
|
||||
|
||||
int Curl_darwinssl_random(unsigned char *entropy,
|
||||
size_t length);
|
||||
CURLcode Curl_darwinssl_random(unsigned char *entropy,
|
||||
size_t length);
|
||||
void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *md5sum, /* output */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -320,7 +320,7 @@ static CURLcode set_ciphers(struct connectdata *conn,
|
||||
|
||||
/* We allocate GSKit buffers of the same size as the input string: since
|
||||
GSKit tokens are always shorter than their cipher names, allocated buffers
|
||||
will always be large enough to accomodate the result. */
|
||||
will always be large enough to accommodate the result. */
|
||||
l = strlen(cipherlist) + 1;
|
||||
memset((char *) ciphers, 0, sizeof ciphers);
|
||||
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
|
||||
@@ -748,6 +748,40 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
return (ssize_t) nread;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
long ssl_version = SSL_CONN_CONFIG(version);
|
||||
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||
long i = ssl_version;
|
||||
switch(ssl_version_max) {
|
||||
case CURL_SSLVERSION_MAX_NONE:
|
||||
ssl_version_max = ssl_version;
|
||||
break;
|
||||
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||
ssl_version_max = CURL_SSLVERSION_TLSv1_2;
|
||||
break;
|
||||
}
|
||||
for(; i <= (ssl_version_max >> 16); ++i) {
|
||||
switch(i) {
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
*protoflags |= CURL_GSKPROTO_TLSV10_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
*protoflags |= CURL_GSKPROTO_TLSV11_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
*protoflags |= CURL_GSKPROTO_TLSV11_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "GSKit: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
@@ -764,7 +798,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
|
||||
conn->host.name;
|
||||
const char *sni;
|
||||
unsigned int protoflags;
|
||||
unsigned int protoflags = 0;
|
||||
long timeout;
|
||||
Qso_OverlappedIO_t commarea;
|
||||
int sockpair[2];
|
||||
@@ -849,17 +883,13 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
protoflags = CURL_GSKPROTO_TLSV10_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
protoflags = CURL_GSKPROTO_TLSV11_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
protoflags = CURL_GSKPROTO_TLSV12_MASK;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "GSKit: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
result = set_ssl_version_min_max(&protoflags, conn);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
default:
|
||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -92,11 +92,11 @@ static bool gtls_inited = FALSE;
|
||||
# define GNUTLS_MAPS_WINSOCK_ERRORS 1
|
||||
# endif
|
||||
|
||||
# if (GNUTLS_VERSION_NUMBER >= 0x030200)
|
||||
# if HAVE_GNUTLS_ALPN_SET_PROTOCOLS
|
||||
# define HAS_ALPN
|
||||
# endif
|
||||
|
||||
# if (GNUTLS_VERSION_NUMBER >= 0x03020d)
|
||||
# if HAVE_GNUTLS_OCSP_REQ_INIT
|
||||
# define HAS_OCSP
|
||||
# endif
|
||||
|
||||
@@ -278,7 +278,7 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
gnutls_session_t session = conn->ssl[sockindex].session;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
long timeout_ms;
|
||||
time_t timeout_ms;
|
||||
int rc;
|
||||
int what;
|
||||
|
||||
@@ -314,7 +314,7 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
else if(timeout_ms) {
|
||||
/* timeout */
|
||||
failf(data, "SSL connection timeout at %ld", timeout_ms);
|
||||
failf(data, "SSL connection timeout at %ld", (long)timeout_ms);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
}
|
||||
@@ -375,11 +375,106 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
long ssl_version = SSL_CONN_CONFIG(version);
|
||||
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||
long i = ssl_version;
|
||||
long protocol_priority_idx = 0;
|
||||
|
||||
switch(ssl_version_max) {
|
||||
case CURL_SSLVERSION_MAX_NONE:
|
||||
ssl_version_max = ssl_version << 16;
|
||||
break;
|
||||
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
break;
|
||||
}
|
||||
|
||||
for(; i <= (ssl_version_max >> 16) &&
|
||||
protocol_priority_idx < list_size; ++i) {
|
||||
switch(i) {
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
#else
|
||||
#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
|
||||
/* If GnuTLS was compiled without support for SRP it will error out if SRP is
|
||||
requested in the priority string, so treat it specially
|
||||
*/
|
||||
#define GNUTLS_SRP "+SRP"
|
||||
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
long ssl_version = SSL_CONN_CONFIG(version);
|
||||
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||
if(ssl_version == CURL_SSLVERSION_TLSv1_3 ||
|
||||
ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) {
|
||||
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
|
||||
ssl_version_max = ssl_version << 16;
|
||||
}
|
||||
switch(ssl_version | ssl_version_max) {
|
||||
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.0:" GNUTLS_SRP;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
|
||||
case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.1:" GNUTLS_SRP;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
|
||||
case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
|
||||
case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
|
||||
*prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.2:" GNUTLS_SRP;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
failf(data, "GnuTLS: cannot set ssl protocol");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode
|
||||
gtls_connect_step1(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
unsigned int init_flags;
|
||||
gnutls_session_t session;
|
||||
int rc;
|
||||
bool sni = TRUE; /* default is SNI enabled */
|
||||
@@ -405,13 +500,8 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
GNUTLS_CIPHER_3DES_CBC,
|
||||
};
|
||||
static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
|
||||
static int protocol_priority[] = { 0, 0, 0, 0 };
|
||||
int protocol_priority[] = { 0, 0, 0, 0 };
|
||||
#else
|
||||
#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
|
||||
/* If GnuTLS was compiled without support for SRP it will error out if SRP is
|
||||
requested in the priority string, so treat it specially
|
||||
*/
|
||||
#define GNUTLS_SRP "+SRP"
|
||||
const char *prioritylist;
|
||||
const char *err = NULL;
|
||||
#endif
|
||||
@@ -526,7 +616,14 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Initialize TLS session as a client */
|
||||
rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
|
||||
init_flags = GNUTLS_CLIENT;
|
||||
|
||||
#if defined(GNUTLS_NO_TICKETS)
|
||||
/* Disable TLS session tickets */
|
||||
init_flags |= GNUTLS_NO_TICKETS;
|
||||
#endif
|
||||
|
||||
rc = gnutls_init(&conn->ssl[sockindex].session, init_flags);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_init() failed: %d", rc);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -568,7 +665,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
switch(SSL_CONN_CONFIG(version) {
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
protocol_priority[0] = GNUTLS_SSL3;
|
||||
break;
|
||||
@@ -579,17 +676,16 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
protocol_priority[2] = GNUTLS_TLS1_2;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
protocol_priority[0] = GNUTLS_TLS1_0;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
protocol_priority[0] = GNUTLS_TLS1_1;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
protocol_priority[0] = GNUTLS_TLS1_2;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
{
|
||||
CURLcode result = set_ssl_version_min_max(protocol_priority,
|
||||
sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
failf(data, "GnuTLS does not support SSLv2");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -617,20 +713,15 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.0:" GNUTLS_SRP;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.1:" GNUTLS_SRP;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
|
||||
"+VERS-TLS1.2:" GNUTLS_SRP;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "GnuTLS: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
{
|
||||
CURLcode result = set_ssl_version_min_max(&prioritylist, conn);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
failf(data, "GnuTLS does not support SSLv2");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -782,7 +873,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
|
||||
/* This might be a reconnect, so we check for a session ID in the cache
|
||||
to speed up things */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
|
||||
@@ -882,7 +973,9 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
gnutls_datum_t proto;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
gnutls_protocol_t version = gnutls_protocol_get_version(session);
|
||||
#endif
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
|
||||
@@ -1311,7 +1404,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
conn->recv[sockindex] = gtls_recv;
|
||||
conn->send[sockindex] = gtls_send;
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
/* we always unconditionally get the session id here, as even if we
|
||||
already got it from the cache and asked to use it in the connection, it
|
||||
might've been rejected and then a new one is in use now and we need to
|
||||
@@ -1625,19 +1718,21 @@ static int Curl_gtls_seed(struct Curl_easy *data)
|
||||
#endif
|
||||
|
||||
/* data might be NULL! */
|
||||
int Curl_gtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length)
|
||||
CURLcode Curl_gtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length)
|
||||
{
|
||||
#if defined(USE_GNUTLS_NETTLE)
|
||||
int rc;
|
||||
(void)data;
|
||||
gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
|
||||
rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
|
||||
return rc?CURLE_FAILED_INIT:CURLE_OK;
|
||||
#elif defined(USE_GNUTLS)
|
||||
if(data)
|
||||
Curl_gtls_seed(data); /* Initiate the seed if not already done */
|
||||
gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
|
||||
#endif
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_gtls_md5sum(unsigned char *tmp, /* input */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, 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
|
||||
@@ -43,9 +43,9 @@ void Curl_gtls_close(struct connectdata *conn, int sockindex);
|
||||
void Curl_gtls_session_free(void *ptr);
|
||||
size_t Curl_gtls_version(char *buffer, size_t size);
|
||||
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex);
|
||||
int Curl_gtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
CURLcode Curl_gtls_random(struct Curl_easy *data,
|
||||
unsigned char *entropy,
|
||||
size_t length);
|
||||
void Curl_gtls_md5sum(unsigned char *tmp, /* input */
|
||||
size_t tmplen,
|
||||
unsigned char *md5sum, /* output */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2017, 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
|
||||
@@ -157,6 +157,71 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
|
||||
static Curl_recv mbed_recv;
|
||||
static Curl_send mbed_send;
|
||||
|
||||
static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
|
||||
{
|
||||
switch(version) {
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
*mbedver = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
*mbedver = MBEDTLS_SSL_MINOR_VERSION_2;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
*mbedver = MBEDTLS_SSL_MINOR_VERSION_3;
|
||||
return CURLE_OK;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
break;
|
||||
}
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
set_ssl_version_min_max(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
long ssl_version = SSL_CONN_CONFIG(version);
|
||||
long ssl_version_max = SSL_CONN_CONFIG(version_max);
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
switch(ssl_version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(ssl_version_max) {
|
||||
case CURL_SSLVERSION_MAX_NONE:
|
||||
ssl_version_max = ssl_version << 16;
|
||||
break;
|
||||
case CURL_SSLVERSION_MAX_DEFAULT:
|
||||
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
|
||||
break;
|
||||
}
|
||||
|
||||
result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version);
|
||||
if(result) {
|
||||
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
|
||||
return result;
|
||||
}
|
||||
result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16);
|
||||
if(result) {
|
||||
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
|
||||
return result;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ver_min);
|
||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
mbedtls_ver_max);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
mbed_connect_step1(struct connectdata *conn,
|
||||
int sockindex)
|
||||
@@ -333,29 +398,15 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
infof(data, "mbedTLS: Set SSL version to SSLv3\n");
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_0:
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_1);
|
||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_1);
|
||||
infof(data, "mbedTLS: Set SSL version to TLS 1.0\n");
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_2);
|
||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_2);
|
||||
infof(data, "mbedTLS: Set SSL version to TLS 1.1\n");
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_3);
|
||||
infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1_3:
|
||||
failf(data, "mbedTLS: TLS 1.3 is not yet supported");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
{
|
||||
CURLcode result = set_ssl_version_min_max(conn, sockindex);
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -373,8 +424,13 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
mbedtls_ssl_conf_ciphersuites(&connssl->config,
|
||||
mbedtls_ssl_list_ciphersuites());
|
||||
|
||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
|
||||
mbedtls_ssl_conf_session_tickets(&connssl->config,
|
||||
MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
|
||||
#endif
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *old_session = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
@@ -439,6 +495,16 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
mbedtls_debug_set_threshold(4);
|
||||
#endif
|
||||
|
||||
/* give application a chance to interfere with mbedTLS set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
ret = (*data->set.ssl.fsslctx)(data, &connssl->config,
|
||||
data->set.ssl.fsslctxp);
|
||||
if(ret) {
|
||||
failf(data, "error signaled by ssl ctx callback");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
connssl->connecting_state = ssl_connect_2;
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -618,7 +684,7 @@ mbed_connect_step3(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
int ret;
|
||||
mbedtls_ssl_session *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
@@ -631,6 +697,7 @@ mbed_connect_step3(struct connectdata *conn,
|
||||
|
||||
ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid);
|
||||
if(ret) {
|
||||
free(our_ssl_sessionid);
|
||||
failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
@@ -729,6 +796,55 @@ size_t Curl_mbedtls_version(char *buffer, size_t size)
|
||||
(version>>16)&0xff, (version>>8)&0xff);
|
||||
}
|
||||
|
||||
CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy,
|
||||
size_t length)
|
||||
{
|
||||
#if defined(MBEDTLS_CTR_DRBG_C)
|
||||
int ret = -1;
|
||||
char errorbuf[128];
|
||||
mbedtls_entropy_context ctr_entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_entropy_init(&ctr_entropy);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
errorbuf[0]=0;
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
|
||||
&ctr_entropy, NULL, 0);
|
||||
|
||||
if(ret) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* MBEDTLS_ERROR_C */
|
||||
failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
|
||||
-ret, errorbuf);
|
||||
}
|
||||
else {
|
||||
ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
|
||||
|
||||
if(ret) {
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* MBEDTLS_ERROR_C */
|
||||
failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
|
||||
-ret, errorbuf);
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&ctr_entropy);
|
||||
|
||||
return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
|
||||
#elif defined(MBEDTLS_HAVEGE_C)
|
||||
mbedtls_havege_state hs;
|
||||
mbedtls_havege_init(&hs);
|
||||
mbedtls_havege_random(&hs, entropy, length);
|
||||
mbedtls_havege_free(&hs);
|
||||
return CURLE_OK;
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
mbed_connect_common(struct connectdata *conn,
|
||||
int sockindex,
|
||||
@@ -883,9 +999,7 @@ void Curl_mbedtls_cleanup(void)
|
||||
|
||||
int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex)
|
||||
{
|
||||
mbedtls_ssl_context *ssl =
|
||||
(mbedtls_ssl_context *)&conn->ssl[sockindex].ssl;
|
||||
return ssl->in_msglen != 0;
|
||||
return mbedtls_ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
|
||||
}
|
||||
|
||||
#endif /* USE_MBEDTLS */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user