curl 2018-09-04 (432eb5f5)

Code extracted from:

    https://github.com/curl/curl.git

at commit 432eb5f5c254ee8383b2522ce597c9219877923e (curl-7_61_1).
This commit is contained in:
Curl Upstream 2018-09-04 23:49:50 +02:00 committed by Brad King
parent d431136e02
commit 18812a9c3d
112 changed files with 2584 additions and 1876 deletions

View File

@ -4,57 +4,57 @@ option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide al
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
if(CURL_HIDDEN_SYMBOLS)
set(SUPPORTS_SYMBOL_HIDING FALSE)
set(SUPPORTS_SYMBOL_HIDING FALSE)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
elseif(CMAKE_COMPILER_IS_GNUCC)
if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
else()
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
endif()
if(NOT GCC_VERSION VERSION_LESS 3.4)
# note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__global")
set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
# note: this should probably just check for version 9.1.045 but I'm not 100% sure
# so let's to it the same way autotools do.
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
check_c_source_compiles("#include <stdio.h>
int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
if(NOT _no_bug)
set(SUPPORTS_SYMBOL_HIDING FALSE)
set(_SYMBOL_EXTERN "")
set(_CFLAG_SYMBOLS_HIDE "")
endif()
elseif(MSVC)
set(SUPPORTS_SYMBOL_HIDING TRUE)
endif()
set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
elseif(MSVC)
if(NOT CMAKE_VERSION VERSION_LESS 3.7)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
elseif(CMAKE_COMPILER_IS_GNUCC)
if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
else()
message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
endif()
elseif()
if(NOT GCC_VERSION VERSION_LESS 3.4)
# note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__global")
set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
# note: this should probably just check for version 9.1.045 but I'm not 100% sure
# so let's to it the same way autotools do.
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
check_c_source_compiles("#include <stdio.h>
int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
if(NOT _no_bug)
set(SUPPORTS_SYMBOL_HIDING FALSE)
set(_SYMBOL_EXTERN "")
set(_CFLAG_SYMBOLS_HIDE "")
endif()
elseif(MSVC)
set(SUPPORTS_SYMBOL_HIDING TRUE)
endif()
set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
elseif(MSVC)
if(NOT CMAKE_VERSION VERSION_LESS 3.7)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
else()
message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
endif()
elseif()
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
endif()
set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})

View File

@ -507,30 +507,30 @@ main ()
#ifdef HAVE_GLIBC_STRERROR_R
#include <string.h>
#include <errno.h>
void check(char c) {}
int
main () {
char buffer[1024]; /* big enough to play with */
char *string =
strerror_r(EACCES, buffer, sizeof(buffer));
/* this should've returned a string */
if(!string || !string[0])
return 99;
return 0;
char buffer[1024];
/* This will not compile if strerror_r does not return a char* */
check(strerror_r(EACCES, buffer, sizeof(buffer))[0]);
return 0;
}
#endif
#ifdef HAVE_POSIX_STRERROR_R
#include <string.h>
#include <errno.h>
/* float, because a pointer can't be implicitly cast to float */
void check(float f) {}
int
main () {
char buffer[1024]; /* big enough to play with */
int error =
strerror_r(EACCES, buffer, sizeof(buffer));
/* This should've returned zero, and written an error string in the
buffer.*/
if(!buffer[0] || error)
return 99;
return 0;
char buffer[1024];
/* This will not compile if strerror_r does not return an int */
check(strerror_r(EACCES, buffer, sizeof(buffer)));
return 0;
}
#endif
#ifdef HAVE_FSETXATTR_6

View File

@ -7,36 +7,36 @@
# also defined, but not for general use are
# CARES_LIBRARY, where to find the c-ares library.
FIND_PATH(CARES_INCLUDE_DIR ares.h
find_path(CARES_INCLUDE_DIR ares.h
/usr/local/include
/usr/include
)
SET(CARES_NAMES ${CARES_NAMES} cares)
FIND_LIBRARY(CARES_LIBRARY
set(CARES_NAMES ${CARES_NAMES} cares)
find_library(CARES_LIBRARY
NAMES ${CARES_NAMES}
PATHS /usr/lib /usr/local/lib
)
IF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
SET(CARES_LIBRARIES ${CARES_LIBRARY})
SET(CARES_FOUND "YES")
ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR)
SET(CARES_FOUND "NO")
ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
if(CARES_LIBRARY AND CARES_INCLUDE_DIR)
set(CARES_LIBRARIES ${CARES_LIBRARY})
set(CARES_FOUND "YES")
else()
set(CARES_FOUND "NO")
endif()
IF (CARES_FOUND)
IF (NOT CARES_FIND_QUIETLY)
MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}")
ENDIF (NOT CARES_FIND_QUIETLY)
ELSE (CARES_FOUND)
IF (CARES_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find c-ares library")
ENDIF (CARES_FIND_REQUIRED)
ENDIF (CARES_FOUND)
if(CARES_FOUND)
if(NOT CARES_FIND_QUIETLY)
message(STATUS "Found c-ares: ${CARES_LIBRARIES}")
endif()
else()
if(CARES_FIND_REQUIRED)
message(FATAL_ERROR "Could not find c-ares library")
endif()
endif()
MARK_AS_ADVANCED(
mark_as_advanced(
CARES_LIBRARY
CARES_INCLUDE_DIR
)

View File

@ -28,211 +28,209 @@ set(_GSS_ROOT_HINTS
# try to find library using system pkg-config if user didn't specify root dir
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
if(UNIX)
find_package(PkgConfig QUIET)
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
elseif(WIN32)
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
endif()
if(UNIX)
find_package(PkgConfig QUIET)
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
elseif(WIN32)
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
endif()
endif()
if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
find_file(_GSS_CONFIGURE_SCRIPT
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
bin
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
)
# if not found in user-supplied directories, maybe system knows better
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
PATH_SUFFIXES
bin
)
if(_GSS_CONFIGURE_SCRIPT)
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
OUTPUT_VARIABLE _GSS_CFLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# should also work in an odd case when multiple directories are given
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
foreach(_flag ${_GSS_CFLAGS})
if(_flag MATCHES "^-I.*")
string(REGEX REPLACE "^-I" "" _val "${_flag}")
list(APPEND _GSS_INCLUDE_DIR "${_val}")
else()
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
OUTPUT_VARIABLE _GSS_LIB_FLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# this script gives us libraries and link directories. Blah. We have to deal with it.
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
foreach(_flag ${_GSS_LIB_FLAGS})
if(_flag MATCHES "^-l.*")
string(REGEX REPLACE "^-l" "" _val "${_flag}")
list(APPEND _GSS_LIBRARIES "${_val}")
elseif(_flag MATCHES "^-L.*")
string(REGEX REPLACE "^-L" "" _val "${_flag}")
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
else()
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
OUTPUT_VARIABLE _GSS_VERSION
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--version" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(_GSS_VERSION 0)
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
OUTPUT_VARIABLE _GSS_VENDOR
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--vendor" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
else()
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
set(GSS_FLAVOUR "Heimdal")
else()
set(GSS_FLAVOUR "MIT")
endif()
endif()
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
find_path(_GSS_INCLUDE_DIR
NAMES
"krb5-config"
"gssapi/gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
bin
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
include
inc
)
# if not found in user-supplied directories, maybe system knows better
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
PATH_SUFFIXES
bin
)
if(_GSS_INCLUDE_DIR) #jay, we've found something
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
if(_GSS_CONFIGURE_SCRIPT)
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
OUTPUT_VARIABLE _GSS_CFLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# should also work in an odd case when multiple directories are given
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
foreach(_flag ${_GSS_CFLAGS})
if(_flag MATCHES "^-I.*")
string(REGEX REPLACE "^-I" "" _val "${_flag}")
list(APPEND _GSS_INCLUDE_DIR "${_val}")
else()
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
OUTPUT_VARIABLE _GSS_LIB_FLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# this script gives us libraries and link directories. Blah. We have to deal with it.
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
foreach(_flag ${_GSS_LIB_FLAGS})
if(_flag MATCHES "^-l.*")
string(REGEX REPLACE "^-l" "" _val "${_flag}")
list(APPEND _GSS_LIBRARIES "${_val}")
elseif(_flag MATCHES "^-L.*")
string(REGEX REPLACE "^-L" "" _val "${_flag}")
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
else()
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
OUTPUT_VARIABLE _GSS_VERSION
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--version" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(_GSS_VERSION 0)
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
OUTPUT_VARIABLE _GSS_VENDOR
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--vendor" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
else()
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
set(GSS_FLAVOUR "Heimdal")
else()
set(GSS_FLAVOUR "MIT")
endif()
endif()
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi/gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR) #jay, we've found something
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
if(_GSS_HAVE_MIT_HEADERS)
set(GSS_FLAVOUR "MIT")
else()
# prevent compiling the header - just check if we can include it
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
set(GSS_FLAVOUR "Heimdal")
endif()
set(CMAKE_REQUIRED_DEFINITIONS "")
endif()
else()
# I'm not convienced if this is the right way but this is what autotools do at the moment
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR)
set(GSS_FLAVOUR "Heimdal")
endif()
endif()
# if we have headers, check if we can link libraries
if(GSS_FLAVOUR)
set(_GSS_LIBDIR_SUFFIXES "")
set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi64")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi32")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi_krb5")
else()
set(_GSS_LIBNAME "gssapi")
endif()
endif()
find_library(_GSS_LIBRARIES
NAMES
${_GSS_LIBNAME}
HINTS
${_GSS_LIBDIR_HINTS}
PATH_SUFFIXES
${_GSS_LIBDIR_SUFFIXES}
)
endif()
endif()
else()
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
if(_GSS_HAVE_MIT_HEADERS)
set(GSS_FLAVOUR "MIT")
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
else()
# prevent compiling the header - just check if we can include it
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
set(GSS_FLAVOUR "Heimdal")
endif()
set(CMAKE_REQUIRED_DEFINITIONS "")
endif()
else()
# I'm not convienced if this is the right way but this is what autotools do at the moment
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR)
set(GSS_FLAVOUR "Heimdal")
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
endif()
endif()
# if we have headers, check if we can link libraries
if(GSS_FLAVOUR)
set(_GSS_LIBDIR_SUFFIXES "")
set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi64")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi32")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi_krb5")
else()
set(_GSS_LIBNAME "gssapi")
endif()
endif()
find_library(_GSS_LIBRARIES
NAMES
${_GSS_LIBNAME}
HINTS
${_GSS_LIBDIR_HINTS}
PATH_SUFFIXES
${_GSS_LIBDIR_SUFFIXES}
)
endif()
endif()
else()
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
set(GSS_FLAVOUR "MIT")
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
else()
set(GSS_FLAVOUR "Heimdal")
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
endif()
endif()
set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
@ -243,35 +241,33 @@ set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
set(GSS_VERSION ${_GSS_VERSION})
if(GSS_FLAVOUR)
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
else()
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
endif()
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
string(REGEX MATCH "[0-9]\\.[^\"]+"
GSS_VERSION "${heimdal_version_str}")
endif()
if(NOT GSS_VERSION)
set(GSS_VERSION "Heimdal Unknown")
endif()
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
if(WIN32 AND _MIT_VERSION)
set(GSS_VERSION "${_MIT_VERSION}")
else()
set(GSS_VERSION "MIT Unknown")
endif()
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
else()
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
endif()
endif()
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
string(REGEX MATCH "[0-9]\\.[^\"]+"
GSS_VERSION "${heimdal_version_str}")
endif()
if(NOT GSS_VERSION)
set(GSS_VERSION "Heimdal Unknown")
endif()
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
if(WIN32 AND _MIT_VERSION)
set(GSS_VERSION "${_MIT_VERSION}")
else()
set(GSS_VERSION "MIT Unknown")
endif()
endif()
endif()
include(FindPackageHandleStandardArgs)

View File

@ -5,14 +5,14 @@
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
# LIBSSH2_LIBRARY - the libssh2 library name
if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
if(LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
set(LibSSH2_FIND_QUIETLY TRUE)
endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
endif()
FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
find_path(LIBSSH2_INCLUDE_DIR libssh2.h
)
FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
find_library(LIBSSH2_LIBRARY NAMES ssh2
)
if(LIBSSH2_INCLUDE_DIR)
@ -27,9 +27,9 @@ if(LIBSSH2_INCLUDE_DIR)
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
endif(LIBSSH2_INCLUDE_DIR)
endif()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
find_package_handle_standard_args(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)
mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)

View File

@ -14,5 +14,5 @@ find_package_handle_standard_args(NGHTTP2
"Could NOT find NGHTTP2"
)
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR} )
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR})
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})

View File

@ -5,35 +5,35 @@
# multiple times with a sequence of possibly dependent libraries in
# order of least-to-most-dependent. Some libraries depend on others
# to link correctly.
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
macro(check_library_exists_concat LIBRARY SYMBOL VARIABLE)
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
${VARIABLE})
if(${VARIABLE})
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
endif(${VARIABLE})
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
endif()
endmacro()
# Check if header file exists and add it to the list.
# This macro is intended to be called multiple times with a sequence of
# possibly dependent header files. Some headers depend on others to be
# compiled correctly.
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
macro(check_include_file_concat FILE VARIABLE)
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
if(${VARIABLE})
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
endif(${VARIABLE})
endmacro(CHECK_INCLUDE_FILE_CONCAT)
endif()
endmacro()
# For other curl specific tests, use this macro.
macro(CURL_INTERNAL_TEST CURL_TEST)
macro(curl_internal_test CURL_TEST)
if(NOT DEFINED "${CURL_TEST}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
endif()
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_compile(${CURL_TEST}
@ -48,53 +48,17 @@ macro(CURL_INTERNAL_TEST CURL_TEST)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
"${OUTPUT}\n")
else(${CURL_TEST})
else()
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}\n")
endif(${CURL_TEST})
endif()
endif()
endmacro(CURL_INTERNAL_TEST)
endmacro()
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
if(NOT DEFINED "${CURL_TEST}_COMPILE")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}")
if(${CURL_TEST}_COMPILE)
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"There was a problem running this test\n")
endif(${CURL_TEST}_COMPILE)
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"\n\n")
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
endif()
endmacro(CURL_INTERNAL_TEST_RUN)
macro(CURL_NROFF_CHECK)
macro(curl_nroff_check)
find_program(NROFF NAMES gnroff nroff)
if(NROFF)
# Need a way to write to stdin, this will do
@ -121,4 +85,4 @@ macro(CURL_NROFF_CHECK)
else()
message(WARNING "Found no *nroff program")
endif()
endmacro(CURL_NROFF_CHECK)
endmacro()

View File

@ -5,8 +5,8 @@ set(_source_epilogue "#undef inline")
macro(add_header_include check header)
if(${check})
set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
endif(${check})
endmacro(add_header_include)
endif()
endmacro()
set(signature_call_conv)
if(HAVE_WINDOWS_H)
@ -19,10 +19,10 @@ if(HAVE_WINDOWS_H)
if(HAVE_LIBWS2_32)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
endif()
else(HAVE_WINDOWS_H)
else()
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
endif(HAVE_WINDOWS_H)
endif()
check_c_source_compiles("${_source_epilogue}
int main(void) {
@ -64,13 +64,13 @@ if(curl_cv_recv)
set(RECV_TYPE_RETV "${recv_retv}")
set(HAVE_RECV 1)
set(curl_cv_func_recv_done 1)
endif(curl_cv_func_recv_test)
endif(NOT curl_cv_func_recv_done)
endforeach(recv_arg4)
endforeach(recv_arg3)
endforeach(recv_arg2)
endforeach(recv_arg1)
endforeach(recv_retv)
endif()
endif()
endforeach()
endforeach()
endforeach()
endforeach()
endforeach()
else()
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
@ -81,10 +81,10 @@ if(curl_cv_recv)
if("${curl_cv_func_recv_args}" STREQUAL "unknown")
message(FATAL_ERROR "Cannot find proper types to use for recv args")
endif("${curl_cv_func_recv_args}" STREQUAL "unknown")
else(curl_cv_recv)
endif()
else()
message(FATAL_ERROR "Unable to link function recv")
endif(curl_cv_recv)
endif()
set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
set(HAVE_RECV 1)
@ -130,13 +130,13 @@ if(curl_cv_send)
set(SEND_TYPE_RETV "${send_retv}")
set(HAVE_SEND 1)
set(curl_cv_func_send_done 1)
endif(curl_cv_func_send_test)
endif(NOT curl_cv_func_send_done)
endforeach(send_arg4)
endforeach(send_arg3)
endforeach(send_arg2)
endforeach(send_arg1)
endforeach(send_retv)
endif()
endif()
endforeach()
endforeach()
endforeach()
endforeach()
endforeach()
else()
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
@ -148,11 +148,11 @@ if(curl_cv_send)
if("${curl_cv_func_send_args}" STREQUAL "unknown")
message(FATAL_ERROR "Cannot find proper types to use for send args")
endif("${curl_cv_func_send_args}" STREQUAL "unknown")
endif()
set(SEND_QUAL_ARG2 "const")
else(curl_cv_send)
else()
message(FATAL_ERROR "Unable to link function send")
endif(curl_cv_send)
endif()
set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
set(HAVE_SEND 1)
@ -184,7 +184,7 @@ if(NOT APPLE)
set(CMAKE_REQUIRED_FLAGS)
if(HAVE_SYS_POLL_H)
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
endif(HAVE_SYS_POLL_H)
endif()
check_c_source_runs("
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
@ -199,7 +199,7 @@ set(CMAKE_REQUIRED_FLAGS)
if(HAVE_SIGNAL_H)
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
endif(HAVE_SIGNAL_H)
endif()
check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
if(HAVE_SIZEOF_SIG_ATOMIC_T)
check_c_source_compiles("
@ -213,8 +213,8 @@ if(HAVE_SIZEOF_SIG_ATOMIC_T)
}" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
endif(HAVE_SIZEOF_SIG_ATOMIC_T)
endif()
endif()
if(HAVE_WINDOWS_H)
set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
@ -222,11 +222,10 @@ else()
set(CMAKE_EXTRA_INCLUDE_FILES)
if(HAVE_SYS_SOCKET_H)
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
endif(HAVE_SYS_SOCKET_H)
endif()
endif()
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
endif(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
endif()

View File

@ -118,8 +118,7 @@ if(NOT UNIX)
set(HAVE_SIGACTION 0)
set(HAVE_MACRO_SIGSETJMP 0)
else(WIN32)
else()
message("This file should be included on Windows platform only")
endif(WIN32)
endif(NOT UNIX)
endif()
endif()

View File

@ -1,44 +1,13 @@
# File containing various utilities
# Converts a CMake list to a string containing elements separated by spaces
function(TO_LIST_SPACES _LIST_NAME OUTPUT_VAR)
set(NEW_LIST_SPACE)
foreach(ITEM ${${_LIST_NAME}})
set(NEW_LIST_SPACE "${NEW_LIST_SPACE} ${ITEM}")
endforeach()
string(STRIP ${NEW_LIST_SPACE} NEW_LIST_SPACE)
set(${OUTPUT_VAR} "${NEW_LIST_SPACE}" PARENT_SCOPE)
endfunction()
# Appends a lis of item to a string which is a space-separated list, if they don't already exist.
function(LIST_SPACES_APPEND_ONCE LIST_NAME)
string(REPLACE " " ";" _LIST ${${LIST_NAME}})
list(APPEND _LIST ${ARGN})
list(REMOVE_DUPLICATES _LIST)
to_list_spaces(_LIST NEW_LIST_SPACE)
set(${LIST_NAME} "${NEW_LIST_SPACE}" PARENT_SCOPE)
endfunction()
# Convenience function that does the same as LIST(FIND ...) but with a TRUE/FALSE return value.
# Ex: IN_STR_LIST(MY_LIST "Searched item" WAS_FOUND)
function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
list(FIND ${LIST_NAME} ${ITEM_SEARCHED} FIND_POS)
if(${FIND_POS} EQUAL -1)
set(${RETVAL} FALSE PARENT_SCOPE)
else()
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})
function(count_true output_count_var)
set(lst)
foreach(option_var IN LISTS ARGN)
if(${option_var})
list(APPEND ${output_var} ${option_var})
list(APPEND lst ${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)
list(LENGTH lst lst_len)
set(${output_count_var} ${lst_len} PARENT_SCOPE)
endfunction()

View File

@ -1,11 +1,11 @@
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
endif()
if (NOT DEFINED CMAKE_INSTALL_PREFIX)
set (CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
endif ()
message(${CMAKE_INSTALL_PREFIX})
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
endif()
message(${CMAKE_INSTALL_PREFIX})
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
@ -19,8 +19,8 @@ foreach(file ${files})
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endif()
else()
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)
endif()
endforeach()

View File

@ -1,59 +0,0 @@
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(NOT CURL_FIND_COMPONENTS)
set(CURL_FIND_COMPONENTS curl libcurl)
if(CURL_FIND_REQUIRED)
set(CURL_FIND_REQUIRED_curl TRUE)
set(CURL_FIND_REQUIRED_libcurl TRUE)
endif()
endif()
set(_curl_missing_components)
foreach(_comp ${CURL_FIND_COMPONENTS})
if(EXISTS "${_DIR}/${_comp}-target.cmake")
include("${_DIR}/${_comp}-target.cmake")
set(CURL_${_comp}_FOUND TRUE)
else()
set(CURL_${_comp}_FOUND FALSE)
if(CURL_FIND_REQUIRED_${_comp})
set(CURL_FOUND FALSE)
list(APPEND _curl_missing_components ${_comp})
endif()
endif()
endforeach()
if(_curl_missing_components)
set(CURL_NOT_FOUND_MESSAGE "Following required components not found: " ${_curl_missing_components})
else()
if(TARGET CURL::libcurl)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _curl_current_config)
if(NOT _curl_current_config)
set(_curl_current_config "NOCONFIG")
endif()
get_target_property(_curl_configurations CURL::libcurl IMPORTED_CONFIGURATIONS)
list(FIND _curl_configurations "${_curl_current_config}" _i)
if(_i LESS 0)
set(_curl_config "RELEASE")
list(FIND _curl_configurations "${_curl_current_config}" _i)
if(_i LESS 0)
set(_curl_config "NOCONFIG")
list(FIND _curl_configurations "${_curl_current_config}" _i)
endif()
endif()
if(_i LESS 0)
set(_curl_current_config "") # let CMake pick config at random
else()
set(_curl_current_config "_${_curl_current_config}")
endif()
get_target_property(CURL_INCLUDE_DIRS CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(CURL_LIBRARIES CURL::libcurl "LOCATION${_curl_current_config}")
set(_curl_current_config)
set(_curl_configurations)
set(_i)
endif()
endif()
unset(_curl_missing_components)

View File

@ -0,0 +1,64 @@
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(NOT CURL_FIND_COMPONENTS)
set(CURL_FIND_COMPONENTS curl libcurl)
if(CURL_FIND_REQUIRED)
set(CURL_FIND_REQUIRED_curl TRUE)
set(CURL_FIND_REQUIRED_libcurl TRUE)
endif()
endif()
include(CMakeFindDependencyMacro)
if(CURL_FIND_REQUIRED_libcurl)
find_dependency(OpenSSL "@OPENSSL_VERSION_MAJOR@")
endif()
set(_curl_missing_components)
foreach(_comp ${CURL_FIND_COMPONENTS})
if(EXISTS "${_DIR}/${_comp}-target.cmake")
include("${_DIR}/${_comp}-target.cmake")
set(CURL_${_comp}_FOUND TRUE)
else()
set(CURL_${_comp}_FOUND FALSE)
if(CURL_FIND_REQUIRED_${_comp})
set(CURL_FOUND FALSE)
list(APPEND _curl_missing_components ${_comp})
endif()
endif()
endforeach()
if(_curl_missing_components)
set(CURL_NOT_FOUND_MESSAGE "Following required components not found: " ${_curl_missing_components})
else()
if(TARGET CURL::libcurl)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _curl_current_config)
if(NOT _curl_current_config)
set(_curl_current_config "NOCONFIG")
endif()
get_target_property(_curl_configurations CURL::libcurl IMPORTED_CONFIGURATIONS)
list(FIND _curl_configurations "${_curl_current_config}" _i)
if(_i LESS 0)
set(_curl_config "RELEASE")
list(FIND _curl_configurations "${_curl_current_config}" _i)
if(_i LESS 0)
set(_curl_config "NOCONFIG")
list(FIND _curl_configurations "${_curl_current_config}" _i)
endif()
endif()
if(_i LESS 0)
set(_curl_current_config "") # let CMake pick config at random
else()
set(_curl_current_config "_${_curl_current_config}")
endif()
get_target_property(CURL_INCLUDE_DIRS CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(CURL_LIBRARIES CURL::libcurl "LOCATION${_curl_current_config}")
set(_curl_current_config)
set(_curl_configurations)
set(_i)
endif()
endif()
unset(_curl_missing_components)

View File

@ -38,24 +38,24 @@
# To check:
# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
include(Utilities)
include(Macros)
include(CMakeDependentOption)
include(CheckCCompilerFlag)
project( CURL C )
project(CURL C)
message(WARNING "the curl cmake build system is poorly maintained. Be aware")
file (READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
string (REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
file(READ ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS)
string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
CURL_VERSION ${CURL_VERSION_H_CONTENTS})
string (REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
string (REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
string (REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
include_regular_expression("^.*$") # Sukender: Is it necessary?
@ -71,19 +71,19 @@ set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
set(OS "\"${CMAKE_SYSTEM_NAME}\"")
include_directories(${PROJECT_BINARY_DIR}/include/curl)
include_directories( ${CURL_SOURCE_DIR}/include )
include_directories(${CURL_SOURCE_DIR}/include)
option(CURL_WERROR "Turn compiler warnings into errors" OFF)
option(PICKY_COMPILER "Enable picky compiler options" ON)
option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
option(CURL_STATICLIB "Set to ON to build libcurl with static linking." OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
if(WIN32)
option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
option(ENABLE_INET_PTON "Set to OFF to prevent usage of inet_pton when building against modern SDKs while still requiring compatibility with older Windows versions, such as Windows XP, Windows Server 2003 etc." ON)
endif()
CMAKE_DEPENDENT_OPTION(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
ON "NOT ENABLE_ARES"
OFF)
@ -91,19 +91,19 @@ option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
if (PICKY_COMPILER)
foreach (_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers)
if(PICKY_COMPILER)
foreach(_CCOPT -pedantic -Wall -W -Wpointer-arith -Wwrite-strings -Wunused -Wshadow -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wundef -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wstrict-aliasing=3 -Wcast-align -Wtype-limits -Wold-style-declaration -Wmissing-parameter-type -Wempty-body -Wclobbered -Wignored-qualifiers -Wconversion -Wno-sign-conversion -Wvla -Wdouble-promotion -Wno-system-headers)
# surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
# test result in.
CHECK_C_COMPILER_FLAG(${_CCOPT} OPT${_CCOPT})
check_c_compiler_flag(${_CCOPT} OPT${_CCOPT})
if(OPT${_CCOPT})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_CCOPT}")
endif()
endforeach()
endif(PICKY_COMPILER)
endif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
endif()
endif()
if (ENABLE_DEBUG)
if(ENABLE_DEBUG)
# DEBUGBUILD will be defined only for Debug builds
if(NOT CMAKE_VERSION VERSION_LESS 3.0)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
@ -113,12 +113,14 @@ if (ENABLE_DEBUG)
set(ENABLE_CURLDEBUG ON)
endif()
if (ENABLE_CURLDEBUG)
if(ENABLE_CURLDEBUG)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
endif()
# For debug libs and exes, add "-d" postfix
set(CMAKE_DEBUG_POSTFIX "-d" CACHE STRING "Set debug library postfix")
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
set(CMAKE_DEBUG_POSTFIX "-d")
endif()
# initialize CURL_LIBS
set(CURL_LIBS "")
@ -126,7 +128,7 @@ set(CURL_LIBS "")
if(ENABLE_ARES)
set(USE_ARES 1)
find_package(CARES REQUIRED)
list(APPEND CURL_LIBS ${CARES_LIBRARY} )
list(APPEND CURL_LIBS ${CARES_LIBRARY})
set(CURL_LIBS ${CURL_LIBS} ${CARES_LIBRARY})
endif()
@ -203,10 +205,10 @@ if(ENABLE_IPV6 AND NOT WIN32)
endif()
endif()
CURL_NROFF_CHECK()
curl_nroff_check()
find_package(Perl)
CMAKE_DEPENDENT_OPTION(ENABLE_MANUAL "to provide the built-in manual"
cmake_dependent_option(ENABLE_MANUAL "to provide the built-in manual"
ON "NROFF_USEFUL;PERL_FOUND"
OFF)
@ -230,28 +232,28 @@ endif()
# Disable warnings on Borland to avoid changing 3rd party code.
if(BORLAND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
endif(BORLAND)
endif()
# If we are on AIX, do the _ALL_SOURCE magic
if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
set(_ALL_SOURCE 1)
endif(${CMAKE_SYSTEM_NAME} MATCHES AIX)
endif()
# Include all the necessary files for macros
include (CheckFunctionExists)
include (CheckIncludeFile)
include (CheckIncludeFiles)
include (CheckLibraryExists)
include (CheckSymbolExists)
include (CheckTypeSize)
include (CheckCSourceCompiles)
include (CMakeDependentOption)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(CheckTypeSize)
include(CheckCSourceCompiles)
include(CMakeDependentOption)
# On windows preload settings
if(WIN32)
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_WINSOCKAPI_=")
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
endif(WIN32)
endif()
if(ENABLE_THREADED_RESOLVER)
find_package(Threads REQUIRED)
@ -274,11 +276,11 @@ if(BEOS)
set(NOT_NEED_LIBNSL 1)
check_library_exists_concat("bind" gethostbyname HAVE_LIBBIND)
check_library_exists_concat("bnetapi" closesocket HAVE_LIBBNETAPI)
endif(BEOS)
endif()
if(NOT NOT_NEED_LIBNSL)
check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
endif(NOT NOT_NEED_LIBNSL)
endif()
check_function_exists(gethostname HAVE_GETHOSTNAME)
@ -307,14 +309,14 @@ if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
endif()
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ${openssl_default})
collect_true(enabled_ssl_options enabled_ssl_options_count
count_true(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.")
if(enabled_ssl_options_count GREATER "1")
set(CURL_WITH_MULTI_SSL ON)
endif()
if(CMAKE_USE_WINSSL)
@ -350,11 +352,10 @@ if(CMAKE_USE_OPENSSL)
set(USE_OPENSSL ON)
set(HAVE_LIBCRYPTO ON)
set(HAVE_LIBSSL ON)
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
include_directories(${OPENSSL_INCLUDE_DIR})
list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
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/rsa.h" HAVE_OPENSSL_RSA_H)
@ -474,7 +475,6 @@ if(NOT CURL_DISABLE_LDAP)
endif()
endif()
endif()
endif()
# No ldap, no ldaps.
@ -554,9 +554,8 @@ if(CMAKE_USE_LIBSSH2)
check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64)
check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
set(CMAKE_EXTRA_INCLUDE_FILES "")
endif(LIBSSH2_FOUND)
endif(CMAKE_USE_LIBSSH2)
endif()
endif()
option(CMAKE_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
mark_as_advanced(CMAKE_USE_GSSAPI)
@ -625,7 +624,6 @@ else()
unset(USE_UNIX_SOCKETS CACHE)
endif()
#
# CA handling
#
@ -637,67 +635,66 @@ set(CURL_CA_PATH "auto" CACHE STRING
"Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
if("${CURL_CA_BUNDLE}" STREQUAL "")
message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
elseif("${CURL_CA_BUNDLE}" STREQUAL "none")
unset(CURL_CA_BUNDLE CACHE)
unset(CURL_CA_BUNDLE CACHE)
elseif("${CURL_CA_BUNDLE}" STREQUAL "auto")
unset(CURL_CA_BUNDLE CACHE)
set(CURL_CA_BUNDLE_AUTODETECT TRUE)
unset(CURL_CA_BUNDLE CACHE)
set(CURL_CA_BUNDLE_AUTODETECT TRUE)
else()
set(CURL_CA_BUNDLE_SET TRUE)
set(CURL_CA_BUNDLE_SET TRUE)
endif()
if("${CURL_CA_PATH}" STREQUAL "")
message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.")
message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.")
elseif("${CURL_CA_PATH}" STREQUAL "none")
unset(CURL_CA_PATH CACHE)
unset(CURL_CA_PATH CACHE)
elseif("${CURL_CA_PATH}" STREQUAL "auto")
unset(CURL_CA_PATH CACHE)
set(CURL_CA_PATH_AUTODETECT TRUE)
unset(CURL_CA_PATH CACHE)
set(CURL_CA_PATH_AUTODETECT TRUE)
else()
set(CURL_CA_PATH_SET TRUE)
set(CURL_CA_PATH_SET TRUE)
endif()
if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT)
# Skip autodetection of unset CA path because CA bundle is set explicitly
# Skip autodetection of unset CA path because CA bundle is set explicitly
elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT)
# Skip autodetection of unset CA bundle because CA path is set explicitly
# Skip autodetection of unset CA bundle because CA path is set explicitly
elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
# first try autodetecting a CA bundle, then a CA path
# first try autodetecting a CA bundle, then a CA path
if(CURL_CA_BUNDLE_AUTODETECT)
set(SEARCH_CA_BUNDLE_PATHS
/etc/ssl/certs/ca-certificates.crt
/etc/pki/tls/certs/ca-bundle.crt
/usr/share/ssl/certs/ca-bundle.crt
/usr/local/share/certs/ca-root-nss.crt
/etc/ssl/cert.pem)
if(CURL_CA_BUNDLE_AUTODETECT)
set(SEARCH_CA_BUNDLE_PATHS
/etc/ssl/certs/ca-certificates.crt
/etc/pki/tls/certs/ca-bundle.crt
/usr/share/ssl/certs/ca-bundle.crt
/usr/local/share/certs/ca-root-nss.crt
/etc/ssl/cert.pem)
foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS})
if(EXISTS "${SEARCH_CA_BUNDLE_PATH}")
message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}")
set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}")
set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
break()
endif()
endforeach()
endif()
if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET))
if(EXISTS "/etc/ssl/certs")
set(CURL_CA_PATH "/etc/ssl/certs")
set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
endif()
foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS})
if(EXISTS "${SEARCH_CA_BUNDLE_PATH}")
message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}")
set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}")
set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
break()
endif()
endforeach()
endif()
if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET))
if(EXISTS "/etc/ssl/certs")
set(CURL_CA_PATH "/etc/ssl/certs")
set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
endif()
endif()
endif()
if(CURL_CA_PATH_SET AND NOT USE_OPENSSL AND NOT USE_MBEDTLS)
message(FATAL_ERROR
"CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
"Set CURL_CA_PATH=none or enable one of those TLS backends.")
message(FATAL_ERROR
"CA path only supported by OpenSSL, GnuTLS or mbed TLS. "
"Set CURL_CA_PATH=none or enable one of those TLS backends.")
endif()
# Check for header files
if(NOT UNIX)
check_include_file_concat("windows.h" HAVE_WINDOWS_H)
@ -707,7 +704,7 @@ if(NOT UNIX)
if(NOT CURL_WINDOWS_SSPI AND USE_OPENSSL)
set(CURL_LIBS ${CURL_LIBS} "crypt32")
endif()
endif(NOT UNIX)
endif()
check_include_file_concat("stdio.h" HAVE_STDIO_H)
check_include_file_concat("inttypes.h" HAVE_INTTYPES_H)
@ -790,17 +787,17 @@ check_type_size("time_t" SIZEOF_TIME_T)
if(NOT HAVE_SIZEOF_SSIZE_T)
if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
set(ssize_t long)
endif(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
endif()
if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
set(ssize_t __int64)
endif(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
endif(NOT HAVE_SIZEOF_SSIZE_T)
endif()
endif()
# off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
if(HAVE_SIZEOF_LONG_LONG)
set(HAVE_LONGLONG 1)
set(HAVE_LL 1)
endif(HAVE_SIZEOF_LONG_LONG)
endif()
find_file(RANDOM_FILE urandom /dev)
mark_as_advanced(RANDOM_FILE)
@ -832,7 +829,7 @@ check_symbol_exists(strncmpi "${CURL_INCLUDES}" HAVE_STRNCMPI)
check_symbol_exists(alarm "${CURL_INCLUDES}" HAVE_ALARM)
if(NOT HAVE_STRNCMPI)
set(HAVE_STRCMPI)
endif(NOT HAVE_STRNCMPI)
endif()
check_symbol_exists(gethostbyaddr "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR)
check_symbol_exists(gethostbyaddr_r "${CURL_INCLUDES}" HAVE_GETHOSTBYADDR_R)
check_symbol_exists(gettimeofday "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
@ -848,6 +845,7 @@ check_symbol_exists(sigsetjmp "${CURL_INCLUDES}" HAVE_SIGSETJMP)
check_symbol_exists(getpass_r "${CURL_INCLUDES}" HAVE_GETPASS_R)
check_symbol_exists(strlcat "${CURL_INCLUDES}" HAVE_STRLCAT)
check_symbol_exists(getpwuid "${CURL_INCLUDES}" HAVE_GETPWUID)
check_symbol_exists(getpwuid_r "${CURL_INCLUDES}" HAVE_GETPWUID_R)
check_symbol_exists(geteuid "${CURL_INCLUDES}" HAVE_GETEUID)
check_symbol_exists(utime "${CURL_INCLUDES}" HAVE_UTIME)
check_symbol_exists(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R)
@ -860,7 +858,7 @@ check_symbol_exists(signal "${CURL_INCLUDES}" HAVE_SIGNAL_FUNC)
check_symbol_exists(SIGALRM "${CURL_INCLUDES}" HAVE_SIGNAL_MACRO)
if(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
set(HAVE_SIGNAL 1)
endif(HAVE_SIGNAL_FUNC AND HAVE_SIGNAL_MACRO)
endif()
check_symbol_exists(uname "${CURL_INCLUDES}" HAVE_UNAME)
check_symbol_exists(strtoll "${CURL_INCLUDES}" HAVE_STRTOLL)
check_symbol_exists(_strtoi64 "${CURL_INCLUDES}" HAVE__STRTOI64)
@ -894,35 +892,35 @@ if(WIN32)
add_definitions(-D_WIN32_WINNT=0x0501)
endif()
else()
check_function_exists(inet_pton HAVE_INET_PTON)
check_function_exists(inet_pton HAVE_INET_PTON)
endif()
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)
curl_internal_test(${CURL_TEST})
endforeach()
endif()
# sigaction and sigsetjmp are special. Use special mechanism for
# detecting those, but only if previous attempt failed.
if(HAVE_SIGNAL_H)
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
endif(HAVE_SIGNAL_H)
endif()
if(NOT HAVE_SIGSETJMP)
if(HAVE_SETJMP_H)
check_symbol_exists(sigsetjmp "setjmp.h" HAVE_MACRO_SIGSETJMP)
if(HAVE_MACRO_SIGSETJMP)
set(HAVE_SIGSETJMP 1)
endif(HAVE_MACRO_SIGSETJMP)
endif(HAVE_SETJMP_H)
endif(NOT HAVE_SIGSETJMP)
endif()
endif()
endif()
# If there is no stricmp(), do not allow LDAP to parse URLs
if(NOT HAVE_STRICMP)
set(HAVE_LDAP_URL_PARSE 1)
endif(NOT HAVE_STRICMP)
endif()
# Do curl specific tests
foreach(CURL_TEST
@ -960,12 +958,12 @@ foreach(CURL_TEST
HAVE_FILE_OFFSET_BITS
)
curl_internal_test(${CURL_TEST})
endforeach(CURL_TEST)
endforeach()
if(HAVE_FILE_OFFSET_BITS)
set(_FILE_OFFSET_BITS 64)
set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
endif(HAVE_FILE_OFFSET_BITS)
endif()
check_type_size("off_t" SIZEOF_OFF_T)
# include this header to get the type
@ -980,8 +978,8 @@ foreach(CURL_TEST
HAVE_GLIBC_STRERROR_R
HAVE_POSIX_STRERROR_R
)
curl_internal_test_run(${CURL_TEST})
endforeach(CURL_TEST)
curl_internal_test(${CURL_TEST})
endforeach()
# Check for reentrant
foreach(CURL_TEST
@ -995,9 +993,9 @@ foreach(CURL_TEST
if(NOT ${CURL_TEST})
if(${CURL_TEST}_REENTRANT)
set(NEED_REENTRANT 1)
endif(${CURL_TEST}_REENTRANT)
endif(NOT ${CURL_TEST})
endforeach(CURL_TEST)
endif()
endif()
endforeach()
if(NEED_REENTRANT)
foreach(CURL_TEST
@ -1010,32 +1008,32 @@ if(NEED_REENTRANT)
set(${CURL_TEST} 0)
if(${CURL_TEST}_REENTRANT)
set(${CURL_TEST} 1)
endif(${CURL_TEST}_REENTRANT)
endforeach(CURL_TEST)
endif(NEED_REENTRANT)
endif()
endforeach()
endif()
if(HAVE_INET_NTOA_R_DECL_REENTRANT)
set(HAVE_INET_NTOA_R_DECL 1)
set(NEED_REENTRANT 1)
endif(HAVE_INET_NTOA_R_DECL_REENTRANT)
endif()
# Some other minor tests
if(NOT HAVE_IN_ADDR_T)
set(in_addr_t "unsigned long")
endif(NOT HAVE_IN_ADDR_T)
endif()
# Fix libz / zlib.h
if(NOT CURL_SPECIAL_LIBZ)
if(NOT HAVE_LIBZ)
set(HAVE_ZLIB_H 0)
endif(NOT HAVE_LIBZ)
endif()
if(NOT HAVE_ZLIB_H)
set(HAVE_LIBZ 0)
endif(NOT HAVE_ZLIB_H)
endif(NOT CURL_SPECIAL_LIBZ)
endif()
endif()
# Check for nonblocking
set(HAVE_DISABLED_NONBLOCKING 1)
@ -1044,16 +1042,13 @@ if(HAVE_FIONBIO OR
HAVE_IOCTLSOCKET_CASE OR
HAVE_O_NONBLOCK)
set(HAVE_DISABLED_NONBLOCKING)
endif(HAVE_FIONBIO OR
HAVE_IOCTLSOCKET OR
HAVE_IOCTLSOCKET_CASE OR
HAVE_O_NONBLOCK)
endif()
if(RETSIGTYPE_TEST)
set(RETSIGTYPE void)
else(RETSIGTYPE_TEST)
else()
set(RETSIGTYPE int)
endif(RETSIGTYPE_TEST)
endif()
if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
include(CheckCCompilerFlag)
@ -1063,13 +1058,13 @@ if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
if(MPRINTF_COMPILE_FLAGS)
set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
else(MPRINTF_COMPILE_FLAGS)
else()
set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
endif(MPRINTF_COMPILE_FLAGS)
endif()
set_source_files_properties(mprintf.c PROPERTIES
COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
endif(HAVE_C_FLAG_Wno_long_double)
endif(CMAKE_COMPILER_IS_GNUCC AND APPLE)
endif()
endif()
if(HAVE_SOCKLEN_T)
set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t")
@ -1104,19 +1099,25 @@ include(CMake/OtherTests.cmake)
add_definitions(-DHAVE_CONFIG_H)
# For windows, all compilers used by cmake should support large files
# For Windows, all compilers used by CMake should support large files
if(WIN32)
set(USE_WIN32_LARGE_FILES ON)
endif(WIN32)
# Use the manifest embedded in the Windows Resource
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST")
endif()
if(MSVC)
# Disable default manifest added by CMake
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
else(CMAKE_C_FLAGS MATCHES "/W[0-4]")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
endif(CMAKE_C_FLAGS MATCHES "/W[0-4]")
endif(MSVC)
endif()
endif()
if(CURL_WERROR)
if(MSVC_VERSION)
@ -1125,7 +1126,7 @@ if(CURL_WERROR)
# this assumes clang or gcc style options
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
endif()
endif(CURL_WERROR)
endif()
# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
@ -1144,9 +1145,9 @@ function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
endfunction()
if(WIN32 AND NOT CYGWIN)
set(CURL_INSTALL_CMAKE_DIR CMake)
set(CURL_INSTALL_CMAKE_DIR CMake)
else()
set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl)
set(CURL_INSTALL_CMAKE_DIR lib/cmake/curl)
endif()
if(USE_MANUAL)
@ -1246,11 +1247,12 @@ set(CONFIGURE_OPTIONS "")
# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
set(CPPFLAG_CURL_STATICLIB "")
set(CURLVERSION "${CURL_VERSION}")
set(ENABLE_SHARED "yes")
if(CURL_STATICLIB)
set(ENABLE_STATIC "yes")
else()
if(BUILD_SHARED_LIBS)
set(ENABLE_SHARED "yes")
set(ENABLE_STATIC "no")
else()
set(ENABLE_SHARED "no")
set(ENABLE_STATIC "yes")
endif()
set(exec_prefix "\${prefix}")
set(includedir "\${prefix}/include")
@ -1274,6 +1276,9 @@ set(REQUIRE_LIB_DEPS "no")
set(VERSIONNUM "${CURL_VERSION_NUM}")
# Finally generate a "curl-config" matching this config
# Use:
# * ENABLE_SHARED
# * ENABLE_STATIC
configure_file("${CURL_SOURCE_DIR}/curl-config.in"
"${CURL_BINARY_DIR}/curl-config" @ONLY)
install(FILES "${CURL_BINARY_DIR}/curl-config"
@ -1307,9 +1312,9 @@ write_basic_package_version_file(
COMPATIBILITY SameMajorVersion
)
configure_file(CMake/curl-config.cmake
configure_file(CMake/curl-config.cmake.in
"${PROJECT_BINARY_DIR}/curl-config.cmake"
COPYONLY
@ONLY
)
install(

View File

@ -691,6 +691,7 @@ typedef enum {
* CURLAUTH_NTLM - HTTP NTLM authentication
* CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
* CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
* CURLAUTH_BEARER - HTTP Bearer token authentication
* CURLAUTH_ONLY - Use together with a single other type to force no
* authentication or just that single type
* CURLAUTH_ANY - All fine types set
@ -708,6 +709,7 @@ typedef enum {
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
#define CURLAUTH_BEARER (((unsigned long)1)<<6)
#define CURLAUTH_ONLY (((unsigned long)1)<<31)
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
@ -1847,6 +1849,13 @@ typedef enum {
/* shuffle addresses before use when DNS returns multiple */
CINIT(DNS_SHUFFLE_ADDRESSES, LONG, 275),
/* Specify which TLS 1.3 ciphers suites to use */
CINIT(TLS13_CIPHERS, STRINGPOINT, 276),
CINIT(PROXY_TLS13_CIPHERS, STRINGPOINT, 277),
/* Disallow specifying username/login in URL. */
CINIT(DISALLOW_USERNAME_IN_URL, LONG, 278),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@ -2527,7 +2536,17 @@ typedef enum {
CURLINFO_SCHEME = CURLINFO_STRING + 49,
/* Fill in new entries below here! */
CURLINFO_LASTONE = 49
/* Preferably these would be defined conditionally based on the
sizeof curl_off_t being 64-bits */
CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50,
CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51,
CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52,
CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53,
CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54,
CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55,
CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56,
CURLINFO_LASTONE = 56
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
@ -2570,6 +2589,7 @@ typedef enum {
CURL_LOCK_DATA_DNS,
CURL_LOCK_DATA_SSL_SESSION,
CURL_LOCK_DATA_CONNECT,
CURL_LOCK_DATA_PSL,
CURL_LOCK_DATA_LAST
} curl_lock_data;

View File

@ -30,13 +30,13 @@
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.60.0-DEV"
#define LIBCURL_VERSION "7.61.1-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 60
#define LIBCURL_VERSION_PATCH 0
#define LIBCURL_VERSION_MINOR 61
#define LIBCURL_VERSION_PATCH 1
/* 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 0x073C00
#define LIBCURL_VERSION_NUM 0x073D01
/*
* This is the date and time when the full source package was created. The

View File

@ -320,6 +320,24 @@
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
#elif defined(__xlc__) /* IBM xlc compiler */
# if !defined(_LP64)
# define CURL_TYPEOF_CURL_OFF_T long long
# define CURL_FORMAT_CURL_OFF_T "lld"
# define CURL_FORMAT_CURL_OFF_TU "llu"
# define CURL_SUFFIX_CURL_OFF_T LL
# define CURL_SUFFIX_CURL_OFF_TU ULL
# else
# define CURL_TYPEOF_CURL_OFF_T long
# define CURL_FORMAT_CURL_OFF_T "ld"
# define CURL_FORMAT_CURL_OFF_TU "lu"
# define CURL_SUFFIX_CURL_OFF_T L
# define CURL_SUFFIX_CURL_OFF_TU UL
# endif
# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
# define CURL_PULL_SYS_TYPES_H 1
# define CURL_PULL_SYS_SOCKET_H 1
/* ===================================== */
/* KEEP MSVC THE PENULTIMATE ENTRY */
/* ===================================== */
@ -344,7 +362,7 @@
/* KEEP GENERIC GCC THE LAST ENTRY */
/* ===================================== */
#elif defined(__GNUC__)
#elif defined(__GNUC__) && !defined(_SCO_DS)
# if !defined(__LP64__) && \
(defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \
defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \

View File

@ -428,7 +428,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
* == or whatsoever.
*/
/* XXX: should evaluate to true iff expr is a pointer */
/* XXX: should evaluate to true if expr is a pointer */
#define _curl_is_any_ptr(expr) \
(sizeof(expr) == sizeof(void *))

View File

@ -1,5 +1,13 @@
set(LIB_NAME libcurl)
if(BUILD_SHARED_LIBS)
set(CURL_STATICLIB NO)
else()
set(CURL_STATICLIB YES)
endif()
# Use:
# * CURL_STATICLIB
configure_file(curl_config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
@ -59,28 +67,23 @@ if(USE_ARES)
include_directories(${CARES_INCLUDE_DIR})
endif()
if(CURL_STATICLIB)
# Static lib
set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC STATIC)
else()
# DLL / so dynamic lib
set(CURL_USER_DEFINED_DYNAMIC_OR_STATIC SHARED)
endif()
add_library(
${LIB_NAME}
${CURL_USER_DEFINED_DYNAMIC_OR_STATIC}
${HHEADERS} ${CSOURCES}
)
if(MSVC AND CURL_STATICLIB)
if(MSVC AND NOT BUILD_SHARED_LIBS)
set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
endif()
if(NOT BUILD_SHARED_LIBS)
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
endif()
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
if(WIN32)
add_definitions( -D_USRDLL )
add_definitions(-D_USRDLL)
endif()
set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
@ -95,21 +98,14 @@ set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
if(WIN32)
if(NOT CURL_STATICLIB)
if(BUILD_SHARED_LIBS)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
set_target_properties (${LIB_NAME} PROPERTIES
DEBUG_POSTFIX "-d"
# Note: no postfix for release variants, let user choose what style of release he wants
# MINSIZEREL_POSTFIX "-z"
# RELWITHDEBINFO_POSTFIX "-g"
)
endif()
endif()
target_include_directories(${LIB_NAME} INTERFACE
$<INSTALL_INTERFACE:include>)
$<INSTALL_INTERFACE:include>)
install(TARGETS ${LIB_NAME}
EXPORT libcurl-target

View File

@ -54,7 +54,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
@ -74,7 +74,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
curl_path.h curl_ctype.h curl_range.h
curl_path.h curl_ctype.h curl_range.h psl.h
LIB_RCFILES = libcurl.rc

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -312,22 +312,25 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
conn->async.os_specific;
CURLcode result = CURLE_OK;
*dns = NULL;
if(dns)
*dns = NULL;
waitperform(conn, 0);
if(res && !res->num_pending) {
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
/* temp_ai ownership is moved to the connection, so we need not free-up
them */
res->temp_ai = NULL;
if(dns) {
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
/* temp_ai ownership is moved to the connection, so we need not free-up
them */
res->temp_ai = NULL;
}
if(!conn->async.dns) {
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
else
else if(dns)
*dns = conn->async.dns;
destroy_async_data(&conn->async);
@ -390,7 +393,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
timeout_ms = 1000;
waitperform(conn, timeout_ms);
result = Curl_resolver_is_resolved(conn, &temp_entry);
result = Curl_resolver_is_resolved(conn, entry?&temp_entry:NULL);
if(result || conn->async.done)
break;
@ -472,17 +475,19 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
return;
res = (struct ResolverResults *)conn->async.os_specific;
res->num_pending--;
if(res) {
res->num_pending--;
if(CURL_ASYNC_SUCCESS == status) {
Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
if(ai) {
compound_results(res, ai);
if(CURL_ASYNC_SUCCESS == status) {
Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
if(ai) {
compound_results(res, ai);
}
}
/* A successful result overwrites any previous error */
if(res->last_status != ARES_SUCCESS)
res->last_status = status;
}
/* A successful result overwrites any previous error */
if(res->last_status != ARES_SUCCESS)
res->last_status = status;
}
/*

View File

@ -182,8 +182,6 @@ static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
return &(((struct thread_data *)conn->async.os_specific)->tsd);
}
#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
/* Destroy resolver thread synchronization data */
static
void destroy_thread_sync_data(struct thread_sync_data * tsd)
@ -481,8 +479,10 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
DEBUGASSERT(conn && td);
/* wait for the thread to resolve the name */
if(Curl_thread_join(&td->thread_hnd))
result = getaddrinfo_complete(conn);
if(Curl_thread_join(&td->thread_hnd)) {
if(entry)
result = getaddrinfo_complete(conn);
}
else
DEBUGASSERT(0);
@ -572,10 +572,10 @@ int Curl_resolver_getsock(struct connectdata *conn,
(void)socks;
(void)numsocks;
ms = Curl_timediff(Curl_now(), reslv->start);
if(ms < 10)
milli = ms/3;
if(ms < 3)
milli = 0;
else if(ms <= 50)
milli = 10;
milli = ms/3;
else if(ms <= 250)
milli = 50;
else

View File

@ -49,13 +49,12 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
unsigned long i, x = 0;
for(i = 0, s = src; i < 4; i++, s++) {
unsigned long v = 0;
if(*s == '=') {
x = (x << 6);
padding++;
}
else {
unsigned long v = 0;
p = base64;
while(*p && (*p != *s)) {

View File

@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2012 - 2018, 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
@ -63,10 +63,9 @@
static void conn_llist_dtor(void *user, void *element)
{
struct connectdata *data = element;
struct connectdata *conn = element;
(void)user;
data->bundle = NULL;
conn->bundle = NULL;
}
static CURLcode bundle_create(struct Curl_easy *data,
@ -96,14 +95,13 @@ static void bundle_destroy(struct connectbundle *cb_ptr)
}
/* Add a connection to a bundle */
static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
struct connectdata *conn)
static void bundle_add_conn(struct connectbundle *cb_ptr,
struct connectdata *conn)
{
Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
&conn->bundle_node);
conn->bundle = cb_ptr;
cb_ptr->num_connections++;
return CURLE_OK;
}
/* Remove a connection from a bundle */
@ -263,7 +261,7 @@ static void conncache_remove_bundle(struct conncache *connc,
CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn)
{
CURLcode result;
CURLcode result = CURLE_OK;
struct connectbundle *bundle;
struct connectbundle *new_bundle = NULL;
struct Curl_easy *data = conn->data;
@ -290,19 +288,13 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
bundle = new_bundle;
}
result = bundle_add_conn(bundle, conn);
if(result) {
if(new_bundle)
conncache_remove_bundle(data->state.conn_cache, new_bundle);
goto unlock;
}
bundle_add_conn(bundle, conn);
conn->connection_id = connc->next_connection_id++;
connc->num_conn++;
DEBUGF(infof(conn->data, "Added connection %ld. "
"The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
conn->connection_id, (curl_off_t) connc->num_conn));
"The cache now contains %zu members\n",
conn->connection_id, connc->num_conn));
unlock:
CONN_UNLOCK(data);
@ -320,7 +312,7 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
due to a failed connection attempt, before being added to a bundle */
if(bundle) {
if(lock) {
CONN_LOCK(conn->data);
CONN_LOCK(data);
}
bundle_remove_conn(bundle, conn);
if(bundle->num_connections == 0)
@ -328,12 +320,11 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
conn->bundle = NULL; /* removed from it */
if(connc) {
connc->num_conn--;
DEBUGF(infof(conn->data, "The cache now contains %"
CURL_FORMAT_CURL_OFF_TU " members\n",
(curl_off_t) connc->num_conn));
DEBUGF(infof(data, "The cache now contains %zu members\n",
connc->num_conn));
}
if(lock) {
CONN_UNLOCK(conn->data);
CONN_UNLOCK(data);
}
}
}
@ -441,18 +432,11 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
infof(data, "Connection cache is full, closing the oldest one.\n");
conn_candidate = Curl_conncache_extract_oldest(data);
if(conn_candidate) {
/* Set the connection's owner correctly */
conn_candidate->data = data;
/* the winner gets the honour of being disconnected */
(void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
(void)Curl_disconnect(data, conn_candidate, /* dead_connection */ FALSE);
}
}
CONN_LOCK(data);
conn->inuse = FALSE; /* Mark the connection unused */
CONN_UNLOCK(data);
return (conn_candidate == conn) ? FALSE : TRUE;
@ -486,7 +470,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
while(curr) {
conn = curr->ptr;
if(!conn->inuse) {
if(!CONN_INUSE(conn)) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->now);
@ -501,9 +485,9 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
/* remove it to prevent another thread from nicking it */
bundle_remove_conn(bundle, conn_candidate);
data->state.conn_cache->num_conn--;
DEBUGF(infof(data, "The cache now contains %"
CURL_FORMAT_CURL_OFF_TU " members\n",
(curl_off_t) data->state.conn_cache->num_conn));
DEBUGF(infof(data, "The cache now contains %zu members\n",
data->state.conn_cache->num_conn));
conn_candidate->data = data; /* associate! */
}
return conn_candidate;
@ -544,7 +528,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
while(curr) {
conn = curr->ptr;
if(!conn->inuse) {
if(!CONN_INUSE(conn)) {
/* Set higher score for the age passed since the connection was used */
score = Curl_timediff(now, conn->now);
@ -563,9 +547,9 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
/* remove it to prevent another thread from nicking it */
bundle_remove_conn(bundle_candidate, conn_candidate);
connc->num_conn--;
DEBUGF(infof(data, "The cache now contains %"
CURL_FORMAT_CURL_OFF_TU " members\n",
(curl_off_t) connc->num_conn));
DEBUGF(infof(data, "The cache now contains %zu members\n",
connc->num_conn));
conn_candidate->data = data; /* associate! */
}
CONN_UNLOCK(data);
@ -586,7 +570,7 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
pointer */
/* This will remove the connection from the cache */
connclose(conn, "kill all");
(void)Curl_disconnect(conn, FALSE);
(void)Curl_disconnect(connc->closure_handle, conn, FALSE);
sigpipe_restore(&pipe_st);
conn = Curl_conncache_find_first_connection(connc);

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2015 - 2018, 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
@ -63,7 +63,7 @@ size_t Curl_conncache_bundle_size(struct connectdata *conn);
bool Curl_conncache_return_conn(struct connectdata *conn);
CURLcode Curl_conncache_add_conn(struct conncache *connc,
struct connectdata *conn);
struct connectdata *conn) WARN_UNUSED_RESULT;
void Curl_conncache_remove_conn(struct connectdata *conn,
bool lock);
bool Curl_conncache_foreach(struct Curl_easy *data,

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -1237,8 +1237,6 @@ static int conn_is_conn(struct connectdata *conn, void *param)
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
struct connectdata **connp)
{
curl_socket_t sockfd;
DEBUGASSERT(data);
/* this works for an easy handle:
@ -1261,15 +1259,15 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
return CURL_SOCKET_BAD;
}
if(connp)
if(connp) {
/* only store this if the caller cares for it */
*connp = c;
sockfd = c->sock[FIRSTSOCKET];
c->data = data;
}
return c->sock[FIRSTSOCKET];
}
else
return CURL_SOCKET_BAD;
return sockfd;
}
/*

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -71,13 +71,13 @@
#define RESERVED 0xE0 /* bits 5..7: reserved */
typedef enum {
ZLIB_UNINIT, /* uninitialized */
ZLIB_INIT, /* initialized */
ZLIB_INFLATING, /* Inflating started. */
ZLIB_GZIP_HEADER, /* reading gzip header */
ZLIB_GZIP_TRAILER, /* reading gzip trailer */
ZLIB_GZIP_INFLATING, /* inflating gzip stream */
ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
ZLIB_UNINIT, /* uninitialized */
ZLIB_INIT, /* initialized */
ZLIB_INFLATING, /* inflating started. */
ZLIB_EXTERNAL_TRAILER, /* reading external trailer */
ZLIB_GZIP_HEADER, /* reading gzip header */
ZLIB_GZIP_INFLATING, /* inflating gzip stream */
ZLIB_INIT_GZIP /* initialized in transparent gzip mode */
} zlibInitState;
/* Writer parameters. */
@ -150,8 +150,8 @@ static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
if(result || !zp->trailerlen)
result = exit_zlib(conn, z, &zp->zlib_init, result);
else {
/* Only occurs for gzip with zlib < 1.2.0.4. */
zp->zlib_init = ZLIB_GZIP_TRAILER;
/* Only occurs for gzip with zlib < 1.2.0.4 or raw deflate. */
zp->zlib_init = ZLIB_EXTERNAL_TRAILER;
}
return result;
}
@ -163,7 +163,6 @@ static CURLcode inflate_stream(struct connectdata *conn,
z_stream *z = &zp->z; /* zlib state structure */
uInt nread = z->avail_in;
Bytef *orig_in = z->next_in;
int status; /* zlib status */
bool done = FALSE;
CURLcode result = CURLE_OK; /* Curl_client_write status */
char *decomp; /* Put the decompressed data here. */
@ -184,13 +183,20 @@ static CURLcode inflate_stream(struct connectdata *conn,
/* because the buffer size is fixed, iteratively decompress and transfer to
the client via downstream_write function. */
while(!done) {
int status; /* zlib status */
done = TRUE;
/* (re)set buffer for decompressed output for every iteration */
z->next_out = (Bytef *) decomp;
z->avail_out = DSIZ;
#ifdef Z_BLOCK
/* Z_BLOCK is only available in zlib ver. >= 1.2.0.5 */
status = inflate(z, Z_BLOCK);
#else
/* fallback for zlib ver. < 1.2.0.5 */
status = inflate(z, Z_SYNC_FLUSH);
#endif
/* Flush output data if some. */
if(z->avail_out != DSIZ) {
@ -227,6 +233,7 @@ static CURLcode inflate_stream(struct connectdata *conn,
z->next_in = orig_in;
z->avail_in = nread;
zp->zlib_init = ZLIB_INFLATING;
zp->trailerlen = 4; /* Tolerate up to 4 unknown trailer bytes. */
done = FALSE;
break;
}
@ -281,6 +288,9 @@ static CURLcode deflate_unencode_write(struct connectdata *conn,
z->next_in = (Bytef *) buf;
z->avail_in = (uInt) nbytes;
if(zp->zlib_init == ZLIB_EXTERNAL_TRAILER)
return process_trailer(conn, zp);
/* Now uncompress the data */
return inflate_stream(conn, writer, ZLIB_INFLATING);
}
@ -526,7 +536,7 @@ static CURLcode gzip_unencode_write(struct connectdata *conn,
}
break;
case ZLIB_GZIP_TRAILER:
case ZLIB_EXTERNAL_TRAILER:
z->next_in = (Bytef *) buf;
z->avail_in = (uInt) nbytes;
return process_trailer(conn, zp);
@ -755,7 +765,6 @@ char *Curl_all_content_encodings(void)
const content_encoding * const *cep;
const content_encoding *ce;
char *ace;
char *p;
for(cep = encodings; *cep; cep++) {
ce = *cep;
@ -768,7 +777,7 @@ char *Curl_all_content_encodings(void)
ace = malloc(len);
if(ace) {
p = ace;
char *p = ace;
for(cep = encodings; *cep; cep++) {
ce = *cep;
if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
@ -915,10 +924,9 @@ void Curl_unencode_cleanup(struct connectdata *conn)
static const content_encoding *find_encoding(const char *name, size_t len)
{
const content_encoding * const *cep;
const content_encoding *ce;
for(cep = encodings; *cep; cep++) {
ce = *cep;
const content_encoding *ce = *cep;
if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
(ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
return ce;

View File

@ -40,7 +40,7 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
received from a server.
The function need to replace previously stored lines that this new
line superceeds.
line supersedes.
It may remove lines that are expired.
@ -84,12 +84,9 @@ Example set of cookies:
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
#ifdef USE_LIBPSL
# include <libpsl.h>
#endif
#include "urldata.h"
#include "cookie.h"
#include "psl.h"
#include "strtok.h"
#include "sendf.h"
#include "slist.h"
@ -253,9 +250,9 @@ static const char *get_top_domain(const char * const domain, size_t *outlen)
len = strlen(domain);
last = memrchr(domain, '.', len);
if(last) {
first = memrchr(domain, '.', (size_t) (last - domain));
first = memrchr(domain, '.', (last - domain));
if(first)
len -= (size_t) (++first - domain);
len -= (++first - domain);
}
if(outlen)
@ -379,13 +376,13 @@ static void strstore(char **str, const char *newstr)
*/
static void remove_expired(struct CookieInfo *cookies)
{
struct Cookie *co, *nx, *pv;
struct Cookie *co, *nx;
curl_off_t now = (curl_off_t)time(NULL);
unsigned int i;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
struct Cookie *pv = NULL;
co = cookies->cookies[i];
pv = NULL;
while(co) {
nx = co->next;
if(co->expires && co->expires < now) {
@ -406,6 +403,12 @@ static void remove_expired(struct CookieInfo *cookies)
}
}
/* Make sure domain contains a dot or is localhost. */
static bool bad_domain(const char *domain)
{
return !strchr(domain, '.') && !strcasecompare(domain, "localhost");
}
/****************************************************************************
*
* Curl_cookie_add()
@ -442,10 +445,6 @@ Curl_cookie_add(struct Curl_easy *data,
bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
size_t myhash;
#ifdef USE_LIBPSL
const psl_ctx_t *psl;
#endif
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)data;
#endif
@ -497,7 +496,7 @@ Curl_cookie_add(struct Curl_easy *data,
name + contents. Chrome and Firefox support 4095 or 4096 bytes
combo. */
freecookie(co);
infof(data, "oversized cookie dropped, name/val %d + %d bytes\n",
infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n",
nlen, len);
return NULL;
}
@ -585,13 +584,8 @@ Curl_cookie_add(struct Curl_easy *data,
* 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 = ":";
}
if(bad_domain(whatptr))
domain = ":";
#endif
is_ip = isip(domain ? domain : whatptr);
@ -723,9 +717,9 @@ Curl_cookie_add(struct Curl_easy *data,
if(!queryp)
endslash = strrchr(path, '/');
else
endslash = memrchr(path, '/', (size_t)(queryp - path));
endslash = memrchr(path, '/', (queryp - path));
if(endslash) {
size_t pathlen = (size_t)(endslash-path + 1); /* include end slash */
size_t pathlen = (endslash-path + 1); /* include end slash */
co->path = malloc(pathlen + 1); /* one extra for the zero byte */
if(co->path) {
memcpy(co->path, path, pathlen);
@ -880,9 +874,10 @@ Curl_cookie_add(struct Curl_easy *data,
}
co->livecookie = c->running;
co->creationtime = ++c->lastct;
/* now, we have parsed the incoming line, we must now check if this
superceeds an already existing cookie, which it may if the previous have
supersedes an already existing cookie, which it may if the previous have
the same domain and path as this */
/* at first, remove expired cookies */
@ -890,14 +885,21 @@ Curl_cookie_add(struct Curl_easy *data,
remove_expired(c);
#ifdef USE_LIBPSL
/* Check if the domain is a Public Suffix and if yes, ignore the cookie.
This needs a libpsl compiled with builtin data. */
/* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
if(domain && co->domain && !isip(co->domain)) {
psl = psl_builtin();
if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
infof(data,
"cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n",
co->name, domain, co->domain);
const psl_ctx_t *psl = Curl_psl_use(data);
int acceptable;
if(psl) {
acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
Curl_psl_release(data);
}
else
acceptable = !bad_domain(domain);
if(!acceptable) {
infof(data, "cookie '%s' dropped, domain '%s' must not "
"set cookies for '%s'\n", co->name, domain, co->domain);
freecookie(co);
return NULL;
}
@ -951,6 +953,9 @@ Curl_cookie_add(struct Curl_easy *data,
if(replace_old) {
co->next = clist->next; /* get the next-pointer first */
/* when replacing, creationtime is kept from old */
co->creationtime = clist->creationtime;
/* then free all the old pointers */
free(clist->name);
free(clist->value);
@ -1140,12 +1145,24 @@ static int cookie_sort(const void *p1, const void *p2)
if(l1 != l2)
return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
/* 3 - compare cookie names */
if(c1->name && c2->name)
return strcmp(c1->name, c2->name);
/* 3 - compare cookie name lengths */
l1 = c1->name ? strlen(c1->name) : 0;
l2 = c2->name ? strlen(c2->name) : 0;
/* sorry, can't be more deterministic */
return 0;
if(l1 != l2)
return (l2 > l1) ? 1 : -1;
/* 4 - compare cookie creation time */
return (c2->creationtime > c1->creationtime) ? 1 : -1;
}
/* sort cookies only according to creation time */
static int cookie_sort_ct(const void *p1, const void *p2)
{
struct Cookie *c1 = *(struct Cookie **)p1;
struct Cookie *c2 = *(struct Cookie **)p2;
return (c2->creationtime > c1->creationtime) ? 1 : -1;
}
#define CLONE(field) \
@ -1174,6 +1191,7 @@ static struct Cookie *dup_cookie(struct Cookie *src)
d->secure = src->secure;
d->livecookie = src->livecookie;
d->httponly = src->httponly;
d->creationtime = src->creationtime;
}
return d;
@ -1384,9 +1402,8 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
****************************************************************************/
void Curl_cookie_cleanup(struct CookieInfo *c)
{
unsigned int i;
if(c) {
unsigned int i;
free(c->filename);
for(i = 0; i < COOKIE_HASH_SIZE; i++)
Curl_cookie_freelist(c->cookies[i]);
@ -1439,6 +1456,8 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
bool use_stdout = FALSE;
char *format_ptr;
unsigned int i;
unsigned int j;
struct Cookie **array;
if((NULL == c) || (0 == c->numcookies))
/* If there are no known cookies, we don't write or even create any
@ -1452,6 +1471,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
if(0 == c->numcookies)
return 0;
array = malloc(sizeof(struct Cookie *) * c->numcookies);
if(!array)
return 1;
if(!strcmp("-", dumphere)) {
/* use stdout */
out = stdout;
@ -1459,8 +1482,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
}
else {
out = fopen(dumphere, FOPEN_WRITETEXT);
if(!out)
if(!out) {
free(array);
return 1; /* failure */
}
}
fputs("# Netscape HTTP Cookie File\n"
@ -1468,22 +1493,33 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
"# This file was generated by libcurl! Edit at your own risk.\n\n",
out);
j = 0;
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
for(co = c->cookies[i]; co; co = co->next) {
if(!co->domain)
continue;
format_ptr = get_netscape_format(co);
if(format_ptr == NULL) {
fprintf(out, "#\n# Fatal libcurl error\n");
if(!use_stdout)
fclose(out);
return 1;
}
fprintf(out, "%s\n", format_ptr);
free(format_ptr);
array[j++] = co;
}
}
qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
for(i = 0; i < j; i++) {
format_ptr = get_netscape_format(array[i]);
if(format_ptr == NULL) {
fprintf(out, "#\n# Fatal libcurl error\n");
if(!use_stdout) {
free(array);
fclose(out);
}
return 1;
}
fprintf(out, "%s\n", format_ptr);
free(format_ptr);
}
free(array);
if(!use_stdout)
fclose(out);

View File

@ -34,7 +34,7 @@ struct Cookie {
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */
bool tailmatch; /* weather we do tail-matchning of the domain name */
bool tailmatch; /* whether we do tail-matching of the domain name */
/* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
char *version; /* Version = <value> */
@ -43,6 +43,7 @@ struct Cookie {
bool secure; /* whether the 'secure' keyword was used */
bool livecookie; /* updated from a server, not a stored file */
bool httponly; /* true if the httponly directive is present */
int creationtime; /* time when the cookie was written */
};
#define COOKIE_HASH_SIZE 256
@ -55,6 +56,7 @@ struct CookieInfo {
bool running; /* state info, for cookie adding information */
long numcookies; /* number of cookies in the "jar" */
bool newsession; /* new session, discard session cookies on load */
int lastct; /* last creation-time used in the jar */
};
/* This is the maximum line length we accept for a cookie line. RFC 2109

View File

@ -536,7 +536,8 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
}
#endif
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
defined(HAVE_FREEADDRINFO)
/*
* curl_dofreeaddrinfo()
*

View File

@ -235,6 +235,9 @@
/* Define to 1 if you have the `getpwuid' function. */
#cmakedefine HAVE_GETPWUID 1
/* Define to 1 if you have the `getpwuid_r' function. */
#cmakedefine HAVE_GETPWUID_R 1
/* Define to 1 if you have the `getrlimit' function. */
#cmakedefine HAVE_GETRLIMIT 1
@ -963,6 +966,9 @@
/* to enable Windows SSL */
#cmakedefine USE_SCHANNEL 1
/* enable multiple SSL backends */
#cmakedefine CURL_WITH_MULTI_SSL 1
/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
#cmakedefine USE_YASSLEMUL 1

View File

@ -30,6 +30,17 @@
/* The last #include file should be: */
#include "memdebug.h"
#ifndef HAVE_FNMATCH
/*
* TODO:
*
* Make this function match POSIX. Test 1307 includes a set of test patterns
* that returns different results with a POSIX fnmatch() than with this
* implementation and this is considered a bug where POSIX is the guiding
* light.
*/
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
@ -334,9 +345,9 @@ static int loop(const unsigned char *pattern, const unsigned char *string,
s++;
break;
}
/* Syntax error in set; mismatch! */
return CURL_FNMATCH_NOMATCH;
/* Syntax error in set: this must be taken as a regular character. */
/* FALLTHROUGH */
default:
if(*p++ != *s++)
return CURL_FNMATCH_NOMATCH;
@ -355,5 +366,31 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
if(!pattern || !string) {
return CURL_FNMATCH_FAIL;
}
return loop((unsigned char *)pattern, (unsigned char *)string, 5);
return loop((unsigned char *)pattern, (unsigned char *)string, 2);
}
#else
#include <fnmatch.h>
/*
* @unittest: 1307
*/
int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
{
int rc;
(void)ptr; /* the argument is specified by the curl_fnmatch_callback
prototype, but not used by Curl_fnmatch() */
if(!pattern || !string) {
return CURL_FNMATCH_FAIL;
}
rc = fnmatch(pattern, string, 0);
switch(rc) {
case 0:
return CURL_FNMATCH_MATCH;
case FNM_NOMATCH:
return CURL_FNMATCH_NOMATCH;
default:
return CURL_FNMATCH_FAIL;
}
/* not reached */
}
#endif

View File

@ -557,8 +557,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
unsigned char *ntbuffer /* 21 bytes */)
{
size_t len = strlen(password);
unsigned char *pw = len ? malloc(len * 2) : strdup("");
unsigned char *pw;
CURLcode result;
if(len > SIZE_T_MAX/2) /* avoid integer overflow */
return CURLE_OUT_OF_MEMORY;
pw = len ? malloc(len * 2) : strdup("");
if(!pw)
return CURLE_OUT_OF_MEMORY;

View File

@ -146,7 +146,6 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
const char *value, size_t len)
{
CURLcode result = CURLE_OK;
unsigned int mechbit;
size_t mechlen;
if(!len)
@ -160,7 +159,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
if(!strncmp(value, "*", len))
sasl->prefmech = SASL_AUTH_DEFAULT;
else {
mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
if(mechbit && mechlen == len)
sasl->prefmech |= mechbit;
else

View File

@ -217,7 +217,7 @@
/*
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
* interface doesnt support IPv4, but supports IPv6, NAT64, and DNS64,
* interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64,
* performing this task will result in a synthesized IPv6 address.
*/
#ifdef __APPLE__
@ -242,6 +242,7 @@
# if defined(_UNICODE) && !defined(UNICODE)
# define UNICODE
# endif
# include <winerror.h>
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
@ -800,4 +801,16 @@ endings either CRLF or LF so 't' is appropriate.
#define CURL_SA_FAMILY_T unsigned short
#endif
/* Some convenience macros to get the larger/smaller value out of two given.
We prefix with CURL to prevent name collisions. */
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
/* Some versions of the Android SDK is missing the declaration */
#if defined(HAVE_GETPWUID_R) && defined(HAVE_DECL_GETPWUID_R_MISSING)
struct passwd;
int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
size_t buflen, struct passwd **result);
#endif
#endif /* HEADER_CURL_SETUP_H */

View File

@ -108,7 +108,8 @@ curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
#ifdef _WIN32_WCE
t = CreateThread(NULL, 0, func, arg, 0, NULL);
#else
t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
uintptr_t thread_handle = _beginthreadex(NULL, 0, func, arg, 0, NULL);
t = (curl_thread_t)thread_handle;
#endif
if((t == 0) || (t == LongToHandle(-1L))) {
#ifdef _WIN32_WCE

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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,17 +95,17 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
{
char *newp = NULL;
char *dictp;
char *ptr;
size_t len;
char ch;
int olen = 0;
CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
if(!newp || result)
return NULL;
dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
dictp = malloc(len*2 + 1); /* add one for terminating zero */
if(dictp) {
char *ptr;
char ch;
int olen = 0;
/* According to RFC2229 section 2.2, these letters need to be escaped with
\[letter] */
for(ptr = newp;

View File

@ -113,7 +113,7 @@ static CURLcode win32_init(void)
res = WSAStartup(wVersionRequested, &wsaData);
if(res != 0)
/* Tell the user that we couldn't find a useable */
/* Tell the user that we couldn't find a usable */
/* winsock.dll. */
return CURLE_FAILED_INIT;
@ -125,7 +125,7 @@ static CURLcode win32_init(void)
if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
/* Tell the user that we couldn't find a useable */
/* Tell the user that we couldn't find a usable */
/* winsock.dll. */
WSACleanup();
@ -661,38 +661,27 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
bool done = FALSE;
CURLMcode mcode = CURLM_OK;
CURLcode result = CURLE_OK;
struct curltime before;
int without_fds = 0; /* count number of consecutive returns from
curl_multi_wait() without any filedescriptors */
while(!done && !mcode) {
int still_running = 0;
int rc;
before = Curl_now();
mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
if(!mcode) {
if(!rc) {
struct curltime after = Curl_now();
long sleep_ms;
/* If it returns without any filedescriptor instantly, we need to
avoid busy-looping during periods where it has nothing particular
to wait for */
if(Curl_timediff(after, before) <= 10) {
without_fds++;
if(without_fds > 2) {
int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
Curl_wait_ms(sleep_ms);
}
curl_multi_timeout(multi, &sleep_ms);
if(sleep_ms) {
if(sleep_ms > 1000)
sleep_ms = 1000;
Curl_wait_ms((int)sleep_ms);
}
else
/* it wasn't "instant", restart counter */
without_fds = 0;
}
else
/* got file descriptor, restart counter */
without_fds = 0;
mcode = curl_multi_perform(multi, &still_running);
}
@ -969,6 +958,13 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
outcurl->change.referer_alloc = TRUE;
}
/* Reinitialize an SSL engine for the new handle
* note: the engine name has already been copied by dupset */
if(outcurl->set.str[STRING_SSL_ENGINE]) {
if(Curl_ssl_set_engine(outcurl, outcurl->set.str[STRING_SSL_ENGINE]))
goto fail;
}
/* Clone the resolver handle, if present, for the new handle */
if(Curl_resolver_duphandle(&outcurl->state.resolver,
data->state.resolver))

View File

@ -82,7 +82,6 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
size_t alloc;
char *ns;
char *testing_ptr = NULL;
unsigned char in; /* we need to treat the characters unsigned */
size_t newlen;
size_t strindex = 0;
size_t length;
@ -100,7 +99,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
length = alloc-1;
while(length--) {
in = *string;
unsigned char in = *string; /* we need to treat the characters unsigned */
if(Curl_isunreserved(in))
/* just copy this */
@ -150,7 +149,6 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
{
size_t alloc = (length?length:strlen(string)) + 1;
char *ns = malloc(alloc);
unsigned char in;
size_t strindex = 0;
unsigned long hex;
CURLcode result;
@ -159,7 +157,7 @@ CURLcode Curl_urldecode(struct Curl_easy *data,
return CURLE_OUT_OF_MEMORY;
while(--alloc > 0) {
in = *string;
unsigned char in = *string;
if(('%' == in) && (alloc > 2) &&
ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */

View File

@ -256,8 +256,6 @@ static CURLcode file_upload(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
char *buf = data->state.buffer;
size_t nread;
size_t nwrite;
curl_off_t bytecount = 0;
struct_stat file_stat;
const char *buf2;
@ -306,7 +304,9 @@ static CURLcode file_upload(struct connectdata *conn)
}
while(!result) {
int readcount;
size_t nread;
size_t nwrite;
size_t readcount;
result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
if(result)
break;
@ -314,7 +314,7 @@ static CURLcode file_upload(struct connectdata *conn)
if(readcount <= 0) /* fix questionable compare error. curlvms */
break;
nread = (size_t)readcount;
nread = readcount;
/*skip bytes before resume point*/
if(data->state.resume_from) {
@ -378,7 +378,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
curl_off_t expected_size = 0;
bool size_known;
bool fstated = FALSE;
ssize_t nread;
struct Curl_easy *data = conn->data;
char *buf = data->state.buffer;
curl_off_t bytecount = 0;
@ -461,7 +460,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
return result;
/* Adjust the start offset in case we want to get the N last bytes
* of the stream iff the filesize could be determined */
* of the stream if the filesize could be determined */
if(data->state.resume_from < 0) {
if(!fstated) {
failf(data, "Can't get the size of file.");
@ -502,6 +501,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
while(!result) {
ssize_t nread;
/* Don't fill a whole buffer if we want less than all data */
size_t bytestoread;

View File

@ -39,16 +39,13 @@
#include "sendf.h"
#include "strdup.h"
#include "rand.h"
#include "warnless.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
/* What kind of Content-Type to use on un-specified files with unrecognized
extensions. */
#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
@ -305,7 +302,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
* Set the contents property.
*/
case CURLFORM_PTRCONTENTS:
current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
current_form->flags |= HTTPPOST_PTRCONTENTS;
/* FALLTHROUGH */
case CURLFORM_COPYCONTENTS:
if(current_form->value)
return_value = CURL_FORMADD_OPTION_TWICE;
@ -725,7 +723,7 @@ int curl_formget(struct curl_httppost *form, void *arg,
while(!result) {
char buffer[8192];
size_t nread = Curl_mime_read(buffer, 1, sizeof buffer, &toppart);
size_t nread = Curl_mime_read(buffer, 1, sizeof(buffer), &toppart);
if(!nread)
break;
@ -812,7 +810,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
{
CURLcode result = CURLE_OK;
curl_mime *form = NULL;
curl_mime *multipart;
curl_mimepart *part;
struct curl_httppost *file;
@ -831,7 +828,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
/* Process each top part. */
for(; !result && post; post = post->next) {
/* If we have more than a file here, create a mime subpart and fill it. */
multipart = form;
curl_mime *multipart = form;
if(post->more) {
part = curl_mime_addpart(form);
if(!part)
@ -883,7 +880,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
compatibility: use of "-" pseudo file name should be avoided. */
result = curl_mime_data_cb(part, (curl_off_t) -1,
(curl_read_callback) fread,
(curl_seek_callback) fseek,
CURLX_FUNCTION_CAST(curl_seek_callback,
fseek),
NULL, (void *) stdin);
}
else

View File

@ -239,8 +239,8 @@ static void close_secondarysocket(struct connectdata *conn)
static void freedirs(struct ftp_conn *ftpc)
{
int i;
if(ftpc->dirs) {
int i;
for(i = 0; i < ftpc->dirdepth; i++) {
free(ftpc->dirs[i]);
ftpc->dirs[i] = NULL;
@ -637,8 +637,6 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* line in a response or continue reading. */
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
time_t timeout; /* timeout in milliseconds */
time_t interval_ms;
struct Curl_easy *data = conn->data;
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
@ -657,7 +655,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
while(!*ftpcode && !result) {
/* check and reset timeout value every lap */
timeout = Curl_pp_state_timeout(pp);
time_t timeout = Curl_pp_state_timeout(pp); /* timeout in milliseconds */
time_t interval_ms;
if(timeout <= 0) {
failf(data, "FTP response timeout");
@ -1589,7 +1588,6 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
struct FTP *ftp = conn->data->req.protop;
struct Curl_easy *data = conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
int seekerr = CURL_SEEKFUNC_OK;
if((data->state.resume_from && !sizechecked) ||
((data->state.resume_from > 0) && sizechecked)) {
@ -1605,6 +1603,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
/* 3. pass file-size number of bytes in the source file */
/* 4. lower the infilesize counter */
/* => transfer as usual */
int seekerr = CURL_SEEKFUNC_OK;
if(data->state.resume_from < 0) {
/* Got no given size to start from, figure it out */
@ -2782,7 +2781,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
char *ptr = &data->state.buffer[4]; /* start on the first letter */
const size_t buf_size = data->set.buffer_size;
char *dir;
char *store;
bool entry_extracted = FALSE;
dir = malloc(nread + 1);
@ -2805,6 +2803,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if('\"' == *ptr) {
/* it started good */
char *store;
ptr++;
for(store = dir; *ptr;) {
if('\"' == *ptr) {
@ -3992,8 +3991,7 @@ CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
break;
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
sptr, (size_t)bytes_written, conn);
Curl_debug(conn->data, CURLINFO_HEADER_OUT, sptr, (size_t)bytes_written);
if(bytes_written != (ssize_t)write_len) {
write_len -= bytes_written;
@ -4384,7 +4382,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
{
struct Curl_easy *data = conn->data;
char *type;
char command;
struct FTP *ftp;
conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
@ -4402,6 +4399,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
type = strstr(conn->host.rawalloc, ";type=");
if(type) {
char command;
*type = 0; /* it was in the middle of the hostname */
command = Curl_raw_toupper(type[6]);
conn->bits.type_set = TRUE;

View File

@ -281,6 +281,28 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
*param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
data->progress.size_ul:-1;
break;
case CURLINFO_TOTAL_TIME_T:
*param_offt = data->progress.timespent;
break;
case CURLINFO_NAMELOOKUP_TIME_T:
*param_offt = data->progress.t_nslookup;
break;
case CURLINFO_CONNECT_TIME_T:
*param_offt = data->progress.t_connect;
break;
case CURLINFO_APPCONNECT_TIME_T:
*param_offt = data->progress.t_appconnect;
break;
case CURLINFO_PRETRANSFER_TIME_T:
*param_offt = data->progress.t_pretransfer;
break;
case CURLINFO_STARTTRANSFER_TIME_T:
*param_offt = data->progress.t_starttransfer;
break;
case CURLINFO_REDIRECT_TIME_T:
*param_offt = data->progress.t_redirect;
break;
default:
return CURLE_UNKNOWN_OPTION;
}

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -89,22 +89,15 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
/* Create selector. Degenerate cases: / and /1 => convert to "" */
if(strlen(path) <= 2) {
sel = (char *)"";
len = (int)strlen(sel);
len = strlen(sel);
}
else {
char *newp;
size_t j, i;
/* Otherwise, drop / and the first character (i.e., item type) ... */
newp = path;
newp += 2;
/* ... then turn ? into TAB for search servers, Veronica, etc. ... */
j = strlen(newp);
for(i = 0; i<j; i++)
if(newp[i] == '?')
newp[i] = '\x09';
/* ... and finally unescape */
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
if(result)

View File

@ -60,8 +60,6 @@ Curl_hash_init(struct curl_hash *h,
comp_function comparator,
curl_hash_dtor dtor)
{
int i;
if(!slots || !hfunc || !comparator ||!dtor) {
return 1; /* failure */
}
@ -74,6 +72,7 @@ Curl_hash_init(struct curl_hash *h,
h->table = malloc(slots * sizeof(struct curl_llist));
if(h->table) {
int i;
for(i = 0; i < slots; ++i)
Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
return 0; /* fine */
@ -140,11 +139,10 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
{
struct curl_llist_element *le;
struct curl_hash_element *he;
struct curl_llist *l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
he = le->ptr;
struct curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
Curl_llist_remove(l, le, (void *) h);
--h->size;
@ -162,13 +160,12 @@ void *
Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
{
struct curl_llist_element *le;
struct curl_hash_element *he;
struct curl_llist *l;
if(h) {
l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
he = le->ptr;
struct curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
return he->ptr;
}
@ -291,7 +288,6 @@ void Curl_hash_start_iterate(struct curl_hash *hash,
struct curl_hash_element *
Curl_hash_next_element(struct curl_hash_iterator *iter)
{
int i;
struct curl_hash *h = iter->hash;
/* Get the next element in the current list, if any */
@ -300,6 +296,7 @@ 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) {
int i;
for(i = iter->slot_index; i < h->slots; i++) {
if(h->table[i].head) {
iter->current_element = h->table[i].head;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -58,7 +58,7 @@ Curl_HMAC_init(const HMAC_params * hashparams,
unsigned char b;
/* Create HMAC context. */
i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize +
hashparams->hmac_resultlen;
ctxt = malloc(i);

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -131,7 +131,7 @@ CURLcode Curl_async_resolved(struct connectdata *conn,
if(result)
/* We're not allowed to return failure with memory left allocated
in the connectdata struct, free those here */
Curl_disconnect(conn, FALSE); /* close the connection */
Curl_disconnect(conn->data, conn, TRUE); /* close the connection */
return result;
}

View File

@ -907,7 +907,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
char *entry_id;
size_t entry_len;
char address[64];
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
char *addresses = NULL;
#endif
char *addr_begin;
char *addr_end;
char *port_ptr;
@ -930,7 +932,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
goto err;
port = (int)tmp_port;
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
addresses = end_ptr + 1;
#endif
while(*end_ptr) {
size_t alen;
@ -1010,24 +1014,28 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
/* See if its already in our dns cache */
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
if(dns) {
infof(data, "RESOLVE %s:%d is - old addresses discarded!\n",
hostname, port);
/* delete old entry entry, there are two reasons for this
1. old entry may have different addresses.
2. even if entry with correct addresses is already in the cache,
but if it is close to expire, then by the time next http
request is made, it can get expired and pruned because old
entry is not necessarily marked as added by CURLOPT_RESOLVE. */
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
}
/* free the allocated entry_id again */
free(entry_id);
if(!dns) {
/* if not in the cache already, put this host in the cache */
dns = Curl_cache_addr(data, head, hostname, port);
if(dns) {
dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
/* release the returned reference; the cache itself will keep the
* entry alive: */
dns->inuse--;
}
}
else {
/* this is a duplicate, free it again */
infof(data, "RESOLVE %s:%d is already cached, %s not stored!\n",
hostname, port, addresses);
Curl_freeaddrinfo(head);
/* put this new host in the cache */
dns = Curl_cache_addr(data, head, hostname, port);
if(dns) {
dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
/* release the returned reference; the cache itself will keep the
* entry alive: */
dns->inuse--;
}
if(data->share)

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -59,39 +59,6 @@
#include "curl_memory.h"
#include "memdebug.h"
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
/* These are strictly for memory tracing and are using the same style as the
* family otherwise present in memdebug.c. I put these ones here since they
* require a bunch of structs I didn't want to include in memdebug.c
*/
/*
* For CURLRES_ARS, this should be written using ares_gethostbyaddr()
* (ignoring the fact c-ares doesn't return 'serv').
*/
int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
GETNAMEINFO_TYPE_ARG2 salen,
char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
GETNAMEINFO_TYPE_ARG7 flags,
int line, const char *source)
{
int res = (getnameinfo)(sa, salen,
host, hostlen,
serv, servlen,
flags);
if(0 == res)
/* success */
curl_memlog("GETNAME %s:%d getnameinfo()\n",
source, line);
else
curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
source, line, res);
return res;
}
#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
/*
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
*/

View File

@ -158,18 +158,20 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
during this request */
struct HTTP *http;
DEBUGASSERT(conn->data->req.protop == NULL);
struct Curl_easy *data = conn->data;
DEBUGASSERT(data->req.protop == NULL);
http = calloc(1, sizeof(struct HTTP));
if(!http)
return CURLE_OUT_OF_MEMORY;
Curl_mime_initpart(&http->form, conn->data);
conn->data->req.protop = http;
Curl_http2_setup_conn(conn);
Curl_http2_setup_req(conn->data);
data->req.protop = http;
if(!CONN_INUSE(conn))
/* if not alredy multi-using, setup connection details */
Curl_http2_setup_conn(conn);
Curl_http2_setup_req(data);
return CURLE_OK;
}
@ -310,22 +312,49 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
return result;
}
/*
* http_output_bearer() sets up an Authorization: header
* for HTTP Bearer authentication.
*
* Returns CURLcode.
*/
static CURLcode http_output_bearer(struct connectdata *conn)
{
char **userp;
CURLcode result = CURLE_OK;
userp = &conn->allocptr.userpwd;
free(*userp);
*userp = aprintf("Authorization: Bearer %s\r\n",
conn->oauth_bearer);
if(!*userp) {
result = CURLE_OUT_OF_MEMORY;
goto fail;
}
fail:
return result;
}
/* pickoneauth() selects the most favourable authentication method from the
* ones available and the ones we want.
*
* return TRUE if one was picked
*/
static bool pickoneauth(struct auth *pick)
static bool pickoneauth(struct auth *pick, unsigned long mask)
{
bool picked;
/* only deal with authentication we want */
unsigned long avail = pick->avail & pick->want;
unsigned long avail = pick->avail & pick->want & mask;
picked = TRUE;
/* The order of these checks is highly relevant, as this will be the order
of preference in case of the existence of multiple accepted types. */
if(avail & CURLAUTH_NEGOTIATE)
pick->picked = CURLAUTH_NEGOTIATE;
else if(avail & CURLAUTH_BEARER)
pick->picked = CURLAUTH_BEARER;
else if(avail & CURLAUTH_DIGEST)
pick->picked = CURLAUTH_DIGEST;
else if(avail & CURLAUTH_NTLM)
@ -479,6 +508,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
bool pickhost = FALSE;
bool pickproxy = FALSE;
CURLcode result = CURLE_OK;
unsigned long authmask = ~0ul;
if(!conn->oauth_bearer)
authmask &= (unsigned long)~CURLAUTH_BEARER;
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
/* this is a transient response code, ignore */
@ -487,17 +520,18 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(data->state.authproblem)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
if(conn->bits.user_passwd &&
if((conn->bits.user_passwd || conn->oauth_bearer) &&
((data->req.httpcode == 401) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
pickhost = pickoneauth(&data->state.authhost);
pickhost = pickoneauth(&data->state.authhost, authmask);
if(!pickhost)
data->state.authproblem = TRUE;
}
if(conn->bits.proxy_user_passwd &&
((data->req.httpcode == 407) ||
(conn->bits.authneg && data->req.httpcode < 300))) {
pickproxy = pickoneauth(&data->state.authproxy);
pickproxy = pickoneauth(&data->state.authproxy,
authmask & ~CURLAUTH_BEARER);
if(!pickproxy)
data->state.authproblem = TRUE;
}
@ -628,6 +662,20 @@ output_auth_headers(struct connectdata *conn,
functions work that way */
authstatus->done = TRUE;
}
if(authstatus->picked == CURLAUTH_BEARER) {
/* Bearer */
if((!proxy && conn->oauth_bearer &&
!Curl_checkheaders(conn, "Authorization:"))) {
auth = "Bearer";
result = http_output_bearer(conn);
if(result)
return result;
}
/* NOTE: this function should set 'done' TRUE, as the other auth
functions work that way */
authstatus->done = TRUE;
}
if(auth) {
infof(data, "%s auth using %s with user '%s'\n",
@ -674,7 +722,7 @@ Curl_http_output_auth(struct connectdata *conn,
authproxy = &data->state.authproxy;
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
conn->bits.user_passwd)
conn->bits.user_passwd || conn->oauth_bearer)
/* continue please */;
else {
authhost->done = TRUE;
@ -883,6 +931,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
data->state.authproblem = TRUE;
}
}
else
if(checkprefix("Bearer", auth)) {
*availp |= CURLAUTH_BEARER;
authp->avail |= CURLAUTH_BEARER;
if(authp->picked == CURLAUTH_BEARER) {
/* We asked for Bearer authentication but got a 40X back
anyway, which basically means our token isn't valid. */
authp->avail = CURLAUTH_NONE;
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
}
/* there may be multiple methods on one line, so keep reading */
while(*auth && *auth != ',') /* read up to the next comma */
@ -1063,7 +1123,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
CURLcode result;
char *ptr;
size_t size;
struct HTTP *http = conn->data->req.protop;
struct Curl_easy *data = conn->data;
struct HTTP *http = data->req.protop;
size_t sendsize;
curl_socket_t sockfd;
size_t headersize;
@ -1083,7 +1144,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
DEBUGASSERT(size > included_body_bytes);
result = Curl_convert_to_network(conn->data, ptr, headersize);
result = Curl_convert_to_network(data, ptr, headersize);
/* Curl_convert_to_network calls failf if unsuccessful */
if(result) {
/* conversion failed, free memory and return to the caller */
@ -1108,8 +1169,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
must copy the data to the uploadbuffer first, since that is the buffer
we will be using if this send is retried later.
*/
memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
ptr = conn->data->state.uploadbuffer;
result = Curl_get_upload_buffer(data);
if(result) {
/* malloc failed, free memory and return to the caller */
Curl_add_buffer_free(in);
return result;
}
memcpy(data->state.ulbuf, ptr, sendsize);
ptr = data->state.ulbuf;
}
else
sendsize = size;
@ -1126,14 +1193,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
size_t bodylen = amount - headlen;
if(conn->data->set.verbose) {
if(data->set.verbose) {
/* this data _may_ contain binary stuff */
Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
if(bodylen) {
/* there was body data sent beyond the initial header part, pass that
on to the debug callback too */
Curl_debug(conn->data, CURLINFO_DATA_OUT,
ptr + headlen, bodylen, conn);
Curl_debug(data, CURLINFO_DATA_OUT,
ptr + headlen, bodylen);
}
}
@ -1157,14 +1224,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
ptr = in->buffer + amount;
/* backup the currently set pointers */
http->backup.fread_func = conn->data->state.fread_func;
http->backup.fread_in = conn->data->state.in;
http->backup.fread_func = data->state.fread_func;
http->backup.fread_in = data->state.in;
http->backup.postdata = http->postdata;
http->backup.postsize = http->postsize;
/* set the new pointers for the request-sending */
conn->data->state.fread_func = (curl_read_callback)readmoredata;
conn->data->state.in = (void *)conn;
data->state.fread_func = (curl_read_callback)readmoredata;
data->state.in = (void *)conn;
http->postdata = ptr;
http->postsize = (curl_off_t)size;
@ -1223,7 +1290,6 @@ CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
{
char *new_rb;
size_t new_size;
if(~size < in->size_used) {
/* If resulting used size of send buffer would wrap size_t, cleanup
@ -1236,10 +1302,10 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
if(!in->buffer ||
((in->size_used + size) > (in->size_max - 1))) {
/* If current buffer size isn't enough to hold the result, use a
buffer size that doubles the required size. If this new size
would wrap size_t, then just use the largest possible one */
size_t new_size;
if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
(~(size * 2) < (in->size_used * 2)))
@ -1406,7 +1472,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
}
snprintf(proxy_header,
sizeof proxy_header,
sizeof(proxy_header),
"PROXY %s %s %s %li %li\r\n",
tcp_version,
conn->data->info.conn_local_ip,
@ -1574,7 +1640,6 @@ static CURLcode expect100(struct Curl_easy *data,
Curl_send_buffer *req_buffer)
{
CURLcode result = CURLE_OK;
const char *ptr;
data->state.expect100header = FALSE; /* default to false unless it is set
to TRUE below */
if(use_http_1_1plus(data, conn) &&
@ -1582,7 +1647,7 @@ static CURLcode expect100(struct Curl_easy *data,
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
Expect: 100-continue to the headers which actually speeds up post
operations (as there is one packet coming back from the web server) */
ptr = Curl_checkheaders(conn, "Expect");
const char *ptr = Curl_checkheaders(conn, "Expect");
if(ptr) {
data->state.expect100header =
Curl_compareheader(ptr, "Expect:", "100-continue");
@ -1819,7 +1884,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
const char *httpstring;
Curl_send_buffer *req_buffer;
curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
int seekerr = CURL_SEEKFUNC_CANTSEEK;
/* Always consider the DO phase done after this function call, even if there
may be parts of the request that is not yet sent, since we can deal with
@ -1863,6 +1927,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
http = data->req.protop;
DEBUGASSERT(http);
if(!data->state.this_is_a_follow) {
/* Free to avoid leaking memory on multiple requests*/
@ -2088,7 +2153,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
else {
/* If the host begins with '[', we start searching for the port after
the bracket has been closed */
int startsearch = 0;
if(*cookiehost == '[') {
char *closingbracket;
/* since the 'cookiehost' is an allocated memory area that will be
@ -2099,6 +2163,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
*closingbracket = 0;
}
else {
int startsearch = 0;
char *colon = strchr(cookiehost + startsearch, ':');
if(colon)
*colon = 0; /* The host must not include an embedded port number */
@ -2244,6 +2309,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* Now, let's read off the proper amount of bytes from the
input. */
int seekerr = CURL_SEEKFUNC_CANTSEEK;
if(conn->seek_func) {
Curl_set_in_callback(data, true);
seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
@ -2828,6 +2894,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
}
else
data->req.writebytecount = http->writebytecount;
}
if((conn->httpversion == 20) && data->req.upload_chunky)
@ -2838,17 +2906,32 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
typedef enum {
STATUS_UNKNOWN, /* not enough data to tell yet */
STATUS_DONE, /* a status line was read */
STATUS_BAD /* not a status line */
} statusline;
/* Check a string for a prefix. Check no more than 'len' bytes */
static bool checkprefixmax(const char *prefix, const char *buffer, size_t len)
{
size_t ch = CURLMIN(strlen(prefix), len);
return curl_strnequal(prefix, buffer, ch);
}
/*
* checkhttpprefix()
*
* Returns TRUE if member of the list matches prefix of string
*/
static bool
static statusline
checkhttpprefix(struct Curl_easy *data,
const char *s)
const char *s, size_t len)
{
struct curl_slist *head = data->set.http200aliases;
bool rc = FALSE;
statusline rc = STATUS_BAD;
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
char *scratch = strdup(s);
@ -2865,15 +2948,15 @@ checkhttpprefix(struct Curl_easy *data,
#endif /* CURL_DOES_CONVERSIONS */
while(head) {
if(checkprefix(head->data, s)) {
rc = TRUE;
if(checkprefixmax(head->data, s, len)) {
rc = onmatch;
break;
}
head = head->next;
}
if(!rc && (checkprefix("HTTP/", s)))
rc = TRUE;
if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
rc = onmatch;
#ifdef CURL_DOES_CONVERSIONS
free(scratch);
@ -2882,11 +2965,12 @@ checkhttpprefix(struct Curl_easy *data,
}
#ifndef CURL_DISABLE_RTSP
static bool
static statusline
checkrtspprefix(struct Curl_easy *data,
const char *s)
const char *s, size_t len)
{
bool result = FALSE;
statusline result = STATUS_BAD;
statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
#ifdef CURL_DOES_CONVERSIONS
/* convert from the network encoding using a scratch area */
@ -2899,30 +2983,31 @@ checkrtspprefix(struct Curl_easy *data,
/* Curl_convert_from_network calls failf if unsuccessful */
result = FALSE; /* can't return CURLE_foobar so return FALSE */
}
else
result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
else if(checkprefixmax("RTSP/", scratch, len))
result = onmatch;
free(scratch);
#else
(void)data; /* unused */
result = checkprefix("RTSP/", s)? TRUE: FALSE;
if(checkprefixmax("RTSP/", s, len))
result = onmatch;
#endif /* CURL_DOES_CONVERSIONS */
return result;
}
#endif /* CURL_DISABLE_RTSP */
static bool
static statusline
checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
const char *s)
const char *s, size_t len)
{
#ifndef CURL_DISABLE_RTSP
if(conn->handler->protocol & CURLPROTO_RTSP)
return checkrtspprefix(data, s);
return checkrtspprefix(data, s, len);
#else
(void)conn;
#endif /* CURL_DISABLE_RTSP */
return checkhttpprefix(data, s);
return checkhttpprefix(data, s, len);
}
/*
@ -2939,7 +3024,7 @@ static CURLcode header_append(struct Curl_easy *data,
/* The reason to have a max limit for this is to avoid the risk of a bad
server feeding libcurl with a never-ending header that will cause
reallocs infinitely */
failf(data, "Rejected %zd bytes header (max is %d)!", newsize,
failf(data, "Rejected %zu bytes header (max is %d)!", newsize,
CURL_MAX_HTTP_HEADER);
return CURLE_OUT_OF_MEMORY;
}
@ -3036,12 +3121,15 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(result)
return result;
if(!k->headerline && (k->hbuflen>5)) {
/* make a first check that this looks like a protocol header */
if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
if(!k->headerline) {
/* check if this looks like a protocol header */
statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
k->hbuflen);
if(st == STATUS_BAD) {
/* this is not the beginning of a protocol first header line */
k->header = FALSE;
k->badheader = HEADER_ALLBAD;
streamclose(conn, "bad HTTP: No end-of-message indicator");
break;
}
}
@ -3070,8 +3158,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(!k->headerline) {
/* the first read header */
if((k->hbuflen>5) &&
!checkprotoprefix(data, conn, data->state.headerbuff)) {
statusline st = checkprotoprefix(data, conn, data->state.headerbuff,
k->hbuflen);
if(st == STATUS_BAD) {
streamclose(conn, "bad HTTP: No end-of-message indicator");
/* this is not the beginning of a protocol first header line */
k->header = FALSE;
if(*nread)
@ -3354,7 +3444,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
k->str_start, headerlen, conn);
k->str_start, headerlen);
break; /* exit header line loop */
}
@ -3440,7 +3530,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
compare header line against list of aliases
*/
if(!nc) {
if(checkhttpprefix(data, k->p)) {
if(checkhttpprefix(data, k->p, k->hbuflen) == STATUS_DONE) {
nc = 1;
k->httpcode = 200;
conn->httpversion = 10;
@ -3487,21 +3577,18 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* depending on how authentication is working. Other codes
* are definitely errors, so give up here.
*/
if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
if(data->state.resume_from && data->set.httpreq == HTTPREQ_GET &&
k->httpcode == 416) {
/* "Requested Range Not Satisfiable", just proceed and
pretend this is no error */
k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
}
else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
((k->httpcode != 401) || !conn->bits.user_passwd) &&
((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
if(data->state.resume_from &&
(data->set.httpreq == HTTPREQ_GET) &&
(k->httpcode == 416)) {
/* "Requested Range Not Satisfiable", just proceed and
pretend this is no error */
}
else {
/* serious error, go home! */
print_http_error(data);
return CURLE_HTTP_RETURNED_ERROR;
}
/* serious error, go home! */
print_http_error(data);
return CURLE_HTTP_RETURNED_ERROR;
}
if(conn->httpversion == 10) {
@ -3812,8 +3899,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
writetype |= CLIENTWRITE_BODY;
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
k->p, (size_t)k->hbuflen, conn);
Curl_debug(data, CURLINFO_HEADER_IN, k->p, (size_t)k->hbuflen);
result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
if(result)

View File

@ -42,7 +42,6 @@
#include "memdebug.h"
#define H2_BUFSIZE 32768
#define MIN(x,y) ((x)<(y)?(x):(y))
#if (NGHTTP2_VERSION_NUM < 0x010000)
#error too old nghttp2 version, upgrade!
@ -154,6 +153,11 @@ static void http2_stream_free(struct HTTP *http)
}
}
/*
* Disconnects *a* connection used for HTTP/2. It might be an old one from the
* connection cache and not the "main" one. Don't touch the easy handle!
*/
static CURLcode http2_disconnect(struct connectdata *conn,
bool dead_connection)
{
@ -164,8 +168,6 @@ static CURLcode http2_disconnect(struct connectdata *conn,
nghttp2_session_del(c->h2);
Curl_safefree(c->inbuf);
http2_stream_free(conn->data->req.protop);
conn->data->state.drain = 0;
H2BUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
@ -345,7 +347,7 @@ const char *Curl_http2_strerror(uint32_t err)
"INADEQUATE_SECURITY", /* 0xC */
"HTTP_1_1_REQUIRED" /* 0xD */
};
return (err < sizeof str / sizeof str[0]) ? str[err] : "unknown";
return (err < sizeof(str) / sizeof(str[0])) ? str[err] : "unknown";
#else
return nghttp2_http2_strerror(err);
#endif
@ -368,6 +370,10 @@ static ssize_t send_callback(nghttp2_session *h2,
(void)h2;
(void)flags;
if(!c->send_underlying)
/* called before setup properly! */
return NGHTTP2_ERR_CALLBACK_FAILURE;
written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
data, length, &result);
@ -441,6 +447,28 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
return NULL;
}
/*
* This specific transfer on this connection has been "drained".
*/
static void drained_transfer(struct Curl_easy *data,
struct http_conn *httpc)
{
DEBUGASSERT(httpc->drain_total >= data->state.drain);
httpc->drain_total -= data->state.drain;
data->state.drain = 0;
}
/*
* Mark this transfer to get "drained".
*/
static void drain_this(struct Curl_easy *data,
struct http_conn *httpc)
{
data->state.drain++;
httpc->drain_total++;
DEBUGASSERT(httpc->drain_total >= data->state.drain);
}
static struct Curl_easy *duphandle(struct Curl_easy *data)
{
struct Curl_easy *second = curl_easy_duphandle(data);
@ -520,6 +548,7 @@ static int push_promise(struct Curl_easy *data,
if(rv) {
/* denied, kill off the new handle again */
http2_stream_free(newhandle->req.protop);
newhandle->req.protop = NULL;
(void)Curl_close(newhandle);
goto fail;
}
@ -535,14 +564,22 @@ static int push_promise(struct Curl_easy *data,
if(rc) {
infof(data, "failed to add handle to multi\n");
http2_stream_free(newhandle->req.protop);
newhandle->req.protop = NULL;
Curl_close(newhandle);
rv = 1;
goto fail;
}
httpc = &conn->proto.httpc;
nghttp2_session_set_stream_user_data(httpc->h2,
frame->promised_stream_id, newhandle);
rv = nghttp2_session_set_stream_user_data(httpc->h2,
frame->promised_stream_id,
newhandle);
if(rv) {
infof(data, "failed to set user_data for stream %d\n",
frame->promised_stream_id);
DEBUGASSERT(0);
goto fail;
}
}
else {
H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
@ -581,7 +618,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
if(max_conn != httpc->settings.max_concurrent_streams) {
/* only signal change if the value actually changed */
infof(conn->data,
"Connection state changed (MAX_CONCURRENT_STREAMS == %d)!\n",
"Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
httpc->settings.max_concurrent_streams);
Curl_multi_connchanged(conn->data->multi);
}
@ -640,7 +677,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
ncopy = MIN(stream->len, left);
ncopy = CURLMIN(stream->len, left);
memcpy(&stream->mem[stream->memlen],
stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
@ -653,8 +690,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
stream->len -= ncopy;
stream->memlen += ncopy;
data_s->state.drain++;
httpc->drain_total++;
drain_this(data_s, httpc);
{
/* get the pointer from userp again since it was re-assigned above */
struct connectdata *conn_s = (struct connectdata *)userp;
@ -683,25 +719,6 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
return 0;
}
static int on_invalid_frame_recv(nghttp2_session *session,
const nghttp2_frame *frame,
int lib_error_code, void *userp)
{
struct Curl_easy *data_s = NULL;
(void)userp;
#if !defined(DEBUG_HTTP2) || 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) {
H2BUGF(infof(data_s,
"on_invalid_frame_recv() was called, error=%d:%s\n",
lib_error_code, nghttp2_strerror(lib_error_code)));
}
return 0;
}
static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const uint8_t *data, size_t len, void *userp)
@ -727,14 +744,13 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
nread = MIN(stream->len, len);
nread = CURLMIN(stream->len, len);
memcpy(&stream->mem[stream->memlen], data, nread);
stream->len -= nread;
stream->memlen += nread;
data_s->state.drain++;
conn->proto.httpc.drain_total++;
drain_this(data_s, &conn->proto.httpc);
/* if we receive data for another handle, wake that up */
if(conn->data != data_s)
@ -768,58 +784,13 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
return 0;
}
static int before_frame_send(nghttp2_session *session,
const nghttp2_frame *frame,
void *userp)
{
struct Curl_easy *data_s;
(void)userp;
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if(data_s) {
H2BUGF(infof(data_s, "before_frame_send() was called\n"));
}
return 0;
}
static int on_frame_send(nghttp2_session *session,
const nghttp2_frame *frame,
void *userp)
{
struct Curl_easy *data_s;
(void)userp;
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
if(data_s) {
H2BUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
frame->hd.length));
}
return 0;
}
static int on_frame_not_send(nghttp2_session *session,
const nghttp2_frame *frame,
int lib_error_code, void *userp)
{
struct Curl_easy *data_s;
(void)userp;
#if !defined(DEBUG_HTTP2) || 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) {
H2BUGF(infof(data_s,
"on_frame_not_send() was called, lib_error_code = %d\n",
lib_error_code));
}
return 0;
}
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
uint32_t error_code, void *userp)
{
struct Curl_easy *data_s;
struct HTTP *stream;
struct connectdata *conn = (struct connectdata *)userp;
int rv;
(void)session;
(void)stream_id;
@ -840,14 +811,19 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return NGHTTP2_ERR_CALLBACK_FAILURE;
stream->closed = TRUE;
data_s->state.drain++;
httpc = &conn->proto.httpc;
httpc->drain_total++;
drain_this(data_s, httpc);
httpc->error_code = error_code;
/* remove the entry from the hash as the stream is now gone */
nghttp2_session_set_stream_user_data(session, stream_id, 0);
rv = nghttp2_session_set_stream_user_data(session, stream_id, 0);
if(rv) {
infof(data_s, "http/2: failed to clear user_data for stream %d!\n",
stream_id);
DEBUGASSERT(0);
}
H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
stream->stream_id = 0; /* cleared */
}
return 0;
}
@ -1052,7 +1028,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
else
return NGHTTP2_ERR_INVALID_ARGUMENT;
nread = MIN(stream->upload_len, length);
nread = CURLMIN(stream->upload_len, length);
if(nread > 0) {
memcpy(buf, stream->upload_mem, nread);
stream->upload_mem += nread;
@ -1109,6 +1085,12 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
struct HTTP *http = data->req.protop;
struct http_conn *httpc = &conn->proto.httpc;
if(!httpc->h2) /* not HTTP/2 ? */
return;
if(data->state.drain)
drained_transfer(data, httpc);
if(http->header_recvbuf) {
Curl_add_buffer_free(http->header_recvbuf);
http->header_recvbuf = NULL; /* clear the pointer */
@ -1126,15 +1108,24 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
if(premature) {
/* RST_STREAM */
nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
NGHTTP2_STREAM_CLOSED);
if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE,
http->stream_id, NGHTTP2_STREAM_CLOSED))
(void)nghttp2_session_send(httpc->h2);
if(http->stream_id == httpc->pause_stream_id) {
infof(data, "stopped the pause stream!\n");
httpc->pause_stream_id = 0;
}
}
if(http->stream_id) {
nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
/* -1 means unassigned and 0 means cleared */
if(http->stream_id > 0) {
int rv = nghttp2_session_set_stream_user_data(httpc->h2,
http->stream_id, 0);
if(rv) {
infof(data, "http/2: failed to clear user_data for stream %d!\n",
http->stream_id);
DEBUGASSERT(0);
}
http->stream_id = 0;
}
}
@ -1164,21 +1155,9 @@ CURLcode Curl_http2_init(struct connectdata *conn)
/* nghttp2_on_frame_recv_callback */
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv);
/* nghttp2_on_invalid_frame_recv_callback */
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
(callbacks, on_invalid_frame_recv);
/* nghttp2_on_data_chunk_recv_callback */
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv);
/* nghttp2_before_frame_send_callback */
nghttp2_session_callbacks_set_before_frame_send_callback
(callbacks, before_frame_send);
/* nghttp2_on_frame_send_callback */
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, on_frame_send);
/* nghttp2_on_frame_not_send_callback */
nghttp2_session_callbacks_set_on_frame_not_send_callback
(callbacks, on_frame_not_send);
/* nghttp2_on_stream_close_callback */
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close);
@ -1280,7 +1259,7 @@ static int h2_process_pending_input(struct connectdata *conn,
if(rv < 0) {
failf(data,
"h2_process_pending_input: nghttp2_session_mem_recv() returned "
"%d:%s\n", rv, nghttp2_strerror((int)rv));
"%zd:%s\n", rv, nghttp2_strerror((int)rv));
*err = CURLE_RECV_ERROR;
return -1;
}
@ -1352,7 +1331,6 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
return result;
}
static ssize_t http2_handle_stream_close(struct connectdata *conn,
struct Curl_easy *data,
struct HTTP *stream, CURLcode *err)
@ -1365,9 +1343,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
httpc->pause_stream_id = 0;
}
DEBUGASSERT(httpc->drain_total >= data->state.drain);
httpc->drain_total -= data->state.drain;
data->state.drain = 0;
drained_transfer(data, httpc);
if(httpc->pause_stream_id == 0) {
if(h2_process_pending_input(conn, httpc, err) != 0) {
@ -1388,7 +1364,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
return -1;
}
else if(httpc->error_code != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
stream->stream_id, Curl_http2_strerror(httpc->error_code),
httpc->error_code);
*err = CURLE_HTTP2_STREAM;
@ -1396,7 +1372,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
}
if(!stream->bodystarted) {
failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
failf(data, "HTTP/2 stream %d was closed cleanly, but before getting "
" all response header fields, treated as error",
stream->stream_id);
*err = CURLE_HTTP2_STREAM;
@ -1510,7 +1486,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
/* If there is body data pending for this stream to return, do that */
size_t left =
stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
size_t ncopy = MIN(len, left);
size_t ncopy = CURLMIN(len, left);
memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
ncopy);
stream->nread_header_recvbuf += ncopy;
@ -1546,13 +1522,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
}
else if(stream->pausedata) {
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
nread = MIN(len, stream->pauselen);
nread = CURLMIN(len, stream->pauselen);
memcpy(mem, stream->pausedata, nread);
stream->pausedata += nread;
stream->pauselen -= nread;
infof(data, "%zu data bytes written\n", nread);
infof(data, "%zd data bytes written\n", nread);
if(stream->pauselen == 0) {
H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
@ -1635,7 +1611,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
if(nghttp2_is_fatal((int)rv)) {
failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
rv, nghttp2_strerror((int)rv));
*err = CURLE_RECV_ERROR;
return -1;
@ -1678,9 +1654,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
stream->stream_id));
}
else if(!stream->closed) {
DEBUGASSERT(httpc->drain_total >= data->state.drain);
httpc->drain_total -= data->state.drain;
data->state.drain = 0; /* this stream is hereby drained */
drained_transfer(data, httpc);
}
return retlen;
@ -2040,7 +2014,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
}
infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
stream_id, conn->data);
stream_id, (void *)conn->data);
stream->stream_id = stream_id;
/* this does not call h2_session_send() since there can not have been any
@ -2154,9 +2128,14 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
return CURLE_HTTP2;
}
nghttp2_session_set_stream_user_data(httpc->h2,
stream->stream_id,
conn->data);
rv = nghttp2_session_set_stream_user_data(httpc->h2,
stream->stream_id,
data);
if(rv) {
infof(data, "http/2: failed to set user_data for stream %d!\n",
stream->stream_id);
DEBUGASSERT(0);
}
}
else {
populate_settings(conn, httpc);

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -65,7 +65,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup_conn(x)
#define Curl_http2_setup_conn(x) Curl_nop_stmt
#define Curl_http2_setup_req(x)
#define Curl_http2_init_state(x)
#define Curl_http2_init_userset(x)

View File

@ -228,7 +228,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
/* connection is already authenticated,
* don't send a header in future requests */
ntlm->state = NTLMSTATE_LAST;
/* fall-through */
/* FALLTHROUGH */
case NTLMSTATE_LAST:
Curl_safefree(*allocuserpwd);
authp->done = TRUE;

View File

@ -188,12 +188,10 @@ static CURLcode CONNECT(struct connectdata *conn,
struct SingleRequest *k = &data->req;
CURLcode result;
curl_socket_t tunnelsocket = conn->sock[sockindex];
timediff_t check;
struct http_connect_state *s = conn->connect_state;
#define SELECT_OK 0
#define SELECT_ERROR 1
#define SELECT_TIMEOUT 2
if(Curl_connect_complete(conn))
return CURLE_OK; /* CONNECT is already completed */
@ -201,12 +199,13 @@ static CURLcode CONNECT(struct connectdata *conn,
conn->bits.proxy_connect_closed = FALSE;
do {
timediff_t check;
if(TUNNEL_INIT == s->tunnel_state) {
/* BEGIN CONNECT PHASE */
char *host_port;
Curl_send_buffer *req_buffer;
infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
hostname, remote_port);
/* This only happens if we've looped here due to authentication
@ -419,7 +418,7 @@ static CURLcode CONNECT(struct connectdata *conn,
/* output debug if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
s->line_start, (size_t)s->perline, conn);
s->line_start, (size_t)s->perline);
if(!data->set.suppress_connect_headers) {
/* send the header to the callback */

View File

@ -609,7 +609,6 @@ static CURLcode imap_perform_list(struct connectdata *conn)
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
struct IMAP *imap = data->req.protop;
char *mailbox;
if(imap->custom)
/* Send the custom request */
@ -617,7 +616,8 @@ static CURLcode imap_perform_list(struct connectdata *conn)
imap->custom_params ? imap->custom_params : "");
else {
/* Make sure the mailbox is in the correct atom format if necessary */
mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) : strdup("");
char *mailbox = imap->mailbox ? imap_atom(imap->mailbox, true)
: strdup("");
if(!mailbox)
return CURLE_OUT_OF_MEMORY;
@ -854,7 +854,6 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
size_t wordlen;
(void)instate; /* no use for this yet */
@ -864,6 +863,7 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
/* Loop through the data line */
for(;;) {
size_t wordlen;
while(*line &&
(*line == ' ' || *line == '\t' ||
*line == '\r' || *line == '\n')) {
@ -1046,12 +1046,12 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
struct IMAP *imap = conn->data->req.protop;
struct imap_conn *imapc = &conn->proto.imapc;
const char *line = data->state.buffer;
char tmp[20];
(void)instate; /* no use for this yet */
if(imapcode == '*') {
/* See if this is an UIDVALIDITY response */
char tmp[20];
if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
Curl_safefree(imapc->mailbox_uidvalidity);
imapc->mailbox_uidvalidity = strdup(tmp);
@ -1119,7 +1119,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
}
if(parsed) {
infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n",
infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download\n",
size);
Curl_pgrsSetDownloadSize(data, size);
@ -1144,10 +1144,8 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
data->req.bytecount += chunk;
infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU
" bytes, %" CURL_FORMAT_CURL_OFF_TU
" bytes are left for transfer\n", (curl_off_t)chunk,
size - chunk);
infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU
" bytes are left for transfer\n", chunk, size - chunk);
/* Have we used the entire cache or just part of it?*/
if(pp->cache_size > chunk) {

View File

@ -49,7 +49,7 @@
*/
static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
{
char tmp[sizeof "255.255.255.255"];
char tmp[sizeof("255.255.255.255")];
size_t len;
DEBUGASSERT(size >= 16);

View File

@ -54,15 +54,6 @@
# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
#endif
/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
* in BoringSSL's <openssl/x509.h>
*/
#ifdef HAVE_BORINGSSL
# undef X509_NAME
# undef X509_CERT_PAIR
# undef X509_EXTENSIONS
#endif
#include "urldata.h"
#include <curl/curl.h>
#include "sendf.h"

View File

@ -484,29 +484,35 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
#endif /* CRYPTO LIBS */
/* Disable this picky gcc-8 compiler warning */
#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
const HMAC_params Curl_HMAC_MD5[] = {
{
(HMAC_hinit_func) MD5_Init, /* Hash initialization function. */
(HMAC_hupdate_func) MD5_Update, /* Hash update function. */
(HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */
sizeof(MD5_CTX), /* Size of hash context structure. */
64, /* Maximum key length. */
16 /* Result size. */
/* Hash initialization function. */
CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
/* Hash update function. */
CURLX_FUNCTION_CAST(HMAC_hupdate_func, MD5_Update),
/* Hash computation end function. */
CURLX_FUNCTION_CAST(HMAC_hfinal_func, MD5_Final),
/* Size of hash context structure. */
sizeof(MD5_CTX),
/* Maximum key length. */
64,
/* Result size. */
16
}
};
const MD5_params Curl_DIGEST_MD5[] = {
{
(Curl_MD5_init_func) MD5_Init, /* Digest initialization function */
(Curl_MD5_update_func) MD5_Update, /* Digest update function */
(Curl_MD5_final_func) MD5_Final, /* Digest computation end function */
sizeof(MD5_CTX), /* Size of digest context struct */
16 /* Result size */
/* Digest initialization function */
CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
/* Digest update function */
CURLX_FUNCTION_CAST(Curl_MD5_update_func, MD5_Update),
/* Digest computation end function */
CURLX_FUNCTION_CAST(Curl_MD5_final_func, MD5_Final),
/* Size of digest context struct */
sizeof(MD5_CTX),
/* Result size */
16
}
};
@ -527,7 +533,7 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
MD5_context *ctxt;
/* Create MD5 context */
ctxt = malloc(sizeof *ctxt);
ctxt = malloc(sizeof(*ctxt));
if(!ctxt)
return ctxt;

View File

@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -137,13 +137,6 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
#endif
#endif /* HAVE_GETADDRINFO */
#ifdef HAVE_GETNAMEINFO
#undef getnameinfo
#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
__LINE__, __FILE__)
#endif /* HAVE_GETNAMEINFO */
#ifdef HAVE_FREEADDRINFO
#undef freeaddrinfo
#define freeaddrinfo(data) \

View File

@ -505,9 +505,6 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
mime_encoder_state *st = &part->encstate;
char *ptr = buffer;
size_t cursize = 0;
int i;
size_t len;
size_t consumed;
int softlinebreak;
char buf[4];
@ -516,9 +513,9 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
character constants that can be interpreted as non-ascii on some
platforms. Preserve ASCII encoding on output too. */
while(st->bufbeg < st->bufend) {
len = 1;
consumed = 1;
i = st->buf[st->bufbeg];
size_t len = 1;
size_t consumed = 1;
int i = st->buf[st->bufbeg];
buf[0] = (char) i;
buf[1] = aschex[(i >> 4) & 0xF];
buf[2] = aschex[i & 0xF];
@ -787,10 +784,10 @@ static size_t read_encoded_part_content(curl_mimepart *part,
st->bufbeg = 0;
st->bufend = len;
}
if(st->bufend >= sizeof st->buf)
if(st->bufend >= sizeof(st->buf))
return cursize? cursize: READ_ERROR; /* Buffer full. */
sz = read_part_content(part, st->buf + st->bufend,
sizeof st->buf - st->bufend);
sizeof(st->buf) - st->bufend);
switch(sz) {
case 0:
ateof = TRUE;
@ -813,8 +810,6 @@ static size_t readback_part(curl_mimepart *part,
char *buffer, size_t bufsize)
{
size_t cursize = 0;
size_t sz;
struct curl_slist *hdr;
#ifdef CURL_DOES_CONVERSIONS
char *convbuf = buffer;
#endif
@ -822,8 +817,8 @@ static size_t readback_part(curl_mimepart *part,
/* Readback from part. */
while(bufsize) {
sz = 0;
hdr = (struct curl_slist *) part->state.ptr;
size_t sz = 0;
struct curl_slist *hdr = (struct curl_slist *) part->state.ptr;
switch(part->state.state) {
case MIMESTATE_BEGIN:
mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
@ -918,8 +913,6 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
{
curl_mime *mime = (curl_mime *) instream;
size_t cursize = 0;
size_t sz;
curl_mimepart *part;
#ifdef CURL_DOES_CONVERSIONS
char *convbuf = buffer;
#endif
@ -927,8 +920,8 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
(void) size; /* Always 1. */
while(nitems) {
sz = 0;
part = mime->state.ptr;
size_t sz = 0;
curl_mimepart *part = mime->state.ptr;
switch(mime->state.state) {
case MIMESTATE_BEGIN:
case MIMESTATE_BODY:
@ -1044,7 +1037,6 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
curl_mime *mime = (curl_mime *) instream;
curl_mimepart *part;
int result = CURL_SEEKFUNC_OK;
int res;
if(whence != SEEK_SET || offset)
return CURL_SEEKFUNC_CANTSEEK; /* Only support full rewind. */
@ -1053,7 +1045,7 @@ static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
return CURL_SEEKFUNC_OK; /* Already rewound. */
for(part = mime->firstpart; part; part = part->nextpart) {
res = mime_part_rewind(part);
int res = mime_part_rewind(part);
if(res != CURL_SEEKFUNC_OK)
result = res;
}
@ -1220,7 +1212,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
{
curl_mime *mime;
mime = (curl_mime *) malloc(sizeof *mime);
mime = (curl_mime *) malloc(sizeof(*mime));
if(mime) {
mime->easy = easy;
@ -1236,8 +1228,13 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
}
memset(mime->boundary, '-', 24);
Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
MIME_RAND_BOUNDARY_CHARS + 1);
if(Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
MIME_RAND_BOUNDARY_CHARS + 1)) {
/* failed to get random separator, bail out */
free(mime->boundary);
free(mime);
return NULL;
}
mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
}
@ -1247,7 +1244,7 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
/* Initialize a mime part. */
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
{
memset((char *) part, 0, sizeof *part);
memset((char *) part, 0, sizeof(*part));
part->easy = easy;
mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
}
@ -1260,7 +1257,7 @@ curl_mimepart *curl_mime_addpart(curl_mime *mime)
if(!mime)
return NULL;
part = (curl_mimepart *) malloc(sizeof *part);
part = (curl_mimepart *) malloc(sizeof(*part));
if(part) {
Curl_mime_initpart(part, mime->easy);
@ -1349,7 +1346,6 @@ CURLcode curl_mime_data(curl_mimepart *part,
CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
{
CURLcode result = CURLE_OK;
char *base;
if(!part)
return CURLE_BAD_FUNCTION_ARGUMENT;
@ -1357,6 +1353,7 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
cleanup_part_content(part);
if(filename) {
char *base;
struct_stat sbuf;
if(stat(filename, &sbuf) || access(filename, R_OK))
@ -1564,7 +1561,6 @@ static size_t slist_size(struct curl_slist *s,
static curl_off_t multipart_size(curl_mime *mime)
{
curl_off_t size;
curl_off_t sz;
size_t boundarysize;
curl_mimepart *part;
@ -1575,7 +1571,7 @@ static curl_off_t multipart_size(curl_mime *mime)
size = boundarysize; /* Final boundary - CRLF after headers. */
for(part = mime->firstpart; part; part = part->nextpart) {
sz = Curl_mime_size(part);
curl_off_t sz = Curl_mime_size(part);
if(sz < 0)
size = sz;
@ -1643,8 +1639,6 @@ static CURLcode add_content_type(struct curl_slist **slp,
const char *Curl_mime_contenttype(const char *filename)
{
unsigned int i;
/*
* If no content type was specified, we scan through a few well-known
* extensions and pick the first we match!
@ -1669,8 +1663,9 @@ const char *Curl_mime_contenttype(const char *filename)
if(filename) {
size_t len1 = strlen(filename);
const char *nameend = filename + len1;
unsigned int i;
for(i = 0; i < sizeof ctts / sizeof ctts[0]; i++) {
for(i = 0; i < sizeof(ctts) / sizeof(ctts[0]); i++) {
size_t len2 = strlen(ctts[i].extension);
if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension))

View File

@ -31,6 +31,7 @@
#include "progress.h"
#include "easyif.h"
#include "share.h"
#include "psl.h"
#include "multiif.h"
#include "sendf.h"
#include "timeval.h"
@ -68,8 +69,8 @@
#define GOOD_MULTI_HANDLE(x) \
((x) && (x)->type == CURL_MULTI_HANDLE)
static void singlesocket(struct Curl_multi *multi,
struct Curl_easy *data);
static CURLMcode singlesocket(struct Curl_multi *multi,
struct Curl_easy *data);
static int update_timer(struct Curl_multi *multi);
static CURLMcode add_next_timeout(struct curltime now,
@ -106,6 +107,16 @@ static const char * const statename[]={
/* function pointer called once when switching TO a state */
typedef void (*init_multistate_func)(struct Curl_easy *data);
static void Curl_init_completed(struct Curl_easy *data)
{
/* this is a completed transfer */
/* Important: reset the conn pointer so that we don't point to memory
that could be freed anytime */
data->easy_conn = NULL;
Curl_expire_clear(data); /* stop all timers */
}
/* always use this function to change state, to make debugging easier */
static void mstate(struct Curl_easy *data, CURLMstate state
#ifdef DEBUGBUILD
@ -115,17 +126,25 @@ static void mstate(struct Curl_easy *data, CURLMstate state
{
CURLMstate oldstate = data->mstate;
static const init_multistate_func finit[CURLM_STATE_LAST] = {
NULL,
NULL,
NULL, /* INIT */
NULL, /* CONNECT_PEND */
Curl_init_CONNECT, /* CONNECT */
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
Curl_connect_free /* DO */
/* the rest is NULL too */
NULL, /* WAITRESOLVE */
NULL, /* WAITCONNECT */
NULL, /* WAITPROXYCONNECT */
NULL, /* SENDPROTOCONNECT */
NULL, /* PROTOCONNECT */
NULL, /* WAITDO */
Curl_connect_free, /* DO */
NULL, /* DOING */
NULL, /* DO_MORE */
NULL, /* DO_DONE */
NULL, /* WAITPERFORM */
NULL, /* PERFORM */
NULL, /* TOOFAST */
NULL, /* DONE */
Curl_init_completed, /* COMPLETED */
NULL /* MSGSENT */
};
#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
@ -409,6 +428,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
else
data->state.conn_cache = &multi->conn_cache;
#ifdef USE_LIBPSL
/* Do the same for PSL. */
if(data->share && (data->share->specifier & (1 << CURL_LOCK_DATA_PSL)))
data->psl = &data->share->psl;
else
data->psl = &multi->psl;
#endif
/* This adds the new entry at the 'end' of the doubly-linked circular
list of Curl_easy structs to try and maintain a FIFO queue so
the pipelined requests are in order. */
@ -449,7 +476,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
happens if the lastcall time is set to the same time when the handle is
removed as when the next handle is added, as then the check in
update_timer() that prevents calling the application multiple times with
the same timer infor will not trigger and then the new handle's timeout
the same timer info will not trigger and then the new handle's timeout
will not be notified to the app.
The work-around is thus simply to clear the 'lastcall' variable to force
@ -506,6 +533,11 @@ static CURLcode multi_done(struct connectdata **connp,
/* Stop if multi_done() has already been called */
return CURLE_OK;
if(data->mstate == CURLM_STATE_WAITRESOLVE) {
/* still waiting for the resolve to complete */
(void)Curl_resolver_wait_resolv(conn, NULL);
}
Curl_getoff_all_pipelines(data, conn);
/* Cleanup possible redirect junk */
@ -546,7 +578,7 @@ static CURLcode multi_done(struct connectdata **connp,
if(conn->send_pipe.size || conn->recv_pipe.size) {
/* Stop if pipeline is not empty . */
data->easy_conn = NULL;
DEBUGF(infof(data, "Connection still in use %d/%d, "
DEBUGF(infof(data, "Connection still in use %zu/%zu, "
"no more multi_done now!\n",
conn->send_pipe.size, conn->recv_pipe.size));
return CURLE_OK;
@ -560,6 +592,7 @@ static CURLcode multi_done(struct connectdata **connp,
conn->dns_entry = NULL;
}
Curl_hostcache_prune(data);
Curl_safefree(data->state.ulbuf);
/* if the transfer was completed in a paused state there can be buffered
data left to free */
@ -590,7 +623,7 @@ static CURLcode multi_done(struct connectdata **connp,
#endif
) || conn->bits.close
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
CURLcode res2 = Curl_disconnect(data, conn, premature);
/* If we had an error already, make sure we return that one. But
if we got a new error, return that. */
@ -608,7 +641,7 @@ static CURLcode multi_done(struct connectdata **connp,
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
conn->host.dispname);
/* the connection is no longer in use */
/* the connection is no longer in use by this transfer */
if(Curl_conncache_return_conn(conn)) {
/* remember the most recently used connection */
data->state.lastconnect = conn;
@ -698,6 +731,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
Curl_getoff_all_pipelines(data, data->easy_conn);
}
if(data->connect_queue.ptr)
/* the handle was in the pending list waiting for an available connection,
so go ahead and remove it */
Curl_llist_remove(&multi->pending, &data->connect_queue, NULL);
if(data->dns.hostcachetype == HCACHE_MULTI) {
/* stop using the multi handle's DNS cache, *after* the possible
multi_done() call above */
@ -727,6 +765,12 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
data->easy_conn = NULL;
}
#ifdef USE_LIBPSL
/* Remove the PSL association. */
if(data->psl == &multi->psl)
data->psl = NULL;
#endif
data->multi = NULL; /* clear the association to this multi handle */
/* make sure there's no pending message in the queue sent from this easy
@ -831,12 +875,10 @@ static int multi_getsock(struct Curl_easy *data,
of sockets */
int numsocks)
{
/* If the pipe broke, or if there's no connection left for this easy handle,
then we MUST bail out now with no bitmask set. The no connection case can
happen when this is called from curl_multi_remove_handle() =>
singlesocket() => multi_getsock().
/* The no connection case can happen when this is called from
curl_multi_remove_handle() => singlesocket() => multi_getsock().
*/
if(data->state.pipe_broke || !data->easy_conn)
if(!data->easy_conn)
return 0;
if(data->mstate > CURLM_STATE_CONNECT &&
@ -902,7 +944,6 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
struct Curl_easy *data;
int this_max_fd = -1;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
int bitmap;
int i;
(void)exc_fd_set; /* not used */
@ -914,7 +955,7 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi,
data = multi->easyp;
while(data) {
bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
int bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
curl_socket_t s = CURL_SOCKET_BAD;
@ -1068,8 +1109,6 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi,
int pollrc;
/* wait... */
pollrc = Curl_poll(ufds, nfds, timeout_ms);
DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
nfds, timeout_ms, pollrc));
if(pollrc > 0) {
retcode = pollrc;
@ -1312,24 +1351,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
bool stream_error = FALSE;
rc = CURLM_OK;
/* Handle the case when the pipe breaks, i.e., the connection
we're using gets cleaned up and we're left with nothing. */
if(data->state.pipe_broke) {
infof(data, "Pipe broke: handle %p, url = %s\n",
(void *)data, data->state.path);
if(data->mstate < CURLM_STATE_COMPLETED) {
/* Head back to the CONNECT state */
multistate(data, CURLM_STATE_CONNECT);
rc = CURLM_CALL_MULTI_PERFORM;
result = CURLE_OK;
}
data->state.pipe_broke = FALSE;
data->easy_conn = NULL;
continue;
}
if(!data->easy_conn &&
data->mstate > CURLM_STATE_CONNECT &&
data->mstate < CURLM_STATE_DONE) {
@ -1555,6 +1576,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
}
}
else if(result)
stream_error = TRUE;
break;
#endif
@ -1909,6 +1932,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
if(!ret)
retry = (newurl)?TRUE:FALSE;
else if(!result)
result = ret;
if(retry) {
/* if we are to retry, set the result to OK and consider the
@ -2040,16 +2065,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
case CURLM_STATE_COMPLETED:
/* this is a completed transfer, it is likely to still be connected */
/* This node should be delinked from the list now and we should post
an information message that we are complete. */
/* Important: reset the conn pointer so that we don't point to memory
that could be freed anytime */
data->easy_conn = NULL;
Curl_expire_clear(data); /* stop all timers */
break;
case CURLM_STATE_MSGSENT:
@ -2071,8 +2086,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* NOTE: no attempt to disconnect connections must be made
in the case blocks above - cleanup happens only here */
data->state.pipe_broke = FALSE;
/* Check if we can move pending requests to send pipe */
process_pending_handles(multi); /* connection */
@ -2087,7 +2100,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* Don't attempt to send data over a connection that timed out */
bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
/* disconnect properly */
Curl_disconnect(data->easy_conn, dead_connection);
Curl_disconnect(data, data->easy_conn, dead_connection);
/* This is where we make sure that the easy_conn pointer is reset.
We don't have to do this in every case block above where a
@ -2101,6 +2114,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
multistate(data, CURLM_STATE_COMPLETED);
rc = CURLM_CALL_MULTI_PERFORM;
}
/* if there's still a connection to use, call the progress function */
else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
@ -2125,14 +2139,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
msg->extmsg.data.result = result;
rc = multi_addmsg(multi, msg);
DEBUGASSERT(!data->easy_conn);
multistate(data, CURLM_STATE_MSGSENT);
}
} while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
data->result = result;
return rc;
}
@ -2220,6 +2232,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
data->state.conn_cache = NULL;
data->multi = NULL; /* clear the association */
#ifdef USE_LIBPSL
if(data->psl == &multi->psl)
data->psl = NULL;
#endif
data = nextdata;
}
@ -2232,6 +2249,7 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
Curl_llist_destroy(&multi->pending, NULL);
Curl_hash_destroy(&multi->hostcache);
Curl_psl_destroy(&multi->psl);
/* Free the blacklists by setting them to NULL */
Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
@ -2286,8 +2304,8 @@ CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
* and if we have a different state in any of those sockets from last time we
* call the callback accordingly.
*/
static void singlesocket(struct Curl_multi *multi,
struct Curl_easy *data)
static CURLMcode singlesocket(struct Curl_multi *multi,
struct Curl_easy *data)
{
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
int i;
@ -2334,7 +2352,7 @@ static void singlesocket(struct Curl_multi *multi,
entry = sh_addentry(&multi->sockhash, s, data);
if(!entry)
/* fatal */
return;
return CURLM_OUT_OF_MEMORY;
}
/* we know (entry != NULL) at this point, see the logic above */
@ -2422,6 +2440,7 @@ static void singlesocket(struct Curl_multi *multi,
memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
data->numsocks = num;
return CURLM_OK;
}
void Curl_updatesocket(struct Curl_easy *data)
@ -2442,20 +2461,23 @@ void Curl_updatesocket(struct Curl_easy *data)
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
{
struct Curl_multi *multi = conn->data->multi;
if(multi) {
/* this is set if this connection is part of a handle that is added to
a multi handle, and only then this is necessary */
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
if(conn->data) {
/* if there's still an easy handle associated with this connection */
struct Curl_multi *multi = conn->data->multi;
if(multi) {
/* this is set if this connection is part of a handle that is added to
a multi handle, and only then this is necessary */
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
if(entry) {
if(multi->socket_cb)
multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
multi->socket_userp,
entry->socketp);
if(entry) {
if(multi->socket_cb)
multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
multi->socket_userp,
entry->socketp);
/* now remove it from the socket hash */
sh_delentry(&multi->sockhash, s);
/* now remove it from the socket hash */
sh_delentry(&multi->sockhash, s);
}
}
}
}
@ -2535,8 +2557,8 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
and callbacks */
if(result != CURLM_BAD_HANDLE) {
data = multi->easyp;
while(data) {
singlesocket(multi, data);
while(data && !result) {
result = singlesocket(multi, data);
data = data->next;
}
}
@ -2590,10 +2612,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
/* clear the bitmask only if not locked */
data->easy_conn->cselect_bits = 0;
if(CURLM_OK >= result)
if(CURLM_OK >= result) {
/* get the socket(s) and check if the state has been changed since
last */
singlesocket(multi, data);
result = singlesocket(multi, data);
if(result)
return result;
}
/* Now we fall-through and do the timer-based stuff, since we don't want
to force the user to have to deal with timeouts as long as at least
@ -2627,10 +2652,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
result = multi_runsingle(multi, now, data);
sigpipe_restore(&pipe_st);
if(CURLM_OK >= result)
if(CURLM_OK >= result) {
/* get the socket(s) and check if the state has been changed since
last */
singlesocket(multi, data);
result = singlesocket(multi, data);
if(result)
return result;
}
}
/* Check if there's one (more) expired timer to deal with! This function
@ -2924,7 +2952,6 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
{
struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime;
int rc;
struct curltime set;
/* this is only interesting while there is still an associated multi struct
@ -2955,6 +2982,7 @@ void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
Compare if the new time is earlier, and only remove-old/add-new if it
is. */
timediff_t diff = Curl_timediff(set, *nowp);
int rc;
if(diff > 0) {
/* The current splay tree entry is sooner than this new expiry time.
@ -3000,7 +3028,6 @@ void Curl_expire_clear(struct Curl_easy *data)
{
struct Curl_multi *multi = data->multi;
struct curltime *nowp = &data->state.expiretime;
int rc;
/* this is only interesting while there is still an associated multi struct
remaining! */
@ -3011,6 +3038,7 @@ void Curl_expire_clear(struct Curl_easy *data)
/* Since this is an cleared time, we must remove the previous entry from
the splay tree */
struct curl_llist *list = &data->state.timeoutlist;
int rc;
rc = Curl_splayremovebyaddr(multi->timetree,
&data->state.timenode,
@ -3100,12 +3128,15 @@ static void process_pending_handles(struct Curl_multi *multi)
}
}
void Curl_set_in_callback(struct Curl_easy *easy, bool value)
void Curl_set_in_callback(struct Curl_easy *data, bool value)
{
if(easy->multi_easy)
easy->multi_easy->in_callback = value;
else if(easy->multi)
easy->multi->in_callback = value;
/* might get called when there is no data pointer! */
if(data) {
if(data->multi_easy)
data->multi_easy->in_callback = value;
else if(data->multi)
data->multi->in_callback = value;
}
}
bool Curl_is_in_callback(struct Curl_easy *easy)

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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,6 +23,7 @@
***************************************************************************/
#include "conncache.h"
#include "psl.h"
struct Curl_message {
struct curl_llist_element list;
@ -97,6 +98,11 @@ struct Curl_multi {
/* Hostname cache */
struct curl_hash hostcache;
#ifdef USE_LIBPSL
/* PSL cache. */
struct PslCache psl;
#endif
/* timetree points to the splay-tree of time nodes to figure out expire
times of all currently set timers */
struct Curl_tree *timetree;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -115,7 +115,7 @@ int Curl_parsenetrc(const char *host,
char *tok;
char *tok_buf;
bool done = FALSE;
char netrcbuffer[256];
char netrcbuffer[4096];
int netrcbuffsize = (int)sizeof(netrcbuffer);
while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -49,7 +49,6 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
struct connectdata *conn = pp->conn;
struct Curl_easy *data = conn->data;
time_t timeout_ms; /* in milliseconds */
time_t timeout2_ms; /* in milliseconds */
long response_time = (data->set.server_response_timeout)?
data->set.server_response_timeout: pp->response_time;
@ -65,7 +64,7 @@ time_t Curl_pp_state_timeout(struct pingpong *pp)
if(data->set.timeout) {
/* if timeout is requested, find out how much remaining time we have */
timeout2_ms = data->set.timeout - /* timeout time */
time_t timeout2_ms = data->set.timeout - /* timeout time */
Curl_timediff(Curl_now(), conn->now); /* spent time */
/* pick the lowest number */
@ -222,8 +221,7 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp,
}
if(conn->data->set.verbose)
Curl_debug(conn->data, CURLINFO_HEADER_OUT,
s, (size_t)bytes_written, conn);
Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written);
if(bytes_written != (ssize_t)write_len) {
/* the whole chunk was not sent, keep it around and adjust sizes */
@ -371,7 +369,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
#endif
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
pp->linestart_resp, (size_t)perline, conn);
pp->linestart_resp, (size_t)perline);
/*
* We pass all response-lines to the callback function registered

View File

@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) 2013 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2013 - 2018, 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
@ -82,7 +82,8 @@ bool Curl_pipeline_penalized(struct Curl_easy *data,
penalized = TRUE;
infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
CURL_FORMAT_CURL_OFF_T "/%" CURL_FORMAT_CURL_OFF_T
"), penalized: %s\n",
conn->connection_id, (void *)conn, recv_size,
conn->chunk.datasize, penalized?"TRUE":"FALSE");
return penalized;
@ -109,8 +110,8 @@ CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
pipeline = &conn->send_pipe;
result = addHandleToPipeline(handle, pipeline);
if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
if((conn->bundle->multiuse == BUNDLE_PIPELINING) &&
(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, EXPIRE_RUN_NOW);

View File

@ -613,7 +613,6 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *line = data->state.buffer;
size_t len = strlen(line);
size_t i;
(void)instate; /* no use for this yet */
@ -625,6 +624,7 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
/* Does the server support APOP authentication? */
if(len >= 4 && line[len - 2] == '>') {
/* Look for the APOP timestamp */
size_t i;
for(i = 3; i < len - 2; ++i) {
if(line[i] == '<') {
/* Calculate the length of the timestamp */
@ -664,7 +664,6 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *line = data->state.buffer;
size_t len = strlen(line);
size_t wordlen;
(void)instate; /* no use for this yet */
@ -689,6 +688,7 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
/* Loop through the data line */
for(;;) {
size_t llen;
size_t wordlen;
unsigned int mechbit;
while(len &&

View File

@ -35,22 +35,22 @@
byte) */
static void time2str(char *r, curl_off_t seconds)
{
curl_off_t d, h, m, s;
curl_off_t h;
if(seconds <= 0) {
strcpy(r, "--:--:--");
return;
}
h = seconds / CURL_OFF_T_C(3600);
if(h <= CURL_OFF_T_C(99)) {
m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
curl_off_t m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
curl_off_t s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
}
else {
/* this equals to more than 99 hours, switch to a more suitable output
format to fit within the limits. */
d = seconds / CURL_OFF_T_C(86400);
curl_off_t d = seconds / CURL_OFF_T_C(86400);
h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
if(d <= CURL_OFF_T_C(999))
snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
@ -369,25 +369,10 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
int Curl_pgrsUpdate(struct connectdata *conn)
{
struct curltime now;
int result;
char max5[6][10];
curl_off_t dlpercen = 0;
curl_off_t ulpercen = 0;
curl_off_t total_percen = 0;
curl_off_t total_transfer;
curl_off_t total_expected_transfer;
curl_off_t timespent;
curl_off_t timespent_ms; /* milliseconds */
struct Curl_easy *data = conn->data;
int nowindex = data->progress.speeder_c% CURR_TIME;
int checkindex;
int countindex; /* amount of seconds stored in the speeder array */
char time_left[10];
char time_total[10];
char time_spent[10];
curl_off_t ulestimate = 0;
curl_off_t dlestimate = 0;
curl_off_t total_estimate;
bool shownow = FALSE;
curl_off_t dl = data->progress.downloaded;
curl_off_t ul = data->progress.uploaded;
@ -413,6 +398,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* Calculations done at most once a second, unless end is reached */
if(data->progress.lastshow != now.tv_sec) {
int countindex; /* amount of seconds stored in the speeder array */
shownow = TRUE;
data->progress.lastshow = now.tv_sec;
@ -438,6 +424,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
/* first of all, we don't do this if there's no counted seconds yet */
if(countindex) {
int checkindex;
timediff_t span_ms;
/* Get the index position to compare with the 'nowindex' position.
@ -477,8 +464,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
if(!(data->progress.flags & PGRS_HIDE)) {
/* progress meter has not been shut off */
char max5[6][10];
curl_off_t dlpercen = 0;
curl_off_t ulpercen = 0;
curl_off_t total_percen = 0;
curl_off_t total_transfer;
curl_off_t total_expected_transfer;
char time_left[10];
char time_total[10];
char time_spent[10];
curl_off_t ulestimate = 0;
curl_off_t dlestimate = 0;
curl_off_t total_estimate;
if(data->set.fxferinfo) {
int result;
/* There's a callback set, call that */
Curl_set_in_callback(data, true);
result = data->set.fxferinfo(data->set.progress_client,
@ -492,6 +492,7 @@ int Curl_pgrsUpdate(struct connectdata *conn)
return result;
}
if(data->set.fprogress) {
int result;
/* The older deprecated callback is set, call that */
Curl_set_in_callback(data, true);
result = data->set.fprogress(data->set.progress_client,

View File

@ -56,23 +56,10 @@ timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
struct curltime start,
struct curltime now);
/* Don't show progress for sizes smaller than: */
#define LEAST_SIZE_PROGRESS BUFSIZE
#define PROGRESS_DOWNLOAD (1<<0)
#define PROGRESS_UPLOAD (1<<1)
#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
#define PGRS_SHOW_DL (1<<0)
#define PGRS_SHOW_UL (1<<1)
#define PGRS_DONE_DL (1<<2)
#define PGRS_DONE_UL (1<<3)
#define PGRS_HIDE (1<<4)
#define PGRS_UL_SIZE_KNOWN (1<<5)
#define PGRS_DL_SIZE_KNOWN (1<<6)
#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
#endif /* HEADER_CURL_PROGRESS_H */

111
lib/psl.c Normal file
View File

@ -0,0 +1,111 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2018, 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.
*
***************************************************************************/
#include "curl_setup.h"
#include <curl/curl.h>
#ifdef USE_LIBPSL
#include "psl.h"
#include "share.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
void Curl_psl_destroy(struct PslCache *pslcache)
{
if(pslcache->psl) {
if(pslcache->dynamic)
psl_free((psl_ctx_t *) pslcache->psl);
pslcache->psl = NULL;
pslcache->dynamic = FALSE;
}
}
static time_t now_seconds(void)
{
struct curltime now = Curl_now();
return now.tv_sec;
}
const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy)
{
struct PslCache *pslcache = easy->psl;
const psl_ctx_t *psl;
time_t now;
if(!pslcache)
return NULL;
Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED);
now = now_seconds();
if(!pslcache->psl || pslcache->expires <= now) {
/* Let a chance to other threads to do the job: avoids deadlock. */
Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
/* Update cache: this needs an exclusive lock. */
Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SINGLE);
/* Recheck in case another thread did the job. */
now = now_seconds();
if(!pslcache->psl || pslcache->expires <= now) {
bool dynamic = FALSE;
time_t expires = TIME_T_MAX;
#if defined(PSL_VERSION_NUMBER) && PSL_VERSION_NUMBER >= 0x001000
psl = psl_latest(NULL);
dynamic = psl != NULL;
/* Take care of possible time computation overflow. */
expires = now < TIME_T_MAX - PSL_TTL? now + PSL_TTL: TIME_T_MAX;
/* Only get the built-in PSL if we do not already have the "latest". */
if(!psl && !pslcache->dynamic)
#endif
psl = psl_builtin();
if(psl) {
Curl_psl_destroy(pslcache);
pslcache->psl = psl;
pslcache->dynamic = dynamic;
pslcache->expires = expires;
}
}
Curl_share_unlock(easy, CURL_LOCK_DATA_PSL); /* Release exclusive lock. */
Curl_share_lock(easy, CURL_LOCK_DATA_PSL, CURL_LOCK_ACCESS_SHARED);
}
psl = pslcache->psl;
if(!psl)
Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
return psl;
}
void Curl_psl_release(struct Curl_easy *easy)
{
Curl_share_unlock(easy, CURL_LOCK_DATA_PSL);
}
#endif /* USE_LIBPSL */

47
lib/psl.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef HEADER_PSL_H
#define HEADER_PSL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2018, 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.
*
***************************************************************************/
#ifdef USE_LIBPSL
#include <libpsl.h>
#define PSL_TTL (72 * 3600) /* PSL time to live before a refresh. */
struct PslCache {
const psl_ctx_t *psl; /* The PSL. */
time_t expires; /* Time this PSL life expires. */
bool dynamic; /* PSL should be released when no longer needed. */
};
const psl_ctx_t *Curl_psl_use(struct Curl_easy *easy);
void Curl_psl_release(struct Curl_easy *easy);
void Curl_psl_destroy(struct PslCache *pslcache);
#else
#define Curl_psl_use(easy) NULL
#define Curl_psl_release(easy)
#define Curl_psl_destroy(pslcache)
#endif /* USE_LIBPSL */
#endif /* HEADER_PSL_H */

View File

@ -158,7 +158,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
DEBUGASSERT(num > 1);
#ifdef __clang_analyzer__
/* This silences a scan-build warning about accesssing this buffer with
/* This silences a scan-build warning about accessing this buffer with
uninitialized memory. */
memset(buffer, 0, sizeof(buffer));
#endif

View File

@ -218,8 +218,6 @@ static CURLcode rtsp_done(struct connectdata *conn,
struct Curl_easy *data = conn->data;
struct RTSP *rtsp = data->req.protop;
CURLcode httpStatus;
long CSeq_sent;
long CSeq_recv;
/* Bypass HTTP empty-reply checks on receive */
if(data->set.rtspreq == RTSPREQ_RECEIVE)
@ -229,8 +227,8 @@ static CURLcode rtsp_done(struct connectdata *conn,
if(rtsp) {
/* Check the sequence numbers */
CSeq_sent = rtsp->CSeq_sent;
CSeq_recv = rtsp->CSeq_recv;
long CSeq_sent = rtsp->CSeq_sent;
long CSeq_recv = rtsp->CSeq_recv;
if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
failf(data,
"The CSeq of this request %ld did not match the response %ld",

View File

@ -390,7 +390,7 @@ int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
if(conn->data->set.verbose) {
buf[decoded_len] = '\n';
Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
}
buf[decoded_len] = '\0';
@ -488,7 +488,7 @@ static CURLcode choose_mech(struct connectdata *conn)
tmp_allocation = realloc(conn->app_data, mech->size);
if(tmp_allocation == NULL) {
failf(data, "Failed realloc of size %u", mech->size);
failf(data, "Failed realloc of size %zu", mech->size);
mech = NULL;
return CURLE_OUT_OF_MEMORY;
}

View File

@ -80,7 +80,6 @@ int Curl_wait_ms(int timeout_ms)
#endif
struct curltime initial_tv;
int pending_ms;
int error;
#endif
int r = 0;
@ -98,6 +97,7 @@ int Curl_wait_ms(int timeout_ms)
pending_ms = timeout_ms;
initial_tv = Curl_now();
do {
int error;
#if defined(HAVE_POLL_FINE)
r = poll(NULL, 0, pending_ms);
#else
@ -160,7 +160,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
#endif
struct curltime initial_tv = {0, 0};
int pending_ms = 0;
int error;
int r;
int ret;
@ -210,6 +209,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
}
do {
int error;
if(timeout_ms < 0)
pending_ms = -1;
else if(!timeout_ms)
@ -291,6 +291,7 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do {
int error;
if(timeout_ms > 0) {
pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000;
@ -402,7 +403,6 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
bool fds_none = TRUE;
unsigned int i;
int pending_ms = 0;
int error;
int r;
if(ufds) {
@ -431,6 +431,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
#ifdef HAVE_POLL_FINE
do {
int error;
if(timeout_ms < 0)
pending_ms = -1;
else if(!timeout_ms)
@ -502,6 +503,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
do {
int error;
if(timeout_ms > 0) {
pending_tv.tv_sec = pending_ms / 1000;
pending_tv.tv_usec = (pending_ms % 1000) * 1000;

View File

@ -240,7 +240,7 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
va_end(ap);
len = strlen(print_buffer);
Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
Curl_debug(data, CURLINFO_TEXT, print_buffer, len);
}
}
@ -265,7 +265,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
if(data->set.verbose) {
error[len] = '\n';
error[++len] = '\0';
Curl_debug(data, CURLINFO_TEXT, error, len, NULL);
Curl_debug(data, CURLINFO_TEXT, error, len);
}
va_end(ap);
}
@ -300,7 +300,7 @@ CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
break;
if(data->set.verbose)
Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written);
if((size_t)bytes_written != write_len) {
/* if not all was written at once, we must advance the pointer, decrease
@ -762,8 +762,8 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */
}
/* return 0 on success */
static int showit(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size)
int Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size)
{
static const char s_infotype[CURLINFO_END][3] = {
"* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
@ -834,41 +834,3 @@ static int showit(struct Curl_easy *data, curl_infotype type,
#endif
return rc;
}
int Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size,
struct connectdata *conn)
{
int rc;
if(data->set.printhost && conn && conn->host.dispname) {
char buffer[160];
const char *t = NULL;
const char *w = "Data";
switch(type) {
case CURLINFO_HEADER_IN:
w = "Header";
/* FALLTHROUGH */
case CURLINFO_DATA_IN:
t = "from";
break;
case CURLINFO_HEADER_OUT:
w = "Header";
/* FALLTHROUGH */
case CURLINFO_DATA_OUT:
t = "to";
break;
default:
break;
}
if(t) {
snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
conn->host.dispname);
rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
if(rc)
return rc;
}
}
rc = showit(data, type, ptr, size);
return rc;
}

View File

@ -84,9 +84,8 @@ CURLcode Curl_write_plain(struct connectdata *conn,
ssize_t *written);
/* the function used to output verbose information */
int Curl_debug(struct Curl_easy *handle, curl_infotype type,
char *data, size_t size,
struct connectdata *conn);
int Curl_debug(struct Curl_easy *data, curl_infotype type,
char *ptr, size_t size);
#endif /* HEADER_CURL_SENDF_H */

View File

@ -142,6 +142,25 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
va_arg(param, char *));
break;
case CURLOPT_TLS13_CIPHERS:
if(Curl_ssl_tls13_ciphersuites()) {
/* set preferred list of TLS 1.3 cipher suites */
result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG],
va_arg(param, char *));
}
else
return CURLE_NOT_BUILT_IN;
break;
case CURLOPT_PROXY_TLS13_CIPHERS:
if(Curl_ssl_tls13_ciphersuites()) {
/* set preferred list of TLS 1.3 cipher suites for proxy */
result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_PROXY],
va_arg(param, char *));
}
else
return CURLE_NOT_BUILT_IN;
break;
case CURLOPT_RANDOM_FILE:
/*
* This is the path name to a file that contains random data to seed
@ -1584,14 +1603,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
* String that holds the SSL crypto engine.
*/
argptr = va_arg(param, char *);
if(argptr && argptr[0])
result = Curl_ssl_set_engine(data, argptr);
if(argptr && argptr[0]) {
result = Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], argptr);
if(!result) {
result = Curl_ssl_set_engine(data, argptr);
}
}
break;
case CURLOPT_SSLENGINE_DEFAULT:
/*
* flag to set engine as default.
*/
Curl_setstropt(&data->set.str[STRING_SSL_ENGINE], NULL);
result = Curl_ssl_set_engine_default(data);
break;
case CURLOPT_CRLF:
@ -1942,6 +1966,11 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
if(data->share->sslsession == data->state.session)
data->state.session = NULL;
#ifdef USE_LIBPSL
if(data->psl == &data->share->psl)
data->psl = data->multi? &data->multi->psl: NULL;
#endif
data->share->dirty--;
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
@ -1973,8 +2002,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
data->state.session = data->share->sslsession;
}
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
#ifdef USE_LIBPSL
if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
data->psl = &data->share->psl;
#endif
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
/* check for host cache not needed,
* it will be done by curl_easy_perform */
@ -2562,6 +2595,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
case CURLOPT_DNS_SHUFFLE_ADDRESSES:
data->set.dns_shuffle_addresses = (0 != va_arg(param, long)) ? TRUE:FALSE;
break;
case CURLOPT_DISALLOW_USERNAME_IN_URL:
data->set.disallow_username_in_url =
(0 != va_arg(param, long)) ? TRUE : FALSE;
break;
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin@gmail.com>
* Copyright (C) 1998 - 2018, Florin Petriuc, <petriuc.florin@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -123,15 +123,11 @@ static const unsigned long K[64] = {
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
#ifndef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
/* compress 512-bits */
static int sha256_compress(struct sha256_state *md,
unsigned char *buf)
{
unsigned long S[8], W[64], t0, t1;
unsigned long t;
unsigned long S[8], W[64];
int i;
/* copy state into S */
for(i = 0; i < 8; i++) {
@ -146,12 +142,13 @@ static int sha256_compress(struct sha256_state *md,
W[i - 16];
}
/* Compress */
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
#define RND(a,b,c,d,e,f,g,h,i) \
unsigned long t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
unsigned long t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for(i = 0; i < 64; ++i) {
unsigned long t;
RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
@ -200,7 +197,7 @@ static int SHA256_Update(struct sha256_state *md,
inlen -= block_size;
}
else {
n = MIN(inlen, (block_size - md->curlen));
n = CURLMIN(inlen, (block_size - md->curlen));
memcpy(md->buf + md->curlen, in, n);
md->curlen += n;
in += n;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -25,6 +25,7 @@
#include <curl/curl.h>
#include "urldata.h"
#include "share.h"
#include "psl.h"
#include "vtls/vtls.h"
#include "curl_memory.h"
@ -106,6 +107,12 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
res = CURLSHE_NOMEM;
break;
case CURL_LOCK_DATA_PSL:
#ifndef USE_LIBPSL
res = CURLSHE_NOT_BUILT_IN;
#endif
break;
default:
res = CURLSHE_BAD_OPTION;
}
@ -205,6 +212,8 @@ curl_share_cleanup(struct Curl_share *share)
}
#endif
Curl_psl_destroy(&share->psl);
if(share->unlockfunc)
share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
free(share);

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -25,6 +25,7 @@
#include "curl_setup.h"
#include <curl/curl.h>
#include "cookie.h"
#include "psl.h"
#include "urldata.h"
#include "conncache.h"
@ -49,6 +50,9 @@ struct Curl_share {
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
struct CookieInfo *cookies;
#endif
#ifdef USE_LIBPSL
struct PslCache psl;
#endif
struct curl_ssl_session *sslsession;
size_t max_ssl_sessions;

105
lib/smb.c
View File

@ -59,6 +59,7 @@
static CURLcode smb_setup_connection(struct connectdata *conn);
static CURLcode smb_connect(struct connectdata *conn, bool *done);
static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
static CURLcode smb_do(struct connectdata *conn, bool *done);
static CURLcode smb_request_state(struct connectdata *conn, bool *done);
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
bool premature);
@ -73,7 +74,7 @@ static CURLcode smb_parse_url_path(struct connectdata *conn);
const struct Curl_handler Curl_handler_smb = {
"SMB", /* scheme */
smb_setup_connection, /* setup_connection */
ZERO_NULL, /* do_it */
smb_do, /* do_it */
smb_done, /* done */
ZERO_NULL, /* do_more */
smb_connect, /* connect_it */
@ -98,7 +99,7 @@ const struct Curl_handler Curl_handler_smb = {
const struct Curl_handler Curl_handler_smbs = {
"SMBS", /* scheme */
smb_setup_connection, /* setup_connection */
ZERO_NULL, /* do_it */
smb_do, /* do_it */
smb_done, /* done */
ZERO_NULL, /* do_more */
smb_connect, /* connect_it */
@ -173,7 +174,6 @@ enum smb_req_state {
/* SMB request data */
struct smb_request {
enum smb_req_state state;
char *share;
char *path;
unsigned short tid; /* Even if we connect to the same tree as another */
unsigned short fid; /* request, the tid will be different */
@ -182,7 +182,7 @@ struct smb_request {
static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
{
struct smb_conn *smb = &conn->proto.smbc;
struct smb_conn *smbc = &conn->proto.smbc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* For debug purposes */
static const char * const names[] = {
@ -194,12 +194,12 @@ static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
/* LAST */
};
if(smb->state != newstate)
if(smbc->state != newstate)
infof(conn->data, "SMB conn %p state change from %s to %s\n",
(void *)smb, names[smb->state], names[newstate]);
(void *)smbc, names[smbc->state], names[newstate]);
#endif
smb->state = newstate;
smbc->state = newstate;
}
static void request_state(struct connectdata *conn,
@ -228,6 +228,8 @@ static void request_state(struct connectdata *conn,
req->state = newstate;
}
/* this should setup things in the connection, not in the easy
handle */
static CURLcode smb_setup_connection(struct connectdata *conn)
{
struct smb_request *req;
@ -253,7 +255,6 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done)
return CURLE_LOGIN_DENIED;
/* Initialize the connection state */
memset(smbc, 0, sizeof(*smbc));
smbc->state = SMB_CONNECTING;
smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
if(!smbc->recv_buf)
@ -366,7 +367,7 @@ static CURLcode smb_send(struct connectdata *conn, ssize_t len,
ssize_t bytes_written;
CURLcode result;
result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
result = Curl_write(conn, FIRSTSOCKET, conn->data->state.ulbuf,
len, &bytes_written);
if(result)
return result;
@ -392,7 +393,7 @@ static CURLcode smb_flush(struct connectdata *conn)
return CURLE_OK;
result = Curl_write(conn, FIRSTSOCKET,
conn->data->state.uploadbuffer + smbc->sent,
conn->data->state.ulbuf + smbc->sent,
len, &bytes_written);
if(result)
return result;
@ -408,9 +409,12 @@ static CURLcode smb_flush(struct connectdata *conn)
static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
const void *msg, size_t msg_len)
{
smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
CURLcode result = Curl_get_upload_buffer(conn->data);
if(result)
return result;
smb_format_message(conn, (struct smb_header *)conn->data->state.ulbuf,
cmd, msg_len);
memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
memcpy(conn->data->state.ulbuf + sizeof(struct smb_header),
msg, msg_len);
return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
@ -475,11 +479,11 @@ static CURLcode smb_send_setup(struct connectdata *conn)
static CURLcode smb_send_tree_connect(struct connectdata *conn)
{
struct smb_request *req = conn->data->req.protop;
struct smb_tree_connect msg;
struct smb_conn *smbc = &conn->proto.smbc;
char *p = msg.bytes;
size_t byte_count = strlen(conn->host.name) + strlen(req->share);
size_t byte_count = strlen(conn->host.name) + strlen(smbc->share);
byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
if(byte_count > sizeof(msg.bytes))
return CURLE_FILESIZE_EXCEEDED;
@ -491,7 +495,7 @@ static CURLcode smb_send_tree_connect(struct connectdata *conn)
MSGCAT("\\\\");
MSGCAT(conn->host.name);
MSGCAT("\\");
MSGCATNULL(req->share);
MSGCATNULL(smbc->share);
MSGCATNULL(SERVICENAME); /* Match any type of service */
byte_count = p - msg.bytes;
msg.byte_count = smb_swap16((unsigned short)byte_count);
@ -571,11 +575,15 @@ static CURLcode smb_send_read(struct connectdata *conn)
static CURLcode smb_send_write(struct connectdata *conn)
{
struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
struct smb_write *msg;
struct smb_request *req = conn->data->req.protop;
curl_off_t offset = conn->data->req.offset;
curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
CURLcode result = Curl_get_upload_buffer(conn->data);
if(result)
return result;
msg = (struct smb_write *)conn->data->state.ulbuf;
if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
upload_size = MAX_PAYLOAD_SIZE - 1;
@ -602,9 +610,9 @@ 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 > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
(int) smbc->upload_size;
conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
size_t nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
smbc->upload_size;
conn->data->req.upload_fromhere = conn->data->state.ulbuf;
result = Curl_fillreadbuffer(conn, nread, &nread);
if(result && result != CURLE_AGAIN)
return result;
@ -910,55 +918,52 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
static CURLcode smb_done(struct connectdata *conn, CURLcode status,
bool premature)
{
struct smb_request *req = conn->data->req.protop;
(void) premature;
Curl_safefree(req->share);
Curl_safefree(conn->data->req.protop);
return status;
}
static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
{
struct smb_conn *smbc = &conn->proto.smbc;
struct smb_request *req = conn->data->req.protop;
(void) dead;
Curl_safefree(smbc->share);
Curl_safefree(smbc->domain);
Curl_safefree(smbc->recv_buf);
/* smb_done is not always called, so cleanup the request */
if(req) {
Curl_safefree(req->share);
}
return CURLE_OK;
}
static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks)
{
struct smb_conn *smbc = &conn->proto.smbc;
if(!numsocks)
return GETSOCK_BLANK;
socks[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
}
if(smbc->send_size || smbc->upload_size)
return GETSOCK_WRITESOCK(0);
static CURLcode smb_do(struct connectdata *conn, bool *done)
{
struct smb_conn *smbc = &conn->proto.smbc;
struct smb_request *req = conn->data->req.protop;
return GETSOCK_READSOCK(0);
*done = FALSE;
if(smbc->share) {
req->path = strchr(smbc->share, '\0');
if(req->path) {
req->path++;
return CURLE_OK;
}
}
return CURLE_URL_MALFORMAT;
}
static CURLcode smb_parse_url_path(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
struct smb_request *req = data->req.protop;
struct smb_conn *smbc = &conn->proto.smbc;
char *path;
char *slash;
@ -968,35 +973,29 @@ static CURLcode smb_parse_url_path(struct connectdata *conn)
return result;
/* Parse the path for the share */
req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
if(!req->share) {
free(path);
smbc->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
free(path);
if(!smbc->share)
return CURLE_OUT_OF_MEMORY;
}
slash = strchr(req->share, '/');
slash = strchr(smbc->share, '/');
if(!slash)
slash = strchr(req->share, '\\');
slash = strchr(smbc->share, '\\');
/* The share must be present */
if(!slash) {
free(path);
Curl_safefree(smbc->share);
return CURLE_URL_MALFORMAT;
}
/* Parse the path for the file path converting any forward slashes into
backslashes */
*slash++ = 0;
req->path = slash;
for(; *slash; slash++) {
if(*slash == '/')
*slash = '\\';
}
free(path);
return CURLE_OK;
}

View File

@ -35,6 +35,7 @@ struct smb_conn {
enum smb_conn_state state;
char *user;
char *domain;
char *share;
unsigned char challenge[8];
unsigned int session_key;
unsigned short uid;

View File

@ -704,7 +704,6 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
struct smtp_conn *smtpc = &conn->proto.smtpc;
const char *line = data->state.buffer;
size_t len = strlen(line);
size_t wordlen;
(void)instate; /* no use for this yet */
@ -739,6 +738,7 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
/* Loop through the data line */
for(;;) {
size_t llen;
size_t wordlen;
unsigned int mechbit;
while(len &&
@ -1563,13 +1563,14 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
if(!scratch || data->set.crlf) {
oldscratch = scratch;
scratch = newscratch = malloc(2 * data->set.buffer_size);
scratch = newscratch = malloc(2 * UPLOAD_BUFSIZE);
if(!newscratch) {
failf(data, "Failed to alloc scratch buffer!");
return CURLE_OUT_OF_MEMORY;
}
}
DEBUGASSERT(UPLOAD_BUFSIZE >= nread);
/* Have we already sent part of the EOB? */
eob_sent = smtp->eob;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -57,10 +57,9 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
ssize_t nread;
ssize_t allread = 0;
int result;
timediff_t timeleft;
*n = 0;
for(;;) {
timeleft = Curl_timeleft(conn->data, NULL, TRUE);
timediff_t timeleft = Curl_timeleft(conn->data, NULL, TRUE);
if(timeleft < 0) {
/* we already got the timeout */
result = CURLE_OPERATION_TIMEDOUT;
@ -116,7 +115,6 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
#define SOCKS4REQLEN 262
unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
id */
int result;
CURLcode code;
curl_socket_t sock = conn->sock[sockindex];
struct Curl_easy *data = conn->data;
@ -220,11 +218,12 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
* Make connection
*/
{
int result;
ssize_t actualread;
ssize_t written;
ssize_t hostnamelen = 0;
int packetsize = 9 +
(int)strlen((char *)socksreq + 8); /* size including NUL */
ssize_t packetsize = 9 +
strlen((char *)socksreq + 8); /* size including NUL */
/* If SOCKS4a, set special invalid IP address 0.0.0.x */
if(protocol4a) {
@ -617,11 +616,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
if(dns)
hp = dns->addr;
if(hp) {
int i;
char buf[64];
Curl_printable_address(hp, buf, sizeof(buf));
if(hp->ai_family == AF_INET) {
int i;
struct sockaddr_in *saddr_in;
socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
@ -634,6 +633,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
}
#ifdef ENABLE_IPV6
else if(hp->ai_family == AF_INET6) {
int i;
struct sockaddr_in6 *saddr_in6;
socksreq[len++] = 4; /* ATYP: IPv6 = 4 */

View File

@ -41,7 +41,6 @@ struct Curl_tree *Curl_splay(struct curltime i,
struct Curl_tree *t)
{
struct Curl_tree N, *l, *r, *y;
long comp;
if(t == NULL)
return t;
@ -49,7 +48,7 @@ struct Curl_tree *Curl_splay(struct curltime i,
l = r = &N;
for(;;) {
comp = compare(i, t->key);
long comp = compare(i, t->key);
if(comp < 0) {
if(t->smaller == NULL)
break;

View File

@ -204,11 +204,21 @@ static CURLcode sftp_error_to_CURLE(int err)
return CURLE_SSH;
}
#ifndef DEBUGBUILD
#define state(x,y) mystate(x,y)
#else
#define state(x,y) mystate(x,y, __LINE__)
#endif
/*
* SSH State machine related code
*/
/* This is the ONLY way to change SSH state! */
static void state(struct connectdata *conn, sshstate nowstate)
static void mystate(struct connectdata *conn, sshstate nowstate
#ifdef DEBUGBUILD
, int lineno
#endif
)
{
struct ssh_conn *sshc = &conn->proto.sshc;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
@ -278,8 +288,9 @@ static void state(struct connectdata *conn, sshstate nowstate)
if(sshc->state != nowstate) {
infof(conn->data, "SSH %p state change from %s to %s\n",
(void *) sshc, names[sshc->state], names[nowstate]);
infof(conn->data, "SSH %p state change from %s to %s (line %d)\n",
(void *) sshc, names[sshc->state], names[nowstate],
lineno);
}
#endif
@ -418,7 +429,7 @@ cleanup:
}
#define MOVE_TO_ERROR_STATE(_r) { \
state(conn, SSH_SESSION_FREE); \
state(conn, SSH_SESSION_DISCONNECT); \
sshc->actualcode = _r; \
rc = SSH_ERROR; \
break; \
@ -486,7 +497,7 @@ restart:
if(rc < 0)
return SSH_ERROR;
/* fallthrough */
/* FALLTHROUGH */
case 1:
sshc->kbd_state = 1;
@ -561,7 +572,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
ssh_set_blocking(sshc->ssh_session, 0);
state(conn, SSH_S_STARTUP);
/* fall-through */
/* FALLTHROUGH */
case SSH_S_STARTUP:
rc = ssh_connect(sshc->ssh_session);
@ -575,7 +586,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_HOSTKEY);
/* fall-through */
/* FALLTHROUGH */
case SSH_HOSTKEY:
rc = myssh_is_known(conn);
@ -584,7 +595,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
}
state(conn, SSH_AUTHLIST);
/* fall through */
/* FALLTHROUGH */
case SSH_AUTHLIST:{
sshc->authed = FALSE;
@ -607,6 +618,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
state(conn, SSH_AUTH_PKEY_INIT);
infof(data, "Authentication using SSH public key file\n");
}
else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
state(conn, SSH_AUTH_GSSAPI);
@ -651,6 +663,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(rc != SSH_OK) {
failf(data, "Could not load private key file %s",
data->set.str[STRING_SSH_PRIVATE_KEY]);
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
break;
}
@ -659,8 +672,6 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
}
else {
infof(data, "Authentication using SSH public key file\n");
rc = ssh_userauth_publickey_auto(sshc->ssh_session, NULL,
data->set.ssl.key_passwd);
if(rc == SSH_AUTH_AGAIN) {
@ -748,7 +759,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
}
state(conn, SSH_AUTH_PASS);
/* fall through */
/* FALLTHROUGH */
case SSH_AUTH_PASS:
rc = ssh_userauth_password(sshc->ssh_session, NULL, conn->passwd);
@ -812,7 +823,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
state(conn, SSH_SFTP_REALPATH);
/* fall through */
/* FALLTHROUGH */
case SSH_SFTP_REALPATH:
/*
* Get the "home" directory
@ -1279,7 +1290,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(sshc->readdir_attrs) {
sshc->readdir_filename = sshc->readdir_attrs->name;
sshc->readdir_longentry = sshc->readdir_attrs->longname;
sshc->readdir_len = (int)strlen(sshc->readdir_filename);
sshc->readdir_len = strlen(sshc->readdir_filename);
if(data->set.ftp_list_only) {
char *tmpLine;
@ -1306,11 +1317,11 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT,
(char *)sshc->readdir_filename,
sshc->readdir_len, conn);
sshc->readdir_len);
}
}
else {
sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
sshc->readdir_currLen = strlen(sshc->readdir_longentry);
sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
if(!sshc->readdir_line) {
@ -1371,12 +1382,12 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
if(sshc->readdir_filename == NULL)
sshc->readdir_len = 0;
else
sshc->readdir_len = (int)strlen(sshc->readdir_tmp);
sshc->readdir_len = strlen(sshc->readdir_tmp);
sshc->readdir_longentry = NULL;
sshc->readdir_filename = sshc->readdir_tmp;
}
else {
sshc->readdir_len = (int)strlen(sshc->readdir_link_attrs->name);
sshc->readdir_len = strlen(sshc->readdir_link_attrs->name);
sshc->readdir_filename = sshc->readdir_link_attrs->name;
sshc->readdir_longentry = sshc->readdir_link_attrs->longname;
}
@ -1408,7 +1419,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
sshc->readdir_longentry = NULL;
state(conn, SSH_SFTP_READDIR_BOTTOM);
/* fall through */
/* FALLTHROUGH */
case SSH_SFTP_READDIR_BOTTOM:
sshc->readdir_currLen += snprintf(sshc->readdir_line +
sshc->readdir_currLen,
@ -1423,7 +1434,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
/* output debug output if that is requested */
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
sshc->readdir_currLen, conn);
sshc->readdir_currLen);
}
data->req.bytecount += sshc->readdir_currLen;
}
@ -1740,7 +1751,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT);
}
state(conn, SSH_SCP_DOWNLOAD);
/* fall through */
/* FALLTHROUGH */
case SSH_SCP_DOWNLOAD:{
curl_off_t bytecount;
@ -1805,7 +1816,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
ssh_set_blocking(sshc->ssh_session, 0);
state(conn, SSH_SESSION_DISCONNECT);
/* fall through */
/* FALLTHROUGH */
case SSH_SESSION_DISCONNECT:
/* during weird times when we've been prematurely aborted, the channel
@ -1822,7 +1833,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block)
conn->data->state.most_recent_ftp_entrypath = NULL;
state(conn, SSH_SESSION_FREE);
/* fall through */
/* FALLTHROUGH */
case SSH_SESSION_FREE:
if(sshc->ssh_session) {
ssh_free(sshc->ssh_session);
@ -2379,7 +2390,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
if(!status && !premature && conn->data->set.postquote) {
if(!status && !premature && conn->data->set.postquote &&
!conn->bits.retry) {
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
state(conn, SSH_SFTP_CLOSE);
}
@ -2437,7 +2449,7 @@ static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
return -1;
}
/* fall-through */
/* FALLTHROUGH */
case 1:
conn->proto.sshc.sftp_recv_state = 1;
@ -2500,8 +2512,8 @@ static void sftp_quote(struct connectdata *conn)
return;
}
if(data->set.verbose) {
Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4, conn);
Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
Curl_debug(data, CURLINFO_HEADER_OUT, (char *) "PWD\n", 4);
Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
}
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when

View File

@ -659,7 +659,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
libssh2_session_set_blocking(sshc->ssh_session, 0);
state(conn, SSH_S_STARTUP);
/* fall-through */
/* FALLTHROUGH */
case SSH_S_STARTUP:
rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
@ -675,7 +675,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_HOSTKEY);
/* fall-through */
/* FALLTHROUGH */
case SSH_HOSTKEY:
/*
* Before we authenticate we should check the hostkey's fingerprint
@ -1175,8 +1175,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
if(data->set.verbose) {
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
}
/* this sends an FTP-like "header" to the header callback so that the
current directory can be read very similar to how it is read when
@ -1933,17 +1933,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
case SSH_SFTP_READDIR:
sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
sshc->readdir_filename,
PATH_MAX,
sshc->readdir_longentry,
PATH_MAX,
&sshc->readdir_attrs);
if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
sshc->readdir_filename,
PATH_MAX,
sshc->readdir_longentry,
PATH_MAX,
&sshc->readdir_attrs);
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
if(sshc->readdir_len > 0) {
if(rc > 0) {
sshc->readdir_len = (size_t) rc;
sshc->readdir_filename[sshc->readdir_len] = '\0';
if(data->set.ftp_list_only) {
@ -1970,11 +1970,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* output debug output if that is requested */
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
sshc->readdir_len, conn);
sshc->readdir_len);
}
}
else {
sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
sshc->readdir_currLen = strlen(sshc->readdir_longentry);
sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
if(!sshc->readdir_line) {
@ -2008,13 +2008,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
}
else if(sshc->readdir_len == 0) {
else if(rc == 0) {
Curl_safefree(sshc->readdir_filename);
Curl_safefree(sshc->readdir_longentry);
state(conn, SSH_SFTP_READDIR_DONE);
break;
}
else if(sshc->readdir_len <= 0) {
else if(rc < 0) {
err = sftp_libssh2_last_error(sshc->sftp_session);
result = sftp_libssh2_error_to_CURLE(err);
sshc->actualcode = result?result:CURLE_SSH;
@ -2029,16 +2029,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
case SSH_SFTP_READDIR_LINK:
sshc->readdir_len =
rc =
libssh2_sftp_symlink_ex(sshc->sftp_session,
sshc->readdir_linkPath,
curlx_uztoui(strlen(sshc->readdir_linkPath)),
sshc->readdir_filename,
PATH_MAX, LIBSSH2_SFTP_READLINK);
if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
rc = LIBSSH2_ERROR_EAGAIN;
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
sshc->readdir_len = (size_t) rc;
Curl_safefree(sshc->readdir_linkPath);
/* get room for the filename and extra output */
@ -2079,7 +2079,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* output debug output if that is requested */
if(data->set.verbose) {
Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
sshc->readdir_currLen, conn);
sshc->readdir_currLen);
}
data->req.bytecount += sshc->readdir_currLen;
}
@ -3219,7 +3219,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
/* Post quote commands are executed after the SFTP_CLOSE state to avoid
errors that could happen due to open file handles during POSTQUOTE
operation */
if(!status && !premature && conn->data->set.postquote) {
if(!status && !premature && conn->data->set.postquote &&
!conn->bits.retry) {
sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
state(conn, SSH_SFTP_CLOSE);
}

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -131,7 +131,7 @@ struct ssh_conn {
quote command fails) */
char *homedir; /* when doing SFTP we figure out home dir in the
connect phase */
int readdir_len, readdir_totalLen, readdir_currLen;
size_t readdir_len, readdir_totalLen, readdir_currLen;
char *readdir_line;
char *readdir_linkPath;
/* end of READDIR stuff */

View File

@ -46,6 +46,5 @@ char Curl_raw_toupper(char in);
#define checkprefix(a,b) curl_strnequal(a,b,strlen(a))
void Curl_strntoupper(char *dest, const char *src, size_t n);
char Curl_raw_toupper(char in);
#endif /* HEADER_CURL_STRCASE_H */

View File

@ -26,6 +26,7 @@
#include <curl/curl.h>
#include "system_win32.h"
#include "warnless.h"
/* The last #include files should be: */
#include "curl_memory.h"
@ -134,8 +135,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
break;
case VERSION_LESS_THAN_EQUAL:
if(osver.dwMajorVersion <= majorVersion &&
osver.dwMinorVersion <= minorVersion)
if(osver.dwMajorVersion < majorVersion ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion <= minorVersion))
matched = TRUE;
break;
@ -146,8 +148,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
break;
case VERSION_GREATER_THAN_EQUAL:
if(osver.dwMajorVersion >= majorVersion &&
osver.dwMinorVersion >= minorVersion)
if(osver.dwMajorVersion > majorVersion ||
(osver.dwMajorVersion == majorVersion &&
osver.dwMinorVersion >= minorVersion))
matched = TRUE;
break;
@ -278,7 +281,9 @@ HMODULE Curl_load_library(LPCTSTR filename)
/* Attempt to find LoadLibraryEx() which is only available on Windows 2000
and above */
pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);
pLoadLibraryEx =
CURLX_FUNCTION_CAST(LOADLIBRARYEX_FN,
(GetProcAddress(hKernel32, LOADLIBARYEX)));
/* Detect if there's already a path in the filename and load the library if
there is. Note: Both back slashes and forward slashes have been supported

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, 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
@ -52,10 +52,6 @@
#include "connect.h"
#include "progress.h"
#include "system_win32.h"
#define TELOPTS
#define TELCMDS
#include "arpa_telnet.h"
#include "select.h"
#include "strcase.h"
@ -74,10 +70,10 @@
x->subend = x->subpointer; \
CURL_SB_CLEAR(x); \
} WHILE_FALSE
#define CURL_SB_ACCUM(x,c) \
do { \
if(x->subpointer < (x->subbuffer + sizeof x->subbuffer)) \
*x->subpointer++ = (c); \
#define CURL_SB_ACCUM(x,c) \
do { \
if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer))) \
*x->subpointer++ = (c); \
} WHILE_FALSE
#define CURL_SB_GET(x) ((*x->subpointer++)&0xff)
@ -92,6 +88,7 @@
#endif
#ifdef USE_WINSOCK
typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void);
typedef FARPROC WSOCK2_FUNC;
static CURLcode check_wsock2(struct Curl_easy *data);
#endif
@ -109,8 +106,10 @@ static void printoption(struct Curl_easy *data,
static void negotiate(struct connectdata *);
static void send_negotiation(struct connectdata *, int cmd, int option);
static void set_local_option(struct connectdata *, int cmd, int option);
static void set_remote_option(struct connectdata *, int cmd, int option);
static void set_local_option(struct connectdata *conn,
int option, int newstate);
static void set_remote_option(struct connectdata *conn,
int option, int newstate);
static void printsub(struct Curl_easy *data,
int direction, unsigned char *pointer,
@ -311,9 +310,6 @@ static void negotiate(struct connectdata *conn)
static void printoption(struct Curl_easy *data,
const char *direction, int cmd, int option)
{
const char *fmt;
const char *opt;
if(data->set.verbose) {
if(cmd == CURL_IAC) {
if(CURL_TELCMD_OK(option))
@ -322,9 +318,12 @@ static void printoption(struct Curl_easy *data,
infof(data, "%s IAC %d\n", direction, option);
}
else {
fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
(cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
const char *fmt = (cmd == CURL_WILL) ? "WILL" :
(cmd == CURL_WONT) ? "WONT" :
(cmd == CURL_DO) ? "DO" :
(cmd == CURL_DONT) ? "DONT" : 0;
if(fmt) {
const char *opt;
if(CURL_TELOPT_OK(option))
opt = CURL_TELOPT(option);
else if(option == CURL_TELOPT_EXOPL)
@ -348,7 +347,6 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
{
unsigned char buf[3];
ssize_t bytes_written;
int err;
struct Curl_easy *data = conn->data;
buf[0] = CURL_IAC;
@ -357,7 +355,7 @@ static void send_negotiation(struct connectdata *conn, int cmd, int option)
bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
if(bytes_written < 0) {
err = SOCKERRNO;
int err = SOCKERRNO;
failf(data,"Sending data failed (%d)",err);
}
@ -710,9 +708,8 @@ static void printsub(struct Curl_easy *data,
unsigned char *pointer, /* where suboption data is */
size_t length) /* length of suboption data */
{
unsigned int i = 0;
if(data->set.verbose) {
unsigned int i = 0;
if(direction) {
infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
if(length >= 3) {
@ -764,7 +761,7 @@ static void printsub(struct Curl_easy *data,
switch(pointer[0]) {
case CURL_TELOPT_NAWS:
if(length > 4)
infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
infof(data, "Width: %d ; Height: %d", (pointer[1]<<8) | pointer[2],
(pointer[3]<<8) | pointer[4]);
break;
default:
@ -928,7 +925,6 @@ static void suboption(struct connectdata *conn)
unsigned char temp[2048];
ssize_t bytes_written;
size_t len;
size_t tmplen;
int err;
char varname[128] = "";
char varval[128] = "";
@ -968,7 +964,7 @@ static void suboption(struct connectdata *conn)
len = 4;
for(v = tn->telnet_vars; v; v = v->next) {
tmplen = (strlen(v->data) + 1);
size_t tmplen = (strlen(v->data) + 1);
/* Add the variable only if it fits */
if(len + tmplen < (int)sizeof(temp)-6) {
if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
@ -1017,7 +1013,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 endian processors */
/* We must deal either with little or big endian processors */
/* Window size must be sent according to the 'network order' */
x = htons(tn->subopt_wsx);
y = htons(tn->subopt_wsy);
@ -1223,7 +1219,7 @@ CURLcode telrcv(struct connectdata *conn,
static CURLcode send_telnet_data(struct connectdata *conn,
char *buffer, ssize_t nread)
{
ssize_t escapes, i, j, outlen;
ssize_t escapes, i, outlen;
unsigned char *outbuf = NULL;
CURLcode result = CURLE_OK;
ssize_t bytes_written, total_written;
@ -1238,6 +1234,7 @@ static CURLcode send_telnet_data(struct connectdata *conn,
if(outlen == nread)
outbuf = (unsigned char *)buffer;
else {
ssize_t j;
outbuf = malloc(nread + escapes + 1);
if(!outbuf)
return CURLE_OUT_OF_MEMORY;
@ -1306,7 +1303,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
#ifdef USE_WINSOCK
HMODULE wsock2;
WSOCK2_FUNC close_event_func;
WSOCK2_FUNC create_event_func;
WSOCK2_EVENT create_event_func;
WSOCK2_FUNC event_select_func;
WSOCK2_FUNC enum_netevents_func;
WSAEVENT event_handle;
@ -1315,7 +1312,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
HANDLE objs[2];
DWORD obj_count;
DWORD wait_timeout;
DWORD waitret;
DWORD readfile_read;
int err;
#else
@ -1361,7 +1357,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
}
/* Grab a pointer to WSACreateEvent */
create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
create_event_func =
CURLX_FUNCTION_CAST(WSOCK2_EVENT,
(GetProcAddress(wsock2, "WSACreateEvent")));
if(create_event_func == NULL) {
failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
FreeLibrary(wsock2);
@ -1438,7 +1436,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
/* Keep on listening and act on events */
while(keepon) {
const DWORD buf_size = (DWORD)data->set.buffer_size;
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
DWORD waitret = WaitForMultipleObjects(obj_count, objs,
FALSE, wait_timeout);
switch(waitret) {
case WAIT_TIMEOUT:
{
@ -1607,7 +1606,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
case 0: /* timeout */
pfd[0].revents = 0;
pfd[1].revents = 0;
/* fall through */
/* FALLTHROUGH */
default: /* read! */
if(pfd[0].revents & POLLIN) {
/* read data from network */

View File

@ -451,7 +451,6 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
ssize_t senddata;
const char *mode = "octet";
char *filename;
char buf[64];
struct Curl_easy *data = state->conn->data;
CURLcode result = CURLE_OK;
@ -504,6 +503,7 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
/* optional addition of TFTP options */
if(!data->set.tftp_no_options) {
char buf[64];
/* add tsize option */
if(data->set.upload && (data->state.infilesize != -1))
snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
@ -710,10 +710,9 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
{
struct Curl_easy *data = state->conn->data;
ssize_t sbytes;
int rblock;
CURLcode result = CURLE_OK;
struct SingleRequest *k = &data->req;
int cb; /* Bytes currently read */
size_t cb; /* Bytes currently read */
switch(event) {
@ -721,7 +720,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
case TFTP_EVENT_OACK:
if(event == TFTP_EVENT_ACK) {
/* Ack the packet */
rblock = getrpacketblock(&state->rpacket);
int rblock = getrpacketblock(&state->rpacket);
if(rblock != state->block &&
/* There's a bug in tftpd-hpa that causes it to send us an ack for
@ -766,7 +765,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
state->retries = 0;
setpacketevent(&state->spacket, TFTP_EVENT_DATA);
setpacketblock(&state->spacket, state->block);
if(state->block > 1 && state->sbytes < (int)state->blksize) {
if(state->block > 1 && state->sbytes < state->blksize) {
state->state = TFTP_STATE_FIN;
return CURLE_OK;
}
@ -782,7 +781,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
&cb);
if(result)
return result;
state->sbytes += cb;
state->sbytes += (int)cb;
state->conn->data->req.upload_fromhere += cb;
} while(state->sbytes < state->blksize && cb != 0);
@ -969,7 +968,7 @@ static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
static CURLcode tftp_connect(struct connectdata *conn, bool *done)
{
tftp_state_data_t *state;
int blksize, rc;
int blksize;
blksize = TFTP_BLKSIZE_DEFAULT;
@ -1028,8 +1027,8 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
* assume uses the same IP version and thus hopefully this works for both
* IPv4 and IPv6...
*/
rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
conn->ip_addr->ai_addrlen);
int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
conn->ip_addr->ai_addrlen);
if(rc) {
failf(conn->data, "bind() failed; %s",
Curl_strerror(conn, SOCKERRNO));
@ -1148,8 +1147,11 @@ static CURLcode tftp_receive_packet(struct connectdata *conn)
case TFTP_EVENT_ERROR:
{
unsigned short error = getrpacketblock(&state->rpacket);
char *str = (char *)state->rpacket.data + 4;
size_t strn = state->rbytes - 4;
state->error = (tftp_error_t)error;
infof(data, "%s\n", (const char *)state->rpacket.data + 4);
if(Curl_strnlen(str, strn) < strn)
infof(data, "TFTP error: %s\n", str);
break;
}
case TFTP_EVENT_ACK:
@ -1221,7 +1223,6 @@ static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
**********************************************************/
static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
{
int rc;
tftp_event_t event;
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
@ -1245,7 +1246,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
}
else {
/* no timeouts to handle, check our socket */
rc = SOCKET_READABLE(state->sockfd, 0);
int rc = SOCKET_READABLE(state->sockfd, 0);
if(rc == -1) {
/* bail out */
@ -1368,7 +1369,6 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
{
struct Curl_easy *data = conn->data;
char *type;
char command;
conn->socktype = SOCK_DGRAM; /* UDP datagram based */
@ -1380,6 +1380,7 @@ static CURLcode tftp_setup_connection(struct connectdata * conn)
type = strstr(conn->host.rawalloc, ";mode=");
if(type) {
char command;
*type = 0; /* it was in the middle of the hostname */
command = Curl_raw_toupper(type[6]);

View File

@ -106,15 +106,26 @@ char *Curl_checkheaders(const struct connectdata *conn,
}
#endif
CURLcode Curl_get_upload_buffer(struct Curl_easy *data)
{
if(!data->state.ulbuf) {
data->state.ulbuf = malloc(data->set.upload_buffer_size);
if(!data->state.ulbuf)
return CURLE_OUT_OF_MEMORY;
}
return CURLE_OK;
}
/*
* This function will call the read callback to fill our buffer with data
* to upload.
*/
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
size_t *nreadp)
{
struct Curl_easy *data = conn->data;
size_t buffersize = (size_t)bytes;
int nread;
size_t buffersize = bytes;
size_t nread;
#ifdef CURL_DOES_CONVERSIONS
bool sending_http_headers = FALSE;
@ -134,11 +145,9 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
}
/* this function returns a size_t, so we typecast to int to prevent warnings
with picky compilers */
Curl_set_in_callback(data, true);
nread = (int)data->state.fread_func(data->req.upload_fromhere, 1,
buffersize, data->state.in);
nread = data->state.fread_func(data->req.upload_fromhere, 1,
buffersize, data->state.in);
Curl_set_in_callback(data, false);
if(nread == CURL_READFUNC_ABORT) {
@ -167,7 +176,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
return CURLE_OK; /* nothing was read */
}
else if((size_t)nread > buffersize) {
else if(nread > buffersize) {
/* the read function returned a too large value */
*nreadp = 0;
failf(data, "read function returned funny value");
@ -226,13 +235,13 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
#ifdef CURL_DOES_CONVERSIONS
{
CURLcode result;
int length;
size_t length;
if(data->set.prefer_ascii)
/* translate the protocol and data */
length = nread;
else
/* just translate the protocol portion */
length = (int)strlen(hexbuffer);
length = strlen(hexbuffer);
result = Curl_convert_to_network(data, data->req.upload_fromhere,
length);
/* Curl_convert_to_network calls failf if unsuccessful */
@ -247,7 +256,7 @@ CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
infof(data, "Signaling end of chunked upload via terminating chunk.\n");
}
nread += (int)strlen(endofline_native); /* for the added end of line */
nread += strlen(endofline_native); /* for the added end of line */
}
#ifdef CURL_DOES_CONVERSIONS
else if((data->set.prefer_ascii) && (!sending_http_headers)) {
@ -444,7 +453,6 @@ static CURLcode readwrite_data(struct Curl_easy *data,
CURLcode result = CURLE_OK;
ssize_t nread; /* number of bytes read */
size_t excess = 0; /* excess bytes read */
bool is_empty_data = FALSE;
bool readmore = FALSE; /* used by RTP to signal for more data */
int maxloops = 100;
@ -454,6 +462,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
/* This is where we loop until we have read everything there is to
read or we get a CURLE_AGAIN */
do {
bool is_empty_data = FALSE;
size_t buffersize = data->set.buffer_size;
size_t bytestoread = buffersize;
@ -660,14 +669,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
if(data->set.verbose) {
if(k->badheader) {
Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
(size_t)k->hbuflen, conn);
(size_t)k->hbuflen);
if(k->badheader == HEADER_PARTHEADER)
Curl_debug(data, CURLINFO_DATA_IN,
k->str, (size_t)nread, conn);
k->str, (size_t)nread);
}
else
Curl_debug(data, CURLINFO_DATA_IN,
k->str, (size_t)nread, conn);
k->str, (size_t)nread);
}
#ifndef CURL_DISABLE_HTTP
@ -797,7 +806,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
nread);
}
}
else
else if(!k->ignorebody)
result = Curl_unencode_write(conn, k->writer_stack, k->str, nread);
}
k->badheader = HEADER_NORMAL; /* taken care of now */
@ -869,6 +878,26 @@ static CURLcode done_sending(struct connectdata *conn,
return CURLE_OK;
}
#ifdef WIN32
#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B
#endif
static void win_update_buffer_size(curl_socket_t sockfd)
{
int result;
ULONG ideal;
DWORD ideallen;
result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0,
&ideal, sizeof(ideal), &ideallen, 0, 0);
if(result == 0) {
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
(const char *)&ideal, sizeof(ideal));
}
}
#else
#define win_update_buffer_size(x)
#endif
/*
* Send data to upload to the server, when the socket is writable.
@ -894,13 +923,16 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
/* only read more data if there's no upload data already
present in the upload buffer */
if(0 == k->upload_present) {
result = Curl_get_upload_buffer(data);
if(result)
return result;
/* init the "upload from here" pointer */
k->upload_fromhere = data->state.uploadbuffer;
k->upload_fromhere = data->state.ulbuf;
if(!k->upload_done) {
/* HTTP pollution, this should be written nicer to become more
protocol agnostic. */
int fillcount;
size_t fillcount;
struct HTTP *http = k->protop;
if((k->exp100 == EXP100_SENDING_REQUEST) &&
@ -931,7 +963,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
if(result)
return result;
nread = (ssize_t)fillcount;
nread = fillcount;
}
else
nread = 0; /* we're done uploading/reading */
@ -959,7 +991,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
(data->set.crlf))) {
/* Do we need to allocate a scratch buffer? */
if(!data->state.scratch) {
data->state.scratch = malloc(2 * data->set.buffer_size);
data->state.scratch = malloc(2 * UPLOAD_BUFSIZE);
if(!data->state.scratch) {
failf(data, "Failed to alloc scratch buffer!");
@ -1020,14 +1052,15 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
k->upload_fromhere, /* buffer pointer */
k->upload_present, /* buffer size */
&bytes_written); /* actually sent */
if(result)
return result;
win_update_buffer_size(conn->writesockfd);
if(data->set.verbose)
/* show the data before we change the pointer upload_fromhere */
Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
(size_t)bytes_written, conn);
(size_t)bytes_written);
k->writebytecount += bytes_written;
@ -1050,7 +1083,10 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
}
else {
/* we've uploaded that buffer now */
k->upload_fromhere = data->state.uploadbuffer;
result = Curl_get_upload_buffer(data);
if(result)
return result;
k->upload_fromhere = data->state.ulbuf;
k->upload_present = 0; /* no more bytes left */
if(k->upload_done) {
@ -1482,7 +1518,7 @@ static size_t strlen_url(const char *url, bool relative)
switch(*ptr) {
case '?':
left = FALSE;
/* fall through */
/* FALLTHROUGH */
default:
if(urlchar_needs_escaping(*ptr))
newlen += 2;
@ -1527,7 +1563,7 @@ static void strcpy_url(char *output, const char *url, bool relative)
switch(*iptr) {
case '?':
left = FALSE;
/* fall through */
/* FALLTHROUGH */
default:
if(urlchar_needs_escaping(*iptr)) {
snprintf(optr, 4, "%%%02x", *iptr);

View File

@ -51,9 +51,11 @@ int Curl_single_getsock(const struct connectdata *conn,
curl_socket_t *socks,
int numsocks);
CURLcode Curl_readrewind(struct connectdata *conn);
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
CURLcode Curl_fillreadbuffer(struct connectdata *conn, size_t bytes,
size_t *nreadp);
CURLcode Curl_retry_request(struct connectdata *conn, char **url);
bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
CURLcode Curl_get_upload_buffer(struct Curl_easy *data);
/* This sets up a forthcoming transfer */
void

219
lib/url.c
View File

@ -127,7 +127,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
static void conn_free(struct connectdata *conn);
static void free_fixed_hostname(struct hostname *host);
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
static CURLcode parse_url_login(struct Curl_easy *data,
struct connectdata *conn,
char **userptr, char **passwdptr,
@ -368,11 +367,9 @@ CURLcode Curl_close(struct Curl_easy *data)
Curl_safefree(data->state.buffer);
Curl_safefree(data->state.headerbuff);
Curl_safefree(data->state.ulbuf);
Curl_flush_cookies(data, 1);
Curl_digest_cleanup(data);
Curl_safefree(data->info.contenttype);
Curl_safefree(data->info.wouldredirect);
@ -535,6 +532,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->expect_100_timeout = 1000L; /* Wait for a second by default. */
set->sep_headers = TRUE; /* separated header lists by default */
set->buffer_size = READBUFFER_SIZE;
set->upload_buffer_size = UPLOAD_BUFSIZE;
set->happy_eyeballs_timeout = CURL_HET_DEFAULT;
Curl_http2_init_userset(set);
@ -734,20 +732,23 @@ static void conn_free(struct connectdata *conn)
* primary connection, like when freeing room in the connection cache or
* killing of a dead old connection.
*
* A connection needs an easy handle when closing down. We support this passed
* in separately since the connection to get closed here is often already
* disassociated from an easy handle.
*
* This function MUST NOT reset state in the Curl_easy struct if that
* isn't strictly bound to the life-time of *this* particular connection.
*
*/
CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
CURLcode Curl_disconnect(struct Curl_easy *data,
struct connectdata *conn, bool dead_connection)
{
struct Curl_easy *data;
if(!conn)
return CURLE_OK; /* this is closed and fine already */
data = conn->data;
if(!data) {
DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
return CURLE_OK;
}
@ -755,13 +756,12 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
* If this connection isn't marked to force-close, leave it open if there
* are other users of it
*/
if(!conn->bits.close &&
(conn->send_pipe.size + conn->recv_pipe.size)) {
DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
conn->send_pipe.size + conn->recv_pipe.size));
if(CONN_INUSE(conn) && !dead_connection) {
DEBUGF(infof(data, "Curl_disconnect when inuse: %zu\n", CONN_INUSE(conn)));
return CURLE_OK;
}
conn->data = data;
if(conn->dns_entry != NULL) {
Curl_resolv_unlock(data, conn->dns_entry);
conn->dns_entry = NULL;
@ -787,16 +787,12 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
free_fixed_hostname(&conn->http_proxy.host);
free_fixed_hostname(&conn->socks_proxy.host);
DEBUGASSERT(conn->data == data);
/* this assumes that the pointer is still there after the connection was
detected from the cache */
Curl_ssl_close(conn, FIRSTSOCKET);
/* Indicate to all handles on the pipe that we're dead */
if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
signalPipeClose(&conn->send_pipe, TRUE);
signalPipeClose(&conn->recv_pipe, TRUE);
}
conn_free(conn);
return CURLE_OK;
}
@ -848,6 +844,7 @@ static int IsPipeliningPossible(const struct Curl_easy *handle,
return avail;
}
/* Returns non-zero if a handle was removed */
int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
struct curl_llist *pipeline)
{
@ -884,6 +881,16 @@ static void Curl_printPipeline(struct curl_llist *pipeline)
static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
{
struct curl_llist_element *curr = pipeline->head;
#ifdef DEBUGBUILD
{
struct curl_llist_element *p = pipeline->head;
while(p) {
struct Curl_easy *e = p->ptr;
DEBUGASSERT(GOOD_EASY_HANDLE(e));
p = p->next;
}
}
#endif
if(curr) {
return (struct Curl_easy *) curr->ptr;
}
@ -896,41 +903,22 @@ static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
void Curl_getoff_all_pipelines(struct Curl_easy *data,
struct connectdata *conn)
{
bool recv_head = (conn->readchannel_inuse &&
Curl_recvpipe_head(data, conn));
bool send_head = (conn->writechannel_inuse &&
Curl_sendpipe_head(data, conn));
if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
Curl_pipeline_leave_read(conn);
if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
Curl_pipeline_leave_write(conn);
}
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
{
struct curl_llist_element *curr;
if(!pipeline)
if(!conn->bundle)
return;
if(conn->bundle->multiuse == BUNDLE_PIPELINING) {
bool recv_head = (conn->readchannel_inuse &&
Curl_recvpipe_head(data, conn));
bool send_head = (conn->writechannel_inuse &&
Curl_sendpipe_head(data, conn));
curr = pipeline->head;
while(curr) {
struct curl_llist_element *next = curr->next;
struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
#ifdef DEBUGBUILD /* debug-only code */
if(data->magic != CURLEASY_MAGIC_NUMBER) {
/* MAJOR BADNESS */
infof(data, "signalPipeClose() found BAAD easy handle\n");
}
#endif
if(pipe_broke)
data->state.pipe_broke = TRUE;
Curl_multi_handlePipeBreak(data);
Curl_llist_remove(pipeline, curr, NULL);
curr = next;
if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
Curl_pipeline_leave_read(conn);
if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
Curl_pipeline_leave_write(conn);
}
else {
(void)Curl_removeHandleFromPipeline(data, &conn->recv_pipe);
(void)Curl_removeHandleFromPipeline(data, &conn->send_pipe);
}
}
@ -959,12 +947,13 @@ static bool extract_if_dead(struct connectdata *conn,
struct Curl_easy *data)
{
size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
if(!pipeLen && !conn->inuse) {
if(!pipeLen && !CONN_INUSE(conn)) {
/* The check for a dead socket makes sense only if there are no
handles in pipeline and the connection isn't already marked in
use */
bool dead;
conn->data = data;
if(conn->handler->connection_check) {
/* The protocol has a special method for checking the state of the
connection. Use it to check if the connection is dead. */
@ -979,9 +968,9 @@ static bool extract_if_dead(struct connectdata *conn,
}
if(dead) {
conn->data = data;
infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
Curl_conncache_remove_conn(conn, FALSE);
conn->data = NULL; /* detach */
return TRUE;
}
}
@ -1025,7 +1014,7 @@ static void prune_dead_connections(struct Curl_easy *data)
while(Curl_conncache_foreach(data, data->state.conn_cache, &prune,
call_extract_if_dead)) {
/* disconnect it */
(void)Curl_disconnect(prune.extracted, /* dead_connection */TRUE);
(void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE);
}
data->state.conn_cache->last_cleanup = now;
}
@ -1139,7 +1128,7 @@ ConnectionExists(struct Curl_easy *data,
if(extract_if_dead(check, data)) {
/* disconnect it */
(void)Curl_disconnect(check, /* dead_connection */TRUE);
(void)Curl_disconnect(data, check, /* dead_connection */TRUE);
continue;
}
@ -1267,12 +1256,12 @@ ConnectionExists(struct Curl_easy *data,
}
}
if(!canpipe && check->inuse)
if(!canpipe && CONN_INUSE(check))
/* this request can't be pipelined but the checked connection is
already in use so we skip it */
continue;
if((check->inuse) && (check->data->multi != needle->data->multi))
if(CONN_INUSE(check) && (check->data->multi != needle->data->multi))
/* this could be subject for pipeline/multiplex use, but only
if they belong to the same multi handle */
continue;
@ -1464,7 +1453,7 @@ ConnectionExists(struct Curl_easy *data,
if(chosen) {
/* mark it as used before releasing the lock */
chosen->inuse = TRUE;
chosen->data = data; /* own it! */
Curl_conncache_unlock(needle);
*usethis = chosen;
return TRUE; /* yes, we found one to use! */
@ -1554,7 +1543,11 @@ int Curl_protocol_getsock(struct connectdata *conn,
{
if(conn->handler->proto_getsock)
return conn->handler->proto_getsock(conn, socks, numsocks);
return GETSOCK_BLANK;
/* Backup getsock logic. Since there is a live socket in use, we must wait
for it or it will be removed from watching when the multi_socket API is
used. */
socks[0] = conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(0) | GETSOCK_WRITESOCK(0);
}
int Curl_doing_getsock(struct connectdata *conn,
@ -1999,7 +1992,6 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
char *fragment;
char *path = data->state.path;
char *query;
int i;
int rc;
const char *protop = "";
CURLcode result;
@ -2051,6 +2043,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
; /* do nothing */
}
else { /* check for a scheme */
int i;
for(i = 0; i < 16 && data->change.url[i]; ++i) {
if(data->change.url[i] == '/')
break;
@ -2203,7 +2196,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
size_t s = strlen(slashbuf);
protop = protobuf;
if(s != 2) {
infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
infof(data, "Unwillingly accepted illegal URL using %zu slash%s!\n",
s, s>1?"es":"");
if(data->change.url_alloc)
@ -2449,7 +2442,7 @@ static CURLcode setup_range(struct Curl_easy *data)
free(s->range);
if(s->resume_from)
s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
s->range = aprintf("%" CURL_FORMAT_CURL_OFF_T "-", s->resume_from);
else
s->range = strdup(data->set.str[STRING_SET_RANGE]);
@ -2481,18 +2474,6 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
{
const struct Curl_handler * p;
CURLcode result;
struct Curl_easy *data = conn->data;
/* in some case in the multi state-machine, we go back to the CONNECT state
and then a second (or third or...) call to this function will be made
without doing a DISCONNECT or DONE in between (since the connection is
yet in place) and therefore this function needs to first make sure
there's no lingering previous data allocated. */
Curl_free_request_state(data);
memset(&data->req, 0, sizeof(struct SingleRequest));
data->req.maxdownload = -1;
conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
/* Perform setup complement if some. */
@ -2539,14 +2520,13 @@ static bool check_noproxy(const char *name, const char *no_proxy)
* not be proxied, or an asterisk to override
* all proxy variables)
*/
size_t tok_start;
size_t tok_end;
const char *separator = ", ";
size_t no_proxy_len;
size_t namelen;
char *endptr;
if(no_proxy && no_proxy[0]) {
size_t tok_start;
size_t tok_end;
const char *separator = ", ";
size_t no_proxy_len;
size_t namelen;
char *endptr;
if(strcasecompare("*", no_proxy)) {
return TRUE;
}
@ -3166,6 +3146,13 @@ static CURLcode parse_url_login(struct Curl_easy *data,
if(userp) {
char *newname;
if(data->set.disallow_username_in_url) {
failf(data, "Option DISALLOW_USERNAME_IN_URL is set "
"and url contains username.");
result = CURLE_LOGIN_DENIED;
goto out;
}
/* We have a user in the URL */
conn->bits.userpwd_in_url = TRUE;
conn->bits.user_passwd = TRUE; /* enable user+password */
@ -3982,6 +3969,7 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->user);
Curl_safefree(old_conn->passwd);
Curl_safefree(old_conn->options);
Curl_safefree(old_conn->http_proxy.user);
Curl_safefree(old_conn->socks_proxy.user);
Curl_safefree(old_conn->http_proxy.passwd);
@ -4297,7 +4285,9 @@ static CURLcode create_conn(struct Curl_easy *data,
conn->data = data;
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
Curl_conncache_add_conn(data->state.conn_cache, conn);
result = Curl_conncache_add_conn(data->state.conn_cache, conn);
if(result)
goto out;
/*
* Setup whatever necessary for a resumed transfer
@ -4343,6 +4333,10 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
@ -4468,13 +4462,11 @@ static CURLcode create_conn(struct Curl_easy *data,
conn_candidate = Curl_conncache_extract_bundle(data, bundle);
Curl_conncache_unlock(conn);
if(conn_candidate) {
/* Set the connection's owner correctly, then kill it */
conn_candidate->data = data;
(void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
}
if(conn_candidate)
(void)Curl_disconnect(data, conn_candidate,
/* dead_connection */ FALSE);
else {
infof(data, "No more connections allowed to host: %d\n",
infof(data, "No more connections allowed to host: %zu\n",
max_host_connections);
connections_available = FALSE;
}
@ -4491,12 +4483,9 @@ static CURLcode create_conn(struct Curl_easy *data,
/* The cache is full. Let's see if we can kill a connection. */
conn_candidate = Curl_conncache_extract_oldest(data);
if(conn_candidate) {
/* Set the connection's owner correctly, then kill it */
conn_candidate->data = data;
(void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
}
if(conn_candidate)
(void)Curl_disconnect(data, conn_candidate,
/* dead_connection */ FALSE);
else {
infof(data, "No connections available in cache\n");
connections_available = FALSE;
@ -4513,14 +4502,13 @@ static CURLcode create_conn(struct Curl_easy *data,
goto out;
}
else {
/* Mark the connection as used, before we add it */
conn->inuse = TRUE;
/*
* This is a brand new connection, so let's store it in the connection
* cache of ours!
*/
Curl_conncache_add_conn(data->state.conn_cache, conn);
result = Curl_conncache_add_conn(data->state.conn_cache, conn);
if(result)
goto out;
}
#if defined(USE_NTLM)
@ -4656,12 +4644,16 @@ CURLcode Curl_connect(struct Curl_easy *data,
*asyncp = FALSE; /* assume synchronous resolves by default */
/* init the single-transfer specific data */
Curl_free_request_state(data);
memset(&data->req, 0, sizeof(struct SingleRequest));
data->req.maxdownload = -1;
/* call the stuff that needs to be called */
result = create_conn(data, in_connect, asyncp);
if(!result) {
/* no error */
if((*in_connect)->send_pipe.size || (*in_connect)->recv_pipe.size)
if(CONN_INUSE(*in_connect))
/* pipelining */
*protocol_done = TRUE;
else if(!*asyncp) {
@ -4676,12 +4668,11 @@ CURLcode Curl_connect(struct Curl_easy *data,
*in_connect = NULL;
return result;
}
if(result && *in_connect) {
/* We're not allowed to return failure with memory left allocated
in the connectdata struct, free those here */
Curl_disconnect(*in_connect, FALSE); /* close the connection */
*in_connect = NULL; /* return a NULL */
else if(result && *in_connect) {
/* We're not allowed to return failure with memory left allocated in the
connectdata struct, free those here */
Curl_disconnect(data, *in_connect, TRUE);
*in_connect = NULL; /* return a NULL */
}
return result;
@ -4701,16 +4692,18 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
{
struct SingleRequest *k = &data->req;
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
use */
if(conn) {
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
use */
/* if the protocol used doesn't support wildcards, switch it off */
if(data->state.wildcardmatch &&
!(conn->handler->flags & PROTOPT_WILDCARD))
data->state.wildcardmatch = FALSE;
}
data->state.done = FALSE; /* *_done() is not called yet */
data->state.expect100header = FALSE;
/* if the protocol used doesn't support wildcards, switch it off */
if(data->state.wildcardmatch &&
!(conn->handler->flags & PROTOPT_WILDCARD))
data->state.wildcardmatch = FALSE;
if(data->set.opt_no_body)
/* in HTTP lingo, no body means using the HEAD request... */

View File

@ -39,7 +39,8 @@ void Curl_freeset(struct Curl_easy * data);
CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
bool *async, bool *protocol_connect);
CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
CURLcode Curl_disconnect(struct Curl_easy *data,
struct connectdata *, bool dead_connection);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);

View File

@ -80,6 +80,7 @@
#define RESP_TIMEOUT (1800*1000)
#include "cookie.h"
#include "psl.h"
#include "formdata.h"
#ifdef HAVE_NETINET_IN_H
@ -142,8 +143,13 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#endif /* HAVE_LIBSSH2_H */
/* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as
it needs to hold a full buffer as could be sent in a write callback */
#define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE
it needs to hold a full buffer as could be sent in a write callback.
The size was 16KB for many years but was bumped to 64KB because it makes
libcurl able to do significantly faster uploads in some circumstances. Even
larger buffers can help further, but this is deemed a fair memory/speed
compromise. */
#define UPLOAD_BUFSIZE 65536
/* The "master buffer" is for HTTP pipelining */
#define MASTERBUF_SIZE 16384
@ -156,11 +162,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
#define GOOD_EASY_HANDLE(x) \
((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
/* Some convenience macros to get the larger/smaller value out of two given.
We prefix with CURL to prevent name collisions. */
#define CURLMAX(x,y) ((x)>(y)?(x):(y))
#define CURLMIN(x,y) ((x)<(y)?(x):(y))
#ifdef HAVE_GSSAPI
/* Types needed for krb5-ftp connections */
struct krb5buffer {
@ -226,6 +227,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 */
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
};
struct ssl_config_data {
@ -779,11 +781,12 @@ struct connectdata {
curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
void *closesocket_client;
bool inuse; /* This is a marker for the connection cache logic. If this is
TRUE this handle is being used by one or more easy handles
and can only used by any other easy handle without careful
consideration (== only for pipelining/multiplexing) and it
cannot be used by another multi handle! */
/* This is used by the connection cache logic. If this returns TRUE, this
handle is being used by one or more easy handles and can only used by any
other easy handle without careful consideration (== only for
pipelining/multiplexing) and it cannot be used by another multi
handle! */
#define CONN_INUSE(c) ((c)->send_pipe.size + (c)->recv_pipe.size)
/**** Fields set when inited and not modified again */
long connection_id; /* Contains a unique number to make it easier to
@ -1222,7 +1225,7 @@ struct UrlState {
size_t headersize; /* size of the allocation */
char *buffer; /* download buffer */
char uploadbuffer[UPLOAD_BUFSIZE + 1]; /* upload buffer */
char *ulbuf; /* alloced upload buffer or NULL */
curl_off_t current_speed; /* the ProgressShow() function sets this,
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
@ -1265,7 +1268,7 @@ struct UrlState {
void *resolver; /* resolver state, if it is used in the URL state -
ares_channel f.e. */
#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
#if defined(USE_OPENSSL)
/* void instead of ENGINE to avoid bleeding OpenSSL into this header */
void *engine;
#endif /* USE_OPENSSL */
@ -1284,9 +1287,6 @@ struct UrlState {
involved in this request */
bool expect100header; /* TRUE if we added Expect: 100-continue */
bool pipe_broke; /* TRUE if the connection we were pipelined on broke
and we need to restart from the beginning */
#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
!defined(__SYMBIAN32__)
/* do FTP line-end conversions on most platforms */
@ -1346,7 +1346,7 @@ struct DynamicStatic {
char *url; /* work URL, copied from UserDefined */
bool url_alloc; /* URL string is malloc()'ed */
char *referer; /* referer string */
bool referer_alloc; /* referer sting is malloc()ed */
bool referer_alloc; /* referer string is malloc()ed */
struct curl_slist *cookielist; /* list of cookie files set by
curl_easy_setopt(COOKIEFILE) calls */
struct curl_slist *resolve; /* set to point to the set.resolve list when
@ -1400,6 +1400,8 @@ enum dupstring {
STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */
STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */
STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */
STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
STRING_USERAGENT, /* User-Agent string */
@ -1407,6 +1409,7 @@ enum dupstring {
STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
STRING_SSL_ENGINE, /* name of ssl engine */
STRING_USERNAME, /* <username>, if used */
STRING_PASSWORD, /* <password>, if used */
STRING_OPTIONS, /* <options>, if used */
@ -1559,6 +1562,8 @@ struct UserDefined {
curl_proxytype proxytype; /* what kind of proxy that is in use */
long dns_cache_timeout; /* DNS cache timeout */
long buffer_size; /* size of receive buffer to use */
long upload_buffer_size; /* size of upload buffer to use,
keep it >= CURL_MAX_WRITE_SIZE */
void *private_data; /* application-private data */
struct curl_slist *http200aliases; /* linked list of aliases for http200 */
@ -1581,8 +1586,6 @@ struct UserDefined {
/* Here follows boolean settings that define how to behave during
this session. They are STATIC, set by libcurl users or at least initially
and they don't change during operations. */
bool printhost; /* printing host name in debug info */
bool get_filetime; /* get the time and get of the remote file */
bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
bool prefer_ascii; /* ASCII rather than binary */
@ -1676,7 +1679,7 @@ struct UserDefined {
bool stream_depends_e; /* set or don't set the Exclusive bit */
int stream_weight;
bool haproxyprotocol; /* whether to send HAProxy PROXY protocol header */
bool haproxyprotocol; /* whether to send HAProxy PROXY protocol v1 header */
struct Curl_http2_dep *stream_dependents;
@ -1685,6 +1688,7 @@ struct UserDefined {
curl_resolver_start_callback resolver_start; /* optional callback called
before resolver start */
void *resolver_start_client; /* pointer to pass to resolver start callback */
bool disallow_username_in_url; /* disallow username in url */
};
struct Names {
@ -1736,6 +1740,9 @@ struct Curl_easy {
struct to which this "belongs" when used
by the easy interface */
struct Curl_share *share; /* Share, handles global variable mutexing */
#ifdef USE_LIBPSL
struct PslCache *psl; /* The associated PSL cache. */
#endif
struct SingleRequest req; /* Request-specific data */
struct UserDefined set; /* values set by the libcurl user */
struct DynamicStatic change; /* possibly modified userdefined data */

View File

@ -158,7 +158,7 @@ static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */
/* Perform quoted-string escaping as described in RFC2616 and its errata */
static char *auth_digest_string_quoted(const char *source)
{
char *dest, *d;
char *dest;
const char *s = source;
size_t n = 1; /* null terminator */
@ -173,8 +173,8 @@ static char *auth_digest_string_quoted(const char *source)
dest = malloc(n);
if(dest) {
char *d = dest;
s = source;
d = dest;
while(*s) {
if(*s == '"' || *s == '\\') {
*d++ = '\\';
@ -696,7 +696,6 @@ static CURLcode _Curl_auth_create_digest_http_message(
unsigned char ha1[65]; /* 64 digits and 1 zero byte */
unsigned char ha2[65]; /* 64 digits and 1 zero byte */
char userh[65];
char cnoncebuf[33];
char *cnonce = NULL;
size_t cnonce_sz = 0;
char *userp_quoted;
@ -707,6 +706,7 @@ static CURLcode _Curl_auth_create_digest_http_message(
digest->nc = 1;
if(!digest->cnonce) {
char cnoncebuf[33];
result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
sizeof(cnoncebuf));
if(result)

View File

@ -445,7 +445,7 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
#ifdef HAVE_BROTLI
version_info.brotli_ver_num = BrotliDecoderVersion();
brotli_version(brotli_buffer, sizeof brotli_buffer);
brotli_version(brotli_buffer, sizeof(brotli_buffer));
version_info.brotli_version = brotli_buffer;
#endif

View File

@ -29,6 +29,11 @@
#include "curl_setup.h"
#ifdef USE_AXTLS
#error axTLS support has been disabled in curl due to doubts about quality,
#error user dedication and a lack of use/testing. We urge users to consider
#error using a more established TLS backend instead.
#include <axTLS/config.h>
#include <axTLS/ssl.h>
#include "axtls.h"

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