mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-07 06:40:16 -05:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2016-11-02 (3c561c65)
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
|
||||
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
|
||||
|
||||
if(CURL_HIDDEN_SYMBOLS)
|
||||
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)
|
||||
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})
|
||||
set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN})
|
||||
@@ -0,0 +1,18 @@
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
|
||||
|
||||
find_library(NGHTTP2_LIBRARY NAMES nghttp2)
|
||||
|
||||
find_package_handle_standard_args(NGHTTP2
|
||||
FOUND_VAR
|
||||
NGHTTP2_FOUND
|
||||
REQUIRED_VARS
|
||||
NGHTTP2_LIBRARY
|
||||
NGHTTP2_INCLUDE_DIR
|
||||
FAIL_MESSAGE
|
||||
"Could NOT find NGHTTP2"
|
||||
)
|
||||
|
||||
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR} )
|
||||
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})
|
||||
@@ -65,7 +65,7 @@ endif()
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -79,7 +79,7 @@ endif()
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
###########################################################################
|
||||
# cURL/libcurl CMake script
|
||||
# curl/libcurl CMake script
|
||||
# by Tetetest and Sukender (Benoit Neil)
|
||||
|
||||
# TODO:
|
||||
@@ -102,6 +102,7 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
|
||||
include(Utilities)
|
||||
include(Macros)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
project( CURL C )
|
||||
|
||||
@@ -135,11 +136,17 @@ set(OS "\"${CMAKE_SYSTEM_NAME}\"")
|
||||
include_directories(${PROJECT_BINARY_DIR}/include/curl)
|
||||
include_directories( ${CURL_SOURCE_DIR}/include )
|
||||
|
||||
option(BUILD_CURL_EXE "Set to ON to build cURL executable." 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(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
|
||||
option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
|
||||
|
||||
if(WIN32)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_THREADED_RESOLVER
|
||||
"Set to ON to enable threaded DNS lookup"
|
||||
ON "NOT ENABLE_ARES"
|
||||
OFF)
|
||||
else()
|
||||
option(ENABLE_THREADED_RESOLVER "Set to ON to enable POSIX threaded DNS lookup" OFF)
|
||||
endif()
|
||||
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)
|
||||
|
||||
@@ -176,8 +183,7 @@ if(MSVC)
|
||||
mark_as_advanced(BUILD_RELEASE_DEBUG_DIRS)
|
||||
endif()
|
||||
|
||||
option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
|
||||
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
|
||||
include(CurlSymbolHiding)
|
||||
|
||||
option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
|
||||
mark_as_advanced(HTTP_ONLY)
|
||||
@@ -313,13 +319,17 @@ if(WIN32)
|
||||
endif(WIN32)
|
||||
|
||||
if(ENABLE_THREADED_RESOLVER)
|
||||
check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
|
||||
if(HAVE_PTHREAD_H)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD 1)
|
||||
find_package(Threads)
|
||||
if(CMAKE_USE_PTHREADS_INIT)
|
||||
set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
||||
set(USE_THREADS_POSIX 1)
|
||||
if(WIN32)
|
||||
set(USE_THREADS_WIN32 ON)
|
||||
else()
|
||||
check_include_file_concat("pthread.h" HAVE_PTHREAD_H)
|
||||
if(HAVE_PTHREAD_H)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD 1)
|
||||
find_package(Threads)
|
||||
if(CMAKE_USE_PTHREADS_INIT)
|
||||
set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
|
||||
set(USE_THREADS_POSIX 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -411,6 +421,13 @@ elseif(APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(USE_NGHTTP2 "Use Nghttp2 library" OFF)
|
||||
if(USE_NGHTTP2)
|
||||
find_package(NGHTTP2 REQUIRED)
|
||||
include_directories(${NGHTTP2_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(NOT CURL_DISABLE_LDAP)
|
||||
if(WIN32)
|
||||
option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
|
||||
@@ -521,13 +538,13 @@ if(NOT CURL_DISABLE_LDAPS)
|
||||
endif()
|
||||
|
||||
# Check for idn
|
||||
check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
|
||||
check_library_exists_concat("idn2" idn2_lookup_ul HAVE_LIBIDN2)
|
||||
|
||||
# Check for symbol dlopen (same as HAVE_LIBDL)
|
||||
check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
option(CURL_ZLIB "Set to ON to enable building cURL with zlib support." ON)
|
||||
option(CURL_ZLIB "Set to ON to enable building curl with zlib support." ON)
|
||||
set(HAVE_LIBZ OFF)
|
||||
set(HAVE_ZLIB_H OFF)
|
||||
set(HAVE_ZLIB OFF)
|
||||
@@ -707,7 +724,7 @@ check_include_file_concat("des.h" HAVE_DES_H)
|
||||
check_include_file_concat("err.h" HAVE_ERR_H)
|
||||
check_include_file_concat("errno.h" HAVE_ERRNO_H)
|
||||
check_include_file_concat("fcntl.h" HAVE_FCNTL_H)
|
||||
check_include_file_concat("idn-free.h" HAVE_IDN_FREE_H)
|
||||
check_include_file_concat("idn2.h" HAVE_IDN2_H)
|
||||
check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
|
||||
check_include_file_concat("io.h" HAVE_IO_H)
|
||||
check_include_file_concat("krb.h" HAVE_KRB_H)
|
||||
@@ -737,7 +754,6 @@ check_include_file_concat("stropts.h" HAVE_STROPTS_H)
|
||||
check_include_file_concat("termio.h" HAVE_TERMIO_H)
|
||||
check_include_file_concat("termios.h" HAVE_TERMIOS_H)
|
||||
check_include_file_concat("time.h" HAVE_TIME_H)
|
||||
check_include_file_concat("tld.h" HAVE_TLD_H)
|
||||
check_include_file_concat("unistd.h" HAVE_UNISTD_H)
|
||||
check_include_file_concat("utime.h" HAVE_UTIME_H)
|
||||
check_include_file_concat("x509.h" HAVE_X509_H)
|
||||
@@ -751,9 +767,6 @@ check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
|
||||
check_include_file_concat("stdint.h" HAVE_STDINT_H)
|
||||
check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
|
||||
check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
|
||||
check_include_file_concat("idna.h" HAVE_IDNA_H)
|
||||
|
||||
|
||||
|
||||
check_type_size(size_t SIZEOF_SIZE_T)
|
||||
check_type_size(ssize_t SIZEOF_SSIZE_T)
|
||||
@@ -763,7 +776,6 @@ check_type_size("short" SIZEOF_SHORT)
|
||||
check_type_size("int" SIZEOF_INT)
|
||||
check_type_size("__int64" SIZEOF___INT64)
|
||||
check_type_size("time_t" SIZEOF_TIME_T)
|
||||
check_type_size("off_t" SIZEOF_OFF_T)
|
||||
|
||||
# Make public versions of some type sizes for curlbuild.h.
|
||||
foreach(t INT LONG LONG_LONG SSIZE_T)
|
||||
@@ -823,8 +835,6 @@ if(CMAKE_USE_OPENSSL)
|
||||
check_symbol_exists(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS)
|
||||
check_symbol_exists(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN)
|
||||
check_symbol_exists(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD)
|
||||
check_symbol_exists(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}"
|
||||
HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
|
||||
if(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
|
||||
set(USE_OPENSSL 1)
|
||||
endif(HAVE_LIBCRYPTO AND HAVE_LIBSSL)
|
||||
@@ -854,9 +864,6 @@ check_symbol_exists(pipe "${CURL_INCLUDES}" HAVE_PIPE)
|
||||
check_symbol_exists(ftruncate "${CURL_INCLUDES}" HAVE_FTRUNCATE)
|
||||
check_symbol_exists(getprotobyname "${CURL_INCLUDES}" HAVE_GETPROTOBYNAME)
|
||||
check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
|
||||
check_symbol_exists(idn_free "${CURL_INCLUDES}" HAVE_IDN_FREE)
|
||||
check_symbol_exists(idna_strerror "${CURL_INCLUDES}" HAVE_IDNA_STRERROR)
|
||||
check_symbol_exists(tld_strerror "${CURL_INCLUDES}" HAVE_TLD_STRERROR)
|
||||
check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
|
||||
check_symbol_exists(setrlimit "${CURL_INCLUDES}" HAVE_SETRLIMIT)
|
||||
check_symbol_exists(fcntl "${CURL_INCLUDES}" HAVE_FCNTL)
|
||||
@@ -923,9 +930,14 @@ foreach(CURL_TEST
|
||||
)
|
||||
curl_internal_test(${CURL_TEST})
|
||||
endforeach(CURL_TEST)
|
||||
|
||||
if(HAVE_FILE_OFFSET_BITS)
|
||||
set(_FILE_OFFSET_BITS 64)
|
||||
set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
|
||||
endif(HAVE_FILE_OFFSET_BITS)
|
||||
check_type_size("off_t" SIZEOF_OFF_T)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
foreach(CURL_TEST
|
||||
HAVE_GLIBC_STRERROR_R
|
||||
HAVE_POSIX_STRERROR_R
|
||||
@@ -987,16 +999,6 @@ if(NOT CURL_SPECIAL_LIBZ)
|
||||
endif(NOT HAVE_ZLIB_H)
|
||||
endif(NOT CURL_SPECIAL_LIBZ)
|
||||
|
||||
if(_FILE_OFFSET_BITS)
|
||||
set(_FILE_OFFSET_BITS 64)
|
||||
endif(_FILE_OFFSET_BITS)
|
||||
set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/curl/curl.h")
|
||||
check_type_size("curl_off_t" SIZEOF_CURL_OFF_T)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
|
||||
# Check for nonblocking
|
||||
set(HAVE_DISABLED_NONBLOCKING 1)
|
||||
if(HAVE_FIONBIO OR
|
||||
@@ -1069,6 +1071,11 @@ if(WIN32)
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
endif(WIN32)
|
||||
|
||||
# For windows, all compilers used by cmake should support large files
|
||||
if(WIN32)
|
||||
set(USE_WIN32_LARGE_FILES ON)
|
||||
endif(WIN32)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
endif(MSVC)
|
||||
@@ -1133,8 +1140,10 @@ _add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL)
|
||||
_add_if("IPv6" ENABLE_IPV6)
|
||||
_add_if("unix-sockets" USE_UNIX_SOCKETS)
|
||||
_add_if("libz" HAVE_LIBZ)
|
||||
_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX)
|
||||
_add_if("IDN" HAVE_LIBIDN)
|
||||
_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
|
||||
_add_if("IDN" HAVE_LIBIDN2)
|
||||
_add_if("Largefile" (CURL_SIZEOF_CURL_OFF_T GREATER 4) AND
|
||||
((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
|
||||
# TODO SSP1 (WinSSL) check is missing
|
||||
_add_if("SSPI" USE_WINDOWS_SSPI)
|
||||
_add_if("GSS-API" HAVE_GSSAPI)
|
||||
@@ -1200,9 +1209,7 @@ set(CURL_CA_BUNDLE "")
|
||||
set(CURLVERSION "${CURL_VERSION}")
|
||||
set(ENABLE_SHARED "yes")
|
||||
if(CURL_STATICLIB)
|
||||
# Broken: LIBCURL_LIBS below; .a lib is not built
|
||||
message(WARNING "Static linking is broken!")
|
||||
set(ENABLE_STATIC "no")
|
||||
set(ENABLE_STATIC "yes")
|
||||
else()
|
||||
set(ENABLE_STATIC "no")
|
||||
endif()
|
||||
@@ -1211,9 +1218,12 @@ set(includedir "\${prefix}/include")
|
||||
set(LDFLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(LIBCURL_LIBS "")
|
||||
set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
# TODO CURL_LIBS also contains absolute paths which don't work with static -l...
|
||||
foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
|
||||
set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}")
|
||||
if(_lib MATCHES ".*/.*")
|
||||
set(LIBCURL_LIBS "${LIBCURL_LIBS} ${_lib}")
|
||||
else()
|
||||
set(LIBCURL_LIBS "${LIBCURL_LIBS} -l${_lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
# "a" (Linux) or "lib" (Windows)
|
||||
string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
* https://cool.haxx.se/mailman/listinfo/curl-library/
|
||||
*/
|
||||
|
||||
#ifdef CURL_NO_OLDIES
|
||||
#define CURL_STRICTER
|
||||
#endif
|
||||
|
||||
#include "curlver.h" /* libcurl version defines */
|
||||
#include "cmcurl/include/curl/curlbuild.h" /* libcurl build definitions */
|
||||
#include "curlrules.h" /* libcurl rules enforcement */
|
||||
@@ -431,7 +435,7 @@ typedef enum {
|
||||
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||
CURLE_COULDNT_CONNECT, /* 7 */
|
||||
CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
|
||||
CURLE_WEIRD_SERVER_REPLY, /* 8 */
|
||||
CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
|
||||
due to lack of access - when login fails
|
||||
this is not returned. */
|
||||
@@ -562,6 +566,7 @@ typedef enum {
|
||||
|
||||
/* compatibility with older names */
|
||||
#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
|
||||
#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
|
||||
|
||||
/* The following were added in 7.21.5, April 2011 */
|
||||
#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
|
||||
@@ -1695,6 +1700,10 @@ typedef enum {
|
||||
/* Set TCP Fast Open */
|
||||
CINIT(TCP_FASTOPEN, LONG, 244),
|
||||
|
||||
/* Continue to send data if the server responds early with an
|
||||
* HTTP status code >= 300 */
|
||||
CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.50.1"
|
||||
#define LIBCURL_VERSION "7.51.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 50
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
#define LIBCURL_VERSION_MINOR 51
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -57,7 +57,7 @@
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x073201
|
||||
#define LIBCURL_VERSION_NUM 0x073300
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -111,6 +111,11 @@ endif()
|
||||
set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
|
||||
|
||||
if(0) # This code not needed for building within CMake.
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
|
||||
endif()
|
||||
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
|
||||
|
||||
@@ -40,13 +40,13 @@ LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||
ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
|
||||
getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c \
|
||||
getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \
|
||||
fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
|
||||
strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
|
||||
http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
|
||||
strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
|
||||
inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
|
||||
ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
|
||||
openldap.c curl_gethostname.c gopher.c idn_win32.c \
|
||||
@@ -58,13 +58,13 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.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 \
|
||||
speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
|
||||
strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
|
||||
hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
|
||||
http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
|
||||
inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
|
||||
easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
|
||||
socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h \
|
||||
socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \
|
||||
slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
|
||||
rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
|
||||
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
|
||||
|
||||
@@ -57,7 +57,7 @@ bool Curl_amiga_init()
|
||||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
|
||||
TAG_DONE)) {
|
||||
__request("SocketBaseTags ERROR");
|
||||
return FALSE;
|
||||
|
||||
@@ -190,6 +190,11 @@ static CURLcode base64_encode(const char *table64,
|
||||
if(!insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
if(insize > UINT_MAX/4)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
base64data = output = malloc(insize * 4 / 3 + 4);
|
||||
if(!output)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "conncache.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
|
||||
@@ -762,7 +762,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
/* check socket for connect */
|
||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
|
||||
rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
|
||||
|
||||
if(rc == 0) { /* no connection yet */
|
||||
error = 0;
|
||||
@@ -1368,25 +1368,26 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
|
||||
* MUST be called with the connclose() or connkeep() macros with a stated
|
||||
* reason. The reason is only shown in debug builds but helps to figure out
|
||||
* decision paths when connections are or aren't re-used as expected.
|
||||
* Curl_conncontrol() marks streams or connection for closure.
|
||||
*/
|
||||
void Curl_conncontrol(struct connectdata *conn, bool closeit,
|
||||
const char *reason)
|
||||
{
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) reason;
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
int ctrl /* see defines in header */
|
||||
#ifdef DEBUGBUILD
|
||||
, const char *reason
|
||||
#endif
|
||||
if(closeit != conn->bits.close) {
|
||||
infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
|
||||
reason);
|
||||
|
||||
)
|
||||
{
|
||||
/* close if a connection, or a stream that isn't multiplexed */
|
||||
bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
|
||||
if((ctrl == CONNCTRL_STREAM) &&
|
||||
(conn->handler->flags & PROTOPT_STREAM))
|
||||
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
|
||||
else if(closeit != conn->bits.close) {
|
||||
DEBUGF(infof(conn->data, "Marked for [%s]: %s\n",
|
||||
closeit?"closure":"keep alive", reason));
|
||||
conn->bits.close = closeit; /* the only place in the source code that
|
||||
should assign this bit */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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
|
||||
@@ -104,21 +104,37 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
|
||||
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Curl_connclose() sets the bit.close bit to TRUE with an explanation.
|
||||
* Nothing else.
|
||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
||||
* argument specifies if it is the end of a connection or a stream.
|
||||
*
|
||||
* For stream-based protocols (such as HTTP/2), a stream close will not cause
|
||||
* a connection close. Other protocols will close the connection for both
|
||||
* cases.
|
||||
*
|
||||
* It sets the bit.close bit to TRUE (with an explanation for debug builds),
|
||||
* when the connection will close.
|
||||
*/
|
||||
|
||||
#define CONNCTRL_KEEP 0 /* undo a marked closure */
|
||||
#define CONNCTRL_CONNECTION 1
|
||||
#define CONNCTRL_STREAM 2
|
||||
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
bool closeit,
|
||||
const char *reason);
|
||||
#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
|
||||
int closeit
|
||||
#ifdef DEBUGBUILD
|
||||
, const char *reason
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
||||
#else /* if !CURLDEBUG */
|
||||
|
||||
#define connclose(x,y) (x)->bits.close = TRUE
|
||||
#define connkeep(x,y) (x)->bits.close = FALSE
|
||||
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_CONNECT_H */
|
||||
|
||||
@@ -90,13 +90,12 @@ Example set of cookies:
|
||||
|
||||
#include "urldata.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "slist.h"
|
||||
#include "share.h"
|
||||
#include "strtoofft.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
@@ -126,7 +125,7 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
||||
if(hostname_len < cookie_domain_len)
|
||||
return FALSE;
|
||||
|
||||
if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
|
||||
if(!strcasecompare(cooke_domain, hostname+hostname_len-cookie_domain_len))
|
||||
return FALSE;
|
||||
|
||||
/* A lead char of cookie_domain is not '.'.
|
||||
@@ -469,9 +468,9 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
/* this was a "<name>=" with no content, and we must allow
|
||||
'secure' and 'httponly' specified this weirdly */
|
||||
done = TRUE;
|
||||
if(Curl_raw_equal("secure", name))
|
||||
if(strcasecompare("secure", name))
|
||||
co->secure = TRUE;
|
||||
else if(Curl_raw_equal("httponly", name))
|
||||
else if(strcasecompare("httponly", name))
|
||||
co->httponly = TRUE;
|
||||
else if(sep)
|
||||
/* there was a '=' so we're not done parsing this field */
|
||||
@@ -479,7 +478,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
}
|
||||
if(done)
|
||||
;
|
||||
else if(Curl_raw_equal("path", name)) {
|
||||
else if(strcasecompare("path", name)) {
|
||||
strstore(&co->path, whatptr);
|
||||
if(!co->path) {
|
||||
badcookie = TRUE; /* out of memory bad */
|
||||
@@ -491,7 +490,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("domain", name)) {
|
||||
else if(strcasecompare("domain", name)) {
|
||||
bool is_ip;
|
||||
const char *dotp;
|
||||
|
||||
@@ -529,14 +528,14 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
whatptr);
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("version", name)) {
|
||||
else if(strcasecompare("version", name)) {
|
||||
strstore(&co->version, whatptr);
|
||||
if(!co->version) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("max-age", name)) {
|
||||
else if(strcasecompare("max-age", name)) {
|
||||
/* Defined in RFC2109:
|
||||
|
||||
Optional. The Max-Age attribute defines the lifetime of the
|
||||
@@ -552,7 +551,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("expires", name)) {
|
||||
else if(strcasecompare("expires", name)) {
|
||||
strstore(&co->expirestr, whatptr);
|
||||
if(!co->expirestr) {
|
||||
badcookie = TRUE;
|
||||
@@ -713,7 +712,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
As far as I can see, it is set to true when the cookie says
|
||||
.domain.com and to false when the domain is complete www.domain.com
|
||||
*/
|
||||
co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
|
||||
co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
|
||||
break;
|
||||
case 2:
|
||||
/* It turns out, that sometimes the file format allows the path
|
||||
@@ -742,7 +741,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
fields++; /* add a field and fall down to secure */
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
|
||||
co->secure = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
|
||||
break;
|
||||
case 4:
|
||||
co->expires = curlx_strtoofft(ptr, NULL, 10);
|
||||
@@ -813,11 +812,12 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
clist = c->cookies;
|
||||
replace_old = FALSE;
|
||||
while(clist) {
|
||||
if(Curl_raw_equal(clist->name, co->name)) {
|
||||
if(strcasecompare(clist->name, co->name)) {
|
||||
/* the names are identical */
|
||||
|
||||
if(clist->domain && co->domain) {
|
||||
if(Curl_raw_equal(clist->domain, co->domain))
|
||||
if(strcasecompare(clist->domain, co->domain) &&
|
||||
(clist->tailmatch == co->tailmatch))
|
||||
/* The domains are identical */
|
||||
replace_old=TRUE;
|
||||
}
|
||||
@@ -828,7 +828,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
/* the domains were identical */
|
||||
|
||||
if(clist->spath && co->spath) {
|
||||
if(Curl_raw_equal(clist->spath, co->spath)) {
|
||||
if(strcasecompare(clist->spath, co->spath)) {
|
||||
replace_old = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -902,6 +902,35 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
return co;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_line() makes sure to only return complete whole lines that fit in 'len'
|
||||
* bytes and end with a newline.
|
||||
*/
|
||||
static char *get_line(char *buf, int len, FILE *input)
|
||||
{
|
||||
bool partial = FALSE;
|
||||
while(1) {
|
||||
char *b = fgets(buf, len, input);
|
||||
if(b) {
|
||||
size_t rlen = strlen(b);
|
||||
if(rlen && (b[rlen-1] == '\n')) {
|
||||
if(partial) {
|
||||
partial = FALSE;
|
||||
continue;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
else
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Curl_cookie_init()
|
||||
@@ -938,7 +967,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
}
|
||||
c->running = FALSE; /* this is not running, this is init */
|
||||
|
||||
if(file && strequal(file, "-")) {
|
||||
if(file && !strcmp(file, "-")) {
|
||||
fp = stdin;
|
||||
fromfile=FALSE;
|
||||
}
|
||||
@@ -958,7 +987,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
line = malloc(MAX_COOKIE_LINE);
|
||||
if(!line)
|
||||
goto fail;
|
||||
while(fgets(line, MAX_COOKIE_LINE, fp)) {
|
||||
while(get_line(line, MAX_COOKIE_LINE, fp)) {
|
||||
if(checkprefix("Set-Cookie:", line)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr=&line[11];
|
||||
@@ -1023,6 +1052,40 @@ static int cookie_sort(const void *p1, const void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CLONE(field) \
|
||||
do { \
|
||||
if(src->field) { \
|
||||
dup->field = strdup(src->field); \
|
||||
if(!dup->field) \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static struct Cookie *dup_cookie(struct Cookie *src)
|
||||
{
|
||||
struct Cookie *dup = calloc(sizeof(struct Cookie), 1);
|
||||
if(dup) {
|
||||
CLONE(expirestr);
|
||||
CLONE(domain);
|
||||
CLONE(path);
|
||||
CLONE(spath);
|
||||
CLONE(name);
|
||||
CLONE(value);
|
||||
CLONE(maxage);
|
||||
CLONE(version);
|
||||
dup->expires = src->expires;
|
||||
dup->tailmatch = src->tailmatch;
|
||||
dup->secure = src->secure;
|
||||
dup->livecookie = src->livecookie;
|
||||
dup->httponly = src->httponly;
|
||||
}
|
||||
return dup;
|
||||
|
||||
fail:
|
||||
freecookie(dup);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Curl_cookie_getlist()
|
||||
@@ -1067,7 +1130,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* now check if the domain is correct */
|
||||
if(!co->domain ||
|
||||
(co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
|
||||
((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
|
||||
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
|
||||
/* the right part of the host matches the domain stuff in the
|
||||
cookie data */
|
||||
|
||||
@@ -1078,11 +1141,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* and now, we know this is a match and we should create an
|
||||
entry for the return-linked-list */
|
||||
|
||||
newco = malloc(sizeof(struct Cookie));
|
||||
newco = dup_cookie(co);
|
||||
if(newco) {
|
||||
/* first, copy the whole source cookie: */
|
||||
memcpy(newco, co, sizeof(struct Cookie));
|
||||
|
||||
/* then modify our next */
|
||||
newco->next = mainco;
|
||||
|
||||
@@ -1094,12 +1154,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
else {
|
||||
fail:
|
||||
/* failure, clear up the allocated chain and return NULL */
|
||||
while(mainco) {
|
||||
co = mainco->next;
|
||||
free(mainco);
|
||||
mainco = co;
|
||||
}
|
||||
|
||||
Curl_cookie_freelist(mainco);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1151,7 +1206,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||
{
|
||||
if(cookies) {
|
||||
Curl_cookie_freelist(cookies->cookies, TRUE);
|
||||
Curl_cookie_freelist(cookies->cookies);
|
||||
cookies->cookies = NULL;
|
||||
cookies->numcookies = 0;
|
||||
}
|
||||
@@ -1163,21 +1218,14 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||
*
|
||||
* Free a list of cookies previously returned by Curl_cookie_getlist();
|
||||
*
|
||||
* The 'cookiestoo' argument tells this function whether to just free the
|
||||
* list or actually also free all cookies within the list as well.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
|
||||
void Curl_cookie_freelist(struct Cookie *co)
|
||||
{
|
||||
struct Cookie *next;
|
||||
while(co) {
|
||||
next = co->next;
|
||||
if(cookiestoo)
|
||||
freecookie(co);
|
||||
else
|
||||
free(co); /* we only free the struct since the "members" are all just
|
||||
pointed out in the main cookie list! */
|
||||
freecookie(co);
|
||||
co = next;
|
||||
}
|
||||
}
|
||||
@@ -1232,7 +1280,7 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||
{
|
||||
if(c) {
|
||||
free(c->filename);
|
||||
Curl_cookie_freelist(c->cookies, TRUE);
|
||||
Curl_cookie_freelist(c->cookies);
|
||||
free(c); /* free the base struct as well */
|
||||
}
|
||||
}
|
||||
@@ -1290,7 +1338,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
/* at first, remove expired cookies */
|
||||
remove_expired(c);
|
||||
|
||||
if(strequal("-", dumphere)) {
|
||||
if(!strcmp("-", dumphere)) {
|
||||
/* use stdout */
|
||||
out = stdout;
|
||||
use_stdout=TRUE;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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,7 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
|
||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
|
||||
const char *, bool);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies);
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
||||
|
||||
/* to make a symbol visible */
|
||||
#cmakedefine CURL_EXTERN_SYMBOL 1
|
||||
#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
|
||||
/* Ensure using CURL_EXTERN_SYMBOL is possible */
|
||||
#ifndef CURL_EXTERN_SYMBOL
|
||||
#define CURL_EXTERN_SYMBOL
|
||||
@@ -900,6 +900,9 @@
|
||||
/* Define if you want to enable POSIX threaded DNS lookup */
|
||||
#cmakedefine USE_THREADS_POSIX 1
|
||||
|
||||
/* Define if you want to enable WIN32 threaded DNS lookup */
|
||||
#cmakedefine USE_THREADS_WIN32 1
|
||||
|
||||
/* Define to disable non-blocking sockets. */
|
||||
#cmakedefine USE_BLOCKING_SOCKETS 1
|
||||
|
||||
@@ -927,6 +930,9 @@
|
||||
/* if OpenSSL is in use */
|
||||
#cmakedefine USE_OPENSSL 1
|
||||
|
||||
/* to enable NGHTTP2 */
|
||||
#cmakedefine USE_NGHTTP2 1
|
||||
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS
|
||||
|
||||
|
||||
@@ -76,6 +76,11 @@
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
# define MD4_DIGEST_LENGTH 16
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
# include <mbedtls/des.h>
|
||||
# include <mbedtls/md4.h>
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
# include <nss.h>
|
||||
@@ -100,7 +105,7 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
@@ -188,6 +193,26 @@ static void setup_des_key(const unsigned char *key_56,
|
||||
gcry_cipher_setkey(*des, key, sizeof(key));
|
||||
}
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
mbedtls_des_context ctx;
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
mbedtls_des_key_set_parity((unsigned char *) key);
|
||||
|
||||
/* Perform the encryption */
|
||||
mbedtls_des_init(&ctx);
|
||||
mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
|
||||
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
|
||||
}
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
/*
|
||||
@@ -400,8 +425,8 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
setup_des_key(keys + 14, &des);
|
||||
gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
||||
|| defined(USE_WIN32_CRYPTO)
|
||||
#elif defined(USE_MBEDTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
encrypt_des(plaintext, results + 16, keys + 14);
|
||||
@@ -464,8 +489,8 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
setup_des_key(pw + 7, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
||||
|| defined(USE_WIN32_CRYPTO)
|
||||
#elif defined(USE_MBEDTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
#endif
|
||||
@@ -543,6 +568,8 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
gcry_md_write(MD4pw, pw, 2 * len);
|
||||
memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
|
||||
gcry_md_close(MD4pw);
|
||||
#elif defined(USE_MBEDTLS)
|
||||
mbedtls_md4(pw, 2 * len, ntbuffer);
|
||||
#elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#elif defined(USE_DARWINSSL)
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "strequal.h"
|
||||
#include "rawstr.h"
|
||||
#include "sendf.h"
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -159,7 +157,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
sasl->prefmech = SASL_AUTH_NONE;
|
||||
}
|
||||
|
||||
if(strnequal(value, "*", len))
|
||||
if(!strncmp(value, "*", len))
|
||||
sasl->prefmech = SASL_AUTH_DEFAULT;
|
||||
else {
|
||||
mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
|
||||
@@ -288,7 +286,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
}
|
||||
else if(conn->bits.user_passwd) {
|
||||
#if defined(USE_KERBEROS5)
|
||||
if(enabledmechs & SASL_MECH_GSSAPI) {
|
||||
if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(conn->user)) {
|
||||
sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
|
||||
mech = SASL_MECH_STRING_GSSAPI;
|
||||
state1 = SASL_GSSAPI;
|
||||
@@ -308,7 +307,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(enabledmechs & SASL_MECH_DIGEST_MD5) {
|
||||
if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
Curl_auth_is_digest_supported()) {
|
||||
mech = SASL_MECH_STRING_DIGEST_MD5;
|
||||
state1 = SASL_DIGESTMD5;
|
||||
sasl->authused = SASL_MECH_DIGEST_MD5;
|
||||
@@ -321,7 +321,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_NTLM
|
||||
if(enabledmechs & SASL_MECH_NTLM) {
|
||||
if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
|
||||
mech = SASL_MECH_STRING_NTLM;
|
||||
state1 = SASL_NTLM;
|
||||
state2 = SASL_NTLM_TYPE2MSG;
|
||||
|
||||
@@ -614,10 +614,9 @@ int netware_init(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
|
||||
/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
|
||||
but we only work with libidn 0.4.1 or later) */
|
||||
#define USE_LIBIDN
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H)
|
||||
/* The lib and header are present */
|
||||
#define USE_LIBIDN2
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_TIME_T
|
||||
@@ -653,6 +652,13 @@ int netware_init(void);
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#define USE_NTLM
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
# include <mbedtls/md4.h>
|
||||
# if defined(MBEDTLS_MD4_C)
|
||||
#define USE_NTLM
|
||||
# endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -761,4 +767,14 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
# endif
|
||||
#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */
|
||||
|
||||
/* Detect Windows App environment which has a restricted access
|
||||
* to the Win32 APIs. */
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)
|
||||
# include <winapifamily.h>
|
||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
|
||||
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define CURL_WINDOWS_APP
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
||||
@@ -64,6 +64,12 @@ PSecurityFunctionTable s_pSecFn = NULL;
|
||||
*
|
||||
* Once this function has been executed, Windows SSPI functions can be
|
||||
* called through the Security Service Provider Interface dispatch table.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sspi_global_init(void)
|
||||
{
|
||||
@@ -102,8 +108,11 @@ CURLcode Curl_sspi_global_init(void)
|
||||
* Curl_sspi_global_cleanup()
|
||||
*
|
||||
* This deinitializes the Security Service Provider Interface from libcurl.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* None.
|
||||
*/
|
||||
|
||||
void Curl_sspi_global_cleanup(void)
|
||||
{
|
||||
if(s_hSecDll) {
|
||||
@@ -205,6 +214,15 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sspi_free_identity()
|
||||
*
|
||||
* This is used to free the contents of a SSPI identifier structure.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* identity [in/out] - The identity structure.
|
||||
*/
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
{
|
||||
if(identity) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -34,8 +34,8 @@
|
||||
functions while they still are offered publicly. They will be made library-
|
||||
private one day */
|
||||
|
||||
#include "strequal.h"
|
||||
/* "strequal.h" provides the strequal protos */
|
||||
#include "strcase.h"
|
||||
/* "strcase.h" provides the strcasecompare protos */
|
||||
|
||||
#include "strtoofft.h"
|
||||
/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
|
||||
@@ -67,15 +67,12 @@
|
||||
be removed from a future libcurl official API:
|
||||
curlx_getenv
|
||||
curlx_mprintf (and its variations)
|
||||
curlx_strequal
|
||||
curlx_strnequal
|
||||
curlx_strcasecompare
|
||||
curlx_strncasecompare
|
||||
|
||||
*/
|
||||
|
||||
#define curlx_getenv curl_getenv
|
||||
#define curlx_strequal curl_strequal
|
||||
#define curlx_strnequal curl_strnequal
|
||||
#define curlx_raw_equal Curl_raw_equal
|
||||
#define curlx_mvsnprintf curl_mvsnprintf
|
||||
#define curlx_msnprintf curl_msnprintf
|
||||
#define curlx_maprintf curl_maprintf
|
||||
|
||||
+12
-13
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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,11 +52,10 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "escape.h"
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
#include "dict.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@@ -96,12 +95,12 @@ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
|
||||
char *newp;
|
||||
char *dictp;
|
||||
char *ptr;
|
||||
int len;
|
||||
size_t len;
|
||||
char ch;
|
||||
int olen=0;
|
||||
|
||||
newp = curl_easy_unescape(data, inputbuff, 0, &len);
|
||||
if(!newp)
|
||||
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 */
|
||||
@@ -145,9 +144,9 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
/* AUTH is missing */
|
||||
}
|
||||
|
||||
if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
|
||||
word = strchr(path, ':');
|
||||
if(word) {
|
||||
@@ -203,9 +202,9 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
}
|
||||
else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
|
||||
else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
|
||||
|
||||
word = strchr(path, ':');
|
||||
if(word) {
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include "strequal.h"
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
@@ -144,28 +143,6 @@ static CURLcode win32_init(void)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
/*
|
||||
* Initialise use of IDNA library.
|
||||
* It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
|
||||
* idna_to_ascii_lz().
|
||||
*/
|
||||
static void idna_init (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char buf[60];
|
||||
UINT cp = GetACP();
|
||||
|
||||
if(!getenv("CHARSET") && cp > 0) {
|
||||
snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
|
||||
putenv(buf);
|
||||
}
|
||||
#else
|
||||
/* to do? */
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_LIBIDN */
|
||||
|
||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||
static unsigned int initialized;
|
||||
static long init_flags;
|
||||
@@ -217,7 +194,7 @@ curl_calloc_callback Curl_ccalloc;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* curl_global_init() globally initializes curl given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
@@ -262,10 +239,6 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
idna_init();
|
||||
#endif
|
||||
|
||||
if(Curl_resolver_global_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
@@ -292,7 +265,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
|
||||
|
||||
/**
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* curl_global_init() globally initializes curl given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
CURLcode curl_global_init(long flags)
|
||||
@@ -301,7 +274,7 @@ CURLcode curl_global_init(long flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_global_init_mem() globally initializes cURL and also registers the
|
||||
* curl_global_init_mem() globally initializes curl and also registers the
|
||||
* user provided callback routines.
|
||||
*/
|
||||
CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
@@ -333,7 +306,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
}
|
||||
|
||||
/**
|
||||
* curl_global_cleanup() globally cleanups cURL, uses the value of
|
||||
* curl_global_cleanup() globally cleanups curl, uses the value of
|
||||
* "init_flags" to determine what needs to be cleaned up and what doesn't.
|
||||
*/
|
||||
void curl_global_cleanup(void)
|
||||
@@ -995,6 +968,9 @@ void curl_easy_reset(struct Curl_easy *data)
|
||||
/* zero out Progress data: */
|
||||
memset(&data->progress, 0, sizeof(struct Progress));
|
||||
|
||||
/* zero out PureInfo data: */
|
||||
Curl_initinfo(data);
|
||||
|
||||
data->progress.flags |= PGRS_HIDE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
}
|
||||
@@ -1044,7 +1020,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
if(!result &&
|
||||
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
||||
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
|
||||
Curl_expire(data, 1); /* get this handle going again */
|
||||
Curl_expire(data, 0); /* get this handle going again */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -78,15 +78,21 @@ char *curl_unescape(const char *string, int length)
|
||||
char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
int inlength)
|
||||
{
|
||||
size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
|
||||
size_t alloc;
|
||||
char *ns;
|
||||
char *testing_ptr = NULL;
|
||||
unsigned char in; /* we need to treat the characters unsigned */
|
||||
size_t newlen = alloc;
|
||||
size_t newlen;
|
||||
size_t strindex=0;
|
||||
size_t length;
|
||||
CURLcode result;
|
||||
|
||||
if(inlength < 0)
|
||||
return NULL;
|
||||
|
||||
alloc = (inlength?(size_t)inlength:strlen(string))+1;
|
||||
newlen = alloc;
|
||||
|
||||
ns = malloc(alloc);
|
||||
if(!ns)
|
||||
return NULL;
|
||||
@@ -211,14 +217,22 @@ char *curl_easy_unescape(struct Curl_easy *data, const char *string,
|
||||
int length, int *olen)
|
||||
{
|
||||
char *str = NULL;
|
||||
size_t inputlen = length;
|
||||
size_t outputlen;
|
||||
CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
|
||||
FALSE);
|
||||
if(res)
|
||||
return NULL;
|
||||
if(olen)
|
||||
*olen = curlx_uztosi(outputlen);
|
||||
if(length >= 0) {
|
||||
size_t inputlen = length;
|
||||
size_t outputlen;
|
||||
CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
|
||||
FALSE);
|
||||
if(res)
|
||||
return NULL;
|
||||
|
||||
if(olen) {
|
||||
if(outputlen <= (size_t) INT_MAX)
|
||||
*olen = curlx_uztosi(outputlen);
|
||||
else
|
||||
/* too large to return in an int, fail! */
|
||||
Curl_safefree(str);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -190,14 +190,15 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
struct FILEPROTO *file = data->req.protop;
|
||||
int fd;
|
||||
#ifdef DOS_FILESYSTEM
|
||||
int i;
|
||||
size_t i;
|
||||
char *actual_path;
|
||||
#endif
|
||||
int real_path_len;
|
||||
size_t real_path_len;
|
||||
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path,
|
||||
&real_path_len, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#ifdef DOS_FILESYSTEM
|
||||
/* If the first character is a slash, and there's
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "urldata.h" /* for struct Curl_easy */
|
||||
#include "formdata.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -201,9 +201,9 @@ static const char *ContentTypeForFilename(const char *filename,
|
||||
if(filename) { /* in case a NULL was passed in */
|
||||
for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
|
||||
if(strlen(filename) >= strlen(ctts[i].extension)) {
|
||||
if(strequal(filename +
|
||||
strlen(filename) - strlen(ctts[i].extension),
|
||||
ctts[i].extension)) {
|
||||
if(strcasecompare(filename +
|
||||
strlen(filename) - strlen(ctts[i].extension),
|
||||
ctts[i].extension)) {
|
||||
contenttype = ctts[i].type;
|
||||
break;
|
||||
}
|
||||
@@ -845,16 +845,23 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
if(type != FORM_DATAMEM) {
|
||||
newform->line = malloc((size_t)length+1);
|
||||
if(!newform->line) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
alloc2 = newform->line;
|
||||
memcpy(newform->line, line, (size_t)length);
|
||||
|
||||
newform->line = malloc((size_t)length+1);
|
||||
if(!newform->line) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
/* zero terminate for easier debugging */
|
||||
newform->line[(size_t)length]=0;
|
||||
}
|
||||
else {
|
||||
newform->line = (char *)line;
|
||||
type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
|
||||
}
|
||||
alloc2 = newform->line;
|
||||
memcpy(newform->line, line, (size_t)length);
|
||||
newform->length = (size_t)length;
|
||||
newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
|
||||
}
|
||||
else
|
||||
/* For callbacks and files we don't have any actual data so we just keep a
|
||||
@@ -863,13 +870,6 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
|
||||
newform->type = type;
|
||||
|
||||
if(*formp) {
|
||||
(*formp)->next = newform;
|
||||
*formp = newform;
|
||||
}
|
||||
else
|
||||
*formp = newform;
|
||||
|
||||
if(size) {
|
||||
if(type != FORM_FILE)
|
||||
/* for static content as well as callback data we add the size given
|
||||
@@ -878,7 +878,7 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
else {
|
||||
/* Since this is a file to be uploaded here, add the size of the actual
|
||||
file */
|
||||
if(!strequal("-", newform->line)) {
|
||||
if(strcmp("-", newform->line)) {
|
||||
struct_stat file;
|
||||
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
|
||||
*size += filesize(newform->line, file);
|
||||
@@ -889,6 +889,14 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*formp) {
|
||||
(*formp)->next = newform;
|
||||
*formp = newform;
|
||||
}
|
||||
else
|
||||
*formp = newform;
|
||||
|
||||
return CURLE_OK;
|
||||
error:
|
||||
if(newform)
|
||||
@@ -906,13 +914,21 @@ static CURLcode AddFormDataf(struct FormData **formp,
|
||||
curl_off_t *size,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
char s[4096];
|
||||
char *s;
|
||||
CURLcode result;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(s, sizeof(s), fmt, ap);
|
||||
s = curl_mvaprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return AddFormData(formp, FORM_DATA, s, 0, size);
|
||||
if(!s)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = AddFormData(formp, FORM_DATAMEM, s, 0, size);
|
||||
if(result)
|
||||
free(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1289,7 +1305,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
/* we should include the contents from the specified file */
|
||||
FILE *fileread;
|
||||
|
||||
fileread = strequal("-", file->contents)?
|
||||
fileread = !strcmp("-", file->contents)?
|
||||
stdin:fopen(file->contents, "rb"); /* binary read for win32 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
enum formtype {
|
||||
FORM_DATAMEM, /* already allocated FORM_DATA memory */
|
||||
FORM_DATA, /* form metadata (convert to network encoding if necessary) */
|
||||
FORM_CONTENT, /* form content (never convert) */
|
||||
FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback
|
||||
|
||||
+50
-57
@@ -61,7 +61,7 @@
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_sec.h"
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
@@ -72,7 +72,7 @@
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "speedcheck.h"
|
||||
#include "warnless.h"
|
||||
#include "http_proxy.h"
|
||||
@@ -475,7 +475,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
if(ftpcode/100 > 3)
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -741,7 +741,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
*/
|
||||
}
|
||||
else {
|
||||
switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
|
||||
switch (SOCKET_READABLE(sockfd, interval_ms)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
failf(data, "FTP response aborted due to select/poll error: %d",
|
||||
SOCKERRNO);
|
||||
@@ -911,7 +911,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
}
|
||||
else {
|
||||
socks[1] = conn->sock[SECONDARYSOCKET];
|
||||
bits |= GETSOCK_WRITESOCK(1);
|
||||
bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
|
||||
}
|
||||
|
||||
return bits;
|
||||
@@ -1835,7 +1835,7 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
if(conn->bits.ipv6) {
|
||||
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
|
||||
failf(conn->data, "Failed EPSV attempt, exiting\n");
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
|
||||
@@ -2742,7 +2742,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
else if(ftpcode != 220) {
|
||||
failf(data, "Got a %03d ftp-server response when 220 was expected",
|
||||
ftpcode);
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* We have received a 220 response fine, now we proceed. */
|
||||
@@ -2999,7 +2999,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
|
||||
/* Check for special servers here. */
|
||||
|
||||
if(strequal(os, "OS/400")) {
|
||||
if(strcasecompare(os, "OS/400")) {
|
||||
/* Force OS400 name format 1. */
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
|
||||
if(result) {
|
||||
@@ -3165,7 +3165,7 @@ static CURLcode ftp_multi_statemach(struct connectdata *conn,
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
|
||||
|
||||
/* Check for the state outside of the Curl_socket_ready() return code checks
|
||||
/* Check for the state outside of the Curl_socket_check() return code checks
|
||||
since at times we are in fact already in this state when this function
|
||||
gets called. */
|
||||
*done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
|
||||
@@ -3250,7 +3250,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
ssize_t nread;
|
||||
int ftpcode;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool was_ctl_valid = ftpc->ctl_valid;
|
||||
char *path;
|
||||
const char *path_to_use = data->state.path;
|
||||
|
||||
@@ -3274,10 +3273,9 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
/* the connection stays alive fine even though this happened */
|
||||
/* fall-through */
|
||||
case CURLE_OK: /* doesn't affect the control connection's status */
|
||||
if(!premature) {
|
||||
ftpc->ctl_valid = was_ctl_valid;
|
||||
if(!premature)
|
||||
break;
|
||||
}
|
||||
|
||||
/* until we cope better with prematurely ended requests, let them
|
||||
* fallback as if in complete failure */
|
||||
default: /* by default, an error means the control connection is
|
||||
@@ -3300,13 +3298,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
ftpc->known_filesize = -1;
|
||||
}
|
||||
|
||||
/* get the "raw" path */
|
||||
path = curl_easy_unescape(data, path_to_use, 0, NULL);
|
||||
if(!path) {
|
||||
/* out of memory, but we can limp along anyway (and should try to
|
||||
* since we may already be in the out of memory cleanup path) */
|
||||
if(!result)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
if(!result)
|
||||
/* get the "raw" path */
|
||||
result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
|
||||
if(result) {
|
||||
/* We can limp along anyway (and should try to since we may already be in
|
||||
* the error path) */
|
||||
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
|
||||
connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
|
||||
ftpc->prevpath = NULL; /* no path remembering */
|
||||
@@ -4094,8 +4091,7 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
const char *fmt, ...)
|
||||
CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
#define SBUF_SIZE 1024
|
||||
@@ -4107,10 +4103,9 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
enum protection_level data_sec = conn->data_prot;
|
||||
#endif
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
write_len = vsnprintf(s, SBUF_SIZE-3, fmt, ap);
|
||||
va_end(ap);
|
||||
write_len = strlen(cmd);
|
||||
if(write_len > (sizeof(s) -3))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
|
||||
write_len +=2;
|
||||
@@ -4292,6 +4287,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
slash_pos=strrchr(cur_pos, '/');
|
||||
if(slash_pos || !*cur_pos) {
|
||||
size_t dirlen = slash_pos-cur_pos;
|
||||
CURLcode result;
|
||||
|
||||
ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
|
||||
if(!ftpc->dirs)
|
||||
@@ -4300,12 +4296,13 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
if(!dirlen)
|
||||
dirlen++;
|
||||
|
||||
ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
|
||||
slash_pos ? curlx_uztosi(dirlen) : 1,
|
||||
NULL);
|
||||
if(!ftpc->dirs[0]) {
|
||||
result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
|
||||
slash_pos ? dirlen : 1,
|
||||
&ftpc->dirs[0], NULL,
|
||||
FALSE);
|
||||
if(result) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return result;
|
||||
}
|
||||
ftpc->dirdepth = 1; /* we consider it to be a single dir */
|
||||
filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
|
||||
@@ -4323,7 +4320,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* we have a special case for listing the root dir only */
|
||||
if(strequal(path_to_use, "/")) {
|
||||
if(!strcmp(path_to_use, "/")) {
|
||||
cur_pos++; /* make it point to the zero byte */
|
||||
ftpc->dirs[0] = strdup("/");
|
||||
ftpc->dirdepth++;
|
||||
@@ -4340,18 +4337,15 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
/* we skip empty path components, like "x//y" since the FTP command
|
||||
CWD requires a parameter and a non-existent parameter a) doesn't
|
||||
work on many servers and b) has no effect on the others. */
|
||||
int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir);
|
||||
ftpc->dirs[ftpc->dirdepth] =
|
||||
curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
|
||||
if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
|
||||
failf(data, "no memory");
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
|
||||
size_t len = slash_pos - cur_pos + absolute_dir;
|
||||
CURLcode result =
|
||||
Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
|
||||
&ftpc->dirs[ftpc->dirdepth], NULL,
|
||||
TRUE);
|
||||
if(result) {
|
||||
free(ftpc->dirs[ftpc->dirdepth]);
|
||||
freedirs(ftpc);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -4387,15 +4381,12 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
} /* switch */
|
||||
|
||||
if(filename && *filename) {
|
||||
ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL);
|
||||
if(NULL == ftpc->file) {
|
||||
CURLcode result =
|
||||
Curl_urldecode(conn->data, filename, 0, &ftpc->file, NULL, TRUE);
|
||||
|
||||
if(result) {
|
||||
freedirs(ftpc);
|
||||
failf(data, "no memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(isBadFtpString(ftpc->file)) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -4413,16 +4404,18 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
if(ftpc->prevpath) {
|
||||
/* prevpath is "raw" so we convert the input path before we compare the
|
||||
strings */
|
||||
int dlen;
|
||||
char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen);
|
||||
if(!path) {
|
||||
size_t dlen;
|
||||
char *path;
|
||||
CURLcode result =
|
||||
Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
|
||||
if(result) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return result;
|
||||
}
|
||||
|
||||
dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0;
|
||||
if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) &&
|
||||
strnequal(path, ftpc->prevpath, dlen)) {
|
||||
dlen -= ftpc->file?strlen(ftpc->file):0;
|
||||
if((dlen == strlen(ftpc->prevpath)) &&
|
||||
!strncmp(path, ftpc->prevpath, dlen)) {
|
||||
infof(data, "Request has same path as previous transfer\n");
|
||||
ftpc->cwddone = TRUE;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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
|
||||
@@ -31,7 +31,7 @@ extern const struct Curl_handler Curl_handler_ftp;
|
||||
extern const struct Curl_handler Curl_handler_ftps;
|
||||
#endif
|
||||
|
||||
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
CURLcode Curl_ftpsend(struct connectdata *, const char *cmd);
|
||||
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
||||
int *ftpcode);
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "fileinfo.h"
|
||||
#include "llist.h"
|
||||
#include "strtoofft.h"
|
||||
#include "rawstr.h"
|
||||
#include "ftp.h"
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_fnmatch.h"
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
static
|
||||
char *GetEnv(const char *variable)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
|
||||
(void)variable;
|
||||
return NULL;
|
||||
#else
|
||||
#ifdef WIN32
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* This is supposed to be called in the beginning of a perform() session
|
||||
* and should reset all session-info variables
|
||||
* This is supposed to be called in the beginning of a perform() session and
|
||||
* in curl_easy_reset() and should reset all session-info variables.
|
||||
*/
|
||||
CURLcode Curl_initinfo(struct Curl_easy *data)
|
||||
{
|
||||
@@ -58,18 +58,27 @@ CURLcode Curl_initinfo(struct Curl_easy *data)
|
||||
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
|
||||
info->timecond = FALSE;
|
||||
|
||||
info->header_size = 0;
|
||||
info->request_size = 0;
|
||||
info->proxyauthavail = 0;
|
||||
info->httpauthavail = 0;
|
||||
info->numconnects = 0;
|
||||
|
||||
free(info->contenttype);
|
||||
info->contenttype = NULL;
|
||||
|
||||
info->header_size = 0;
|
||||
info->request_size = 0;
|
||||
info->numconnects = 0;
|
||||
free(info->wouldredirect);
|
||||
info->wouldredirect = NULL;
|
||||
|
||||
info->conn_primary_ip[0] = '\0';
|
||||
info->conn_local_ip[0] = '\0';
|
||||
info->conn_primary_port = 0;
|
||||
info->conn_local_port = 0;
|
||||
|
||||
#ifdef USE_SSL
|
||||
Curl_ssl_free_certinfo(data);
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -28,13 +28,11 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
#include "gopher.h"
|
||||
#include "rawstr.h"
|
||||
#include "select.h"
|
||||
#include "url.h"
|
||||
#include "escape.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@@ -83,7 +81,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
char *sel;
|
||||
char *sel_org = NULL;
|
||||
ssize_t amount, k;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@@ -107,7 +105,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
newp[i] = '\x09';
|
||||
|
||||
/* ... and finally unescape */
|
||||
sel = curl_easy_unescape(data, newp, 0, &len);
|
||||
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
|
||||
if(!sel)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
sel_org = sel;
|
||||
@@ -121,20 +119,17 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||
if(!result) { /* Which may not have written it all! */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||
if(result) {
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
if(result)
|
||||
break;
|
||||
|
||||
k -= amount;
|
||||
sel += amount;
|
||||
if(k < 1)
|
||||
break; /* but it did write it all */
|
||||
}
|
||||
else {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
/* Don't busyloop. The entire loop thing is a work-around as it causes a
|
||||
BLOCKING behavior which is a NO-NO. This function should rather be
|
||||
split up in a do and a doing piece where the pieces that aren't
|
||||
@@ -144,14 +139,18 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
Wait a while for the socket to be writable. Note that this doesn't
|
||||
acknowledge the timeout.
|
||||
*/
|
||||
Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
|
||||
if(SOCKET_WRITABLE(sockfd, 100) < 0) {
|
||||
result = CURLE_SEND_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(sel_org);
|
||||
|
||||
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||
save allocing another string/doing another _write loop. */
|
||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||
if(!result)
|
||||
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||
save allocing another string/doing another _write loop. */
|
||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||
if(result) {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
return result;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "hostcheck.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
@@ -77,7 +77,7 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
pattern_wildcard = strchr(pattern, '*');
|
||||
if(pattern_wildcard == NULL)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
return strcasecompare(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
/* detect IP address as hostname and fail the match if so */
|
||||
@@ -94,16 +94,16 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
pattern_label_end = strchr(pattern, '.');
|
||||
if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
|
||||
pattern_wildcard > pattern_label_end ||
|
||||
Curl_raw_nequal(pattern, "xn--", 4)) {
|
||||
strncasecompare(pattern, "xn--", 4)) {
|
||||
wildcard_enabled = 0;
|
||||
}
|
||||
if(!wildcard_enabled)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
return strcasecompare(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
hostname_label_end = strchr(hostname, '.');
|
||||
if(hostname_label_end == NULL ||
|
||||
!Curl_raw_equal(pattern_label_end, hostname_label_end))
|
||||
!strcasecompare(pattern_label_end, hostname_label_end))
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
/* The wildcard must match at least one character, so the left-most
|
||||
@@ -114,8 +114,8 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
prefixlen = pattern_wildcard - pattern;
|
||||
suffixlen = pattern_label_end - (pattern_wildcard+1);
|
||||
return Curl_raw_nequal(pattern, hostname, prefixlen) &&
|
||||
Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
return strncasecompare(pattern, hostname, prefixlen) &&
|
||||
strncasecompare(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
suffixlen) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
}
|
||||
|
||||
@@ -603,11 +603,14 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
|
||||
return Curl_resolv(conn, hostname, port, entry);
|
||||
|
||||
if(timeout < 1000)
|
||||
if(timeout < 1000) {
|
||||
/* The alarm() function only provides integer second resolution, so if
|
||||
we want to wait less than one second we must bail out already now. */
|
||||
failf(data,
|
||||
"remaining timeout of %ld too small to resolve via SIGALRM method",
|
||||
timeout);
|
||||
return CURLRESOLV_TIMEDOUT;
|
||||
|
||||
}
|
||||
/* This allows us to time-out from the name resolver, as the timeout
|
||||
will generate a signal and we will siglongjmp() from that here.
|
||||
This technique has problems (see alarmfunc).
|
||||
|
||||
+149
-131
@@ -53,7 +53,6 @@
|
||||
#include "progress.h"
|
||||
#include "curl_base64.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "http_digest.h"
|
||||
@@ -68,7 +67,7 @@
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "strtoofft.h"
|
||||
#include "multiif.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "content_encoding.h"
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
@@ -182,7 +181,7 @@ char *Curl_checkheaders(const struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = data->set.headers;head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
if(strncasecompare(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
|
||||
@@ -208,7 +207,7 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
for(head = (conn->bits.proxy && data->set.sep_headers) ?
|
||||
data->set.proxyheaders : data->set.headers;
|
||||
head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
if(strncasecompare(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
|
||||
@@ -462,7 +461,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
#endif
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
connclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
streamclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
/* There still is data left to send, but this connection is marked for
|
||||
@@ -726,7 +725,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
conn->bits.netrc ||
|
||||
!data->state.first_host ||
|
||||
data->set.http_disable_hostname_check_before_authentication ||
|
||||
Curl_raw_equal(data->state.first_host, conn->host.name)) {
|
||||
strcasecompare(data->state.first_host, conn->host.name)) {
|
||||
result = output_auth_headers(conn, authhost, request, path, FALSE);
|
||||
}
|
||||
else
|
||||
@@ -784,23 +783,27 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
while(*auth) {
|
||||
#ifdef USE_SPNEGO
|
||||
if(checkprefix("Negotiate", auth)) {
|
||||
*availp |= CURLAUTH_NEGOTIATE;
|
||||
authp->avail |= CURLAUTH_NEGOTIATE;
|
||||
if((authp->avail & CURLAUTH_NEGOTIATE) ||
|
||||
Curl_auth_is_spnego_supported()) {
|
||||
*availp |= CURLAUTH_NEGOTIATE;
|
||||
authp->avail |= CURLAUTH_NEGOTIATE;
|
||||
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
|
||||
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(!result) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received a GSS auth token and we dealt with it fine */
|
||||
negdata->state = GSS_AUTHRECV;
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
if(negdata->state == GSS_AUTHSENT ||
|
||||
negdata->state == GSS_AUTHNONE) {
|
||||
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(!result) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received a GSS auth token and we dealt with it fine */
|
||||
negdata->state = GSS_AUTHRECV;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,39 +812,44 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
#ifdef USE_NTLM
|
||||
/* NTLM support requires the SSL crypto libs */
|
||||
if(checkprefix("NTLM", auth)) {
|
||||
*availp |= CURLAUTH_NTLM;
|
||||
authp->avail |= CURLAUTH_NTLM;
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
CURLcode result = Curl_input_ntlm(conn, proxy, auth);
|
||||
if(!result) {
|
||||
data->state.authproblem = FALSE;
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authp->picked == CURLAUTH_NTLM_WB) {
|
||||
*availp &= ~CURLAUTH_NTLM;
|
||||
authp->avail &= ~CURLAUTH_NTLM;
|
||||
*availp |= CURLAUTH_NTLM_WB;
|
||||
authp->avail |= CURLAUTH_NTLM_WB;
|
||||
if((authp->avail & CURLAUTH_NTLM) ||
|
||||
(authp->avail & CURLAUTH_NTLM_WB) ||
|
||||
Curl_auth_is_ntlm_supported()) {
|
||||
*availp |= CURLAUTH_NTLM;
|
||||
authp->avail |= CURLAUTH_NTLM;
|
||||
|
||||
/* Get the challenge-message which will be passed to
|
||||
* ntlm_auth for generating the type 3 message later */
|
||||
while(*auth && ISSPACE(*auth))
|
||||
auth++;
|
||||
if(checkprefix("NTLM", auth)) {
|
||||
auth += strlen("NTLM");
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
CURLcode result = Curl_input_ntlm(conn, proxy, auth);
|
||||
if(!result) {
|
||||
data->state.authproblem = FALSE;
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authp->picked == CURLAUTH_NTLM_WB) {
|
||||
*availp &= ~CURLAUTH_NTLM;
|
||||
authp->avail &= ~CURLAUTH_NTLM;
|
||||
*availp |= CURLAUTH_NTLM_WB;
|
||||
authp->avail |= CURLAUTH_NTLM_WB;
|
||||
|
||||
/* Get the challenge-message which will be passed to
|
||||
* ntlm_auth for generating the type 3 message later */
|
||||
while(*auth && ISSPACE(*auth))
|
||||
auth++;
|
||||
if(*auth)
|
||||
if((conn->challenge_header = strdup(auth)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(checkprefix("NTLM", auth)) {
|
||||
auth += strlen("NTLM");
|
||||
while(*auth && ISSPACE(*auth))
|
||||
auth++;
|
||||
if(*auth)
|
||||
if((conn->challenge_header = strdup(auth)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -849,18 +857,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(checkprefix("Digest", auth)) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0)
|
||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||
}
|
||||
else {
|
||||
else if(Curl_auth_is_digest_supported()) {
|
||||
CURLcode result;
|
||||
|
||||
*availp |= CURLAUTH_DIGEST;
|
||||
authp->avail |= CURLAUTH_DIGEST;
|
||||
|
||||
/* We call this function on input Digest headers even if Digest
|
||||
* authentication isn't activated yet, as we need to store the
|
||||
* incoming data from this header in case we are gonna use
|
||||
* Digest. */
|
||||
* incoming data from this header in case we are going to use
|
||||
* Digest */
|
||||
result = Curl_input_digest(conn, proxy, auth);
|
||||
if(result) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
@@ -1296,7 +1304,7 @@ Curl_compareheader(const char *headerline, /* line to check */
|
||||
const char *start;
|
||||
const char *end;
|
||||
|
||||
if(!Curl_raw_nequal(headerline, header, hlen))
|
||||
if(!strncasecompare(headerline, header, hlen))
|
||||
return FALSE; /* doesn't start with header */
|
||||
|
||||
/* pass the header */
|
||||
@@ -1322,7 +1330,7 @@ Curl_compareheader(const char *headerline, /* line to check */
|
||||
|
||||
/* find the content string in the rest of the line */
|
||||
for(;len>=clen;len--, start++) {
|
||||
if(Curl_raw_nequal(start, content, clen))
|
||||
if(strncasecompare(start, content, clen))
|
||||
return TRUE; /* match! */
|
||||
}
|
||||
|
||||
@@ -1443,9 +1451,8 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
#ifdef USE_NGHTTP2
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
#endif
|
||||
|
||||
infof(data, "Curl_http_done: called premature == %d\n", premature);
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
@@ -1458,7 +1465,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
* Do not close CONNECT_ONLY connections. */
|
||||
if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
|
||||
!data->set.connect_only)
|
||||
connclose(conn, "Negotiate transfer completed");
|
||||
streamclose(conn, "Negotiate transfer completed");
|
||||
Curl_cleanup_negotiate(data);
|
||||
}
|
||||
#endif
|
||||
@@ -1475,27 +1482,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
http->send_buffer = NULL; /* clear the pointer */
|
||||
}
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(http->header_recvbuf) {
|
||||
DEBUGF(infof(data, "free header_recvbuf!!\n"));
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
Curl_add_buffer_free(http->trailer_recvbuf);
|
||||
http->trailer_recvbuf = NULL; /* clear the pointer */
|
||||
if(http->push_headers) {
|
||||
/* if they weren't used and then freed before */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
}
|
||||
if(http->stream_id) {
|
||||
nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
|
||||
http->stream_id = 0;
|
||||
}
|
||||
#endif
|
||||
Curl_http2_done(conn, premature);
|
||||
|
||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||
data->req.bytecount = http->readbytecount + http->writebytecount;
|
||||
@@ -1660,6 +1647,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
Connection: */
|
||||
checkprefix("Connection", headers->data))
|
||||
;
|
||||
else if((conn->httpversion == 20) &&
|
||||
checkprefix("Transfer-Encoding:", headers->data))
|
||||
/* HTTP/2 doesn't support chunked requests */
|
||||
;
|
||||
else {
|
||||
CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
|
||||
headers->data);
|
||||
@@ -1946,47 +1937,42 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(conn->httpversion == 20)
|
||||
/* In HTTP2 forbids Transfer-Encoding: chunked */
|
||||
ptr = NULL;
|
||||
ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
data->req.upload_chunky =
|
||||
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
|
||||
}
|
||||
else {
|
||||
ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
data->req.upload_chunky =
|
||||
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
|
||||
}
|
||||
else {
|
||||
if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
|
||||
data->set.upload &&
|
||||
(data->state.infilesize == -1)) {
|
||||
if(conn->bits.authneg)
|
||||
/* don't enable chunked during auth neg */
|
||||
;
|
||||
else if(use_http_1_1plus(data, conn)) {
|
||||
/* HTTP, upload, unknown file size and not HTTP 1.0 */
|
||||
data->req.upload_chunky = TRUE;
|
||||
}
|
||||
else {
|
||||
failf(data, "Chunky upload is not supported by HTTP 1.0");
|
||||
return CURLE_UPLOAD_FAILED;
|
||||
}
|
||||
if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
|
||||
data->set.upload &&
|
||||
(data->state.infilesize == -1)) {
|
||||
if(conn->bits.authneg)
|
||||
/* don't enable chunked during auth neg */
|
||||
;
|
||||
else if(use_http_1_1plus(data, conn)) {
|
||||
/* HTTP, upload, unknown file size and not HTTP 1.0 */
|
||||
data->req.upload_chunky = TRUE;
|
||||
}
|
||||
else {
|
||||
/* else, no chunky upload */
|
||||
data->req.upload_chunky = FALSE;
|
||||
failf(data, "Chunky upload is not supported by HTTP 1.0");
|
||||
return CURLE_UPLOAD_FAILED;
|
||||
}
|
||||
|
||||
if(data->req.upload_chunky)
|
||||
te = "Transfer-Encoding: chunked\r\n";
|
||||
}
|
||||
else {
|
||||
/* else, no chunky upload */
|
||||
data->req.upload_chunky = FALSE;
|
||||
}
|
||||
|
||||
if(data->req.upload_chunky)
|
||||
te = "Transfer-Encoding: chunked\r\n";
|
||||
}
|
||||
|
||||
Curl_safefree(conn->allocptr.host);
|
||||
|
||||
ptr = Curl_checkheaders(conn, "Host:");
|
||||
if(ptr && (!data->state.this_is_a_follow ||
|
||||
Curl_raw_equal(data->state.first_host, conn->host.name))) {
|
||||
strcasecompare(data->state.first_host, conn->host.name))) {
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
/* If we have a given custom Host: header, we extract the host name in
|
||||
order to possibly use it for cookie reasons later on. We only allow the
|
||||
@@ -2305,6 +2291,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
"%s" /* TE: */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* referer */
|
||||
"%s" /* Proxy-Connection */
|
||||
"%s",/* transfer-encoding */
|
||||
|
||||
ftp_typecode,
|
||||
@@ -2327,6 +2314,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
conn->allocptr.accept_encoding:"",
|
||||
(data->change.referer && conn->allocptr.ref)?
|
||||
conn->allocptr.ref:"" /* Referer: <data> */,
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
te
|
||||
);
|
||||
|
||||
@@ -2392,7 +2383,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
co = co->next; /* next cookie please */
|
||||
}
|
||||
Curl_cookie_freelist(store, FALSE); /* free the cookie list */
|
||||
Curl_cookie_freelist(store);
|
||||
}
|
||||
if(addcookies && !result) {
|
||||
if(!count)
|
||||
@@ -2768,6 +2759,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
}
|
||||
|
||||
if((conn->httpversion == 20) && data->req.upload_chunky)
|
||||
/* upload_chunky was set above to set up the request in a chunky fashion,
|
||||
but is disabled here again to avoid that the chunked encoded version is
|
||||
actually used when sending the request body over h2 */
|
||||
data->req.upload_chunky = FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3040,19 +3036,19 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(100 <= k->httpcode && 199 >= k->httpcode) {
|
||||
/*
|
||||
* We have made a HTTP PUT or POST and this is 1.1-lingo
|
||||
* that tells us that the server is OK with this and ready
|
||||
* to receive the data.
|
||||
* However, we'll get more headers now so we must get
|
||||
* back into the header-parsing state!
|
||||
*/
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
|
||||
/* "A user agent MAY ignore unexpected 1xx status responses." */
|
||||
switch(k->httpcode) {
|
||||
case 100:
|
||||
/*
|
||||
* We have made a HTTP PUT or POST and this is 1.1-lingo
|
||||
* that tells us that the server is OK with this and ready
|
||||
* to receive the data.
|
||||
* However, we'll get more headers now so we must get
|
||||
* back into the header-parsing state!
|
||||
*/
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
|
||||
/* if we did wait for this do enable write now! */
|
||||
if(k->exp100 > EXP100_SEND_DATA) {
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
@@ -3062,9 +3058,14 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
case 101:
|
||||
/* Switching Protocols */
|
||||
if(k->upgr101 == UPGR101_REQUESTED) {
|
||||
/* Switching to HTTP/2 */
|
||||
infof(data, "Received 101\n");
|
||||
k->upgr101 = UPGR101_RECEIVED;
|
||||
|
||||
/* we'll get more headers (HTTP/2 response) */
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
|
||||
/* switch to http2 now. The bytes after response headers
|
||||
are also processed here, otherwise they are lost. */
|
||||
result = Curl_http2_switched(conn, k->str, *nread);
|
||||
@@ -3072,8 +3073,16 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
return result;
|
||||
*nread = 0;
|
||||
}
|
||||
else {
|
||||
/* Switching to another protocol (e.g. WebSocket) */
|
||||
k->header = FALSE; /* no more header to parse! */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* the status code 1xx indicates a provisional response, so
|
||||
we'll get another set of headers */
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3091,7 +3100,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
signal the end of the document. */
|
||||
infof(data, "no chunk, no close, no size. Assume close to "
|
||||
"signal end\n");
|
||||
connclose(conn, "HTTP: No end-of-message indicator");
|
||||
streamclose(conn, "HTTP: No end-of-message indicator");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3171,12 +3180,21 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* connection for closure after we've read the entire response.
|
||||
*/
|
||||
if(!k->upload_done) {
|
||||
infof(data, "HTTP error before end of send, stop sending\n");
|
||||
connclose(conn, "Stop sending data before everything sent");
|
||||
k->upload_done = TRUE;
|
||||
k->keepon &= ~KEEP_SEND; /* don't send */
|
||||
if(data->state.expect100header)
|
||||
k->exp100 = EXP100_FAILED;
|
||||
if(data->set.http_keep_sending_on_error) {
|
||||
infof(data, "HTTP error before end of send, keep sending\n");
|
||||
if(k->exp100 > EXP100_SEND_DATA) {
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
k->keepon |= KEEP_SEND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
infof(data, "HTTP error before end of send, stop sending\n");
|
||||
streamclose(conn, "Stop sending data before everything sent");
|
||||
k->upload_done = TRUE;
|
||||
k->keepon &= ~KEEP_SEND; /* don't send */
|
||||
if(data->state.expect100header)
|
||||
k->exp100 = EXP100_FAILED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3476,7 +3494,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
/* Negative Content-Length is really odd, and we know it
|
||||
happens for example when older Apache servers send large
|
||||
files */
|
||||
connclose(conn, "negative content-length");
|
||||
streamclose(conn, "negative content-length");
|
||||
infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
|
||||
", closing after transfer\n", contentlength);
|
||||
}
|
||||
@@ -3549,7 +3567,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* the connection will close when this request has been
|
||||
* served.
|
||||
*/
|
||||
connclose(conn, "Connection: close used");
|
||||
streamclose(conn, "Connection: close used");
|
||||
}
|
||||
else if(checkprefix("Transfer-Encoding:", k->p)) {
|
||||
/* One or more encodings. We check for chunked and/or a compression
|
||||
|
||||
@@ -168,6 +168,7 @@ struct HTTP {
|
||||
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
|
||||
size_t pauselen; /* the number of bytes left in data */
|
||||
bool closed; /* TRUE on HTTP2 stream close */
|
||||
bool close_handled; /* TRUE if stream closure is handled by libcurl */
|
||||
uint32_t error_code; /* HTTP/2 error code */
|
||||
|
||||
char *mem; /* points to a buffer in memory to store received data */
|
||||
|
||||
+119
-53
@@ -29,7 +29,7 @@
|
||||
#include "http.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_base64.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "multiif.h"
|
||||
#include "conncache.h"
|
||||
#include "url.h"
|
||||
@@ -92,8 +92,9 @@ static int http2_perform_getsock(const struct connectdata *conn,
|
||||
because of renegotiation. */
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(nghttp2_session_want_read(c->h2))
|
||||
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
/* in a HTTP/2 connection we can basically always get a frame so we should
|
||||
always be ready for one */
|
||||
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
|
||||
if(nghttp2_session_want_write(c->h2))
|
||||
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
|
||||
@@ -150,6 +151,7 @@ void Curl_http2_setup_req(struct Curl_easy *data)
|
||||
http->pauselen = 0;
|
||||
http->error_code = NGHTTP2_NO_ERROR;
|
||||
http->closed = FALSE;
|
||||
http->close_handled = FALSE;
|
||||
http->mem = data->state.buffer;
|
||||
http->len = BUFSIZE;
|
||||
http->memlen = 0;
|
||||
@@ -184,7 +186,7 @@ const struct Curl_handler Curl_handler_http2 = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTP, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
PROTOPT_STREAM /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
@@ -204,7 +206,7 @@ const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTP, /* defport */
|
||||
CURLPROTO_HTTPS, /* protocol */
|
||||
PROTOPT_SSL /* flags */
|
||||
PROTOPT_SSL | PROTOPT_STREAM /* flags */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -317,7 +319,7 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
|
||||
the middle of header, it could be matched in middle of the value,
|
||||
this is because we do prefix match.*/
|
||||
if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
|
||||
Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
|
||||
!strcmp(header, ":") || strchr(header + 1, ':'))
|
||||
return NULL;
|
||||
else {
|
||||
struct HTTP *stream = h->data->req.protop;
|
||||
@@ -488,8 +490,11 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
}
|
||||
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
if(!stream) {
|
||||
DEBUGF(infof(conn->data, "No proto pointer for stream: %x\n",
|
||||
stream_id));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
|
||||
frame->hd.type, stream_id));
|
||||
@@ -547,7 +552,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn_s->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 0);
|
||||
}
|
||||
break;
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
@@ -621,8 +626,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
|
||||
immediately? */
|
||||
Curl_expire(data_s, 0);
|
||||
|
||||
DEBUGF(infof(data_s, "%zu data received for stream %u "
|
||||
"(%zu left in buffer %p, total %zu)\n",
|
||||
@@ -883,7 +887,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 0);
|
||||
|
||||
DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
||||
stream->status_code, data_s));
|
||||
@@ -899,7 +903,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 0);
|
||||
|
||||
DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
|
||||
value));
|
||||
@@ -941,11 +945,12 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
memcpy(buf, stream->upload_mem, nread);
|
||||
stream->upload_mem += nread;
|
||||
stream->upload_len -= nread;
|
||||
stream->upload_left -= nread;
|
||||
if(data_s->state.infilesize != -1)
|
||||
stream->upload_left -= nread;
|
||||
}
|
||||
|
||||
if(stream->upload_left == 0)
|
||||
*data_flags = 1;
|
||||
*data_flags = NGHTTP2_DATA_FLAG_EOF;
|
||||
else if(nread == 0)
|
||||
return NGHTTP2_ERR_DEFERRED;
|
||||
|
||||
@@ -979,6 +984,43 @@ static int error_callback(nghttp2_session *session,
|
||||
}
|
||||
#endif
|
||||
|
||||
void Curl_http2_done(struct connectdata *conn, bool premature)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
|
||||
if(http->header_recvbuf) {
|
||||
DEBUGF(infof(data, "free header_recvbuf!!\n"));
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
Curl_add_buffer_free(http->trailer_recvbuf);
|
||||
http->trailer_recvbuf = NULL; /* clear the pointer */
|
||||
if(http->push_headers) {
|
||||
/* if they weren't used and then freed before */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(premature) {
|
||||
/* RST_STREAM */
|
||||
nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
|
||||
NGHTTP2_STREAM_CLOSED);
|
||||
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);
|
||||
http->stream_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize nghttp2 for a Curl connection
|
||||
*/
|
||||
@@ -1091,9 +1133,10 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
/*
|
||||
* Returns nonzero if current HTTP/2 session should be closed.
|
||||
*/
|
||||
static int should_close_session(struct http_conn *httpc) {
|
||||
static int should_close_session(struct http_conn *httpc)
|
||||
{
|
||||
return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) &&
|
||||
!nghttp2_session_want_write(httpc->h2);
|
||||
!nghttp2_session_want_write(httpc->h2);
|
||||
}
|
||||
|
||||
static int h2_session_send(struct Curl_easy *data,
|
||||
@@ -1107,7 +1150,8 @@ static int h2_session_send(struct Curl_easy *data,
|
||||
*/
|
||||
static int h2_process_pending_input(struct Curl_easy *data,
|
||||
struct http_conn *httpc,
|
||||
CURLcode *err) {
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
char *inbuf;
|
||||
ssize_t rv;
|
||||
@@ -1155,9 +1199,41 @@ static int h2_process_pending_input(struct Curl_easy *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from transfer.c:done_sending when we stop uploading.
|
||||
*/
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if((conn->handler == &Curl_handler_http2_ssl) ||
|
||||
(conn->handler == &Curl_handler_http2)) {
|
||||
/* make sure this is only attempted for HTTP/2 transfers */
|
||||
|
||||
struct HTTP *stream = conn->data->req.protop;
|
||||
|
||||
if(stream->upload_left) {
|
||||
/* If the stream still thinks there's data left to upload. */
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
nghttp2_session *h2 = httpc->h2;
|
||||
|
||||
stream->upload_left = 0; /* DONE! */
|
||||
|
||||
/* resume sending here to trigger the callback to get called again so
|
||||
that it can signal EOF to nghttp2 */
|
||||
(void)nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
|
||||
(void)h2_process_pending_input(conn->data, httpc, &result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
struct HTTP *stream, CURLcode *err) {
|
||||
struct HTTP *stream, CURLcode *err)
|
||||
{
|
||||
char *trailer_pos, *trailer_end;
|
||||
CURLcode result;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
@@ -1178,8 +1254,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(data->state.drain == 0);
|
||||
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data
|
||||
function. */
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
|
||||
stream->closed = FALSE;
|
||||
if(stream->error_code != NGHTTP2_NO_ERROR) {
|
||||
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
|
||||
@@ -1216,6 +1291,8 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
stream->close_handled = TRUE;
|
||||
|
||||
DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
|
||||
return 0;
|
||||
}
|
||||
@@ -1268,10 +1345,6 @@ static int h2_session_send(struct Curl_easy *data,
|
||||
return nghttp2_session_send(h2);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
|
||||
* a regular CURLcode value.
|
||||
*/
|
||||
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
@@ -1382,6 +1455,8 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
socket is not read. But it seems that usually streams are
|
||||
notified with its drain property, and socket is read again
|
||||
quickly. */
|
||||
DEBUGF(infof(data, "stream %x is paused, pause id: %x\n",
|
||||
stream->stream_id, httpc->pause_stream_id));
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
@@ -1497,7 +1572,6 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
#define HEADER_OVERFLOW(x) \
|
||||
(x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen)
|
||||
|
||||
/* return number of received (decrypted) bytes */
|
||||
static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
@@ -1525,6 +1599,14 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
|
||||
|
||||
if(stream->stream_id != -1) {
|
||||
if(stream->close_handled) {
|
||||
infof(conn->data, "stream %d closed\n", stream->stream_id);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
}
|
||||
else if(stream->closed) {
|
||||
return http2_handle_stream_close(conn, conn->data, stream, err);
|
||||
}
|
||||
/* If stream_id != -1, we have dispatched request HEADERS, and now
|
||||
are going to send or sending request body in DATA frame */
|
||||
stream->upload_mem = mem;
|
||||
@@ -1661,12 +1743,12 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
goto fail;
|
||||
hlen = end - hdbuf;
|
||||
|
||||
if(hlen == 10 && Curl_raw_nequal("connection", hdbuf, 10)) {
|
||||
if(hlen == 10 && strncasecompare("connection", hdbuf, 10)) {
|
||||
/* skip Connection: headers! */
|
||||
skip = 1;
|
||||
--nheader;
|
||||
}
|
||||
else if(hlen == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
|
||||
else if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
|
||||
authority_idx = i;
|
||||
nva[i].name = (unsigned char *)":authority";
|
||||
nva[i].namelen = strlen((char *)nva[i].name);
|
||||
@@ -1687,28 +1769,6 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
failf(conn->data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
/* Inspect Content-Length header field and retrieve the request
|
||||
entity length so that we can set END_STREAM to the last DATA
|
||||
frame. */
|
||||
if(nva[i].namelen == 14 &&
|
||||
Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) {
|
||||
size_t j;
|
||||
stream->upload_left = 0;
|
||||
if(!nva[i].valuelen)
|
||||
goto fail;
|
||||
for(j = 0; j < nva[i].valuelen; ++j) {
|
||||
if(nva[i].value[j] < '0' || nva[i].value[j] > '9')
|
||||
goto fail;
|
||||
if(stream->upload_left >= CURL_OFF_T_MAX / 10)
|
||||
goto fail;
|
||||
stream->upload_left *= 10;
|
||||
stream->upload_left += nva[i].value[j] - '0';
|
||||
}
|
||||
DEBUGF(infof(conn->data,
|
||||
"request content-length=%"
|
||||
CURL_FORMAT_CURL_OFF_T
|
||||
"\n", stream->upload_left));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@@ -1736,6 +1796,10 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
if(nva[i].valuelen > max_acc - acc)
|
||||
break;
|
||||
acc += nva[i].valuelen;
|
||||
|
||||
DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
|
||||
nva[i].namelen, nva[i].name,
|
||||
nva[i].valuelen, nva[i].value));
|
||||
}
|
||||
|
||||
if(i != nheader) {
|
||||
@@ -1751,6 +1815,12 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
case HTTPREQ_PUT:
|
||||
if(conn->data->state.infilesize != -1)
|
||||
stream->upload_left = conn->data->state.infilesize;
|
||||
else
|
||||
/* data sending without specifying the data amount up front */
|
||||
stream->upload_left = -1; /* unknown, but not zero */
|
||||
|
||||
data_prd.read_callback = data_source_read_callback;
|
||||
data_prd.source.ptr = NULL;
|
||||
stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
|
||||
@@ -1850,10 +1920,6 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
|
||||
Curl_multi_connchanged(conn->data->multi);
|
||||
|
||||
/* switch on TCP_NODELAY as we need to send off packets without delay for
|
||||
maximum throughput */
|
||||
Curl_tcpnodelay(conn, conn->sock[FIRSTSOCKET]);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -51,6 +51,8 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
void Curl_http2_setup_req(struct Curl_easy *data);
|
||||
void Curl_http2_done(struct connectdata *conn, bool premature);
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
@@ -61,6 +63,8 @@ void Curl_http2_setup_req(struct Curl_easy *data);
|
||||
#define Curl_http2_setup_req(x)
|
||||
#define Curl_http2_init_state(x)
|
||||
#define Curl_http2_init_userset(x)
|
||||
#define Curl_http2_done(x,y)
|
||||
#define Curl_http2_done_sending(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "http_digest.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "vauth/vauth.h"
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "vauth/vauth.h"
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "http.h"
|
||||
#include "url.h"
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "progress.h"
|
||||
#include "non-ascii.h"
|
||||
#include "connect.h"
|
||||
@@ -160,6 +159,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
if(!result) {
|
||||
char *host=(char *)"";
|
||||
const char *proxyconn="";
|
||||
const char *useragent="";
|
||||
const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
"1.0" : "1.1";
|
||||
@@ -185,6 +185,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
|
||||
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = conn->allocptr.uagent;
|
||||
@@ -194,13 +197,15 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
"CONNECT %s HTTP/%s\r\n"
|
||||
"%s" /* Host: */
|
||||
"%s" /* Proxy-Authorization */
|
||||
"%s", /* User-Agent */
|
||||
"%s" /* User-Agent */
|
||||
"%s", /* Proxy-Connection */
|
||||
hostheader,
|
||||
http,
|
||||
host,
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
useragent);
|
||||
useragent,
|
||||
proxyconn);
|
||||
|
||||
if(host && *host)
|
||||
free(host);
|
||||
@@ -239,7 +244,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(!blocking) {
|
||||
if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
|
||||
if(0 == SOCKET_READABLE(tunnelsocket, 0))
|
||||
/* return so we'll be called again polling-style */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
@@ -274,8 +279,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* loop every second at least, less if the timeout is near */
|
||||
switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
|
||||
check<1000L?check:1000)) {
|
||||
switch (SOCKET_READABLE(tunnelsocket, check<1000L?check:1000)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Proxy CONNECT aborted due to select/poll error");
|
||||
@@ -568,7 +572,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
/* failure, close this connection to avoid re-use */
|
||||
connclose(conn, "proxy CONNECT failure");
|
||||
streamclose(conn, "proxy CONNECT failure");
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#endif
|
||||
|
||||
#include "inet_ntop.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "if2ip.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -102,7 +102,7 @@ bool Curl_if_is_interface_name(const char *interf)
|
||||
|
||||
if(getifaddrs(&head) >= 0) {
|
||||
for(iface=head; iface != NULL; iface=iface->ifa_next) {
|
||||
if(curl_strequal(iface->ifa_name, interf)) {
|
||||
if(strcasecompare(iface->ifa_name, interf)) {
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
for(iface = head; iface != NULL; iface=iface->ifa_next) {
|
||||
if(iface->ifa_addr != NULL) {
|
||||
if(iface->ifa_addr->sa_family == af) {
|
||||
if(curl_strequal(iface->ifa_name, interf)) {
|
||||
if(strcasecompare(iface->ifa_name, interf)) {
|
||||
void *addr;
|
||||
char *ip;
|
||||
char scope[12] = "";
|
||||
@@ -180,7 +180,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
}
|
||||
}
|
||||
else if((res == IF2IP_NOT_FOUND) &&
|
||||
curl_strequal(iface->ifa_name, interf)) {
|
||||
strcasecompare(iface->ifa_name, interf)) {
|
||||
res = IF2IP_AF_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-13
@@ -68,16 +68,15 @@
|
||||
#include "http.h" /* for HTTP proxy tunnel stuff */
|
||||
#include "socks.h"
|
||||
#include "imap.h"
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
|
||||
@@ -271,7 +270,7 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd)
|
||||
|
||||
/* Does the command name match and is it followed by a space character or at
|
||||
the end of line? */
|
||||
if(line + cmd_len <= end && Curl_raw_nequal(line, cmd, cmd_len) &&
|
||||
if(line + cmd_len <= end && strncasecompare(line, cmd, cmd_len) &&
|
||||
(line[cmd_len] == ' ' || line + cmd_len + 2 == end))
|
||||
return TRUE;
|
||||
|
||||
@@ -846,7 +845,7 @@ static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
|
||||
|
||||
if(imapcode != 'O') {
|
||||
failf(data, "Got unexpected imap-server response");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
else
|
||||
result = imap_perform_capability(conn);
|
||||
@@ -1179,7 +1178,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
else {
|
||||
/* We don't know how to parse this line */
|
||||
failf(pp->conn->data, "Failed to parse FETCH response.");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* End of DO phase */
|
||||
@@ -1198,7 +1197,7 @@ static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
|
||||
(void)instate; /* No use for this yet */
|
||||
|
||||
if(imapcode != 'O')
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
else
|
||||
/* End of DONE phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@@ -1275,7 +1274,7 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
|
||||
|
||||
/* Was there an error parsing the response line? */
|
||||
if(imapcode == -1)
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
|
||||
if(!imapcode)
|
||||
break;
|
||||
@@ -1935,7 +1934,7 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
|
||||
while(*ptr && *ptr != ';')
|
||||
ptr++;
|
||||
|
||||
if(strnequal(key, "AUTH=", 5))
|
||||
if(strncasecompare(key, "AUTH=", 5))
|
||||
result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
|
||||
value, ptr - value);
|
||||
else
|
||||
@@ -2031,28 +2030,28 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
|
||||
PARTIAL) stripping of the trailing slash character if it is present.
|
||||
|
||||
Note: Unknown parameters trigger a URL_MALFORMAT error. */
|
||||
if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) {
|
||||
if(strcasecompare(name, "UIDVALIDITY") && !imap->uidvalidity) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
imap->uidvalidity = value;
|
||||
value = NULL;
|
||||
}
|
||||
else if(Curl_raw_equal(name, "UID") && !imap->uid) {
|
||||
else if(strcasecompare(name, "UID") && !imap->uid) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
imap->uid = value;
|
||||
value = NULL;
|
||||
}
|
||||
else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
|
||||
else if(strcasecompare(name, "SECTION") && !imap->section) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
imap->section = value;
|
||||
value = NULL;
|
||||
}
|
||||
else if(Curl_raw_equal(name, "PARTIAL") && !imap->partial) {
|
||||
else if(strcasecompare(name, "PARTIAL") && !imap->partial) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
for(;;) {
|
||||
/* this really shouldn't be repeated here, but can't help it */
|
||||
if(service == srv_host) {
|
||||
result = Curl_ftpsendf(conn, "AUTH GSSAPI");
|
||||
result = Curl_ftpsend(conn, "AUTH GSSAPI");
|
||||
if(result)
|
||||
return -2;
|
||||
|
||||
@@ -243,16 +243,22 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(output_buffer.length != 0) {
|
||||
char *cmd;
|
||||
|
||||
result = Curl_base64_encode(data, (char *)output_buffer.value,
|
||||
output_buffer.length, &p, &base64_sz);
|
||||
if(result) {
|
||||
Curl_infof(data, "base64-encoding: %s\n",
|
||||
curl_easy_strerror(result));
|
||||
ret = AUTH_CONTINUE;
|
||||
ret = AUTH_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
result = Curl_ftpsendf(conn, "ADAT %s", p);
|
||||
cmd = aprintf("ADAT %s", p);
|
||||
if(cmd)
|
||||
result = Curl_ftpsend(conn, cmd);
|
||||
else
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
free(p);
|
||||
|
||||
|
||||
+31
-28
@@ -69,12 +69,11 @@
|
||||
#include "escape.h"
|
||||
#include "progress.h"
|
||||
#include "transfer.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "strtok.h"
|
||||
#include "curl_ldap.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_base64.h"
|
||||
#include "rawstr.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -284,7 +283,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
/* Novell SDK supports DER or BASE64 files. */
|
||||
int cert_type = LDAPSSL_CERT_FILETYPE_B64;
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
|
||||
(strcasecompare(data->set.str[STRING_CERT_TYPE], "DER")))
|
||||
cert_type = LDAPSSL_CERT_FILETYPE_DER;
|
||||
if(!ldap_ca) {
|
||||
failf(data, "LDAP local: ERROR %s CA cert not set!",
|
||||
@@ -325,7 +324,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* OpenLDAP SDK supports BASE64 files. */
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
|
||||
(!strcasecompare(data->set.str[STRING_CERT_TYPE], "PEM"))) {
|
||||
failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
@@ -708,16 +707,16 @@ static void _ldap_trace (const char *fmt, ...)
|
||||
*/
|
||||
static int str2scope (const char *p)
|
||||
{
|
||||
if(strequal(p, "one"))
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
if(strequal(p, "onetree"))
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
if(strequal(p, "base"))
|
||||
return LDAP_SCOPE_BASE;
|
||||
if(strequal(p, "sub"))
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
if(strequal(p, "subtree"))
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
if(strcasecompare(p, "one"))
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
if(strcasecompare(p, "onetree"))
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
if(strcasecompare(p, "base"))
|
||||
return LDAP_SCOPE_BASE;
|
||||
if(strcasecompare(p, "sub"))
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
if(strcasecompare(p, "subtree"))
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -767,7 +766,7 @@ static bool split_str(char *str, char ***out, size_t *count)
|
||||
*
|
||||
* Defined in RFC4516 section 2.
|
||||
*/
|
||||
static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
{
|
||||
int rc = LDAP_SUCCESS;
|
||||
char *path;
|
||||
@@ -776,9 +775,9 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
size_t i;
|
||||
|
||||
if(!conn->data ||
|
||||
!conn->data->state.path ||
|
||||
conn->data->state.path[0] != '/' ||
|
||||
!checkprefix("LDAP", conn->data->change.url))
|
||||
!conn->data->state.path ||
|
||||
conn->data->state.path[0] != '/' ||
|
||||
!checkprefix("LDAP", conn->data->change.url))
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
|
||||
ludp->lud_scope = LDAP_SCOPE_BASE;
|
||||
@@ -798,12 +797,13 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(*p) {
|
||||
char *dn = p;
|
||||
char *unescaped;
|
||||
CURLcode result;
|
||||
|
||||
LDAP_TRACE (("DN '%s'\n", dn));
|
||||
|
||||
/* Unescape the DN */
|
||||
unescaped = curl_easy_unescape(conn->data, dn, 0, NULL);
|
||||
if(!unescaped) {
|
||||
result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, FALSE);
|
||||
if(result) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
goto quit;
|
||||
@@ -862,12 +862,14 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
char *unescaped;
|
||||
CURLcode result;
|
||||
|
||||
LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i]));
|
||||
|
||||
/* Unescape the attribute */
|
||||
unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
|
||||
if(!unescaped) {
|
||||
result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
|
||||
FALSE);
|
||||
if(result) {
|
||||
free(attributes);
|
||||
|
||||
rc = LDAP_NO_MEMORY;
|
||||
@@ -930,12 +932,13 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(*p) {
|
||||
char *filter = p;
|
||||
char *unescaped;
|
||||
CURLcode result;
|
||||
|
||||
LDAP_TRACE (("filter '%s'\n", filter));
|
||||
|
||||
/* Unescape the filter */
|
||||
unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
|
||||
if(!unescaped) {
|
||||
result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE);
|
||||
if(result) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
goto quit;
|
||||
@@ -971,8 +974,8 @@ quit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _ldap_url_parse (const struct connectdata *conn,
|
||||
LDAPURLDesc **ludpp)
|
||||
static int _ldap_url_parse(const struct connectdata *conn,
|
||||
LDAPURLDesc **ludpp)
|
||||
{
|
||||
LDAPURLDesc *ludp = calloc(1, sizeof(*ludp));
|
||||
int rc;
|
||||
@@ -981,7 +984,7 @@ static int _ldap_url_parse (const struct connectdata *conn,
|
||||
if(!ludp)
|
||||
return LDAP_NO_MEMORY;
|
||||
|
||||
rc = _ldap_url_parse2 (conn, ludp);
|
||||
rc = _ldap_url_parse2(conn, ludp);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
_ldap_free_urldesc(ludp);
|
||||
ludp = NULL;
|
||||
@@ -990,7 +993,7 @@ static int _ldap_url_parse (const struct connectdata *conn,
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static void _ldap_free_urldesc (LDAPURLDesc *ludp)
|
||||
static void _ldap_free_urldesc(LDAPURLDesc *ludp)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -44,12 +44,12 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "The cURL library, https://curl.haxx.se/\0"
|
||||
VALUE "CompanyName", "The curl library, https://curl.haxx.se/\0"
|
||||
VALUE "FileDescription", "libcurl Shared Library\0"
|
||||
VALUE "FileVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "InternalName", "libcurl\0"
|
||||
VALUE "OriginalFilename", "libcurl.dll\0"
|
||||
VALUE "ProductName", "The cURL library\0"
|
||||
VALUE "ProductName", "The curl library\0"
|
||||
VALUE "ProductVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "LegalCopyright", "© " LIBCURL_COPYRIGHT "\0"
|
||||
VALUE "License", "https://curl.haxx.se/docs/copyright.html\0"
|
||||
|
||||
@@ -124,7 +124,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
CC_MD5_Final(digest, ctx);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
|
||||
|
||||
#include <wincrypt.h>
|
||||
#include "curl_memory.h"
|
||||
|
||||
@@ -223,10 +223,12 @@ static bool dprintf_IsQualifierNoDollar(const char *fmt)
|
||||
* Create an index with the type of each parameter entry and its
|
||||
* value (may vary in size)
|
||||
*
|
||||
* Returns zero on success.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
va_list arglist)
|
||||
static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
va_list arglist)
|
||||
{
|
||||
char *fmt = (char *)format;
|
||||
int param_num = 0;
|
||||
@@ -389,6 +391,10 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
|
||||
i = this_param - 1;
|
||||
|
||||
if((i < 0) || (i >= MAX_PARAMETERS))
|
||||
/* out of allowed range */
|
||||
return 1;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'S':
|
||||
flags |= FLAGS_ALT;
|
||||
@@ -545,7 +551,7 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
}
|
||||
}
|
||||
|
||||
return max_param;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -583,7 +589,8 @@ static int dprintf_formatf(
|
||||
char *workend = &work[sizeof(work) - 2];
|
||||
|
||||
/* Do the actual %-code parsing */
|
||||
dprintf_Pass1(format, vto, endpos, ap_save);
|
||||
if(dprintf_Pass1(format, vto, endpos, ap_save))
|
||||
return -1;
|
||||
|
||||
end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
|
||||
created for us */
|
||||
@@ -988,7 +995,7 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
|
||||
info.max = maxlength;
|
||||
|
||||
retcode = dprintf_formatf(&info, addbyter, format, ap_save);
|
||||
if(info.max) {
|
||||
if((retcode != -1) && info.max) {
|
||||
/* we terminate this with a zero byte */
|
||||
if(info.max == info.length)
|
||||
/* we're at maximum, scrap the last letter */
|
||||
@@ -1025,16 +1032,19 @@ static int alloc_addbyter(int output, FILE *data)
|
||||
infop->len =0;
|
||||
}
|
||||
else if(infop->len+1 >= infop->alloc) {
|
||||
char *newptr;
|
||||
char *newptr = NULL;
|
||||
size_t newsize = infop->alloc*2;
|
||||
|
||||
newptr = realloc(infop->buffer, infop->alloc*2);
|
||||
/* detect wrap-around or other overflow problems */
|
||||
if(newsize > infop->alloc)
|
||||
newptr = realloc(infop->buffer, newsize);
|
||||
|
||||
if(!newptr) {
|
||||
infop->fail = 1;
|
||||
return -1; /* fail */
|
||||
}
|
||||
infop->buffer = newptr;
|
||||
infop->alloc *= 2;
|
||||
infop->alloc = newsize;
|
||||
}
|
||||
|
||||
infop->buffer[ infop->len ] = outc;
|
||||
|
||||
+154
-125
@@ -42,6 +42,7 @@
|
||||
#include "multihandle.h"
|
||||
#include "pipeline.h"
|
||||
#include "sigpipe.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -442,7 +443,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
sockets that time-out or have actions will be dealt with. Since this
|
||||
handle has no action yet, we make sure it times out to get things to
|
||||
happen. */
|
||||
Curl_expire(data, 1);
|
||||
Curl_expire(data, 0);
|
||||
|
||||
/* increase the node-counter */
|
||||
multi->num_easy++;
|
||||
@@ -462,6 +463,14 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
handle is added */
|
||||
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
||||
|
||||
/* The closure handle only ever has default timeouts set. To improve the
|
||||
state somewhat we clone the timeouts from each added handle so that the
|
||||
closure handle always has the same timeouts as the most recently added
|
||||
easy handle. */
|
||||
multi->closure_handle->set.timeout = data->set.timeout;
|
||||
multi->closure_handle->set.server_response_timeout =
|
||||
data->set.server_response_timeout;
|
||||
|
||||
update_timer(multi);
|
||||
return CURLM_OK;
|
||||
}
|
||||
@@ -569,12 +578,12 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
if((!premature &&
|
||||
conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||
!data->set.reuse_forbid &&
|
||||
!conn->bits.close)) {
|
||||
if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||
!data->set.reuse_forbid &&
|
||||
!conn->bits.close) {
|
||||
/* Stop if pipeline is not empty and we do not have to close
|
||||
connection. */
|
||||
data->easy_conn = NULL;
|
||||
DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -685,7 +694,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
/* If the handle is in a pipeline and has started sending off its
|
||||
request but not received its response yet, we need to close
|
||||
connection. */
|
||||
connclose(data->easy_conn, "Removed with partial response");
|
||||
streamclose(data->easy_conn, "Removed with partial response");
|
||||
/* Set connection owner so that the DONE function closes it. We can
|
||||
safely do this here since connection is killed. */
|
||||
data->easy_conn->data = easy;
|
||||
@@ -695,7 +704,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
/* The timer must be shut down before data->multi is set to NULL,
|
||||
else the timenode will remain in the splay tree after
|
||||
curl_easy_cleanup is called. */
|
||||
Curl_expire(data, 0);
|
||||
Curl_expire_clear(data);
|
||||
|
||||
if(data->dns.hostcachetype == HCACHE_MULTI) {
|
||||
/* stop using the multi handle's DNS cache */
|
||||
@@ -1298,7 +1307,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
do {
|
||||
bool disconnect_conn = FALSE;
|
||||
/* A "stream" here is a logical stream if the protocol can handle that
|
||||
(HTTP/2), or the full connection for older protocols */
|
||||
bool stream_error = FALSE;
|
||||
rc = CURLM_OK;
|
||||
|
||||
/* Handle the case when the pipe breaks, i.e., the connection
|
||||
@@ -1376,8 +1387,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
/* Force connection closed if the connection has indeed been used */
|
||||
if(data->mstate > CURLM_STATE_DO) {
|
||||
connclose(data->easy_conn, "Disconnected with pending data");
|
||||
disconnect_conn = TRUE;
|
||||
streamclose(data->easy_conn, "Disconnected with pending data");
|
||||
stream_error = TRUE;
|
||||
}
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
(void)multi_done(&data->easy_conn, result, TRUE);
|
||||
@@ -1426,7 +1437,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* Add this handle to the send or pend pipeline */
|
||||
result = Curl_add_handle_to_pipeline(data, data->easy_conn);
|
||||
if(result)
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
else {
|
||||
if(async)
|
||||
/* We're now waiting for an asynchronous name lookup */
|
||||
@@ -1518,7 +1529,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
if(result) {
|
||||
/* failure detected */
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1558,7 +1569,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
else if(result) {
|
||||
/* failure detected */
|
||||
/* Just break, the cleaning up is handled all in one place */
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1578,7 +1589,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, TRUE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1595,7 +1606,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, TRUE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1670,7 +1681,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
if(drc) {
|
||||
/* a failure here pretty much implies an out of memory */
|
||||
result = drc;
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
else
|
||||
retry = (newurl)?TRUE:FALSE;
|
||||
@@ -1703,7 +1714,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
}
|
||||
else {
|
||||
/* Have error handler disconnect conn if we can't retry */
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
free(newurl);
|
||||
}
|
||||
}
|
||||
@@ -1712,7 +1723,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
Curl_posttransfer(data);
|
||||
if(data->easy_conn)
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1734,7 +1745,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1763,7 +1774,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1800,9 +1811,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
result = Curl_speedcheck(data, now);
|
||||
|
||||
if(( (data->set.max_send_speed == 0) ||
|
||||
(data->progress.ulspeed < data->set.max_send_speed)) &&
|
||||
(Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now) <= 0)) &&
|
||||
( (data->set.max_recv_speed == 0) ||
|
||||
(data->progress.dlspeed < data->set.max_recv_speed)))
|
||||
(Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now) <= 0)))
|
||||
multistate(data, CURLM_STATE_PERFORM);
|
||||
break;
|
||||
|
||||
@@ -1810,41 +1829,38 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
{
|
||||
char *newurl = NULL;
|
||||
bool retry = FALSE;
|
||||
bool comeback = FALSE;
|
||||
|
||||
/* check if over send speed */
|
||||
if((data->set.max_send_speed > 0) &&
|
||||
(data->progress.ulspeed > data->set.max_send_speed)) {
|
||||
int buffersize;
|
||||
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
|
||||
/* calculate upload rate-limitation timeout. */
|
||||
buffersize = (int)(data->set.buffer_size ?
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
timeout_ms = Curl_sleep_time(data->set.max_send_speed,
|
||||
data->progress.ulspeed, buffersize);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
if(data->set.max_send_speed > 0) {
|
||||
timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now);
|
||||
if(timeout_ms > 0) {
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if over recv speed */
|
||||
if((data->set.max_recv_speed > 0) &&
|
||||
(data->progress.dlspeed > data->set.max_recv_speed)) {
|
||||
int buffersize;
|
||||
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
|
||||
/* Calculate download rate-limitation timeout. */
|
||||
buffersize = (int)(data->set.buffer_size ?
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
|
||||
data->progress.dlspeed, buffersize);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
if(data->set.max_recv_speed > 0) {
|
||||
timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now);
|
||||
if(timeout_ms > 0) {
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* read/write data if it is ready to do so */
|
||||
result = Curl_readwrite(data->easy_conn, data, &done);
|
||||
result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
|
||||
|
||||
k = &data->req;
|
||||
|
||||
@@ -1884,10 +1900,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
|
||||
result != CURLE_HTTP2_STREAM)
|
||||
connclose(data->easy_conn, "Transfer returned error");
|
||||
streamclose(data->easy_conn, "Transfer returned error");
|
||||
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
multi_done(&data->easy_conn, result, TRUE);
|
||||
}
|
||||
else if(done) {
|
||||
followtype follow=FOLLOW_NONE;
|
||||
@@ -1900,7 +1916,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
/* expire the new receiving pipeline head */
|
||||
if(data->easy_conn->recv_pipe->head)
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
|
||||
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
@@ -1943,13 +1959,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
if(!result)
|
||||
newurl = NULL; /* allocation was handed over Curl_follow() */
|
||||
else
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
|
||||
multistate(data, CURLM_STATE_DONE);
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
}
|
||||
else if(comeback)
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
|
||||
free(newurl);
|
||||
break;
|
||||
@@ -2008,7 +2026,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
that could be freed anytime */
|
||||
data->easy_conn = NULL;
|
||||
|
||||
Curl_expire(data, 0); /* stop all timers */
|
||||
Curl_expire_clear(data); /* stop all timers */
|
||||
break;
|
||||
|
||||
case CURLM_STATE_MSGSENT:
|
||||
@@ -2042,7 +2060,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
|
||||
if(disconnect_conn) {
|
||||
if(stream_error) {
|
||||
/* Don't attempt to send data over a connection that timed out */
|
||||
bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
|
||||
/* disconnect properly */
|
||||
@@ -2066,7 +2084,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* aborted due to progress callback return code must close the
|
||||
connection */
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
connclose(data->easy_conn, "Aborted by callback");
|
||||
streamclose(data->easy_conn, "Aborted by callback");
|
||||
|
||||
/* if not yet in DONE state, go there, otherwise COMPLETED */
|
||||
multistate(data, (data->mstate < CURLM_STATE_DONE)?
|
||||
@@ -2160,6 +2178,7 @@ static void close_all_connections(struct Curl_multi *multi)
|
||||
conn->data->easy_conn = NULL; /* clear the easy handle's connection
|
||||
pointer */
|
||||
/* This will remove the connection from the cache */
|
||||
connclose(conn, "kill all");
|
||||
(void)Curl_disconnect(conn, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
@@ -2876,92 +2895,59 @@ multi_addtimeout(struct curl_llist *timeoutlist,
|
||||
* given a number of milliseconds from now to use to set the 'act before
|
||||
* this'-time for the transfer, to be extracted by curl_multi_timeout()
|
||||
*
|
||||
* Note that the timeout will be added to a queue of timeouts if it defines a
|
||||
* moment in time that is later than the current head of queue.
|
||||
*
|
||||
* Pass zero to clear all timeout values for this handle.
|
||||
*/
|
||||
* The timeout will be added to a queue of timeouts if it defines a moment in
|
||||
* time that is later than the current head of queue.
|
||||
*/
|
||||
void Curl_expire(struct Curl_easy *data, long milli)
|
||||
{
|
||||
struct Curl_multi *multi = data->multi;
|
||||
struct timeval *nowp = &data->state.expiretime;
|
||||
int rc;
|
||||
struct timeval set;
|
||||
|
||||
/* this is only interesting while there is still an associated multi struct
|
||||
remaining! */
|
||||
if(!multi)
|
||||
return;
|
||||
|
||||
if(!milli) {
|
||||
/* No timeout, clear the time data. */
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
the splay tree */
|
||||
struct curl_llist *list = data->state.timeoutlist;
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += milli/1000;
|
||||
set.tv_usec += (milli%1000)*1000;
|
||||
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error clearing splay node = %d\n", rc);
|
||||
|
||||
/* flush the timeout list too */
|
||||
while(list->size > 0)
|
||||
Curl_llist_remove(list, list->tail, NULL);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
infof(data, "Expire cleared\n");
|
||||
#endif
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
}
|
||||
if(set.tv_usec >= 1000000) {
|
||||
set.tv_sec++;
|
||||
set.tv_usec -= 1000000;
|
||||
}
|
||||
else {
|
||||
struct timeval set;
|
||||
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += milli/1000;
|
||||
set.tv_usec += (milli%1000)*1000;
|
||||
|
||||
if(set.tv_usec >= 1000000) {
|
||||
set.tv_sec++;
|
||||
set.tv_usec -= 1000000;
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* This means that the struct is added as a node in the splay tree.
|
||||
Compare if the new time is earlier, and only remove-old/add-new if it
|
||||
is. */
|
||||
long diff = curlx_tvdiff(set, *nowp);
|
||||
if(diff > 0) {
|
||||
/* the new expire time was later so just add it to the queue
|
||||
and get out */
|
||||
multi_addtimeout(data->state.timeoutlist, &set);
|
||||
return;
|
||||
}
|
||||
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* This means that the struct is added as a node in the splay tree.
|
||||
Compare if the new time is earlier, and only remove-old/add-new if it
|
||||
is. */
|
||||
long diff = curlx_tvdiff(set, *nowp);
|
||||
if(diff > 0) {
|
||||
/* the new expire time was later so just add it to the queue
|
||||
and get out */
|
||||
multi_addtimeout(data->state.timeoutlist, &set);
|
||||
return;
|
||||
}
|
||||
/* the new time is newer than the presently set one, so add the current
|
||||
to the queue and update the head */
|
||||
multi_addtimeout(data->state.timeoutlist, nowp);
|
||||
|
||||
/* the new time is newer than the presently set one, so add the current
|
||||
to the queue and update the head */
|
||||
multi_addtimeout(data->state.timeoutlist, nowp);
|
||||
|
||||
/* Since this is an updated time, we must remove the previous entry from
|
||||
the splay tree first and then re-add the new value */
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error removing splay node = %d\n", rc);
|
||||
}
|
||||
|
||||
*nowp = set;
|
||||
data->state.timenode.payload = data;
|
||||
multi->timetree = Curl_splayinsert(*nowp,
|
||||
multi->timetree,
|
||||
&data->state.timenode);
|
||||
/* Since this is an updated time, we must remove the previous entry from
|
||||
the splay tree first and then re-add the new value */
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error removing splay node = %d\n", rc);
|
||||
}
|
||||
#if 0
|
||||
Curl_splayprint(multi->timetree, 0, TRUE);
|
||||
#endif
|
||||
|
||||
*nowp = set;
|
||||
data->state.timenode.payload = data;
|
||||
multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
|
||||
&data->state.timenode);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3004,6 +2990,49 @@ void Curl_expire_latest(struct Curl_easy *data, long milli)
|
||||
Curl_expire(data, milli);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_expire_clear()
|
||||
*
|
||||
* Clear ALL timeout values for this handle.
|
||||
*/
|
||||
void Curl_expire_clear(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_multi *multi = data->multi;
|
||||
struct timeval *nowp = &data->state.expiretime;
|
||||
int rc;
|
||||
|
||||
/* this is only interesting while there is still an associated multi struct
|
||||
remaining! */
|
||||
if(!multi)
|
||||
return;
|
||||
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
the splay tree */
|
||||
struct curl_llist *list = data->state.timeoutlist;
|
||||
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error clearing splay node = %d\n", rc);
|
||||
|
||||
/* flush the timeout list too */
|
||||
while(list->size > 0)
|
||||
Curl_llist_remove(list, list->tail, NULL);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
infof(data, "Expire cleared\n");
|
||||
#endif
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
|
||||
void *hashp)
|
||||
{
|
||||
@@ -3064,7 +3093,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
Curl_llist_remove(multi->pending, e, NULL);
|
||||
|
||||
/* Make sure that the handle will be processed soonish. */
|
||||
Curl_expire_latest(data, 1);
|
||||
Curl_expire_latest(data, 0);
|
||||
}
|
||||
|
||||
e = next; /* operate on next handle */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* Prototypes for library-wide functions provided by multi.c
|
||||
*/
|
||||
void Curl_expire(struct Curl_easy *data, long milli);
|
||||
void Curl_expire_clear(struct Curl_easy *data);
|
||||
void Curl_expire_latest(struct Curl_easy *data, long milli);
|
||||
bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
|
||||
void Curl_multi_handlePipeBreak(struct Curl_easy *data);
|
||||
|
||||
@@ -28,10 +28,8 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "netrc.h"
|
||||
|
||||
#include "strequal.h"
|
||||
#include "strtok.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -130,20 +128,20 @@ int Curl_parsenetrc(const char *host,
|
||||
|
||||
switch(state) {
|
||||
case NOTHING:
|
||||
if(Curl_raw_equal("machine", tok)) {
|
||||
if(strcasecompare("machine", tok)) {
|
||||
/* the next tok is the machine name, this is in itself the
|
||||
delimiter that starts the stuff entered for this machine,
|
||||
after this we need to search for 'login' and
|
||||
'password'. */
|
||||
state=HOSTFOUND;
|
||||
}
|
||||
else if(Curl_raw_equal("default", tok)) {
|
||||
else if(strcasecompare("default", tok)) {
|
||||
state=HOSTVALID;
|
||||
retcode=0; /* we did find our host */
|
||||
}
|
||||
break;
|
||||
case HOSTFOUND:
|
||||
if(Curl_raw_equal(host, tok)) {
|
||||
if(strcasecompare(host, tok)) {
|
||||
/* and yes, this is our host! */
|
||||
state=HOSTVALID;
|
||||
retcode=0; /* we did find our host */
|
||||
@@ -156,7 +154,7 @@ int Curl_parsenetrc(const char *host,
|
||||
/* we are now parsing sub-keywords concerning "our" host */
|
||||
if(state_login) {
|
||||
if(specific_login) {
|
||||
state_our_login = Curl_raw_equal(*loginp, tok);
|
||||
state_our_login = strcasecompare(*loginp, tok);
|
||||
}
|
||||
else {
|
||||
free(*loginp);
|
||||
@@ -179,11 +177,11 @@ int Curl_parsenetrc(const char *host,
|
||||
}
|
||||
state_password=0;
|
||||
}
|
||||
else if(Curl_raw_equal("login", tok))
|
||||
else if(strcasecompare("login", tok))
|
||||
state_login=1;
|
||||
else if(Curl_raw_equal("password", tok))
|
||||
else if(strcasecompare("password", tok))
|
||||
state_password=1;
|
||||
else if(Curl_raw_equal("machine", tok)) {
|
||||
else if(strcasecompare("machine", tok)) {
|
||||
/* ok, there's machine here go => */
|
||||
state = HOSTFOUND;
|
||||
state_our_login = FALSE;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -80,7 +80,7 @@
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
#include "parsedate.h"
|
||||
|
||||
@@ -211,7 +211,7 @@ static int checkday(const char *check, size_t len)
|
||||
else
|
||||
what = &Curl_wkday[0];
|
||||
for(i=0; i<7; i++) {
|
||||
if(Curl_raw_equal(check, what[0])) {
|
||||
if(strcasecompare(check, what[0])) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ static int checkmonth(const char *check)
|
||||
|
||||
what = &Curl_month[0];
|
||||
for(i=0; i<12; i++) {
|
||||
if(Curl_raw_equal(check, what[0])) {
|
||||
if(strcasecompare(check, what[0])) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -248,7 +248,7 @@ static int checktz(const char *check)
|
||||
|
||||
what = tz;
|
||||
for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) {
|
||||
if(Curl_raw_equal(check, what->name)) {
|
||||
if(strcasecompare(check, what->name)) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -386,15 +386,17 @@ static int parsedate(const char *date, time_t *output)
|
||||
/* a digit */
|
||||
int val;
|
||||
char *end;
|
||||
int len=0;
|
||||
if((secnum == -1) &&
|
||||
(3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
|
||||
(3 == sscanf(date, "%02d:%02d:%02d%n",
|
||||
&hournum, &minnum, &secnum, &len))) {
|
||||
/* time stamp! */
|
||||
date += 8;
|
||||
date += len;
|
||||
}
|
||||
else if((secnum == -1) &&
|
||||
(2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) {
|
||||
(2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) {
|
||||
/* time stamp without seconds */
|
||||
date += 5;
|
||||
date += len;
|
||||
secnum = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -108,7 +108,8 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
|
||||
/* We are receiving and there is data ready in the SSL library */
|
||||
rc = 1;
|
||||
else
|
||||
rc = Curl_socket_ready(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
|
||||
rc = Curl_socket_check(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
|
||||
CURL_SOCKET_BAD,
|
||||
pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
|
||||
interval_ms);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2013-2016, 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
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "multiif.h"
|
||||
#include "pipeline.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@@ -114,7 +114,7 @@ CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
|
||||
if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
|
||||
/* this is a new one as head, expire it */
|
||||
Curl_pipeline_leave_write(conn); /* not in use yet */
|
||||
Curl_expire(conn->send_pipe->head->ptr, 1);
|
||||
Curl_expire(conn->send_pipe->head->ptr, 0);
|
||||
}
|
||||
|
||||
#if 0 /* enable for pipeline debugging */
|
||||
@@ -149,7 +149,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
|
||||
infof(conn->data, "%p is at send pipe head B!\n",
|
||||
(void *)conn->send_pipe->head->ptr);
|
||||
#endif
|
||||
Curl_expire(conn->send_pipe->head->ptr, 1);
|
||||
Curl_expire(conn->send_pipe->head->ptr, 0);
|
||||
}
|
||||
|
||||
/* The receiver's list is not really interesting here since either this
|
||||
@@ -177,7 +177,7 @@ bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
|
||||
struct site_blacklist_entry *site;
|
||||
|
||||
site = curr->ptr;
|
||||
if(Curl_raw_equal(site->hostname, conn->host.name) &&
|
||||
if(strcasecompare(site->hostname, conn->host.name) &&
|
||||
site->port == conn->remote_port) {
|
||||
infof(handle, "Site %s:%d is pipeline blacklisted\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
@@ -269,7 +269,7 @@ bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
|
||||
char *bl_server_name;
|
||||
|
||||
bl_server_name = curr->ptr;
|
||||
if(Curl_raw_nequal(bl_server_name, server_name,
|
||||
if(strncasecompare(bl_server_name, server_name,
|
||||
strlen(bl_server_name))) {
|
||||
infof(handle, "Server %s is blacklisted\n", server_name);
|
||||
return TRUE;
|
||||
|
||||
@@ -70,16 +70,14 @@
|
||||
#include "http.h" /* for HTTP proxy tunnel stuff */
|
||||
#include "socks.h"
|
||||
#include "pop3.h"
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "curl_md5.h"
|
||||
#include "warnless.h"
|
||||
@@ -663,7 +661,7 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
|
||||
|
||||
if(pop3code != '+') {
|
||||
failf(data, "Got unexpected pop3-server response");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
else {
|
||||
/* Does the server support APOP authentication? */
|
||||
@@ -1412,11 +1410,11 @@ static CURLcode pop3_parse_url_options(struct connectdata *conn)
|
||||
while(*ptr && *ptr != ';')
|
||||
ptr++;
|
||||
|
||||
if(strnequal(key, "AUTH=", 5)) {
|
||||
if(strncasecompare(key, "AUTH=", 5)) {
|
||||
result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
|
||||
value, ptr - value);
|
||||
|
||||
if(result && strnequal(value, "+APOP", ptr - value)) {
|
||||
if(result && strncasecompare(value, "+APOP", ptr - value)) {
|
||||
pop3c->preftype = POP3_TYPE_APOP;
|
||||
pop3c->sasl.prefmech = SASL_AUTH_NONE;
|
||||
result = CURLE_OK;
|
||||
|
||||
@@ -216,18 +216,93 @@ void Curl_pgrsStartNow(struct Curl_easy *data)
|
||||
{
|
||||
data->progress.speeder_c = 0; /* reset the progress meter display */
|
||||
data->progress.start = Curl_tvnow();
|
||||
data->progress.ul_limit_start.tv_sec = 0;
|
||||
data->progress.ul_limit_start.tv_usec = 0;
|
||||
data->progress.dl_limit_start.tv_sec = 0;
|
||||
data->progress.dl_limit_start.tv_usec = 0;
|
||||
/* clear all bits except HIDE and HEADERS_OUT */
|
||||
data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used to handle speed limits, calculating how much milliseconds we
|
||||
* need to wait until we're back under the speed limit, if needed.
|
||||
*
|
||||
* The way it works is by having a "starting point" (time & amount of data
|
||||
* transfered by then) used in the speed computation, to be used instead of the
|
||||
* start of the transfer.
|
||||
* This starting point is regularly moved as transfer goes on, to keep getting
|
||||
* accurate values (instead of average over the entire tranfer).
|
||||
*
|
||||
* This function takes the current amount of data transfered, the amount at the
|
||||
* starting point, the limit (in bytes/s), the time of the starting point and
|
||||
* the current time.
|
||||
*
|
||||
* Returns -1 if no waiting is needed (not enough data transfered since
|
||||
* starting point yet), 0 when no waiting is needed but the starting point
|
||||
* should be reset (to current), or the number of milliseconds to wait to get
|
||||
* back under the speed limit.
|
||||
*/
|
||||
long Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
||||
curl_off_t startsize,
|
||||
curl_off_t limit,
|
||||
struct timeval start,
|
||||
struct timeval now)
|
||||
{
|
||||
curl_off_t size = cursize - startsize;
|
||||
long minimum, actual;
|
||||
|
||||
/* we don't have a starting point yet -- return 0 so it gets (re)set */
|
||||
if(start.tv_sec == 0 && start.tv_usec == 0)
|
||||
return 0;
|
||||
|
||||
/* not enough data yet */
|
||||
if(size < limit)
|
||||
return -1;
|
||||
|
||||
minimum = (long) (CURL_OFF_T_C(1000) * size / limit);
|
||||
actual = Curl_tvdiff(now, start);
|
||||
|
||||
if(actual < minimum)
|
||||
return minimum - actual;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
|
||||
{
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
data->progress.downloaded = size;
|
||||
|
||||
/* download speed limit */
|
||||
if((data->set.max_recv_speed > 0) &&
|
||||
(Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now) == 0)) {
|
||||
data->progress.dl_limit_start = now;
|
||||
data->progress.dl_limit_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
|
||||
{
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
data->progress.uploaded = size;
|
||||
|
||||
/* upload speed limit */
|
||||
if((data->set.max_send_speed > 0) &&
|
||||
(Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now) == 0)) {
|
||||
data->progress.ul_limit_start = now;
|
||||
data->progress.ul_limit_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
|
||||
|
||||
@@ -49,7 +49,11 @@ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
|
||||
int Curl_pgrsUpdate(struct connectdata *);
|
||||
void Curl_pgrsResetTimesSizes(struct Curl_easy *data);
|
||||
void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
|
||||
|
||||
long Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
||||
curl_off_t startsize,
|
||||
curl_off_t limit,
|
||||
struct timeval start,
|
||||
struct timeval now);
|
||||
|
||||
/* Don't show progress for sizes smaller than: */
|
||||
#define LEAST_SIZE_PROGRESS BUFSIZE
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "url.h"
|
||||
#include "progress.h"
|
||||
#include "rtsp.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "select.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -147,7 +147,7 @@ bool Curl_rtsp_connisdead(struct connectdata *check)
|
||||
int sval;
|
||||
bool ret_val = TRUE;
|
||||
|
||||
sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0);
|
||||
sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0);
|
||||
if(sval == 0) {
|
||||
/* timeout */
|
||||
ret_val = FALSE;
|
||||
@@ -796,19 +796,15 @@ CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If the Session ID is not set, and we find it in a response, then
|
||||
set it */
|
||||
|
||||
/* The session ID can be an alphanumeric or a 'safe' character
|
||||
/* If the Session ID is not set, and we find it in a response, then set
|
||||
* it.
|
||||
*
|
||||
* RFC 2326 15.1 Base Syntax:
|
||||
* safe = "\$" | "-" | "_" | "." | "+"
|
||||
* */
|
||||
* Allow any non whitespace content, up to the field seperator or end of
|
||||
* line. RFC 2326 isn't 100% clear on the session ID and for example
|
||||
* gstreamer does url-encoded session ID's not covered by the standard.
|
||||
*/
|
||||
char *end = start;
|
||||
while(*end &&
|
||||
(ISALNUM(*end) || *end == '-' || *end == '_' || *end == '.' ||
|
||||
*end == '+' ||
|
||||
(*end == '\\' && *(end + 1) && *(end + 1) == '$' && (++end, 1))))
|
||||
while(*end && *end != ';' && !ISSPACE(*end))
|
||||
end++;
|
||||
|
||||
/* Copy the id substring into a new buffer */
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
#include "curl_sec.h"
|
||||
#include "ftp.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
@@ -122,7 +122,7 @@ static int ftp_send_command(struct connectdata *conn, const char *message, ...)
|
||||
vsnprintf(print_buffer, sizeof(print_buffer), message, args);
|
||||
va_end(args);
|
||||
|
||||
if(Curl_ftpsendf(conn, print_buffer)) {
|
||||
if(Curl_ftpsend(conn, print_buffer)) {
|
||||
ftp_code = -1;
|
||||
}
|
||||
else {
|
||||
@@ -192,15 +192,18 @@ static CURLcode read_data(struct connectdata *conn,
|
||||
struct krb5buffer *buf)
|
||||
{
|
||||
int len;
|
||||
void* tmp;
|
||||
void *tmp = NULL;
|
||||
CURLcode result;
|
||||
|
||||
result = socket_read(fd, &len, sizeof(len));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
len = ntohl(len);
|
||||
tmp = realloc(buf->data, len);
|
||||
if(len) {
|
||||
/* only realloc if there was a length */
|
||||
len = ntohl(len);
|
||||
tmp = realloc(buf->data, len);
|
||||
}
|
||||
if(tmp == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -51,15 +51,14 @@
|
||||
#include "warnless.h"
|
||||
|
||||
/* Convenience local macros */
|
||||
|
||||
#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
|
||||
#define ELAPSED_MS() (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
|
||||
|
||||
int Curl_ack_eintr = 0;
|
||||
#define error_not_EINTR (Curl_ack_eintr || error != EINTR)
|
||||
#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
|
||||
|
||||
/*
|
||||
* Internal function used for waiting a specific amount of ms
|
||||
* in Curl_socket_ready() and Curl_poll() when no file descriptor
|
||||
* in Curl_socket_check() and Curl_poll() when no file descriptor
|
||||
* is provided to wait on, just being used to delay execution.
|
||||
* WinSock select() and poll() timeout mechanisms need a valid
|
||||
* socket descriptor in a not null file descriptor set to work.
|
||||
@@ -109,9 +108,9 @@ int Curl_wait_ms(int timeout_ms)
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && error_not_EINTR)
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
pending_ms = timeout_ms - elapsed_ms;
|
||||
pending_ms = timeout_ms - ELAPSED_MS();
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
@@ -165,6 +164,12 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
int r;
|
||||
int ret;
|
||||
|
||||
#if SIZEOF_LONG != SIZEOF_INT
|
||||
/* wrap-around precaution */
|
||||
if(timeout_ms >= INT_MAX)
|
||||
timeout_ms = INT_MAX;
|
||||
#endif
|
||||
|
||||
if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
|
||||
(writefd == CURL_SOCKET_BAD)) {
|
||||
/* no sockets, just wait */
|
||||
@@ -213,10 +218,10 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && error_not_EINTR)
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = (int)(timeout_ms - elapsed_ms);
|
||||
pending_ms = (int)(timeout_ms - ELAPSED_MS());
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
@@ -328,10 +333,10 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && error_not_EINTR)
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = timeout_ms - elapsed_ms;
|
||||
pending_ms = (int)(timeout_ms - ELAPSED_MS());
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
@@ -434,10 +439,10 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && error_not_EINTR)
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = timeout_ms - elapsed_ms;
|
||||
pending_ms = (int)(timeout_ms - ELAPSED_MS());
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
@@ -521,10 +526,10 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
|
||||
if(r != -1)
|
||||
break;
|
||||
error = SOCKERRNO;
|
||||
if(error && error_not_EINTR)
|
||||
if(error && ERROR_NOT_EINTR(error))
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = timeout_ms - elapsed_ms;
|
||||
pending_ms = timeout_ms - ELAPSED_MS();
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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
|
||||
@@ -75,9 +75,10 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
|
||||
curl_socket_t writefd,
|
||||
long timeout_ms);
|
||||
|
||||
/* provide the former API internally */
|
||||
#define Curl_socket_ready(x,y,z) \
|
||||
Curl_socket_check(x, CURL_SOCKET_BAD, y, z)
|
||||
#define SOCKET_READABLE(x,z) \
|
||||
Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
|
||||
#define SOCKET_WRITABLE(x,z) \
|
||||
Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
|
||||
|
||||
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
|
||||
|
||||
|
||||
@@ -673,7 +673,7 @@ static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
|
||||
|
||||
switch(smbc->state) {
|
||||
case SMB_NEGOTIATE:
|
||||
if(h->status) {
|
||||
if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) {
|
||||
connclose(conn, "SMB: negotiation failed");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
@@ -712,6 +712,7 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct smb_request *req = conn->data->req.protop;
|
||||
struct smb_header *h;
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
enum smb_req_state next_state = SMB_DONE;
|
||||
unsigned short len;
|
||||
unsigned short off;
|
||||
@@ -754,7 +755,7 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
break;
|
||||
|
||||
case SMB_OPEN:
|
||||
if(h->status) {
|
||||
if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
|
||||
req->result = CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
next_state = SMB_TREE_DISCONNECT;
|
||||
break;
|
||||
@@ -775,7 +776,7 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
break;
|
||||
|
||||
case SMB_DOWNLOAD:
|
||||
if(h->status) {
|
||||
if(h->status || smbc->got < sizeof(struct smb_header) + 14) {
|
||||
req->result = CURLE_RECV_ERROR;
|
||||
next_state = SMB_CLOSE;
|
||||
break;
|
||||
@@ -785,7 +786,6 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
off = Curl_read16_le(((unsigned char *) msg) +
|
||||
sizeof(struct smb_header) + 13);
|
||||
if(len > 0) {
|
||||
struct smb_conn *smbc = &conn->proto.smbc;
|
||||
if(off + sizeof(unsigned int) + len > smbc->got) {
|
||||
failf(conn->data, "Invalid input packet");
|
||||
result = CURLE_RECV_ERROR;
|
||||
@@ -807,7 +807,7 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done)
|
||||
break;
|
||||
|
||||
case SMB_UPLOAD:
|
||||
if(h->status) {
|
||||
if(h->status || smbc->got < sizeof(struct smb_header) + 6) {
|
||||
req->result = CURLE_UPLOAD_FAILED;
|
||||
next_state = SMB_CLOSE;
|
||||
break;
|
||||
|
||||
@@ -69,16 +69,14 @@
|
||||
#include "http.h" /* for HTTP proxy tunnel stuff */
|
||||
#include "socks.h"
|
||||
#include "smtp.h"
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_gethostname.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
@@ -674,7 +672,7 @@ static CURLcode smtp_state_servergreet_resp(struct connectdata *conn,
|
||||
|
||||
if(smtpcode/100 != 2) {
|
||||
failf(data, "Got unexpected smtp-server response: %d", smtpcode);
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
else
|
||||
result = smtp_perform_ehlo(conn);
|
||||
@@ -1512,7 +1510,7 @@ static CURLcode smtp_parse_url_options(struct connectdata *conn)
|
||||
while(*ptr && *ptr != ';')
|
||||
ptr++;
|
||||
|
||||
if(strnequal(key, "AUTH=", 5))
|
||||
if(strncasecompare(key, "AUTH=", 5))
|
||||
result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
|
||||
value, ptr - value);
|
||||
else
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "strequal.h"
|
||||
#include "select.h"
|
||||
#include "connect.h"
|
||||
#include "timeval.h"
|
||||
@@ -67,7 +66,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
break;
|
||||
}
|
||||
if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) {
|
||||
if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
|
||||
result = ~CURLE_OK;
|
||||
break;
|
||||
}
|
||||
@@ -170,24 +169,26 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
hp=dns->addr;
|
||||
if(hp) {
|
||||
char buf[64];
|
||||
unsigned short ip[4];
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
|
||||
if(4 == sscanf(buf, "%hu.%hu.%hu.%hu",
|
||||
&ip[0], &ip[1], &ip[2], &ip[3])) {
|
||||
/* Set DSTIP */
|
||||
socksreq[4] = (unsigned char)ip[0];
|
||||
socksreq[5] = (unsigned char)ip[1];
|
||||
socksreq[6] = (unsigned char)ip[2];
|
||||
socksreq[7] = (unsigned char)ip[3];
|
||||
if(hp->ai_family == AF_INET) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
|
||||
saddr_in = (struct sockaddr_in*)(void*)hp->ai_addr;
|
||||
socksreq[4] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[0];
|
||||
socksreq[5] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[1];
|
||||
socksreq[6] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[2];
|
||||
socksreq[7] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[3];
|
||||
|
||||
infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf);
|
||||
}
|
||||
else
|
||||
else {
|
||||
hp = NULL; /* fail! */
|
||||
|
||||
infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
|
||||
failf(data, "SOCKS4 connection to %s not supported\n", buf);
|
||||
}
|
||||
|
||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||
|
||||
}
|
||||
if(!hp) {
|
||||
failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
|
||||
@@ -399,7 +400,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
/* wait until socket gets connected */
|
||||
result = Curl_socket_ready(CURL_SOCKET_BAD, sock, timeout);
|
||||
result = SOCKET_WRITABLE(sock, timeout);
|
||||
|
||||
if(-1 == result) {
|
||||
failf(conn->data, "SOCKS5: no connection here");
|
||||
@@ -429,6 +430,8 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
|
||||
(void)curlx_nonblock(sock, FALSE);
|
||||
|
||||
infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
|
||||
&written);
|
||||
if(code || (written != (2 + (int)socksreq[1]))) {
|
||||
@@ -438,7 +441,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
|
||||
result = Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout);
|
||||
result = SOCKET_READABLE(sock, timeout);
|
||||
|
||||
if(-1 == result) {
|
||||
failf(conn->data, "SOCKS5 nothing to read");
|
||||
@@ -594,34 +597,40 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
if(dns)
|
||||
hp=dns->addr;
|
||||
if(hp) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *saddr_in6;
|
||||
#endif
|
||||
int i;
|
||||
char buf[64];
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
|
||||
if(hp->ai_family == AF_INET) {
|
||||
struct sockaddr_in *saddr_in;
|
||||
socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
|
||||
|
||||
saddr_in = (struct sockaddr_in*)(void*)hp->ai_addr;
|
||||
for(i = 0; i < 4; i++) {
|
||||
socksreq[len++] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[i];
|
||||
infof(data, "%d\n", socksreq[len-1]);
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf);
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(hp->ai_family == AF_INET6) {
|
||||
struct sockaddr_in6 *saddr_in6;
|
||||
socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
|
||||
|
||||
saddr_in6 = (struct sockaddr_in6*)(void*)hp->ai_addr;
|
||||
for(i = 0; i < 16; i++) {
|
||||
socksreq[len++] = ((unsigned char*)&saddr_in6->sin6_addr.s6_addr)[i];
|
||||
}
|
||||
|
||||
infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
else {
|
||||
hp = NULL; /* fail! */
|
||||
|
||||
failf(data, "SOCKS5 connection to %s not supported\n", buf);
|
||||
}
|
||||
|
||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||
}
|
||||
if(!hp) {
|
||||
@@ -668,39 +677,6 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
"SOCKS5 reply has wrong version, version should be 5.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
if(socksreq[1] != 0) { /* Anything besides 0 is an error */
|
||||
if(socksreq[3] == 1) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
else if(socksreq[3] == 3) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %s:%d. (%d)",
|
||||
hostname,
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
else if(socksreq[3] == 4) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(unsigned char)socksreq[8], (unsigned char)socksreq[9],
|
||||
(unsigned char)socksreq[10], (unsigned char)socksreq[11],
|
||||
(unsigned char)socksreq[12], (unsigned char)socksreq[13],
|
||||
(unsigned char)socksreq[14], (unsigned char)socksreq[15],
|
||||
(unsigned char)socksreq[16], (unsigned char)socksreq[17],
|
||||
(unsigned char)socksreq[18], (unsigned char)socksreq[19],
|
||||
(((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* Fix: in general, returned BND.ADDR is variable length parameter by RFC
|
||||
1928, so the reply packet should be read until the end to avoid errors at
|
||||
@@ -735,10 +711,9 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
/* decrypt_gssapi_blockread already read the whole packet */
|
||||
#endif
|
||||
if(len > 10) {
|
||||
len -= 10;
|
||||
result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
|
||||
len, &actualread);
|
||||
if(result || (len != actualread)) {
|
||||
len - 10, &actualread);
|
||||
if(result || ((len - 10) != actualread)) {
|
||||
failf(data, "Failed to receive SOCKS5 connect request ack.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
@@ -747,6 +722,49 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
}
|
||||
#endif
|
||||
|
||||
if(socksreq[1] != 0) { /* Anything besides 0 is an error */
|
||||
if(socksreq[3] == 1) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(((unsigned char)socksreq[8] << 8) |
|
||||
(unsigned char)socksreq[9]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
else if(socksreq[3] == 3) {
|
||||
unsigned char port_upper = (unsigned char)socksreq[len - 2];
|
||||
socksreq[len - 2] = 0;
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %s:%d. (%d)",
|
||||
(char *)&socksreq[5],
|
||||
((port_upper << 8) |
|
||||
(unsigned char)socksreq[len - 1]),
|
||||
(unsigned char)socksreq[1]);
|
||||
socksreq[len - 2] = port_upper;
|
||||
}
|
||||
else if(socksreq[3] == 4) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(unsigned char)socksreq[8], (unsigned char)socksreq[9],
|
||||
(unsigned char)socksreq[10], (unsigned char)socksreq[11],
|
||||
(unsigned char)socksreq[12], (unsigned char)socksreq[13],
|
||||
(unsigned char)socksreq[14], (unsigned char)socksreq[15],
|
||||
(unsigned char)socksreq[16], (unsigned char)socksreq[17],
|
||||
(unsigned char)socksreq[18], (unsigned char)socksreq[19],
|
||||
(((unsigned char)socksreq[20] << 8) |
|
||||
(unsigned char)socksreq[21]),
|
||||
(unsigned char)socksreq[1]);
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else {
|
||||
infof(data, "SOCKS5 request granted.\n");
|
||||
}
|
||||
|
||||
(void)curlx_nonblock(sock, TRUE);
|
||||
return CURLE_OK; /* Proxy was successful! */
|
||||
}
|
||||
|
||||
+25
-30
@@ -72,7 +72,7 @@
|
||||
#include "speedcheck.h"
|
||||
#include "getinfo.h"
|
||||
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
@@ -416,12 +416,12 @@ static CURLcode ssh_getworkingpath(struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *real_path = NULL;
|
||||
char *working_path;
|
||||
int working_path_len;
|
||||
|
||||
working_path = curl_easy_unescape(data, data->state.path, 0,
|
||||
&working_path_len);
|
||||
if(!working_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
size_t working_path_len;
|
||||
CURLcode result =
|
||||
Curl_urldecode(data, data->state.path, 0, &working_path,
|
||||
&working_path_len, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Check for /~/, indicating relative to the user's home directory */
|
||||
if(conn->handler->protocol & CURLPROTO_SCP) {
|
||||
@@ -676,7 +676,7 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn)
|
||||
* against a known fingerprint, if available.
|
||||
*/
|
||||
if(pubkey_md5 && strlen(pubkey_md5) == 32) {
|
||||
if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
|
||||
if(!fingerprint || strcmp(md5buffer, pubkey_md5)) {
|
||||
if(fingerprint)
|
||||
failf(data,
|
||||
"Denied establishing ssh session: mismatch md5 fingerprint. "
|
||||
@@ -1233,7 +1233,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->acceptfail = TRUE;
|
||||
}
|
||||
|
||||
if(curl_strequal("pwd", cmd)) {
|
||||
if(strcasecompare("pwd", cmd)) {
|
||||
/* output debug output if that is requested */
|
||||
char *tmp = aprintf("257 \"%s\" is current directory.\n",
|
||||
sftp_scp->path);
|
||||
@@ -1297,9 +1297,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
* OpenSSH's sftp program and call the appropriate libssh2
|
||||
* functions.
|
||||
*/
|
||||
if(curl_strnequal(cmd, "chgrp ", 6) ||
|
||||
curl_strnequal(cmd, "chmod ", 6) ||
|
||||
curl_strnequal(cmd, "chown ", 6) ) {
|
||||
if(strncasecompare(cmd, "chgrp ", 6) ||
|
||||
strncasecompare(cmd, "chmod ", 6) ||
|
||||
strncasecompare(cmd, "chown ", 6) ) {
|
||||
/* attribute change */
|
||||
|
||||
/* sshc->quote_path1 contains the mode to set */
|
||||
@@ -1321,8 +1321,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_SFTP_QUOTE_STAT);
|
||||
break;
|
||||
}
|
||||
else if(curl_strnequal(cmd, "ln ", 3) ||
|
||||
curl_strnequal(cmd, "symlink ", 8)) {
|
||||
else if(strncasecompare(cmd, "ln ", 3) ||
|
||||
strncasecompare(cmd, "symlink ", 8)) {
|
||||
/* symbolic linking */
|
||||
/* sshc->quote_path1 is the source */
|
||||
/* get the destination */
|
||||
@@ -1342,12 +1342,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_SFTP_QUOTE_SYMLINK);
|
||||
break;
|
||||
}
|
||||
else if(curl_strnequal(cmd, "mkdir ", 6)) {
|
||||
else if(strncasecompare(cmd, "mkdir ", 6)) {
|
||||
/* create dir */
|
||||
state(conn, SSH_SFTP_QUOTE_MKDIR);
|
||||
break;
|
||||
}
|
||||
else if(curl_strnequal(cmd, "rename ", 7)) {
|
||||
else if(strncasecompare(cmd, "rename ", 7)) {
|
||||
/* rename file */
|
||||
/* first param is the source path */
|
||||
/* second param is the dest. path */
|
||||
@@ -1366,17 +1366,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_SFTP_QUOTE_RENAME);
|
||||
break;
|
||||
}
|
||||
else if(curl_strnequal(cmd, "rmdir ", 6)) {
|
||||
else if(strncasecompare(cmd, "rmdir ", 6)) {
|
||||
/* delete dir */
|
||||
state(conn, SSH_SFTP_QUOTE_RMDIR);
|
||||
break;
|
||||
}
|
||||
else if(curl_strnequal(cmd, "rm ", 3)) {
|
||||
else if(strncasecompare(cmd, "rm ", 3)) {
|
||||
state(conn, SSH_SFTP_QUOTE_UNLINK);
|
||||
break;
|
||||
}
|
||||
#ifdef HAS_STATVFS_SUPPORT
|
||||
else if(curl_strnequal(cmd, "statvfs ", 8)) {
|
||||
else if(strncasecompare(cmd, "statvfs ", 8)) {
|
||||
state(conn, SSH_SFTP_QUOTE_STATVFS);
|
||||
break;
|
||||
}
|
||||
@@ -1431,7 +1431,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->acceptfail = TRUE;
|
||||
}
|
||||
|
||||
if(!curl_strnequal(cmd, "chmod", 5)) {
|
||||
if(!strncasecompare(cmd, "chmod", 5)) {
|
||||
/* Since chown and chgrp only set owner OR group but libssh2 wants to
|
||||
* set them both at once, we need to obtain the current ownership
|
||||
* first. This takes an extra protocol round trip.
|
||||
@@ -1457,7 +1457,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
|
||||
/* Now set the new attributes... */
|
||||
if(curl_strnequal(cmd, "chgrp", 5)) {
|
||||
if(strncasecompare(cmd, "chgrp", 5)) {
|
||||
sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
|
||||
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
|
||||
if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
|
||||
@@ -1471,7 +1471,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(curl_strnequal(cmd, "chmod", 5)) {
|
||||
else if(strncasecompare(cmd, "chmod", 5)) {
|
||||
sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
|
||||
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
|
||||
/* permissions are octal */
|
||||
@@ -1486,7 +1486,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(curl_strnequal(cmd, "chown", 5)) {
|
||||
else if(strncasecompare(cmd, "chown", 5)) {
|
||||
sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
|
||||
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
|
||||
if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
|
||||
@@ -1895,7 +1895,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
/* since we don't really wait for anything at this point, we want the
|
||||
state machine to move on as soon as possible so we set a very short
|
||||
timeout here */
|
||||
Curl_expire(data, 1);
|
||||
Curl_expire(data, 0);
|
||||
|
||||
state(conn, SSH_STOP);
|
||||
}
|
||||
@@ -2860,7 +2860,7 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
|
||||
if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
|
||||
fd_write = sock;
|
||||
/* wait for the socket to become ready */
|
||||
Curl_socket_ready(fd_read, fd_write,
|
||||
Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
|
||||
left>1000?1000:left); /* ignore result */
|
||||
}
|
||||
#endif
|
||||
@@ -3109,7 +3109,6 @@ static CURLcode scp_done(struct connectdata *conn, CURLcode status,
|
||||
|
||||
}
|
||||
|
||||
/* return number of received (decrypted) bytes */
|
||||
static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
@@ -3134,10 +3133,6 @@ static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
|
||||
* a regular CURLcode value.
|
||||
*/
|
||||
static ssize_t scp_recv(struct connectdata *conn, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,7 +22,9 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "rawstr.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "strcase.h"
|
||||
|
||||
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
|
||||
its behavior is altered by the current locale. */
|
||||
@@ -99,9 +101,11 @@ char Curl_raw_toupper(char in)
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
|
||||
int Curl_raw_equal(const char *first, const char *second)
|
||||
int Curl_strcasecompare(const char *first, const char *second)
|
||||
{
|
||||
while(*first && *second) {
|
||||
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
|
||||
@@ -116,7 +120,10 @@ int Curl_raw_equal(const char *first, const char *second)
|
||||
return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
|
||||
}
|
||||
|
||||
int Curl_raw_nequal(const char *first, const char *second, size_t max)
|
||||
/*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
int Curl_strncasecompare(const char *first, const char *second, size_t max)
|
||||
{
|
||||
while(*first && *second && max) {
|
||||
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
|
||||
@@ -146,3 +153,14 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
|
||||
*dest++ = Curl_raw_toupper(*src);
|
||||
} while(*src++ && --n);
|
||||
}
|
||||
|
||||
/* --- public functions --- */
|
||||
|
||||
int curl_strequal(const char *first, const char *second)
|
||||
{
|
||||
return Curl_strcasecompare(first, second);
|
||||
}
|
||||
int curl_strnequal(const char *first, const char *second, size_t max)
|
||||
{
|
||||
return Curl_strncasecompare(first, second, max);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef HEADER_CURL_RAWSTR_H
|
||||
#define HEADER_CURL_RAWSTR_H
|
||||
#ifndef HEADER_CURL_STRCASE_H
|
||||
#define HEADER_CURL_STRCASE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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,23 +25,26 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
|
||||
* to be locale independent and only compare strings we know are safe for
|
||||
* this.
|
||||
* Only "raw" case insensitive strings. This is meant to be locale independent
|
||||
* and only compare strings we know are safe for this.
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
*/
|
||||
int Curl_raw_equal(const char *first, const char *second);
|
||||
int Curl_raw_nequal(const char *first, const char *second, size_t max);
|
||||
|
||||
#define strcasecompare(a,b) Curl_strcasecompare(a,b)
|
||||
#define strncasecompare(a,b,c) Curl_strncasecompare(a,b,c)
|
||||
|
||||
int Curl_strcasecompare(const char *first, const char *second);
|
||||
int Curl_strncasecompare(const char *first, const char *second, size_t max);
|
||||
|
||||
char Curl_raw_toupper(char in);
|
||||
|
||||
/* checkprefix() is a shorter version of the above, used when the first
|
||||
argument is zero-byte terminated */
|
||||
#define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a))
|
||||
#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_RAWSTR_H */
|
||||
|
||||
#endif /* HEADER_CURL_STRCASE_H */
|
||||
@@ -65,9 +65,9 @@ char *curlx_strdup(const char *str)
|
||||
* Returns the new pointer or NULL on failure.
|
||||
*
|
||||
***************************************************************************/
|
||||
char *Curl_memdup(const char *src, size_t length)
|
||||
void *Curl_memdup(const void *src, size_t length)
|
||||
{
|
||||
char *buffer = malloc(length);
|
||||
void *buffer = malloc(length);
|
||||
if(!buffer)
|
||||
return NULL; /* fail */
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -26,6 +26,6 @@
|
||||
#ifndef HAVE_STRDUP
|
||||
extern char *curlx_strdup(const char *str);
|
||||
#endif
|
||||
char *Curl_memdup(const char *src, size_t buffer_length);
|
||||
void *Curl_memdup(const void *src, size_t buffer_length);
|
||||
|
||||
#endif /* HEADER_CURL_STRDUP_H */
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, 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"
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "strequal.h"
|
||||
|
||||
/*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
int curl_strequal(const char *first, const char *second)
|
||||
{
|
||||
#if defined(HAVE_STRCASECMP)
|
||||
return !(strcasecmp)(first, second);
|
||||
#elif defined(HAVE_STRCMPI)
|
||||
return !(strcmpi)(first, second);
|
||||
#elif defined(HAVE_STRICMP)
|
||||
return !(stricmp)(first, second);
|
||||
#else
|
||||
while(*first && *second) {
|
||||
if(toupper(*first) != toupper(*second)) {
|
||||
break;
|
||||
}
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
return toupper(*first) == toupper(*second);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* @unittest: 1301
|
||||
*/
|
||||
int curl_strnequal(const char *first, const char *second, size_t max)
|
||||
{
|
||||
#if defined(HAVE_STRNCASECMP)
|
||||
return !strncasecmp(first, second, max);
|
||||
#elif defined(HAVE_STRNCMPI)
|
||||
return !strncmpi(first, second, max);
|
||||
#elif defined(HAVE_STRNICMP)
|
||||
return !strnicmp(first, second, max);
|
||||
#else
|
||||
while(*first && *second && max) {
|
||||
if(toupper(*first) != toupper(*second)) {
|
||||
break;
|
||||
}
|
||||
max--;
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
if(0 == max)
|
||||
return 1; /* they are equal this far */
|
||||
|
||||
return toupper(*first) == toupper(*second);
|
||||
#endif
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef HEADER_CURL_STREQUAL_H
|
||||
#define HEADER_CURL_STREQUAL_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, 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/curl.h>
|
||||
|
||||
#define strequal(a,b) curl_strequal(a,b)
|
||||
#define strnequal(a,b,c) curl_strnequal(a,b,c)
|
||||
|
||||
#endif /* HEADER_CURL_STREQUAL_H */
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
#include <idna.h>
|
||||
#ifdef USE_LIBIDN2
|
||||
#include <idn2.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
@@ -79,8 +79,8 @@ curl_easy_strerror(CURLcode error)
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
return "Couldn't connect to server";
|
||||
|
||||
case CURLE_FTP_WEIRD_SERVER_REPLY:
|
||||
return "FTP: weird server reply";
|
||||
case CURLE_WEIRD_SERVER_REPLY:
|
||||
return "Weird server reply";
|
||||
|
||||
case CURLE_REMOTE_ACCESS_DENIED:
|
||||
return "Access denied to remote resource";
|
||||
@@ -427,7 +427,7 @@ curl_share_strerror(CURLSHcode error)
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
|
||||
/* This function handles most / all (?) Winsock errors cURL is able to produce.
|
||||
/* This function handles most / all (?) Winsock errors curl is able to produce.
|
||||
*/
|
||||
static const char *
|
||||
get_winsock_error (int err, char *buf, size_t len)
|
||||
@@ -726,83 +726,6 @@ const char *Curl_strerror(struct connectdata *conn, int err)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
/*
|
||||
* Return error-string for libidn status as returned from idna_to_ascii_lz().
|
||||
*/
|
||||
const char *Curl_idn_strerror (struct connectdata *conn, int err)
|
||||
{
|
||||
#ifdef HAVE_IDNA_STRERROR
|
||||
(void)conn;
|
||||
return idna_strerror((Idna_rc) err);
|
||||
#else
|
||||
const char *str;
|
||||
char *buf;
|
||||
size_t max;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
|
||||
buf = conn->syserr_buf;
|
||||
max = sizeof(conn->syserr_buf)-1;
|
||||
*buf = '\0';
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
switch ((Idna_rc)err) {
|
||||
case IDNA_SUCCESS:
|
||||
str = "No error";
|
||||
break;
|
||||
case IDNA_STRINGPREP_ERROR:
|
||||
str = "Error in string preparation";
|
||||
break;
|
||||
case IDNA_PUNYCODE_ERROR:
|
||||
str = "Error in Punycode operation";
|
||||
break;
|
||||
case IDNA_CONTAINS_NON_LDH:
|
||||
str = "Illegal ASCII characters";
|
||||
break;
|
||||
case IDNA_CONTAINS_MINUS:
|
||||
str = "Contains minus";
|
||||
break;
|
||||
case IDNA_INVALID_LENGTH:
|
||||
str = "Invalid output length";
|
||||
break;
|
||||
case IDNA_NO_ACE_PREFIX:
|
||||
str = "No ACE prefix (\"xn--\")";
|
||||
break;
|
||||
case IDNA_ROUNDTRIP_VERIFY_ERROR:
|
||||
str = "Round trip verify error";
|
||||
break;
|
||||
case IDNA_CONTAINS_ACE_PREFIX:
|
||||
str = "Already have ACE prefix (\"xn--\")";
|
||||
break;
|
||||
case IDNA_ICONV_ERROR:
|
||||
str = "Locale conversion failed";
|
||||
break;
|
||||
case IDNA_MALLOC_ERROR:
|
||||
str = "Allocation failed";
|
||||
break;
|
||||
case IDNA_DLOPEN_ERROR:
|
||||
str = "dlopen() error";
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, max, "error %d", err);
|
||||
str = NULL;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if((Idna_rc)err == IDNA_SUCCESS)
|
||||
str = "No error";
|
||||
else
|
||||
str = "Error";
|
||||
#endif
|
||||
if(str)
|
||||
strncpy(buf, str, max);
|
||||
buf[max] = '\0';
|
||||
return (buf);
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_LIBIDN */
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
const char *Curl_sspi_strerror (struct connectdata *conn, int err)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
const char *Curl_strerror (struct connectdata *conn, int err);
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
#ifdef USE_LIBIDN2
|
||||
const char *Curl_idn_strerror (struct connectdata *conn, int err);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -83,7 +83,39 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
{
|
||||
bool matched = FALSE;
|
||||
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
#if defined(CURL_WINDOWS_APP)
|
||||
/* We have no way to determine the Windows version from Windows apps,
|
||||
so let's assume we're running on the target Windows version. */
|
||||
const WORD fullVersion = MAKEWORD(minorVersion, majorVersion);
|
||||
const WORD targetVersion = (WORD)_WIN32_WINNT;
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
matched = targetVersion < fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_LESS_THAN_EQUAL:
|
||||
matched = targetVersion <= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_EQUAL:
|
||||
matched = targetVersion == fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN_EQUAL:
|
||||
matched = targetVersion >= fullVersion;
|
||||
break;
|
||||
|
||||
case VERSION_GREATER_THAN:
|
||||
matched = targetVersion > fullVersion;
|
||||
break;
|
||||
}
|
||||
|
||||
if(matched && (platform == PLATFORM_WINDOWS)) {
|
||||
/* we're always running on PLATFORM_WINNT */
|
||||
matched = FALSE;
|
||||
}
|
||||
#elif !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
@@ -128,7 +160,7 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
}
|
||||
|
||||
/* Verify the platform identifier (if necessary) */
|
||||
if(matched && platform != PLATFORM_DONT_CARE) {
|
||||
if(matched) {
|
||||
switch(platform) {
|
||||
case PLATFORM_WINDOWS:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
|
||||
@@ -138,6 +170,9 @@ bool Curl_verify_windows_version(const unsigned int majorVersion,
|
||||
case PLATFORM_WINNT:
|
||||
if(osver.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
matched = FALSE;
|
||||
|
||||
default: /* like platform == PLATFORM_DONT_CARE */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,7 @@
|
||||
|
||||
#include "arpa_telnet.h"
|
||||
#include "select.h"
|
||||
#include "strequal.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -846,7 +845,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
option_keyword, option_arg) == 2) {
|
||||
|
||||
/* Terminal type */
|
||||
if(Curl_raw_equal(option_keyword, "TTYPE")) {
|
||||
if(strcasecompare(option_keyword, "TTYPE")) {
|
||||
strncpy(tn->subopt_ttype, option_arg, 31);
|
||||
tn->subopt_ttype[31] = 0; /* String termination */
|
||||
tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
|
||||
@@ -854,7 +853,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* Display variable */
|
||||
if(Curl_raw_equal(option_keyword, "XDISPLOC")) {
|
||||
if(strcasecompare(option_keyword, "XDISPLOC")) {
|
||||
strncpy(tn->subopt_xdisploc, option_arg, 127);
|
||||
tn->subopt_xdisploc[127] = 0; /* String termination */
|
||||
tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
|
||||
@@ -862,7 +861,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* Environment variable */
|
||||
if(Curl_raw_equal(option_keyword, "NEW_ENV")) {
|
||||
if(strcasecompare(option_keyword, "NEW_ENV")) {
|
||||
beg = curl_slist_append(tn->telnet_vars, option_arg);
|
||||
if(!beg) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@@ -874,7 +873,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* Window Size */
|
||||
if(Curl_raw_equal(option_keyword, "WS")) {
|
||||
if(strcasecompare(option_keyword, "WS")) {
|
||||
if(sscanf(option_arg, "%hu%*[xX]%hu",
|
||||
&tn->subopt_wsx, &tn->subopt_wsy) == 2)
|
||||
tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
|
||||
@@ -887,7 +886,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* To take care or not of the 8th bit in data exchange */
|
||||
if(Curl_raw_equal(option_keyword, "BINARY")) {
|
||||
if(strcasecompare(option_keyword, "BINARY")) {
|
||||
binary_option=atoi(option_arg);
|
||||
if(binary_option!=1) {
|
||||
tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
|
||||
|
||||
@@ -55,9 +55,10 @@
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "speedcheck.h"
|
||||
#include "select.h"
|
||||
#include "escape.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -484,10 +485,10 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
|
||||
/* As RFC3617 describes the separator slash is not actually part of the
|
||||
file name so we skip the always-present first letter of the path
|
||||
string. */
|
||||
filename = curl_easy_unescape(data, &state->conn->data->state.path[1], 0,
|
||||
NULL);
|
||||
if(!filename)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_urldecode(data, &state->conn->data->state.path[1], 0,
|
||||
&filename, NULL, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
snprintf((char *)state->spacket.data+2,
|
||||
state->blksize,
|
||||
@@ -705,6 +706,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
||||
int rblock;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SingleRequest *k = &data->req;
|
||||
int cb; /* Bytes currently read */
|
||||
|
||||
switch(event) {
|
||||
|
||||
@@ -762,9 +764,20 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes);
|
||||
if(result)
|
||||
return result;
|
||||
/* TFTP considers data block size < 512 bytes as an end of session. So
|
||||
* in some cases we must wait for additional data to build full (512 bytes)
|
||||
* data block.
|
||||
* */
|
||||
state->sbytes = 0;
|
||||
state->conn->data->req.upload_fromhere = (char *)state->spacket.data+4;
|
||||
do {
|
||||
result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
|
||||
&cb);
|
||||
if(result)
|
||||
return result;
|
||||
state->sbytes += cb;
|
||||
state->conn->data->req.upload_fromhere += cb;
|
||||
} while(state->sbytes < state->blksize && cb != 0);
|
||||
|
||||
sbytes = sendto(state->sockfd, (void *) state->spacket.data,
|
||||
4 + state->sbytes, SEND_4TH_ARG,
|
||||
@@ -1221,7 +1234,7 @@ static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
|
||||
}
|
||||
else {
|
||||
/* no timeouts to handle, check our socket */
|
||||
rc = Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, 0);
|
||||
rc = SOCKET_READABLE(state->sockfd, 0);
|
||||
|
||||
if(rc == -1) {
|
||||
/* bail out */
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "rawstr.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
@@ -75,6 +72,7 @@
|
||||
#include "multiif.h"
|
||||
#include "connect.h"
|
||||
#include "non-ascii.h"
|
||||
#include "http2.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -384,11 +382,15 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
|
||||
* Go ahead and do a read if we have a readable socket or if
|
||||
* the stream was rewound (in which case we have data in a
|
||||
* buffer)
|
||||
*
|
||||
* return '*comeback' TRUE if we didn't properly drain the socket so this
|
||||
* function should get called again without select() or similar in between!
|
||||
*/
|
||||
static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
struct SingleRequest *k,
|
||||
int *didwhat, bool *done)
|
||||
int *didwhat, bool *done,
|
||||
bool *comeback)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
ssize_t nread; /* number of bytes read */
|
||||
@@ -398,6 +400,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
int maxloops = 100;
|
||||
|
||||
*done = FALSE;
|
||||
*comeback = FALSE;
|
||||
|
||||
/* This is where we loop until we have read everything there is to
|
||||
read or we get a CURLE_AGAIN */
|
||||
@@ -529,6 +532,13 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
is non-headers. */
|
||||
if(k->str && !k->header && (nread > 0 || is_empty_data)) {
|
||||
|
||||
if(data->set.opt_no_body) {
|
||||
/* data arrives although we want none, bail out */
|
||||
streamclose(conn, "ignoring body");
|
||||
*done = TRUE;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if(0 == k->bodywrites && !is_empty_data) {
|
||||
/* These checks are only made the first time we are about to
|
||||
@@ -804,6 +814,12 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
|
||||
} while(data_pending(conn) && maxloops--);
|
||||
|
||||
if(maxloops <= 0) {
|
||||
/* we mark it as read-again-please */
|
||||
conn->cselect_bits = CURL_CSELECT_IN;
|
||||
*comeback = TRUE;
|
||||
}
|
||||
|
||||
if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
|
||||
conn->bits.close) {
|
||||
/* When we've read the entire thing and the close bit is set, the server
|
||||
@@ -821,6 +837,8 @@ static CURLcode done_sending(struct connectdata *conn,
|
||||
{
|
||||
k->keepon &= ~KEEP_SEND; /* we're done writing */
|
||||
|
||||
Curl_http2_done_sending(conn);
|
||||
|
||||
if(conn->bits.rewindaftersend) {
|
||||
CURLcode result = Curl_readrewind(conn);
|
||||
if(result)
|
||||
@@ -1029,10 +1047,14 @@ static CURLcode readwrite_upload(struct Curl_easy *data,
|
||||
/*
|
||||
* Curl_readwrite() is the low-level function to be called when data is to
|
||||
* be read and written to/from the connection.
|
||||
*
|
||||
* return '*comeback' TRUE if we didn't properly drain the socket so this
|
||||
* function should get called again without select() or similar in between!
|
||||
*/
|
||||
CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
struct Curl_easy *data,
|
||||
bool *done)
|
||||
bool *done,
|
||||
bool *comeback)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result;
|
||||
@@ -1064,7 +1086,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
|
||||
if(!select_res) /* Call for select()/poll() only, if read/write/error
|
||||
status is not known. */
|
||||
select_res = Curl_socket_ready(fd_read, fd_write, 0);
|
||||
select_res = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0);
|
||||
|
||||
if(select_res == CURL_CSELECT_ERR) {
|
||||
failf(data, "select/poll returned error");
|
||||
@@ -1077,7 +1099,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
if((k->keepon & KEEP_RECV) &&
|
||||
((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
|
||||
|
||||
result = readwrite_data(data, conn, k, &didwhat, done);
|
||||
result = readwrite_data(data, conn, k, &didwhat, done, comeback);
|
||||
if(result || *done)
|
||||
return result;
|
||||
}
|
||||
@@ -1249,60 +1271,6 @@ int Curl_single_getsock(const struct connectdata *conn,
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine optimum sleep time based on configured rate, current rate,
|
||||
* and packet size.
|
||||
* Returns value in milliseconds.
|
||||
*
|
||||
* The basic idea is to adjust the desired rate up/down in this method
|
||||
* based on whether we are running too slow or too fast. Then, calculate
|
||||
* how many milliseconds to wait for the next packet to achieve this new
|
||||
* rate.
|
||||
*/
|
||||
long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
|
||||
int pkt_size)
|
||||
{
|
||||
curl_off_t min_sleep = 0;
|
||||
curl_off_t rv = 0;
|
||||
|
||||
if(rate_bps == 0)
|
||||
return 0;
|
||||
|
||||
/* If running faster than about .1% of the desired speed, slow
|
||||
* us down a bit. Use shift instead of division as the 0.1%
|
||||
* cutoff is arbitrary anyway.
|
||||
*/
|
||||
if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) {
|
||||
/* running too fast, decrease target rate by 1/64th of rate */
|
||||
rate_bps -= rate_bps >> 6;
|
||||
min_sleep = 1;
|
||||
}
|
||||
else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) {
|
||||
/* running too slow, increase target rate by 1/64th of rate */
|
||||
rate_bps += rate_bps >> 6;
|
||||
}
|
||||
|
||||
/* Determine number of milliseconds to wait until we do
|
||||
* the next packet at the adjusted rate. We should wait
|
||||
* longer when using larger packets, for instance.
|
||||
*/
|
||||
rv = ((curl_off_t)(pkt_size * 1000) / rate_bps);
|
||||
|
||||
/* Catch rounding errors and always slow down at least 1ms if
|
||||
* we are running too fast.
|
||||
*/
|
||||
if(rv < min_sleep)
|
||||
rv = min_sleep;
|
||||
|
||||
/* Bound value to fit in 'long' on 32-bit platform. That's
|
||||
* plenty long enough anyway!
|
||||
*/
|
||||
if(rv > 0x7fffffff)
|
||||
rv = 0x7fffffff;
|
||||
|
||||
return (long)rv;
|
||||
}
|
||||
|
||||
/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
|
||||
which means this gets called once for each subsequent redirect etc */
|
||||
void Curl_init_CONNECT(struct Curl_easy *data)
|
||||
@@ -1875,13 +1843,12 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
|
||||
if((data->req.bytecount + data->req.headerbytecount == 0) &&
|
||||
conn->bits.reuse &&
|
||||
!data->set.opt_no_body &&
|
||||
(data->set.rtspreq != RTSPREQ_RECEIVE)) {
|
||||
/* We got no data, we attempted to re-use a connection and yet we want a
|
||||
"body". This might happen if the connection was left alive when we were
|
||||
done using it before, but that was closed when we wanted to read from
|
||||
it again. Bad luck. Retry the same request on a fresh connect! */
|
||||
conn->bits.reuse &&
|
||||
(data->set.rtspreq != RTSPREQ_RECEIVE)) {
|
||||
/* We didn't get a single byte when we attempted to re-use a
|
||||
connection. This might happen if the connection was left alive when we
|
||||
were done using it before, but that was closed when we wanted to use it
|
||||
again. Bad luck. Retry the same request on a fresh connect! */
|
||||
infof(conn->data, "Connection died, retrying a fresh connect\n");
|
||||
*url = strdup(conn->data->change.url);
|
||||
if(!*url)
|
||||
|
||||
@@ -40,10 +40,9 @@ typedef enum {
|
||||
|
||||
CURLcode Curl_follow(struct Curl_easy *data, char *newurl,
|
||||
followtype type);
|
||||
|
||||
|
||||
CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
struct Curl_easy *data, bool *done);
|
||||
struct Curl_easy *data, bool *done,
|
||||
bool *comeback);
|
||||
int Curl_single_getsock(const struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
@@ -65,8 +64,5 @@ Curl_setup_transfer (struct connectdata *data,
|
||||
curl_off_t *writecountp /* return number of bytes written */
|
||||
);
|
||||
|
||||
long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
|
||||
int pkt_size);
|
||||
|
||||
#endif /* HEADER_CURL_TRANSFER_H */
|
||||
|
||||
|
||||
+104
-141
@@ -59,24 +59,13 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
#include <idna.h>
|
||||
#include <tld.h>
|
||||
#include <stringprep.h>
|
||||
#ifdef HAVE_IDN_FREE_H
|
||||
#include <idn-free.h>
|
||||
#else
|
||||
/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */
|
||||
void idn_free (void *ptr);
|
||||
#endif
|
||||
#ifndef HAVE_IDN_FREE
|
||||
/* if idn_free() was not found in this version of libidn use free() instead */
|
||||
#define idn_free(x) (free)(x)
|
||||
#endif
|
||||
#ifdef USE_LIBIDN2
|
||||
#include <idn2.h>
|
||||
|
||||
#elif defined(USE_WIN32_IDN)
|
||||
/* prototype for curl_win32_idn_to_ascii() */
|
||||
bool curl_win32_idn_to_ascii(const char *in, char **out);
|
||||
#endif /* USE_LIBIDN */
|
||||
#endif /* USE_LIBIDN2 */
|
||||
|
||||
#include "urldata.h"
|
||||
#include "netrc.h"
|
||||
@@ -88,7 +77,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
|
||||
#include "sendf.h"
|
||||
#include "progress.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "strerror.h"
|
||||
#include "escape.h"
|
||||
#include "strtok.h"
|
||||
@@ -100,7 +89,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
|
||||
#include "multiif.h"
|
||||
#include "easyif.h"
|
||||
#include "speedcheck.h"
|
||||
#include "rawstr.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "inet_pton.h"
|
||||
@@ -405,7 +393,7 @@ CURLcode Curl_close(struct Curl_easy *data)
|
||||
if(!data)
|
||||
return CURLE_OK;
|
||||
|
||||
Curl_expire(data, 0); /* shut off timers */
|
||||
Curl_expire_clear(data); /* shut off timers */
|
||||
|
||||
m = data->multi;
|
||||
|
||||
@@ -602,6 +590,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
||||
set->tcp_keepintvl = 60;
|
||||
set->tcp_keepidle = 60;
|
||||
set->tcp_fastopen = FALSE;
|
||||
set->tcp_nodelay = TRUE;
|
||||
|
||||
set->ssl_enable_npn = TRUE;
|
||||
set->ssl_enable_alpn = TRUE;
|
||||
@@ -781,6 +770,10 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
||||
*/
|
||||
data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
|
||||
break;
|
||||
case CURLOPT_KEEP_SENDING_ON_ERROR:
|
||||
data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
|
||||
TRUE : FALSE;
|
||||
break;
|
||||
case CURLOPT_UPLOAD:
|
||||
case CURLOPT_PUT:
|
||||
/*
|
||||
@@ -1225,23 +1218,23 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
||||
if(argptr == NULL)
|
||||
break;
|
||||
|
||||
if(Curl_raw_equal(argptr, "ALL")) {
|
||||
if(strcasecompare(argptr, "ALL")) {
|
||||
/* clear all cookies */
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
Curl_cookie_clearall(data->cookies);
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
else if(Curl_raw_equal(argptr, "SESS")) {
|
||||
else if(strcasecompare(argptr, "SESS")) {
|
||||
/* clear session cookies */
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
Curl_cookie_clearsess(data->cookies);
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
else if(Curl_raw_equal(argptr, "FLUSH")) {
|
||||
else if(strcasecompare(argptr, "FLUSH")) {
|
||||
/* flush cookies to file, takes care of the locking */
|
||||
Curl_flush_cookies(data, 0);
|
||||
}
|
||||
else if(Curl_raw_equal(argptr, "RELOAD")) {
|
||||
else if(strcasecompare(argptr, "RELOAD")) {
|
||||
/* reload cookies from file */
|
||||
Curl_cookie_loadfiles(data);
|
||||
break;
|
||||
@@ -2614,7 +2607,7 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
|
||||
break;
|
||||
case CURLOPT_TLSAUTH_TYPE:
|
||||
if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
|
||||
if(strncasecompare((char *)va_arg(param, char *), "SRP", strlen("SRP")))
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_SRP;
|
||||
else
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_NONE;
|
||||
@@ -2829,6 +2822,17 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(conn->dns_entry != NULL) {
|
||||
Curl_resolv_unlock(data, conn->dns_entry);
|
||||
conn->dns_entry = NULL;
|
||||
@@ -2876,7 +2880,7 @@ static bool SocketIsDead(curl_socket_t sock)
|
||||
int sval;
|
||||
bool ret_val = TRUE;
|
||||
|
||||
sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
|
||||
sval = SOCKET_READABLE(sock, 0);
|
||||
if(sval == 0)
|
||||
/* timeout */
|
||||
ret_val = FALSE;
|
||||
@@ -2892,7 +2896,8 @@ static bool IsPipeliningPossible(const struct Curl_easy *handle,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
/* If a HTTP protocol and pipelining is enabled */
|
||||
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
|
||||
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||
(!conn->bits.protoconnstart || !conn->bits.close)) {
|
||||
|
||||
if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
|
||||
(handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
|
||||
@@ -3267,6 +3272,8 @@ ConnectionExists(struct Curl_easy *data,
|
||||
pipeLen = check->send_pipe->size + check->recv_pipe->size;
|
||||
|
||||
if(canPipeline) {
|
||||
if(check->bits.protoconnstart && check->bits.close)
|
||||
continue;
|
||||
|
||||
if(!check->bits.multiplex) {
|
||||
/* If not multiplexing, make sure the pipe has only GET requests */
|
||||
@@ -3341,7 +3348,7 @@ ConnectionExists(struct Curl_easy *data,
|
||||
(needle->proxytype != check->proxytype ||
|
||||
needle->bits.httpproxy != check->bits.httpproxy ||
|
||||
needle->bits.tunnel_proxy != check->bits.tunnel_proxy ||
|
||||
!Curl_raw_equal(needle->proxy.name, check->proxy.name) ||
|
||||
!strcasecompare(needle->proxy.name, check->proxy.name) ||
|
||||
needle->port != check->port))
|
||||
/* don't mix connections that use different proxies */
|
||||
continue;
|
||||
@@ -3384,8 +3391,8 @@ ConnectionExists(struct Curl_easy *data,
|
||||
if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
|
||||
/* This protocol requires credentials per connection,
|
||||
so verify that we're using the same name and password as well */
|
||||
if(!strequal(needle->user, check->user) ||
|
||||
!strequal(needle->passwd, check->passwd)) {
|
||||
if(strcmp(needle->user, check->user) ||
|
||||
strcmp(needle->passwd, check->passwd)) {
|
||||
/* one of them was different */
|
||||
continue;
|
||||
}
|
||||
@@ -3396,14 +3403,14 @@ ConnectionExists(struct Curl_easy *data,
|
||||
/* The requested connection does not use a HTTP proxy or it uses SSL or
|
||||
it is a non-SSL protocol tunneled over the same HTTP proxy name and
|
||||
port number */
|
||||
if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) ||
|
||||
if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
|
||||
(get_protocol_family(check->handler->protocol) ==
|
||||
needle->handler->protocol && check->tls_upgraded)) &&
|
||||
(!needle->bits.conn_to_host || Curl_raw_equal(
|
||||
(!needle->bits.conn_to_host || strcasecompare(
|
||||
needle->conn_to_host.name, check->conn_to_host.name)) &&
|
||||
(!needle->bits.conn_to_port ||
|
||||
needle->conn_to_port == check->conn_to_port) &&
|
||||
Curl_raw_equal(needle->host.name, check->host.name) &&
|
||||
strcasecompare(needle->host.name, check->host.name) &&
|
||||
needle->remote_port == check->remote_port) {
|
||||
/* The schemes match or the the protocol family is the same and the
|
||||
previous connection was TLS upgraded, and the hostname and host
|
||||
@@ -3445,8 +3452,8 @@ ConnectionExists(struct Curl_easy *data,
|
||||
possible. (Especially we must not reuse the same connection if
|
||||
partway through a handshake!) */
|
||||
if(wantNTLMhttp) {
|
||||
if(!strequal(needle->user, check->user) ||
|
||||
!strequal(needle->passwd, check->passwd))
|
||||
if(strcmp(needle->user, check->user) ||
|
||||
strcmp(needle->passwd, check->passwd))
|
||||
continue;
|
||||
}
|
||||
else if(check->ntlm.state != NTLMSTATE_NONE) {
|
||||
@@ -3460,8 +3467,8 @@ ConnectionExists(struct Curl_easy *data,
|
||||
if(!check->proxyuser || !check->proxypasswd)
|
||||
continue;
|
||||
|
||||
if(!strequal(needle->proxyuser, check->proxyuser) ||
|
||||
!strequal(needle->proxypasswd, check->proxypasswd))
|
||||
if(strcmp(needle->proxyuser, check->proxyuser) ||
|
||||
strcmp(needle->proxypasswd, check->proxypasswd))
|
||||
continue;
|
||||
}
|
||||
else if(check->proxyntlm.state != NTLMSTATE_NONE) {
|
||||
@@ -3752,58 +3759,15 @@ static bool is_ASCII_name(const char *hostname)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
/*
|
||||
* Check if characters in hostname is allowed in Top Level Domain.
|
||||
*/
|
||||
static bool tld_check_name(struct Curl_easy *data,
|
||||
const char *ace_hostname)
|
||||
{
|
||||
size_t err_pos;
|
||||
char *uc_name = NULL;
|
||||
int rc;
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
const char *tld_errmsg = "<no msg>";
|
||||
#else
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
/* Convert (and downcase) ACE-name back into locale's character set */
|
||||
rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
|
||||
if(rc != IDNA_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
/* Warning: err_pos receives "the decoded character offset rather than the
|
||||
byte position in the string." And as of libidn 1.32 that character offset
|
||||
is for UTF-8, even if the passed in string is another locale. */
|
||||
rc = tld_check_lz(uc_name, &err_pos, NULL);
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
#ifdef HAVE_TLD_STRERROR
|
||||
if(rc != TLD_SUCCESS)
|
||||
tld_errmsg = tld_strerror((Tld_rc)rc);
|
||||
#endif
|
||||
if(rc != TLD_SUCCESS)
|
||||
infof(data, "WARNING: TLD check for %s failed; %s\n",
|
||||
uc_name, tld_errmsg);
|
||||
#endif /* CURL_DISABLE_VERBOSE_STRINGS */
|
||||
if(uc_name)
|
||||
idn_free(uc_name);
|
||||
if(rc != TLD_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Perform any necessary IDN conversion of hostname
|
||||
*/
|
||||
static void fix_hostname(struct Curl_easy *data,
|
||||
struct connectdata *conn, struct hostname *host)
|
||||
static void fix_hostname(struct connectdata *conn, struct hostname *host)
|
||||
{
|
||||
size_t len;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
#ifndef USE_LIBIDN
|
||||
#ifndef USE_LIBIDN2
|
||||
(void)data;
|
||||
(void)conn;
|
||||
#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
@@ -3821,25 +3785,18 @@ static void fix_hostname(struct Curl_easy *data,
|
||||
|
||||
/* Check name for non-ASCII and convert hostname to ACE form if we can */
|
||||
if(!is_ASCII_name(host->name)) {
|
||||
#ifdef USE_LIBIDN
|
||||
if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
|
||||
#ifdef USE_LIBIDN2
|
||||
if(idn2_check_version(IDN2_VERSION)) {
|
||||
char *ace_hostname = NULL;
|
||||
|
||||
int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
|
||||
infof(data, "Input domain encoded as `%s'\n",
|
||||
stringprep_locale_charset());
|
||||
if(rc == IDNA_SUCCESS) {
|
||||
/* tld_check_name() displays a warning if the host name contains
|
||||
"illegal" characters for this TLD */
|
||||
(void)tld_check_name(data, ace_hostname);
|
||||
|
||||
host->encalloc = ace_hostname;
|
||||
int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, 0);
|
||||
if(rc == IDN2_OK) {
|
||||
host->encalloc = (char *)ace_hostname;
|
||||
/* change the name pointer to point to the encoded hostname */
|
||||
host->name = host->encalloc;
|
||||
}
|
||||
else
|
||||
infof(data, "Failed to convert %s to ACE; %s\n", host->name,
|
||||
Curl_idn_strerror(conn, rc));
|
||||
idn2_strerror(rc));
|
||||
}
|
||||
#elif defined(USE_WIN32_IDN)
|
||||
char *ace_hostname = NULL;
|
||||
@@ -3862,9 +3819,9 @@ static void fix_hostname(struct Curl_easy *data,
|
||||
*/
|
||||
static void free_fixed_hostname(struct hostname *host)
|
||||
{
|
||||
#if defined(USE_LIBIDN)
|
||||
#if defined(USE_LIBIDN2)
|
||||
if(host->encalloc) {
|
||||
idn_free(host->encalloc); /* must be freed with idn_free() since this was
|
||||
idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
|
||||
allocated by libidn */
|
||||
host->encalloc = NULL;
|
||||
}
|
||||
@@ -4022,7 +3979,7 @@ static CURLcode findprotocol(struct Curl_easy *data,
|
||||
variables based on the URL. Now that the handler may be changed later
|
||||
when the protocol specific setup function is called. */
|
||||
for(pp = protocols; (p = *pp) != NULL; pp++) {
|
||||
if(Curl_raw_equal(p->scheme, protostr)) {
|
||||
if(strcasecompare(p->scheme, protostr)) {
|
||||
/* Protocol found in table. Check if allowed */
|
||||
if(!(data->set.allowed_protocols & p->protocol))
|
||||
/* nope, get out */
|
||||
@@ -4091,7 +4048,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
************************************************************/
|
||||
if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
|
||||
protobuf, path)) &&
|
||||
Curl_raw_equal(protobuf, "file")) {
|
||||
strcasecompare(protobuf, "file")) {
|
||||
if(path[0] == '/' && path[1] == '/') {
|
||||
/* Allow omitted hostname (e.g. file:/<path>). This is not strictly
|
||||
* speaking a valid file: URL by RFC 1738, but treating file:/<path> as
|
||||
@@ -4145,7 +4102,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
path[0]=0;
|
||||
|
||||
rc = sscanf(data->change.url,
|
||||
"%15[^\n:]:%3[/]%[^\n/?]%[^\n]",
|
||||
"%15[^\n:]:%3[/]%[^\n/?#]%[^\n]",
|
||||
protobuf, slashbuf, conn->host.name, path);
|
||||
if(2 == rc) {
|
||||
failf(data, "Bad URL");
|
||||
@@ -4157,7 +4114,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
* The URL was badly formatted, let's try the browser-style _without_
|
||||
* protocol specified like 'http://'.
|
||||
*/
|
||||
rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
|
||||
rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
|
||||
if(1 > rc) {
|
||||
/*
|
||||
* We couldn't even get this format.
|
||||
@@ -4262,10 +4219,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
/* If the URL is malformatted (missing a '/' after hostname before path) we
|
||||
* insert a slash here. The only letter except '/' we accept to start a path
|
||||
* is '?'.
|
||||
* insert a slash here. The only letters except '/' that can start a path is
|
||||
* '?' and '#' - as controlled by the two sscanf() patterns above.
|
||||
*/
|
||||
if(path[0] == '?') {
|
||||
if(path[0] != '/') {
|
||||
/* We need this function to deal with overlapping memory areas. We know
|
||||
that the memory area 'path' points to is 'urllen' bytes big and that
|
||||
is bigger than the path. Use +1 to move the zero byte too. */
|
||||
@@ -4531,7 +4488,7 @@ static bool check_noproxy(const char* name, const char* no_proxy)
|
||||
char *endptr;
|
||||
|
||||
if(no_proxy && no_proxy[0]) {
|
||||
if(Curl_raw_equal("*", no_proxy)) {
|
||||
if(strcasecompare("*", no_proxy)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -4569,7 +4526,7 @@ static bool check_noproxy(const char* name, const char* no_proxy)
|
||||
if((tok_end - tok_start) <= namelen) {
|
||||
/* Match the last part of the name to the domain we are checking. */
|
||||
const char *checkn = name + namelen - (tok_end - tok_start);
|
||||
if(Curl_raw_nequal(no_proxy + tok_start, checkn,
|
||||
if(strncasecompare(no_proxy + tok_start, checkn,
|
||||
tok_end - tok_start)) {
|
||||
if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
|
||||
/* We either have an exact match, or the previous character is a .
|
||||
@@ -4648,7 +4605,7 @@ static char *detect_proxy(struct connectdata *conn)
|
||||
* This can cause 'internal' http/ftp requests to be
|
||||
* arbitrarily redirected by any external attacker.
|
||||
*/
|
||||
if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
|
||||
if(!prox && !strcasecompare("http_proxy", proxy_env)) {
|
||||
/* There was no lowercase variable, try the uppercase version: */
|
||||
Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
|
||||
prox=curl_getenv(proxy_env);
|
||||
@@ -4705,7 +4662,13 @@ static CURLcode parse_proxy(struct Curl_easy *data,
|
||||
conn->proxytype = CURLPROXY_SOCKS4A;
|
||||
else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
|
||||
conn->proxytype = CURLPROXY_SOCKS4;
|
||||
/* Any other xxx:// : change to http proxy */
|
||||
else if(checkprefix("http:", proxy))
|
||||
; /* leave it as HTTP or HTTP/1.0 */
|
||||
else {
|
||||
/* Any other xxx:// reject! */
|
||||
failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
else
|
||||
proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
|
||||
@@ -4725,21 +4688,24 @@ static CURLcode parse_proxy(struct Curl_easy *data,
|
||||
them. */
|
||||
Curl_safefree(conn->proxyuser);
|
||||
if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
|
||||
conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
|
||||
else
|
||||
conn->proxyuser = strdup("");
|
||||
|
||||
if(!conn->proxyuser)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_urldecode(data, proxyuser, 0, &conn->proxyuser, NULL,
|
||||
FALSE);
|
||||
else {
|
||||
conn->proxyuser = strdup("");
|
||||
if(!conn->proxyuser)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!result) {
|
||||
Curl_safefree(conn->proxypasswd);
|
||||
if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
|
||||
conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
|
||||
else
|
||||
result = Curl_urldecode(data, proxypasswd, 0,
|
||||
&conn->proxypasswd, NULL, FALSE);
|
||||
else {
|
||||
conn->proxypasswd = strdup("");
|
||||
|
||||
if(!conn->proxypasswd)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
if(!conn->proxypasswd)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if(!result) {
|
||||
@@ -4846,6 +4812,7 @@ static CURLcode parse_proxy_auth(struct Curl_easy *data,
|
||||
{
|
||||
char proxyuser[MAX_CURL_USER_LENGTH]="";
|
||||
char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
|
||||
CURLcode result;
|
||||
|
||||
if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
|
||||
strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
|
||||
@@ -4858,15 +4825,11 @@ static CURLcode parse_proxy_auth(struct Curl_easy *data,
|
||||
proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
|
||||
}
|
||||
|
||||
conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
|
||||
if(!conn->proxyuser)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
|
||||
if(!conn->proxypasswd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
result = Curl_urldecode(data, proxyuser, 0, &conn->proxyuser, NULL, FALSE);
|
||||
if(!result)
|
||||
result = Curl_urldecode(data, proxypasswd, 0, &conn->proxypasswd, NULL,
|
||||
FALSE);
|
||||
return result;
|
||||
}
|
||||
#endif /* CURL_DISABLE_PROXY */
|
||||
|
||||
@@ -4940,9 +4903,8 @@ static CURLcode parse_url_login(struct Curl_easy *data,
|
||||
conn->bits.user_passwd = TRUE; /* enable user+password */
|
||||
|
||||
/* Decode the user */
|
||||
newname = curl_easy_unescape(data, userp, 0, NULL);
|
||||
if(!newname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE);
|
||||
if(result) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -4952,9 +4914,9 @@ static CURLcode parse_url_login(struct Curl_easy *data,
|
||||
|
||||
if(passwdp) {
|
||||
/* We have a password in the URL so decode it */
|
||||
char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
|
||||
if(!newpasswd) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
char *newpasswd;
|
||||
result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE);
|
||||
if(result) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -4964,9 +4926,9 @@ static CURLcode parse_url_login(struct Curl_easy *data,
|
||||
|
||||
if(optionsp) {
|
||||
/* We have an options list in the URL so decode it */
|
||||
char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
|
||||
if(!newoptions) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
char *newoptions;
|
||||
result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE);
|
||||
if(result) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5457,7 +5419,8 @@ static CURLcode parse_connect_to_string(struct Curl_easy *data,
|
||||
if(!hostname_to_match)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
hostname_to_match_len = strlen(hostname_to_match);
|
||||
host_match = curl_strnequal(ptr, hostname_to_match, hostname_to_match_len);
|
||||
host_match = strncasecompare(ptr, hostname_to_match,
|
||||
hostname_to_match_len);
|
||||
free(hostname_to_match);
|
||||
ptr += hostname_to_match_len;
|
||||
|
||||
@@ -6021,18 +5984,18 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||
/*************************************************************
|
||||
* IDN-fix the hostnames
|
||||
*************************************************************/
|
||||
fix_hostname(data, conn, &conn->host);
|
||||
fix_hostname(conn, &conn->host);
|
||||
if(conn->bits.conn_to_host)
|
||||
fix_hostname(data, conn, &conn->conn_to_host);
|
||||
fix_hostname(conn, &conn->conn_to_host);
|
||||
if(conn->proxy.name && *conn->proxy.name)
|
||||
fix_hostname(data, conn, &conn->proxy);
|
||||
fix_hostname(conn, &conn->proxy);
|
||||
|
||||
/*************************************************************
|
||||
* Check whether the host and the "connect to host" are equal.
|
||||
* Do this after the hostnames have been IDN-fixed .
|
||||
*************************************************************/
|
||||
if(conn->bits.conn_to_host &&
|
||||
Curl_raw_equal(conn->conn_to_host.name, conn->host.name)) {
|
||||
strcasecompare(conn->conn_to_host.name, conn->host.name)) {
|
||||
conn->bits.conn_to_host = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -330,6 +330,7 @@ struct ssl_connect_data {
|
||||
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
|
||||
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
|
||||
bool recv_connection_closed; /* true if connection closed, regardless how */
|
||||
bool use_alpn; /* true if ALPN is used for this connection */
|
||||
#elif defined(USE_DARWINSSL)
|
||||
SSLContextRef ssl_ctx;
|
||||
curl_socket_t ssl_sockfd;
|
||||
@@ -373,6 +374,7 @@ struct ssl_config_data {
|
||||
struct curl_ssl_session {
|
||||
char *name; /* host name for which this ID was used */
|
||||
char *conn_to_host; /* host name for the connection (may be NULL) */
|
||||
const char *scheme; /* protocol scheme used */
|
||||
void *sessionid; /* as returned from the SSL layer */
|
||||
size_t idsize; /* if known, otherwise 0 */
|
||||
long age; /* just a number, the higher the more recent */
|
||||
@@ -817,6 +819,7 @@ struct Curl_handler {
|
||||
#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
|
||||
request instead of per connection */
|
||||
#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
|
||||
#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */
|
||||
|
||||
/* return the count of bytes sent, or -1 on error */
|
||||
typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
|
||||
@@ -1102,9 +1105,10 @@ struct connectdata {
|
||||
|
||||
/*
|
||||
* Struct to keep statistical and informational data.
|
||||
* All variables in this struct must be reset in Curl_initinfo().
|
||||
*/
|
||||
struct PureInfo {
|
||||
int httpcode; /* Recent HTTP, FTP, or RTSP response code */
|
||||
int httpcode; /* Recent HTTP, FTP, RTSP or SMTP response code */
|
||||
int httpproxycode; /* response code from proxy when received separate */
|
||||
int httpversion; /* the http version number X.Y = X*10+Y */
|
||||
long filetime; /* If requested, this is might get set. Set to -1 if the time
|
||||
@@ -1171,6 +1175,14 @@ struct Progress {
|
||||
struct timeval t_startsingle;
|
||||
struct timeval t_startop;
|
||||
struct timeval t_acceptdata;
|
||||
|
||||
/* upload speed limit */
|
||||
struct timeval ul_limit_start;
|
||||
curl_off_t ul_limit_size;
|
||||
/* download speed limit */
|
||||
struct timeval dl_limit_start;
|
||||
curl_off_t dl_limit_size;
|
||||
|
||||
#define CURR_TIME (5+1) /* 6 entries for 5 seconds */
|
||||
|
||||
curl_off_t speeder[ CURR_TIME ];
|
||||
@@ -1600,6 +1612,7 @@ struct UserDefined {
|
||||
bool ftp_use_port; /* use the FTP PORT command */
|
||||
bool hide_progress; /* don't use the progress meter */
|
||||
bool http_fail_on_error; /* fail on HTTP error codes >= 400 */
|
||||
bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */
|
||||
bool http_follow_location; /* follow HTTP redirects */
|
||||
bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
|
||||
bool http_disable_hostname_check_before_authentication;
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include "curl_md5.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "strequal.h"
|
||||
#include "rawstr.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "vtls/vtls.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
#include "curl_printf.h"
|
||||
|
||||
@@ -217,11 +217,11 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
|
||||
|
||||
token = strtok_r(tmp, ",", &tok_buf);
|
||||
while(token != NULL) {
|
||||
if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH))
|
||||
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
|
||||
*value |= DIGEST_QOP_VALUE_AUTH;
|
||||
else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
|
||||
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
|
||||
*value |= DIGEST_QOP_VALUE_AUTH_INT;
|
||||
else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
|
||||
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
|
||||
*value |= DIGEST_QOP_VALUE_AUTH_CONF;
|
||||
|
||||
token = strtok_r(NULL, ",", &tok_buf);
|
||||
@@ -305,6 +305,20 @@ static CURLcode auth_decode_digest_md5_message(const char *chlg64,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_is_digest_supported()
|
||||
*
|
||||
* This is used to evaluate if DIGEST is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE as DIGEST as handled by libcurl.
|
||||
*/
|
||||
bool Curl_auth_is_digest_supported(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_create_digest_md5_message()
|
||||
*
|
||||
@@ -524,31 +538,31 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
||||
|
||||
/* Extract a value=content pair */
|
||||
if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) {
|
||||
if(Curl_raw_equal(value, "nonce")) {
|
||||
if(strcasecompare(value, "nonce")) {
|
||||
free(digest->nonce);
|
||||
digest->nonce = strdup(content);
|
||||
if(!digest->nonce)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(Curl_raw_equal(value, "stale")) {
|
||||
if(Curl_raw_equal(content, "true")) {
|
||||
else if(strcasecompare(value, "stale")) {
|
||||
if(strcasecompare(content, "true")) {
|
||||
digest->stale = TRUE;
|
||||
digest->nc = 1; /* we make a new nonce now */
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal(value, "realm")) {
|
||||
else if(strcasecompare(value, "realm")) {
|
||||
free(digest->realm);
|
||||
digest->realm = strdup(content);
|
||||
if(!digest->realm)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(Curl_raw_equal(value, "opaque")) {
|
||||
else if(strcasecompare(value, "opaque")) {
|
||||
free(digest->opaque);
|
||||
digest->opaque = strdup(content);
|
||||
if(!digest->opaque)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(Curl_raw_equal(value, "qop")) {
|
||||
else if(strcasecompare(value, "qop")) {
|
||||
char *tok_buf;
|
||||
/* Tokenize the list and choose auth if possible, use a temporary
|
||||
clone of the buffer since strtok_r() ruins it */
|
||||
@@ -558,10 +572,10 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
||||
|
||||
token = strtok_r(tmp, ",", &tok_buf);
|
||||
while(token != NULL) {
|
||||
if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
|
||||
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
|
||||
foundAuth = TRUE;
|
||||
}
|
||||
else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
|
||||
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
|
||||
foundAuthInt = TRUE;
|
||||
}
|
||||
token = strtok_r(NULL, ",", &tok_buf);
|
||||
@@ -583,15 +597,15 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal(value, "algorithm")) {
|
||||
else if(strcasecompare(value, "algorithm")) {
|
||||
free(digest->algorithm);
|
||||
digest->algorithm = strdup(content);
|
||||
if(!digest->algorithm)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(Curl_raw_equal(content, "MD5-sess"))
|
||||
if(strcasecompare(content, "MD5-sess"))
|
||||
digest->algo = CURLDIGESTALGO_MD5SESS;
|
||||
else if(Curl_raw_equal(content, "MD5"))
|
||||
else if(strcasecompare(content, "MD5"))
|
||||
digest->algo = CURLDIGESTALGO_MD5;
|
||||
else
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
@@ -730,7 +744,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
|
||||
md5this = (unsigned char *) aprintf("%s:%s", request, uripath);
|
||||
|
||||
if(digest->qop && Curl_raw_equal(digest->qop, "auth-int")) {
|
||||
if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
|
||||
/* We don't support auth-int for PUT or POST at the moment.
|
||||
TODO: replace md5 of empty string with entity-body for PUT/POST */
|
||||
unsigned char *md5this2 = (unsigned char *)
|
||||
@@ -806,7 +820,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
digest->qop,
|
||||
request_digest);
|
||||
|
||||
if(Curl_raw_equal(digest->qop, "auth"))
|
||||
if(strcasecompare(digest->qop, "auth"))
|
||||
digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
|
||||
padded which tells to the server how many times you are
|
||||
using the same nonce in the qop=auth mode */
|
||||
|
||||
@@ -37,12 +37,33 @@
|
||||
#include "curl_multibyte.h"
|
||||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_auth_is_digest_supported()
|
||||
*
|
||||
* This is used to evaluate if DIGEST is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE if DIGEST is supported by Windows SSPI.
|
||||
*/
|
||||
bool Curl_auth_is_digest_supported(void)
|
||||
{
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
/* Query the security package for Digest */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST),
|
||||
&SecurityPackage);
|
||||
|
||||
return (status == SEC_E_OK ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_create_digest_md5_message()
|
||||
*
|
||||
@@ -256,7 +277,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
|
||||
/* Extract a value=content pair */
|
||||
if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) {
|
||||
if(Curl_raw_equal(value, "realm")) {
|
||||
if(strcasecompare(value, "realm")) {
|
||||
|
||||
/* Setup identity's domain and length */
|
||||
domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *) content);
|
||||
|
||||
@@ -41,6 +41,20 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_auth_is_gssapi_supported()
|
||||
*
|
||||
* This is used to evaluate if GSSAPI (Kerberos V5) is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE if Kerberos V5 is supported by the GSS-API library.
|
||||
*/
|
||||
bool Curl_auth_is_gssapi_supported(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_create_gssapi_user_message()
|
||||
*
|
||||
|
||||
@@ -39,6 +39,28 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_auth_is_gssapi_supported()
|
||||
*
|
||||
* This is used to evaluate if GSSAPI (Kerberos V5) is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE if Kerberos V5 is supported by Windows SSPI.
|
||||
*/
|
||||
bool Curl_auth_is_gssapi_supported(void)
|
||||
{
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
/* Query the security package for Kerberos */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
|
||||
TEXT(SP_NAME_KERBEROS),
|
||||
&SecurityPackage);
|
||||
|
||||
return (status == SEC_E_OK ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_create_gssapi_user_message()
|
||||
*
|
||||
|
||||
@@ -216,6 +216,20 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
|
||||
from the beginning of the NTLM message.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Curl_auth_is_ntlm_supported()
|
||||
*
|
||||
* This is used to evaluate if NTLM is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE as NTLM as handled by libcurl.
|
||||
*/
|
||||
bool Curl_auth_is_ntlm_supported(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_decode_ntlm_type2_message()
|
||||
*
|
||||
|
||||
@@ -37,6 +37,27 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_auth_is_ntlm_supported()
|
||||
*
|
||||
* This is used to evaluate if NTLM is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE if NTLM is supported by Windows SSPI.
|
||||
*/
|
||||
bool Curl_auth_is_ntlm_supported(void)
|
||||
{
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
/* Query the security package for NTLM */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM),
|
||||
&SecurityPackage);
|
||||
|
||||
return (status == SEC_E_OK ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_create_ntlm_type1_message()
|
||||
*
|
||||
|
||||
@@ -40,6 +40,20 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_auth_is_spnego_supported()
|
||||
*
|
||||
* This is used to evaluate if SPNEGO (Negotiate) is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE if Negotiate supported by the GSS-API library.
|
||||
*/
|
||||
bool Curl_auth_is_spnego_supported(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_decode_spnego_message()
|
||||
*
|
||||
|
||||
@@ -39,6 +39,28 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_auth_is_spnego_supported()
|
||||
*
|
||||
* This is used to evaluate if SPNEGO (Negotiate) is supported.
|
||||
*
|
||||
* Parameters: None
|
||||
*
|
||||
* Returns TRUE if Negotiate is supported by Windows SSPI.
|
||||
*/
|
||||
bool Curl_auth_is_spnego_supported(void)
|
||||
{
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
/* Query the security package for Negotiate */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
|
||||
TEXT(SP_NAME_NEGOTIATE),
|
||||
&SecurityPackage);
|
||||
|
||||
return (status == SEC_E_OK ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_auth_decode_spnego_message()
|
||||
*
|
||||
@@ -249,8 +271,10 @@ CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!*outptr || !*outlen)
|
||||
if(!*outptr || !*outlen) {
|
||||
free(*outptr);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -104,3 +104,44 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
|
||||
}
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
|
||||
/*
|
||||
* Curl_auth_user_contains_domain()
|
||||
*
|
||||
* This is used to test if the specified user contains a Windows domain name as
|
||||
* follows:
|
||||
*
|
||||
* User\Domain (Down-level Logon Name)
|
||||
* User/Domain (curl Down-level format - for compatibility with existing code)
|
||||
* User@Domain (User Principal Name)
|
||||
*
|
||||
* Note: The user name may be empty when using a GSS-API library or Windows SSPI
|
||||
* as the user and domain are either obtained from the credientals cache when
|
||||
* using GSS-API or via the currently logged in user's credientals when using
|
||||
* Windows SSPI.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* user [in] - The user name.
|
||||
*
|
||||
* Returns TRUE on success; otherwise FALSE.
|
||||
*/
|
||||
bool Curl_auth_user_contains_domain(const char *user)
|
||||
{
|
||||
bool valid = FALSE;
|
||||
|
||||
if(user && *user) {
|
||||
/* Check we have a domain name or UPN present */
|
||||
char *p = strpbrk(user, "\\/@");
|
||||
|
||||
valid = (p != NULL && p > user && p < user + strlen(user) - 1 ? TRUE :
|
||||
FALSE);
|
||||
}
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
else
|
||||
/* User and domain are obtained from the GSS-API credientials cache or the
|
||||
currently logged in user from Windows */
|
||||
valid = TRUE;
|
||||
#endif
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host,
|
||||
const char *realm);
|
||||
#endif
|
||||
|
||||
/* This is used to test if the user contains a Windows domain name */
|
||||
bool Curl_auth_user_contains_domain(const char *user);
|
||||
|
||||
/* This is used to generate a base64 encoded PLAIN cleartext message */
|
||||
CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
|
||||
const char *userp,
|
||||
@@ -83,6 +86,9 @@ CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
|
||||
const char *passwdp,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
/* This is used to evaluate if DIGEST is supported */
|
||||
bool Curl_auth_is_digest_supported(void);
|
||||
|
||||
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
||||
CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
const char *chlg64,
|
||||
@@ -109,6 +115,9 @@ void Curl_auth_digest_cleanup(struct digestdata *digest);
|
||||
#endif /* !CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
/* This is used to evaluate if NTLM is supported */
|
||||
bool Curl_auth_is_ntlm_supported(void);
|
||||
|
||||
/* This is used to generate a base64 encoded NTLM type-1 message */
|
||||
CURLcode Curl_auth_create_ntlm_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
@@ -140,6 +149,9 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
|
||||
const char *bearer,
|
||||
char **outptr, size_t *outlen);
|
||||
#if defined(USE_KERBEROS5)
|
||||
/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */
|
||||
bool Curl_auth_is_gssapi_supported(void);
|
||||
|
||||
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
|
||||
message */
|
||||
CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
|
||||
@@ -165,6 +177,9 @@ void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5);
|
||||
#endif /* USE_KERBEROS5 */
|
||||
|
||||
#if defined(USE_SPNEGO)
|
||||
/* This is used to evaluate if SPNEGO (Negotiate) is supported */
|
||||
bool Curl_auth_is_spnego_supported(void);
|
||||
|
||||
/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge
|
||||
message */
|
||||
CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
# include <ares.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
#include <stringprep.h>
|
||||
#ifdef USE_LIBIDN2
|
||||
#include <idn2.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBPSL
|
||||
@@ -111,9 +111,9 @@ char *curl_version(void)
|
||||
left -= len;
|
||||
ptr += len;
|
||||
#endif
|
||||
#ifdef USE_LIBIDN
|
||||
if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
|
||||
len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL));
|
||||
#ifdef USE_LIBIDN2
|
||||
if(idn2_check_version(IDN2_VERSION)) {
|
||||
len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
|
||||
left -= len;
|
||||
ptr += len;
|
||||
}
|
||||
@@ -365,10 +365,10 @@ curl_version_info_data *curl_version_info(CURLversion stamp)
|
||||
version_info.ares_num = aresnum;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_LIBIDN
|
||||
#ifdef USE_LIBIDN2
|
||||
/* This returns a version string if we use the given version or later,
|
||||
otherwise it returns NULL */
|
||||
version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION);
|
||||
version_info.libidn = idn2_check_version(IDN2_VERSION);
|
||||
if(version_info.libidn)
|
||||
version_info.features |= CURL_VERSION_IDN;
|
||||
#elif defined(USE_WIN32_IDN)
|
||||
|
||||
@@ -579,8 +579,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
|
||||
if(connssl->ssl) {
|
||||
int what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
|
||||
if(what > 0) {
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server. buf is managed internally by
|
||||
|
||||
@@ -55,7 +55,7 @@ and that's a problem since options.h hasn't been included yet. */
|
||||
#include "parsedate.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "x509asn1.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
@@ -118,9 +118,9 @@ static int do_file_type(const char *type)
|
||||
{
|
||||
if(!type || !type[0])
|
||||
return SSL_FILETYPE_PEM;
|
||||
if(Curl_raw_equal(type, "PEM"))
|
||||
if(strcasecompare(type, "PEM"))
|
||||
return SSL_FILETYPE_PEM;
|
||||
if(Curl_raw_equal(type, "DER"))
|
||||
if(strcasecompare(type, "DER"))
|
||||
return SSL_FILETYPE_ASN1;
|
||||
return -1;
|
||||
}
|
||||
@@ -803,7 +803,8 @@ cyassl_connect_common(struct connectdata *conn,
|
||||
curl_socket_t readfd = ssl_connect_2_reading==
|
||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||
|
||||
what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
|
||||
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
|
||||
nonblocking?0:timeout_ms);
|
||||
if(what < 0) {
|
||||
/* fatal error */
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2016, 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
|
||||
@@ -920,7 +920,7 @@ static OSStatus CopyIdentityWithLabel(char *label,
|
||||
#if CURL_SUPPORT_MAC_10_6
|
||||
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
|
||||
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
|
||||
#endif /* CURL_SUPPORT_MAC_10_7 */
|
||||
#endif /* CURL_SUPPORT_MAC_10_6 */
|
||||
}
|
||||
#elif CURL_SUPPORT_MAC_10_6
|
||||
/* For developers building on older cats, we have no choice but to fall back
|
||||
@@ -955,7 +955,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
|
||||
|
||||
/* Here we go: */
|
||||
status = SecPKCS12Import(pkcs_data, options, &items);
|
||||
if(status == noErr && items && CFArrayGetCount(items)) {
|
||||
if(status == errSecSuccess && items && CFArrayGetCount(items)) {
|
||||
CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
|
||||
const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
|
||||
kSecImportItemIdentity);
|
||||
@@ -1438,6 +1438,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
/* Disable IDEA: */
|
||||
case SSL_RSA_WITH_IDEA_CBC_SHA:
|
||||
case SSL_RSA_WITH_IDEA_CBC_MD5:
|
||||
/* Disable RC4: */
|
||||
case SSL_RSA_WITH_RC4_128_MD5:
|
||||
case SSL_RSA_WITH_RC4_128_SHA:
|
||||
case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
|
||||
case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
|
||||
case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
|
||||
case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
|
||||
case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
|
||||
case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
|
||||
case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
|
||||
break;
|
||||
default: /* enable everything else */
|
||||
allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
|
||||
@@ -2140,7 +2150,8 @@ darwinssl_connect_common(struct connectdata *conn,
|
||||
curl_socket_t readfd = ssl_connect_2_reading ==
|
||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||
|
||||
what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
|
||||
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
|
||||
nonblocking?0:timeout_ms);
|
||||
if(what < 0) {
|
||||
/* fatal error */
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
@@ -2262,8 +2273,7 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
rc = 0;
|
||||
|
||||
what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
|
||||
|
||||
for(;;) {
|
||||
if(what < 0) {
|
||||
@@ -2291,7 +2301,7 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
|
||||
if(nread <= 0)
|
||||
break;
|
||||
|
||||
what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
|
||||
what = SOCKET_READABLE(conn->sock[sockindex], 0);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, 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
|
||||
@@ -72,7 +72,7 @@
|
||||
#include "vtls.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "x509asn1.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
@@ -1001,8 +1001,8 @@ int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
close_one(connssl, data);
|
||||
rc = 0;
|
||||
what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
what = SOCKET_READABLE(conn->sock[sockindex],
|
||||
SSL_SHUTDOWN_TIMEOUT);
|
||||
|
||||
for(;;) {
|
||||
if(what < 0) {
|
||||
@@ -1031,7 +1031,7 @@ int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
if(nread <= 0)
|
||||
break;
|
||||
|
||||
what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
|
||||
what = SOCKET_READABLE(conn->sock[sockindex], 0);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#include "parsedate.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
#include "x509asn1.h"
|
||||
#include "curl_printf.h"
|
||||
@@ -289,7 +289,7 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
curl_socket_t readfd = ssl_connect_2_reading==
|
||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||
|
||||
what = Curl_socket_ready(readfd, writefd,
|
||||
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
|
||||
nonblocking?0:
|
||||
timeout_ms?timeout_ms:1000);
|
||||
if(what < 0) {
|
||||
@@ -356,9 +356,9 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type)
|
||||
{
|
||||
if(!type || !type[0])
|
||||
return GNUTLS_X509_FMT_PEM;
|
||||
if(Curl_raw_equal(type, "PEM"))
|
||||
if(strcasecompare(type, "PEM"))
|
||||
return GNUTLS_X509_FMT_PEM;
|
||||
if(Curl_raw_equal(type, "DER"))
|
||||
if(strcasecompare(type, "DER"))
|
||||
return GNUTLS_X509_FMT_DER;
|
||||
return -1;
|
||||
}
|
||||
@@ -1445,8 +1445,8 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(conn->ssl[sockindex].session) {
|
||||
while(!done) {
|
||||
int what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
int what = SOCKET_READABLE(conn->sock[sockindex],
|
||||
SSL_SHUTDOWN_TIMEOUT);
|
||||
if(what > 0) {
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server */
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#ifdef USE_MBEDTLS
|
||||
|
||||
#include <mbedtls/net.h>
|
||||
#include <mbedtls/net_sockets.h>
|
||||
#include <mbedtls/ssl.h>
|
||||
#include <mbedtls/certs.h>
|
||||
#include <mbedtls/x509.h>
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "parsedate.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "polarssl_threadlock.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
@@ -420,7 +419,15 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_DEBUG
|
||||
/* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
|
||||
mbedtls_ssl_conf_dbg(&connssl->config, mbed_debug, data);
|
||||
/* - 0 No debug
|
||||
* - 1 Error
|
||||
* - 2 State change
|
||||
* - 3 Informational
|
||||
* - 4 Verbose
|
||||
*/
|
||||
mbedtls_debug_set_threshold(4);
|
||||
#endif
|
||||
|
||||
connssl->connecting_state = ssl_connect_2;
|
||||
@@ -765,7 +772,8 @@ mbed_connect_common(struct connectdata *conn,
|
||||
curl_socket_t readfd = ssl_connect_2_reading==
|
||||
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
|
||||
|
||||
what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
|
||||
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
|
||||
nonblocking ? 0 : timeout_ms);
|
||||
if(what < 0) {
|
||||
/* fatal error */
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "formdata.h" /* for the boundary function */
|
||||
#include "url.h" /* for the ssl config check function */
|
||||
#include "connect.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "select.h"
|
||||
#include "vtls.h"
|
||||
#include "llist.h"
|
||||
@@ -64,7 +64,7 @@
|
||||
#include <ocsp.h>
|
||||
#endif
|
||||
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "warnless.h"
|
||||
#include "x509asn1.h"
|
||||
|
||||
@@ -78,13 +78,12 @@
|
||||
#define SLOTSIZE 13
|
||||
|
||||
PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
|
||||
|
||||
PRLock * nss_initlock = NULL;
|
||||
PRLock * nss_crllock = NULL;
|
||||
struct curl_llist *nss_crl_list = NULL;
|
||||
NSSInitContext * nss_context = NULL;
|
||||
|
||||
volatile int initialized = 0;
|
||||
static PRLock *nss_initlock = NULL;
|
||||
static PRLock *nss_crllock = NULL;
|
||||
static PRLock *nss_findslot_lock = NULL;
|
||||
static struct curl_llist *nss_crl_list = NULL;
|
||||
static NSSInitContext *nss_context = NULL;
|
||||
static volatile int initialized = 0;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
@@ -150,7 +149,7 @@ static const cipher_s cipherlist[] = {
|
||||
{"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
|
||||
{"echde_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA},
|
||||
{"ecdhe_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA},
|
||||
{"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
||||
{"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
|
||||
@@ -180,10 +179,29 @@ static const cipher_s cipherlist[] = {
|
||||
{"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
{"ecdh_rsa_aes_128_gcm_sha_256", TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
|
||||
#endif
|
||||
#ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
/* cipher suites using SHA384 */
|
||||
{"rsa_aes_256_gcm_sha_384", TLS_RSA_WITH_AES_256_GCM_SHA384},
|
||||
{"dhe_rsa_aes_256_gcm_sha_384", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
|
||||
{"dhe_dss_aes_256_gcm_sha_384", TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},
|
||||
{"ecdhe_ecdsa_aes_256_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
|
||||
{"ecdhe_rsa_aes_256_sha_384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
|
||||
{"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
|
||||
{"ecdhe_rsa_aes_256_gcm_sha_384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
|
||||
#endif
|
||||
#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
/* chacha20-poly1305 cipher suites */
|
||||
{"ecdhe_rsa_chacha20_poly1305_sha_256",
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
|
||||
{"ecdhe_ecdsa_chacha20_poly1305_sha_256",
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
|
||||
{"dhe_rsa_chacha20_poly1305_sha_256",
|
||||
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char* pem_library = "libnsspem.so";
|
||||
SECMODModule* mod = NULL;
|
||||
static SECMODModule* mod = NULL;
|
||||
|
||||
/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
|
||||
static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
|
||||
@@ -243,7 +261,7 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
|
||||
found = PR_FALSE;
|
||||
|
||||
for(i=0; i<NUM_OF_CIPHERS; i++) {
|
||||
if(Curl_raw_equal(cipher, cipherlist[i].name)) {
|
||||
if(strcasecompare(cipher, cipherlist[i].name)) {
|
||||
cipher_state[i] = PR_TRUE;
|
||||
found = PR_TRUE;
|
||||
break;
|
||||
@@ -340,6 +358,19 @@ static char* dup_nickname(struct Curl_easy *data, enum dupstring cert_kind)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Lock/unlock wrapper for PK11_FindSlotByName() to work around race condition
|
||||
* in nssSlot_IsTokenPresent() causing spurious SEC_ERROR_NO_TOKEN. For more
|
||||
* details, go to <https://bugzilla.mozilla.org/1297397>.
|
||||
*/
|
||||
static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
|
||||
{
|
||||
PK11SlotInfo *slot;
|
||||
PR_Lock(nss_initlock);
|
||||
slot = PK11_FindSlotByName(slot_name);
|
||||
PR_Unlock(nss_initlock);
|
||||
return slot;
|
||||
}
|
||||
|
||||
/* Call PK11_CreateGenericObject() with the given obj_class and filename. If
|
||||
* the call succeeds, append the object handle to the list of objects so that
|
||||
* the object can be destroyed in Curl_nss_close(). */
|
||||
@@ -362,7 +393,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
if(!slot_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
slot = PK11_FindSlotByName(slot_name);
|
||||
slot = nss_find_slot_by_name(slot_name);
|
||||
free(slot_name);
|
||||
if(!slot)
|
||||
return result;
|
||||
@@ -563,7 +594,7 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
|
||||
return result;
|
||||
}
|
||||
|
||||
slot = PK11_FindSlotByName("PEM Token #1");
|
||||
slot = nss_find_slot_by_name("PEM Token #1");
|
||||
if(!slot)
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
@@ -1013,7 +1044,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||
struct CERTCertificateStr *cert;
|
||||
struct SECKEYPrivateKeyStr *key;
|
||||
|
||||
PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
|
||||
PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
|
||||
if(NULL == slot) {
|
||||
failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
|
||||
return SECFailure;
|
||||
@@ -1249,6 +1280,7 @@ int Curl_nss_init(void)
|
||||
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
|
||||
nss_initlock = PR_NewLock();
|
||||
nss_crllock = PR_NewLock();
|
||||
nss_findslot_lock = PR_NewLock();
|
||||
}
|
||||
|
||||
/* We will actually initialize NSS later */
|
||||
@@ -1303,6 +1335,7 @@ void Curl_nss_cleanup(void)
|
||||
|
||||
PR_DestroyLock(nss_initlock);
|
||||
PR_DestroyLock(nss_crllock);
|
||||
PR_DestroyLock(nss_findslot_lock);
|
||||
nss_initlock = NULL;
|
||||
|
||||
initialized = 0;
|
||||
@@ -1888,8 +1921,11 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
|
||||
const bool blocking = (done == NULL);
|
||||
CURLcode result;
|
||||
|
||||
if(connssl->state == ssl_connection_complete)
|
||||
if(connssl->state == ssl_connection_complete) {
|
||||
if(!blocking)
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(connssl->connecting_state == ssl_connect_1) {
|
||||
result = nss_setup_connect(conn, sockindex);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user