mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2019-05-22 (885ce314)
This commit is contained in:
@@ -240,6 +240,7 @@ int main()
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)inet_ntoa_r;
|
||||
(void)func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -255,6 +256,7 @@ int main()
|
||||
#ifndef inet_ntoa_r
|
||||
func_type func;
|
||||
func = (func_type)&inet_ntoa_r;
|
||||
(void)func;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -553,8 +555,8 @@ main() {
|
||||
#include <time.h>
|
||||
int
|
||||
main() {
|
||||
struct timespec ts = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
struct timespec ts = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -565,3 +567,49 @@ main() {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_VARIADIC_MACROS_C99
|
||||
#define c99_vmacro3(first, ...) fun3(first, __VA_ARGS__)
|
||||
#define c99_vmacro2(first, ...) fun2(first, __VA_ARGS__)
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3);
|
||||
int fun2(int arg1, int arg2);
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3) {
|
||||
return arg1 + arg2 + arg3;
|
||||
}
|
||||
int fun2(int arg1, int arg2) {
|
||||
return arg1 + arg2;
|
||||
}
|
||||
|
||||
int
|
||||
main() {
|
||||
int res3 = c99_vmacro3(1, 2, 3);
|
||||
int res2 = c99_vmacro2(1, 2);
|
||||
(void)res3;
|
||||
(void)res2;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_VARIADIC_MACROS_GCC
|
||||
#define gcc_vmacro3(first, args...) fun3(first, args)
|
||||
#define gcc_vmacro2(first, args...) fun2(first, args)
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3);
|
||||
int fun2(int arg1, int arg2);
|
||||
|
||||
int fun3(int arg1, int arg2, int arg3) {
|
||||
return arg1 + arg2 + arg3;
|
||||
}
|
||||
int fun2(int arg1, int arg2) {
|
||||
return arg1 + arg2;
|
||||
}
|
||||
|
||||
int
|
||||
main() {
|
||||
int res3 = gcc_vmacro3(1, 2, 3);
|
||||
int res2 = gcc_vmacro2(1, 2);
|
||||
(void)res3;
|
||||
(void)res2;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -68,7 +68,7 @@ if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approac
|
||||
# should also work in an odd case when multiple directories are given
|
||||
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
|
||||
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
|
||||
|
||||
foreach(_flag ${_GSS_CFLAGS})
|
||||
if(_flag MATCHES "^-I.*")
|
||||
@@ -91,7 +91,7 @@ if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approac
|
||||
# this script gives us libraries and link directories. Blah. We have to deal with it.
|
||||
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
|
||||
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
|
||||
|
||||
foreach(_flag ${_GSS_LIB_FLAGS})
|
||||
if(_flag MATCHES "^-l.*")
|
||||
|
||||
@@ -24,6 +24,8 @@ else()
|
||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
endif()
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
check_c_source_compiles("${_source_epilogue}
|
||||
int main(void) {
|
||||
recv(0, 0, 0, 0);
|
||||
@@ -177,23 +179,6 @@ int main(void) {
|
||||
return 0;
|
||||
}" HAVE_STRUCT_TIMEVAL)
|
||||
|
||||
|
||||
include(CheckCSourceRuns)
|
||||
# See HAVE_POLL in CMakeLists.txt for why poll is disabled on macOS
|
||||
if(NOT APPLE)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(HAVE_SYS_POLL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
|
||||
endif()
|
||||
check_c_source_runs("
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
#endif
|
||||
int main(void) {
|
||||
return poll((void *)0, 0, 10 /*ms*/);
|
||||
}" HAVE_POLL_FINE)
|
||||
endif()
|
||||
|
||||
set(HAVE_SIG_ATOMIC_T 1)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(HAVE_SIGNAL_H)
|
||||
@@ -229,3 +214,51 @@ check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
|
||||
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
|
||||
endif()
|
||||
|
||||
unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
|
||||
|
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
# if not cross-compilation...
|
||||
include(CheckCSourceRuns)
|
||||
set(CMAKE_REQUIRED_FLAGS "")
|
||||
if(HAVE_SYS_POLL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
|
||||
elseif(HAVE_POLL_H)
|
||||
set(CMAKE_REQUIRED_FLAGS "-DHAVE_POLL_H")
|
||||
endif()
|
||||
check_c_source_runs("
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
#elif HAVE_POLL_H
|
||||
# include <poll.h>
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(0 != poll(0, 0, 10)) {
|
||||
return 1; /* fail */
|
||||
}
|
||||
else {
|
||||
/* detect the 10.12 poll() breakage */
|
||||
struct timeval before, after;
|
||||
int rc;
|
||||
size_t us;
|
||||
|
||||
gettimeofday(&before, NULL);
|
||||
rc = poll(NULL, 0, 500);
|
||||
gettimeofday(&after, NULL);
|
||||
|
||||
us = (after.tv_sec - before.tv_sec) * 1000000 +
|
||||
(after.tv_usec - before.tv_usec);
|
||||
|
||||
if(us < 400000) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}" HAVE_POLL_FINE)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ endif()
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -143,7 +143,6 @@ string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
|
||||
CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
|
||||
string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
|
||||
|
||||
include_regular_expression("^.*$") # Sukender: Is it necessary?
|
||||
|
||||
# Setup package meta-data
|
||||
# SET(PACKAGE "curl")
|
||||
@@ -158,7 +157,6 @@ endif()
|
||||
set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
|
||||
set(OS "\"${CMAKE_SYSTEM_NAME}\"")
|
||||
|
||||
include_directories(${PROJECT_BINARY_DIR}/include/curl)
|
||||
include_directories(${CURL_SOURCE_DIR}/include)
|
||||
|
||||
option(CURL_WERROR "Turn compiler warnings into errors" OFF)
|
||||
@@ -193,11 +191,7 @@ endif()
|
||||
|
||||
if(ENABLE_DEBUG)
|
||||
# DEBUGBUILD will be defined only for Debug builds
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.0)
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
|
||||
else()
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG DEBUGBUILD)
|
||||
endif()
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
|
||||
set(ENABLE_CURLDEBUG ON)
|
||||
endif()
|
||||
|
||||
@@ -393,10 +387,10 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
# check SSL libraries
|
||||
# TODO support GNUTLS, NSS, POLARSSL, AXTLS, CYASSL
|
||||
# TODO support GNUTLS, NSS, POLARSSL, CYASSL
|
||||
|
||||
if(APPLE)
|
||||
option(CMAKE_USE_DARWINSSL "enable Apple OS native SSL/TLS" OFF)
|
||||
option(CMAKE_USE_SECTRANSP "enable Apple OS native SSL/TLS" OFF)
|
||||
endif()
|
||||
if(WIN32)
|
||||
option(CMAKE_USE_WINSSL "enable Windows native SSL/TLS" OFF)
|
||||
@@ -406,13 +400,13 @@ endif()
|
||||
option(CMAKE_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF)
|
||||
|
||||
set(openssl_default ON)
|
||||
if(WIN32 OR CMAKE_USE_DARWINSSL OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
|
||||
if(WIN32 OR CMAKE_USE_SECTRANSP OR CMAKE_USE_WINSSL OR CMAKE_USE_MBEDTLS)
|
||||
set(openssl_default OFF)
|
||||
endif()
|
||||
|
||||
count_true(enabled_ssl_options_count
|
||||
CMAKE_USE_WINSSL
|
||||
CMAKE_USE_DARWINSSL
|
||||
CMAKE_USE_SECTRANSP
|
||||
CMAKE_USE_OPENSSL
|
||||
CMAKE_USE_MBEDTLS
|
||||
)
|
||||
@@ -432,6 +426,10 @@ if(CURL_WINDOWS_SSPI)
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_DARWINSSL)
|
||||
message(FATAL_ERROR "The cmake option CMAKE_USE_DARWINSSL was renamed to CMAKE_USE_SECTRANSP.")
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_SECTRANSP)
|
||||
find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
|
||||
if(NOT COREFOUNDATION_FRAMEWORK)
|
||||
message(FATAL_ERROR "CoreFoundation framework not found")
|
||||
@@ -443,7 +441,7 @@ if(CMAKE_USE_DARWINSSL)
|
||||
endif()
|
||||
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_DARWINSSL ON)
|
||||
set(USE_SECTRANSP ON)
|
||||
list(APPEND CURL_LIBS "${COREFOUNDATION_FRAMEWORK}" "${SECURITY_FRAMEWORK}")
|
||||
endif()
|
||||
|
||||
@@ -578,6 +576,7 @@ if(NOT CURL_DISABLE_LDAP)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
|
||||
endif()
|
||||
check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
if(NOT_NEED_LBER_H)
|
||||
set(NEED_LBER_H OFF)
|
||||
@@ -685,6 +684,7 @@ if(CMAKE_USE_LIBSSH2)
|
||||
check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64)
|
||||
check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "")
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -699,7 +699,7 @@ if(CMAKE_USE_GSSAPI)
|
||||
|
||||
message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
|
||||
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIRECTORIES})
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIR})
|
||||
check_include_file_concat("gssapi/gssapi.h" HAVE_GSSAPI_GSSAPI_H)
|
||||
check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
|
||||
check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
|
||||
@@ -732,10 +732,11 @@ if(CMAKE_USE_GSSAPI)
|
||||
if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
|
||||
set(HAVE_OLD_GSSMIT ON)
|
||||
endif()
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
endif()
|
||||
|
||||
include_directories(${GSS_INCLUDE_DIRECTORIES})
|
||||
include_directories(${GSS_INCLUDE_DIR})
|
||||
link_directories(${GSS_LINK_DIRECTORIES})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
|
||||
@@ -942,12 +943,8 @@ endif()
|
||||
|
||||
check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME)
|
||||
check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
|
||||
# poll on macOS is unreliable, it first did not exist, then was broken until
|
||||
# fixed in 10.9 only to break again in 10.12.
|
||||
if(NOT APPLE)
|
||||
check_symbol_exists(poll "${CURL_INCLUDES}" HAVE_POLL)
|
||||
endif()
|
||||
check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT)
|
||||
check_symbol_exists(poll "${CURL_INCLUDES}" HAVE_POLL)
|
||||
check_symbol_exists(strdup "${CURL_INCLUDES}" HAVE_STRDUP)
|
||||
check_symbol_exists(strstr "${CURL_INCLUDES}" HAVE_STRSTR)
|
||||
check_symbol_exists(strtok_r "${CURL_INCLUDES}" HAVE_STRTOK_R)
|
||||
@@ -1003,6 +1000,8 @@ check_symbol_exists(freeifaddrs "${CURL_INCLUDES}" HAVE_FREEIFADDRS)
|
||||
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(getpeername "${CURL_INCLUDES}" HAVE_GETPEERNAME)
|
||||
check_symbol_exists(getsockname "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
|
||||
check_symbol_exists(getrlimit "${CURL_INCLUDES}" HAVE_GETRLIMIT)
|
||||
check_symbol_exists(setlocale "${CURL_INCLUDES}" HAVE_SETLOCALE)
|
||||
check_symbol_exists(setmode "${CURL_INCLUDES}" HAVE_SETMODE)
|
||||
@@ -1086,6 +1085,8 @@ foreach(CURL_TEST
|
||||
HAVE_INET_NTOA_R_DECL_REENTRANT
|
||||
HAVE_GETADDRINFO
|
||||
HAVE_FILE_OFFSET_BITS
|
||||
HAVE_VARIADIC_MACROS_C99
|
||||
HAVE_VARIADIC_MACROS_GCC
|
||||
)
|
||||
curl_internal_test(${CURL_TEST})
|
||||
endforeach()
|
||||
@@ -1247,7 +1248,7 @@ if(CURL_WERROR)
|
||||
endif()
|
||||
|
||||
# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
|
||||
function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE)
|
||||
function(transform_makefile_inc INPUT_FILE OUTPUT_FILE)
|
||||
file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
|
||||
string(REPLACE "$(top_srcdir)" "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
|
||||
@@ -1311,10 +1312,7 @@ endfunction()
|
||||
|
||||
# Clear list and try to detect available features
|
||||
set(_items)
|
||||
_add_if("WinSSL" SSL_ENABLED AND USE_WINDOWS_SSPI)
|
||||
_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL)
|
||||
_add_if("DarwinSSL" SSL_ENABLED AND USE_DARWINSSL)
|
||||
_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS)
|
||||
_add_if("SSL" SSL_ENABLED)
|
||||
_add_if("IPv6" ENABLE_IPV6)
|
||||
_add_if("unix-sockets" USE_UNIX_SOCKETS)
|
||||
_add_if("libz" HAVE_LIBZ)
|
||||
@@ -1332,7 +1330,7 @@ _add_if("Kerberos" NOT CURL_DISABLE_CRYPTO_AUTH AND
|
||||
(HAVE_GSSAPI OR USE_WINDOWS_SSPI))
|
||||
# NTLM support requires crypto function adaptions from various SSL libs
|
||||
# TODO alternative SSL libs tests for SSP1, GNUTLS, NSS
|
||||
if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_DARWINSSL OR USE_MBEDTLS))
|
||||
if(NOT CURL_DISABLE_CRYPTO_AUTH AND (USE_OPENSSL OR USE_WINDOWS_SSPI OR USE_SECTRANSP OR USE_MBEDTLS))
|
||||
_add_if("NTLM" 1)
|
||||
# TODO missing option (autoconf: --enable-ntlm-wb)
|
||||
_add_if("NTLM_WB" NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
|
||||
@@ -1371,10 +1369,24 @@ _add_if("SCP" USE_LIBSSH2)
|
||||
_add_if("SFTP" USE_LIBSSH2)
|
||||
_add_if("RTSP" NOT CURL_DISABLE_RTSP)
|
||||
_add_if("RTMP" USE_LIBRTMP)
|
||||
list(SORT _items)
|
||||
if(_items)
|
||||
list(SORT _items)
|
||||
endif()
|
||||
string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}")
|
||||
message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
|
||||
|
||||
# Clear list and collect SSL backends
|
||||
set(_items)
|
||||
_add_if("WinSSL" SSL_ENABLED AND USE_WINDOWS_SSPI)
|
||||
_add_if("OpenSSL" SSL_ENABLED AND USE_OPENSSL)
|
||||
_add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
|
||||
_add_if("mbedTLS" SSL_ENABLED AND USE_MBEDTLS)
|
||||
if(_items)
|
||||
list(SORT _items)
|
||||
endif()
|
||||
string(REPLACE ";" " " SSL_BACKENDS "${_items}")
|
||||
message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}")
|
||||
|
||||
# curl-config needs the following options to be set.
|
||||
set(CC "${CMAKE_C_COMPILER}")
|
||||
# TODO probably put a -D... options here?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2018, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
Copyright (c) 1996 - 2019, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||
contributors, see the THANKS file.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -91,6 +91,11 @@
|
||||
#include <support/SupportDefs.h>
|
||||
#endif
|
||||
|
||||
/* Compatibility for non-Clang compilers */
|
||||
#ifndef __has_declspec_attribute
|
||||
# define __has_declspec_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -109,7 +114,9 @@ typedef void CURLSH;
|
||||
|
||||
#ifdef CURL_STATICLIB
|
||||
# define CURL_EXTERN
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
|
||||
#elif defined(WIN32) || defined(__SYMBIAN32__) || \
|
||||
(__has_declspec_attribute(dllexport) && \
|
||||
__has_declspec_attribute(dllimport))
|
||||
# if defined(BUILDING_LIBCURL)
|
||||
# define CURL_EXTERN __declspec(dllexport)
|
||||
# else
|
||||
@@ -144,8 +151,8 @@ typedef enum {
|
||||
CURLSSLBACKEND_POLARSSL = 6,
|
||||
CURLSSLBACKEND_WOLFSSL = 7,
|
||||
CURLSSLBACKEND_SCHANNEL = 8,
|
||||
CURLSSLBACKEND_DARWINSSL = 9,
|
||||
CURLSSLBACKEND_AXTLS = 10,
|
||||
CURLSSLBACKEND_SECURETRANSPORT = 9,
|
||||
CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */
|
||||
CURLSSLBACKEND_MBEDTLS = 11,
|
||||
CURLSSLBACKEND_MESALINK = 12
|
||||
} curl_sslbackend;
|
||||
@@ -153,7 +160,10 @@ typedef enum {
|
||||
/* aliases for library clones and renames */
|
||||
#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL
|
||||
#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL
|
||||
|
||||
/* deprecated names: */
|
||||
#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
|
||||
#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT
|
||||
|
||||
struct curl_httppost {
|
||||
struct curl_httppost *next; /* next entry in the list */
|
||||
@@ -280,7 +290,7 @@ typedef enum {
|
||||
struct curl_fileinfo {
|
||||
char *filename;
|
||||
curlfiletype filetype;
|
||||
time_t time;
|
||||
time_t time; /* always zero! */
|
||||
unsigned int perm;
|
||||
int uid;
|
||||
int gid;
|
||||
@@ -355,11 +365,21 @@ typedef int (*curl_seek_callback)(void *instream,
|
||||
signal libcurl to pause sending data on the current transfer. */
|
||||
#define CURL_READFUNC_PAUSE 0x10000001
|
||||
|
||||
/* Return code for when the trailing headers' callback has terminated
|
||||
without any errors*/
|
||||
#define CURL_TRAILERFUNC_OK 0
|
||||
/* Return code for when was an error in the trailing header's list and we
|
||||
want to abort the request */
|
||||
#define CURL_TRAILERFUNC_ABORT 1
|
||||
|
||||
typedef size_t (*curl_read_callback)(char *buffer,
|
||||
size_t size,
|
||||
size_t nitems,
|
||||
void *instream);
|
||||
|
||||
typedef int (*curl_trailer_callback)(struct curl_slist **list,
|
||||
void *userdata);
|
||||
|
||||
typedef enum {
|
||||
CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
|
||||
CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
|
||||
@@ -585,9 +605,6 @@ typedef enum {
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
/* added in 7.62.0 */
|
||||
#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
|
||||
@@ -602,6 +619,9 @@ typedef enum {
|
||||
#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
|
||||
#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
|
||||
|
||||
/* The following were added in 7.62.0 */
|
||||
#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION
|
||||
|
||||
/* The following were added in 7.21.5, April 2011 */
|
||||
#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
|
||||
|
||||
@@ -861,6 +881,14 @@ typedef enum {
|
||||
#define CURLHEADER_UNIFIED 0
|
||||
#define CURLHEADER_SEPARATE (1<<0)
|
||||
|
||||
/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */
|
||||
#define CURLALTSVC_IMMEDIATELY (1<<0)
|
||||
#define CURLALTSVC_ALTUSED (1<<1)
|
||||
#define CURLALTSVC_READONLYFILE (1<<2)
|
||||
#define CURLALTSVC_H1 (1<<3)
|
||||
#define CURLALTSVC_H2 (1<<4)
|
||||
#define CURLALTSVC_H3 (1<<5)
|
||||
|
||||
/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
|
||||
#define CURLPROTO_HTTP (1<<0)
|
||||
#define CURLPROTO_HTTPS (1<<1)
|
||||
@@ -1872,6 +1900,27 @@ typedef enum {
|
||||
/* Time in ms between connection upkeep calls for long-lived connections. */
|
||||
CINIT(UPKEEP_INTERVAL_MS, LONG, 281),
|
||||
|
||||
/* Specify URL using CURL URL API. */
|
||||
CINIT(CURLU, OBJECTPOINT, 282),
|
||||
|
||||
/* add trailing data just after no more data is available */
|
||||
CINIT(TRAILERFUNCTION, FUNCTIONPOINT, 283),
|
||||
|
||||
/* pointer to be passed to HTTP_TRAILER_FUNCTION */
|
||||
CINIT(TRAILERDATA, OBJECTPOINT, 284),
|
||||
|
||||
/* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
|
||||
CINIT(HTTP09_ALLOWED, LONG, 285),
|
||||
|
||||
/* alt-svc control bitmask */
|
||||
CINIT(ALTSVC_CTRL, LONG, 286),
|
||||
|
||||
/* alt-svc cache file name to possibly read from/write to */
|
||||
CINIT(ALTSVC, STRINGPOINT, 287),
|
||||
|
||||
/* maximum age of a connection to consider it for reuse (in seconds) */
|
||||
CINIT(MAXAGE_CONN, LONG, 288),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -2734,6 +2783,7 @@ typedef struct {
|
||||
#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */
|
||||
#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */
|
||||
#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */
|
||||
#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,16 +26,16 @@
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2018 Daniel Stenberg, <daniel@haxx.se>."
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2019 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.62.0"
|
||||
#define LIBCURL_VERSION "7.65.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 62
|
||||
#define LIBCURL_VERSION_MINOR 65
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
@@ -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 0x073E00
|
||||
#define LIBCURL_VERSION_NUM 0x074100
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@@ -70,7 +70,7 @@
|
||||
*/
|
||||
#define LIBCURL_TIMESTAMP "[unreleased]"
|
||||
|
||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
|
||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z))
|
||||
#define CURL_AT_LEAST_VERSION(x,y,z) \
|
||||
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -113,7 +113,6 @@ __extension__ ({ \
|
||||
})
|
||||
|
||||
/* wraps curl_easy_getinfo() with typechecking */
|
||||
/* FIXME: don't allow const pointers */
|
||||
#define curl_easy_getinfo(handle, info, arg) \
|
||||
__extension__ ({ \
|
||||
__typeof__(info) _curl_info = info; \
|
||||
@@ -146,9 +145,8 @@ __extension__ ({ \
|
||||
curl_easy_getinfo(handle, _curl_info, arg); \
|
||||
})
|
||||
|
||||
/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
|
||||
* for now just make sure that the functions are called with three
|
||||
* arguments
|
||||
/*
|
||||
* For now, just make sure that the functions are called with three arguments
|
||||
*/
|
||||
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
|
||||
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
|
||||
@@ -256,6 +254,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
#define _curl_is_string_option(option) \
|
||||
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
|
||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
(option) == CURLOPT_ALTSVC || \
|
||||
(option) == CURLOPT_CAINFO || \
|
||||
(option) == CURLOPT_CAPATH || \
|
||||
(option) == CURLOPT_COOKIE || \
|
||||
@@ -363,6 +362,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
(option) == CURLOPT_SSL_CTX_DATA || \
|
||||
(option) == CURLOPT_WRITEDATA || \
|
||||
(option) == CURLOPT_RESOLVER_START_DATA || \
|
||||
(option) == CURLOPT_CURLU || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a POST data argument (void* or char*) */
|
||||
@@ -504,10 +504,6 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
|
||||
_curl_is_arr((expr), char) || \
|
||||
_curl_is_arr((expr), unsigned char))
|
||||
|
||||
/* FIXME: the whole callback checking is messy...
|
||||
* The idea is to tolerate char vs. void and const vs. not const
|
||||
* pointers in arguments at least
|
||||
*/
|
||||
/* helper: __builtin_types_compatible_p distinguishes between functions and
|
||||
* function pointers, hide it */
|
||||
#define _curl_callback_compatible(func, type) \
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2019, 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,6 +22,8 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -58,7 +60,8 @@ typedef enum {
|
||||
CURLUPART_PORT,
|
||||
CURLUPART_PATH,
|
||||
CURLUPART_QUERY,
|
||||
CURLUPART_FRAGMENT
|
||||
CURLUPART_FRAGMENT,
|
||||
CURLUPART_ZONEID /* added in 7.65.0 */
|
||||
} CURLUPart;
|
||||
|
||||
#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2019, 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,13 @@ LIB_VAUTH_CFILES = vauth/vauth.c vauth/cleartext.c vauth/cram.c \
|
||||
LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
|
||||
|
||||
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
|
||||
vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
|
||||
vtls/polarssl.c vtls/polarssl_threadlock.c \
|
||||
vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \
|
||||
vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
|
||||
vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c
|
||||
|
||||
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \
|
||||
vtls/cyassl.h vtls/schannel.h vtls/darwinssl.h vtls/gskit.h \
|
||||
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \
|
||||
vtls/cyassl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \
|
||||
vtls/mbedtls.h vtls/mesalink.h
|
||||
|
||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
@@ -52,10 +52,10 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
openldap.c curl_gethostname.c gopher.c idn_win32.c \
|
||||
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
|
||||
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c dotdot.c \
|
||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \
|
||||
mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \
|
||||
doh.c urlapi.c
|
||||
doh.c urlapi.c curl_get_line.c altsvc.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 \
|
||||
@@ -72,10 +72,11 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
|
||||
http_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
|
||||
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h dotdot.h \
|
||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
||||
curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \
|
||||
curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h
|
||||
curl_path.h curl_ctype.h curl_range.h psl.h doh.h urlapi-int.h \
|
||||
curl_get_line.h altsvc.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
|
||||
@@ -0,0 +1,569 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019, 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
* The Alt-Svc: header is defined in RFC 7838:
|
||||
* https://tools.ietf.org/html/rfc7838
|
||||
*/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
#include "altsvc.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "strcase.h"
|
||||
#include "parsedate.h"
|
||||
#include "sendf.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_ALTSVC_LINE 4095
|
||||
#define MAX_ALTSVC_DATELENSTR "64"
|
||||
#define MAX_ALTSVC_DATELEN 64
|
||||
#define MAX_ALTSVC_HOSTLENSTR "512"
|
||||
#define MAX_ALTSVC_HOSTLEN 512
|
||||
#define MAX_ALTSVC_ALPNLENSTR "10"
|
||||
#define MAX_ALTSVC_ALPNLEN 10
|
||||
|
||||
static enum alpnid alpn2alpnid(char *name)
|
||||
{
|
||||
if(strcasecompare(name, "h1"))
|
||||
return ALPN_h1;
|
||||
if(strcasecompare(name, "h2"))
|
||||
return ALPN_h2;
|
||||
if(strcasecompare(name, "h2c"))
|
||||
return ALPN_h2c;
|
||||
if(strcasecompare(name, "h3"))
|
||||
return ALPN_h3;
|
||||
return ALPN_none; /* unknown, probably rubbish input */
|
||||
}
|
||||
|
||||
/* Given the ALPN ID, return the name */
|
||||
const char *Curl_alpnid2str(enum alpnid id)
|
||||
{
|
||||
switch(id) {
|
||||
case ALPN_h1:
|
||||
return "h1";
|
||||
case ALPN_h2:
|
||||
return "h2";
|
||||
case ALPN_h2c:
|
||||
return "h2c";
|
||||
case ALPN_h3:
|
||||
return "h3";
|
||||
default:
|
||||
return ""; /* bad */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void altsvc_free(struct altsvc *as)
|
||||
{
|
||||
free(as->srchost);
|
||||
free(as->dsthost);
|
||||
free(as);
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_createid(const char *srchost,
|
||||
const char *dsthost,
|
||||
enum alpnid srcalpnid,
|
||||
enum alpnid dstalpnid,
|
||||
unsigned int srcport,
|
||||
unsigned int dstport)
|
||||
{
|
||||
struct altsvc *as = calloc(sizeof(struct altsvc), 1);
|
||||
if(!as)
|
||||
return NULL;
|
||||
|
||||
as->srchost = strdup(srchost);
|
||||
if(!as->srchost)
|
||||
goto error;
|
||||
as->dsthost = strdup(dsthost);
|
||||
if(!as->dsthost)
|
||||
goto error;
|
||||
|
||||
as->srcalpnid = srcalpnid;
|
||||
as->dstalpnid = dstalpnid;
|
||||
as->srcport = curlx_ultous(srcport);
|
||||
as->dstport = curlx_ultous(dstport);
|
||||
|
||||
return as;
|
||||
error:
|
||||
altsvc_free(as);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct altsvc *altsvc_create(char *srchost,
|
||||
char *dsthost,
|
||||
char *srcalpn,
|
||||
char *dstalpn,
|
||||
unsigned int srcport,
|
||||
unsigned int dstport)
|
||||
{
|
||||
enum alpnid dstalpnid = alpn2alpnid(dstalpn);
|
||||
enum alpnid srcalpnid = alpn2alpnid(srcalpn);
|
||||
if(!srcalpnid || !dstalpnid)
|
||||
return NULL;
|
||||
return altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid,
|
||||
srcport, dstport);
|
||||
}
|
||||
|
||||
/* only returns SERIOUS errors */
|
||||
static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
|
||||
{
|
||||
/* Example line:
|
||||
h2 example.com 443 h3 shiny.example.com 8443 "20191231 10:00:00" 1
|
||||
*/
|
||||
char srchost[MAX_ALTSVC_HOSTLEN + 1];
|
||||
char dsthost[MAX_ALTSVC_HOSTLEN + 1];
|
||||
char srcalpn[MAX_ALTSVC_ALPNLEN + 1];
|
||||
char dstalpn[MAX_ALTSVC_ALPNLEN + 1];
|
||||
char date[MAX_ALTSVC_DATELEN + 1];
|
||||
unsigned int srcport;
|
||||
unsigned int dstport;
|
||||
unsigned int prio;
|
||||
unsigned int persist;
|
||||
int rc;
|
||||
|
||||
rc = sscanf(line,
|
||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
||||
"%" MAX_ALTSVC_ALPNLENSTR "s %" MAX_ALTSVC_HOSTLENSTR "s %u "
|
||||
"\"%" MAX_ALTSVC_DATELENSTR "[^\"]\" %u %u",
|
||||
srcalpn, srchost, &srcport,
|
||||
dstalpn, dsthost, &dstport,
|
||||
date, &persist, &prio);
|
||||
if(9 == rc) {
|
||||
struct altsvc *as;
|
||||
time_t expires = curl_getdate(date, NULL);
|
||||
as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
|
||||
if(as) {
|
||||
as->expires = expires;
|
||||
as->prio = prio;
|
||||
as->persist = persist ? 1 : 0;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
asi->num++; /* one more entry */
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load alt-svc entries from the given file. The text based line-oriented file
|
||||
* format is documented here:
|
||||
* https://github.com/curl/curl/wiki/QUIC-implementation
|
||||
*
|
||||
* This function only returns error on major problems that prevents alt-svc
|
||||
* handling to work completely. It will ignore individual syntactical errors
|
||||
* etc.
|
||||
*/
|
||||
static CURLcode altsvc_load(struct altsvcinfo *asi, const char *file)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *line = NULL;
|
||||
FILE *fp = fopen(file, FOPEN_READTEXT);
|
||||
if(fp) {
|
||||
line = malloc(MAX_ALTSVC_LINE);
|
||||
if(!line)
|
||||
goto fail;
|
||||
while(Curl_get_line(line, MAX_ALTSVC_LINE, fp)) {
|
||||
char *lineptr = line;
|
||||
while(*lineptr && ISBLANK(*lineptr))
|
||||
lineptr++;
|
||||
if(*lineptr == '#')
|
||||
/* skip commented lines */
|
||||
continue;
|
||||
|
||||
altsvc_add(asi, lineptr);
|
||||
}
|
||||
free(line); /* free the line buffer */
|
||||
fclose(fp);
|
||||
}
|
||||
return result;
|
||||
|
||||
fail:
|
||||
free(line);
|
||||
fclose(fp);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write this single altsvc entry to a single output line
|
||||
*/
|
||||
|
||||
static CURLcode altsvc_out(struct altsvc *as, FILE *fp)
|
||||
{
|
||||
struct tm stamp;
|
||||
CURLcode result = Curl_gmtime(as->expires, &stamp);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
fprintf(fp,
|
||||
"%s %s %u "
|
||||
"%s %s %u "
|
||||
"\"%d%02d%02d "
|
||||
"%02d:%02d:%02d\" "
|
||||
"%u %d\n",
|
||||
Curl_alpnid2str(as->srcalpnid), as->srchost, as->srcport,
|
||||
Curl_alpnid2str(as->dstalpnid), as->dsthost, as->dstport,
|
||||
stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday,
|
||||
stamp.tm_hour, stamp.tm_min, stamp.tm_sec,
|
||||
as->persist, as->prio);
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* ---- library-wide functions below ---- */
|
||||
|
||||
/*
|
||||
* Curl_altsvc_init() creates a new altsvc cache.
|
||||
* It returns the new instance or NULL if something goes wrong.
|
||||
*/
|
||||
struct altsvcinfo *Curl_altsvc_init(void)
|
||||
{
|
||||
struct altsvcinfo *asi = calloc(sizeof(struct altsvcinfo), 1);
|
||||
if(!asi)
|
||||
return NULL;
|
||||
Curl_llist_init(&asi->list, NULL);
|
||||
|
||||
/* set default behavior */
|
||||
asi->flags = CURLALTSVC_H1
|
||||
#ifdef USE_NGHTTP2
|
||||
| CURLALTSVC_H2
|
||||
#endif
|
||||
#ifdef USE_HTTP3
|
||||
| CURLALTSVC_H3
|
||||
#endif
|
||||
;
|
||||
return asi;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_load() loads alt-svc from file.
|
||||
*/
|
||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file)
|
||||
{
|
||||
CURLcode result;
|
||||
DEBUGASSERT(asi);
|
||||
result = altsvc_load(asi, file);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_ctrl() passes on the external bitmask.
|
||||
*/
|
||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl)
|
||||
{
|
||||
DEBUGASSERT(asi);
|
||||
if(!ctrl)
|
||||
/* unexpected */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
asi->flags = ctrl;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_cleanup() frees an altsvc cache instance and all associated
|
||||
* resources.
|
||||
*/
|
||||
void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
if(altsvc) {
|
||||
for(e = altsvc->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
altsvc_free(as);
|
||||
}
|
||||
free(altsvc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_altsvc_save() writes the altsvc cache to a file.
|
||||
*/
|
||||
CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
CURLcode result = CURLE_OK;
|
||||
FILE *out;
|
||||
|
||||
if(!altsvc)
|
||||
/* no cache activated */
|
||||
return CURLE_OK;
|
||||
|
||||
if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0])
|
||||
/* marked as read-only or zero length file name */
|
||||
return CURLE_OK;
|
||||
out = fopen(file, FOPEN_WRITETEXT);
|
||||
if(!out)
|
||||
return CURLE_WRITE_ERROR;
|
||||
fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n"
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n",
|
||||
out);
|
||||
for(e = altsvc->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
result = altsvc_out(as, out);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
fclose(out);
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode getalnum(const char **ptr, char *alpnbuf, size_t buflen)
|
||||
{
|
||||
size_t len;
|
||||
const char *protop;
|
||||
const char *p = *ptr;
|
||||
while(*p && ISBLANK(*p))
|
||||
p++;
|
||||
protop = p;
|
||||
while(*p && ISALNUM(*p))
|
||||
p++;
|
||||
len = p - protop;
|
||||
|
||||
if(!len || (len >= buflen))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
memcpy(alpnbuf, protop, len);
|
||||
alpnbuf[len] = 0;
|
||||
*ptr = p;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* altsvc_flush() removes all alternatives for this source origin from the
|
||||
list */
|
||||
static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
|
||||
const char *srchost, unsigned short srcport)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
for(e = asi->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
if((srcalpnid == as->srcalpnid) &&
|
||||
(srcport == as->srcport) &&
|
||||
strcasecompare(srchost, as->srchost)) {
|
||||
Curl_llist_remove(&asi->list, e, NULL);
|
||||
altsvc_free(as);
|
||||
asi->num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
/* to play well with debug builds, we can *set* a fixed time this will
|
||||
return */
|
||||
static time_t debugtime(void *unused)
|
||||
{
|
||||
char *timestr = getenv("CURL_TIME");
|
||||
(void)unused;
|
||||
if(timestr) {
|
||||
unsigned long val = strtol(timestr, NULL, 10);
|
||||
return (time_t)val;
|
||||
}
|
||||
return time(NULL);
|
||||
}
|
||||
#define time(x) debugtime(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_altsvc_parse() takes an incoming alt-svc response header and stores
|
||||
* the data correctly in the cache.
|
||||
*
|
||||
* 'value' points to the header *value*. That's contents to the right of the
|
||||
* header name.
|
||||
*/
|
||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
struct altsvcinfo *asi, const char *value,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
unsigned short srcport)
|
||||
{
|
||||
const char *p = value;
|
||||
size_t len;
|
||||
enum alpnid dstalpnid = srcalpnid; /* the same by default */
|
||||
char namebuf[MAX_ALTSVC_HOSTLEN] = "";
|
||||
char alpnbuf[MAX_ALTSVC_ALPNLEN] = "";
|
||||
struct altsvc *as;
|
||||
unsigned short dstport = srcport; /* the same by default */
|
||||
const char *semip;
|
||||
time_t maxage = 24 * 3600; /* default is 24 hours */
|
||||
bool persist = FALSE;
|
||||
CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
DEBUGASSERT(asi);
|
||||
|
||||
/* Flush all cached alternatives for this source origin, if any */
|
||||
altsvc_flush(asi, srcalpnid, srchost, srcport);
|
||||
|
||||
/* "clear" is a magic keyword */
|
||||
if(strcasecompare(alpnbuf, "clear")) {
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* The 'ma' and 'persist' flags are annoyingly meant for all alternatives
|
||||
but are set after the list on the line. Scan for the semicolons and get
|
||||
those fields first! */
|
||||
semip = p;
|
||||
do {
|
||||
semip = strchr(semip, ';');
|
||||
if(semip) {
|
||||
char option[32];
|
||||
unsigned long num;
|
||||
char *end_ptr;
|
||||
semip++; /* pass the semicolon */
|
||||
result = getalnum(&semip, option, sizeof(option));
|
||||
if(result)
|
||||
break;
|
||||
while(*semip && ISBLANK(*semip))
|
||||
semip++;
|
||||
if(*semip != '=')
|
||||
continue;
|
||||
semip++;
|
||||
num = strtoul(semip, &end_ptr, 10);
|
||||
if(num < ULONG_MAX) {
|
||||
if(strcasecompare("ma", option))
|
||||
maxage = num;
|
||||
else if(strcasecompare("persist", option) && (num == 1))
|
||||
persist = TRUE;
|
||||
}
|
||||
semip = end_ptr;
|
||||
}
|
||||
} while(semip);
|
||||
|
||||
do {
|
||||
if(*p == '=') {
|
||||
/* [protocol]="[host][:port]" */
|
||||
dstalpnid = alpn2alpnid(alpnbuf);
|
||||
if(!dstalpnid) {
|
||||
infof(data, "Unknown alt-svc protocol \"%s\", ignoring...\n", alpnbuf);
|
||||
return CURLE_OK;
|
||||
}
|
||||
p++;
|
||||
if(*p == '\"') {
|
||||
const char *dsthost;
|
||||
p++;
|
||||
if(*p != ':') {
|
||||
/* host name starts here */
|
||||
const char *hostp = p;
|
||||
while(*p && (ISALNUM(*p) || (*p == '.') || (*p == '-')))
|
||||
p++;
|
||||
len = p - hostp;
|
||||
if(!len || (len >= MAX_ALTSVC_HOSTLEN))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
memcpy(namebuf, hostp, len);
|
||||
namebuf[len] = 0;
|
||||
dsthost = namebuf;
|
||||
}
|
||||
else {
|
||||
/* no destination name, use source host */
|
||||
dsthost = srchost;
|
||||
}
|
||||
if(*p == ':') {
|
||||
/* a port number */
|
||||
char *end_ptr;
|
||||
unsigned long port = strtoul(++p, &end_ptr, 10);
|
||||
if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
|
||||
infof(data, "Unknown alt-svc port number, ignoring...\n");
|
||||
return CURLE_OK;
|
||||
}
|
||||
p = end_ptr;
|
||||
dstport = curlx_ultous(port);
|
||||
}
|
||||
if(*p++ != '\"')
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
as = altsvc_createid(srchost, dsthost,
|
||||
srcalpnid, dstalpnid,
|
||||
srcport, dstport);
|
||||
if(as) {
|
||||
/* The expires time also needs to take the Age: value (if any) into
|
||||
account. [See RFC 7838 section 3.1] */
|
||||
as->expires = maxage + time(NULL);
|
||||
as->persist = persist;
|
||||
Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node);
|
||||
asi->num++; /* one more entry */
|
||||
infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport,
|
||||
Curl_alpnid2str(dstalpnid));
|
||||
}
|
||||
}
|
||||
/* after the double quote there can be a comma if there's another
|
||||
string or a semicolon if no more */
|
||||
if(*p == ',') {
|
||||
/* comma means another alternative is presented */
|
||||
p++;
|
||||
result = getalnum(&p, alpnbuf, sizeof(alpnbuf));
|
||||
if(result)
|
||||
/* failed to parse, but since we already did at least one host we
|
||||
return OK */
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
} while(*p && (*p != ';') && (*p != '\n') && (*p != '\r'));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE on a match
|
||||
*/
|
||||
bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
enum alpnid *dstalpnid, const char **dsthost,
|
||||
int *dstport)
|
||||
{
|
||||
struct curl_llist_element *e;
|
||||
struct curl_llist_element *n;
|
||||
time_t now = time(NULL);
|
||||
DEBUGASSERT(asi);
|
||||
DEBUGASSERT(srchost);
|
||||
DEBUGASSERT(dsthost);
|
||||
|
||||
for(e = asi->list.head; e; e = n) {
|
||||
struct altsvc *as = e->ptr;
|
||||
n = e->next;
|
||||
if(as->expires < now) {
|
||||
/* an expired entry, remove */
|
||||
altsvc_free(as);
|
||||
continue;
|
||||
}
|
||||
if((as->srcalpnid == srcalpnid) &&
|
||||
strcasecompare(as->srchost, srchost) &&
|
||||
as->srcport == srcport) {
|
||||
/* match */
|
||||
*dstalpnid = as->dstalpnid;
|
||||
*dsthost = as->dsthost;
|
||||
*dstport = as->dstport;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef HEADER_CURL_ALTSVC_H
|
||||
#define HEADER_CURL_ALTSVC_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2019, 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"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_ALTSVC)
|
||||
#include <curl/curl.h>
|
||||
#include "llist.h"
|
||||
|
||||
enum alpnid {
|
||||
ALPN_none,
|
||||
ALPN_h1,
|
||||
ALPN_h2,
|
||||
ALPN_h2c,
|
||||
ALPN_h3
|
||||
};
|
||||
|
||||
struct altsvc {
|
||||
char *srchost;
|
||||
char *dsthost;
|
||||
unsigned short srcport;
|
||||
unsigned short dstport;
|
||||
enum alpnid srcalpnid;
|
||||
enum alpnid dstalpnid;
|
||||
time_t expires;
|
||||
bool persist;
|
||||
int prio;
|
||||
struct curl_llist_element node;
|
||||
};
|
||||
|
||||
struct altsvcinfo {
|
||||
char *filename;
|
||||
struct curl_llist list; /* list of entries */
|
||||
size_t num; /* number of alt-svc entries */
|
||||
long flags; /* the publicly set bitmask */
|
||||
};
|
||||
|
||||
const char *Curl_alpnid2str(enum alpnid id);
|
||||
struct altsvcinfo *Curl_altsvc_init(void);
|
||||
CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
|
||||
CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
|
||||
CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
|
||||
void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
|
||||
CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
||||
struct altsvcinfo *altsvc, const char *value,
|
||||
enum alpnid srcalpn, const char *srchost,
|
||||
unsigned short srcport);
|
||||
bool Curl_altsvc_lookup(struct altsvcinfo *asi,
|
||||
enum alpnid srcalpnid, const char *srchost,
|
||||
int srcport,
|
||||
enum alpnid *dstalpnid, const char **dsthost,
|
||||
int *dstport);
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_altsvc_save(a,b)
|
||||
#endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
|
||||
#endif /* HEADER_CURL_ALTSVC_H */
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,17 +22,26 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(__AMIGA__) && !defined(__ixemul__)
|
||||
#ifdef __AMIGA__
|
||||
# include "amigaos.h"
|
||||
# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
|
||||
# include <amitcp/socketbasetags.h>
|
||||
# endif
|
||||
# ifdef __libnix__
|
||||
# include <stabs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <amitcp/socketbasetags.h>
|
||||
|
||||
#include "amigaos.h"
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef __AMIGA__
|
||||
#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL)
|
||||
struct Library *SocketBase = NULL;
|
||||
extern int errno, h_errno;
|
||||
|
||||
#ifdef __libnix__
|
||||
#include <stabs.h>
|
||||
void __request(const char *msg);
|
||||
#else
|
||||
# define __request(msg) Printf(msg "\n\a")
|
||||
@@ -74,4 +83,13 @@ bool Curl_amiga_init()
|
||||
ADD2EXIT(Curl_amiga_cleanup, -50);
|
||||
#endif
|
||||
|
||||
#endif /* __AMIGA__ && ! __ixemul__ */
|
||||
#endif /* HAVE_PROTO_BSDSOCKET_H */
|
||||
|
||||
#ifdef USE_AMISSL
|
||||
void Curl_amiga_X509_free(X509 *a)
|
||||
{
|
||||
X509_free(a);
|
||||
}
|
||||
#endif /* USE_AMISSL */
|
||||
#endif /* __AMIGA__ */
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -23,7 +23,7 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(__AMIGA__) && !defined(__ixemul__)
|
||||
#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL)
|
||||
|
||||
bool Curl_amiga_init();
|
||||
void Curl_amiga_cleanup();
|
||||
@@ -35,4 +35,10 @@ void Curl_amiga_cleanup();
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_AMISSL
|
||||
#include <openssl/x509v3.h>
|
||||
void Curl_amiga_X509_free(X509 *a);
|
||||
#endif /* USE_AMISSL */
|
||||
|
||||
#endif /* HEADER_CURL_AMIGAOS_H */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -68,7 +68,7 @@
|
||||
#include "progress.h"
|
||||
|
||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
||||
(defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
|
||||
(defined(WIN32) || defined(__SYMBIAN32__))
|
||||
# define CARES_STATICLIB
|
||||
# endif
|
||||
# include <ares.h>
|
||||
@@ -89,8 +89,20 @@ struct ResolverResults {
|
||||
int num_pending; /* number of ares_gethostbyname() requests */
|
||||
Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
|
||||
int last_status;
|
||||
struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */
|
||||
};
|
||||
|
||||
/* How long we are willing to wait for additional parallel responses after
|
||||
obtaining a "definitive" one.
|
||||
|
||||
This is intended to equal the c-ares default timeout. cURL always uses that
|
||||
default value. Unfortunately, c-ares doesn't expose its default timeout in
|
||||
its API, but it is officially documented as 5 seconds.
|
||||
|
||||
See query_completed_cb() for an explanation of how this is used.
|
||||
*/
|
||||
#define HAPPY_EYEBALLS_DNS_TIMEOUT 5000
|
||||
|
||||
/*
|
||||
* Curl_resolver_global_init() - the generic low-level asynchronous name
|
||||
* resolve API. Called from curl_global_init() to initialize global resolver
|
||||
@@ -119,6 +131,17 @@ void Curl_resolver_global_cleanup(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void Curl_ares_sock_state_cb(void *data, ares_socket_t socket_fd,
|
||||
int readable, int writable)
|
||||
{
|
||||
struct Curl_easy *easy = data;
|
||||
if(!readable && !writable) {
|
||||
DEBUGASSERT(easy);
|
||||
Curl_multi_closed(easy, socket_fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_init()
|
||||
*
|
||||
@@ -126,9 +149,14 @@ void Curl_resolver_global_cleanup(void)
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure). Fills the passed pointer by the initialized ares_channel.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(void **resolver)
|
||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
|
||||
{
|
||||
int status = ares_init((ares_channel*)resolver);
|
||||
int status;
|
||||
struct ares_options options;
|
||||
int optmask = ARES_OPT_SOCK_STATE_CB;
|
||||
options.sock_state_cb = Curl_ares_sock_state_cb;
|
||||
options.sock_state_cb_data = easy;
|
||||
status = ares_init_options((ares_channel*)resolver, &options, optmask);
|
||||
if(status != ARES_SUCCESS) {
|
||||
if(status == ARES_ENOMEM)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -159,12 +187,15 @@ void Curl_resolver_cleanup(void *resolver)
|
||||
* environment ('resolver' member of the UrlState structure). Duplicates the
|
||||
* 'from' ares channel and passes the resulting channel to the 'to' pointer.
|
||||
*/
|
||||
int Curl_resolver_duphandle(void **to, void *from)
|
||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
|
||||
{
|
||||
/* Clone the ares channel for the new handle */
|
||||
if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
|
||||
return CURLE_FAILED_INIT;
|
||||
return CURLE_OK;
|
||||
(void)from;
|
||||
/*
|
||||
* it would be better to call ares_dup instead, but right now
|
||||
* it is not possible to set 'sock_state_cb_data' outside of
|
||||
* ares_init_options
|
||||
*/
|
||||
return Curl_resolver_init(easy, to);
|
||||
}
|
||||
|
||||
static void destroy_async_data(struct Curl_async *async);
|
||||
@@ -179,6 +210,17 @@ void Curl_resolver_cancel(struct connectdata *conn)
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
/*
|
||||
* We're equivalent to Curl_resolver_cancel() for the c-ares resolver. We
|
||||
* never block.
|
||||
*/
|
||||
void Curl_resolver_kill(struct connectdata *conn)
|
||||
{
|
||||
/* We don't need to check the resolver state because we can be called safely
|
||||
at any time and we always do the same thing. */
|
||||
Curl_resolver_cancel(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy_async_data() cleans up async resolver data.
|
||||
*/
|
||||
@@ -289,9 +331,9 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
/* move through the descriptors and ask for processing on them */
|
||||
for(i = 0; i < num; i++)
|
||||
ares_process_fd((ares_channel)data->state.resolver,
|
||||
pfd[i].revents & (POLLRDNORM|POLLIN)?
|
||||
(pfd[i].revents & (POLLRDNORM|POLLIN))?
|
||||
pfd[i].fd:ARES_SOCKET_BAD,
|
||||
pfd[i].revents & (POLLWRNORM|POLLOUT)?
|
||||
(pfd[i].revents & (POLLWRNORM|POLLOUT))?
|
||||
pfd[i].fd:ARES_SOCKET_BAD);
|
||||
}
|
||||
return nfds;
|
||||
@@ -317,6 +359,29 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
|
||||
waitperform(conn, 0);
|
||||
|
||||
/* Now that we've checked for any last minute results above, see if there are
|
||||
any responses still pending when the EXPIRE_HAPPY_EYEBALLS_DNS timer
|
||||
expires. */
|
||||
if(res
|
||||
&& res->num_pending
|
||||
/* This is only set to non-zero if the timer was started. */
|
||||
&& (res->happy_eyeballs_dns_time.tv_sec
|
||||
|| res->happy_eyeballs_dns_time.tv_usec)
|
||||
&& (Curl_timediff(Curl_now(), res->happy_eyeballs_dns_time)
|
||||
>= HAPPY_EYEBALLS_DNS_TIMEOUT)) {
|
||||
/* Remember that the EXPIRE_HAPPY_EYEBALLS_DNS timer is no longer
|
||||
running. */
|
||||
memset(
|
||||
&res->happy_eyeballs_dns_time, 0, sizeof(res->happy_eyeballs_dns_time));
|
||||
|
||||
/* Cancel the raw c-ares request, which will fire query_completed_cb() with
|
||||
ARES_ECANCELLED synchronously for all pending responses. This will
|
||||
leave us with res->num_pending == 0, which is perfect for the next
|
||||
block. */
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
DEBUGASSERT(res->num_pending == 0);
|
||||
}
|
||||
|
||||
if(res && !res->num_pending) {
|
||||
if(dns) {
|
||||
(void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
|
||||
@@ -342,13 +407,13 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* waits for a resolve to finish. This function should be avoided since using
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
@@ -425,9 +490,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
|
||||
if(result)
|
||||
/* close the connection, since we can't return failure here without
|
||||
cleaning up this connection properly.
|
||||
TODO: remove this action from here, it is not a name resolver decision.
|
||||
*/
|
||||
cleaning up this connection properly. */
|
||||
connclose(conn, "c-ares resolve failed");
|
||||
|
||||
return result;
|
||||
@@ -487,6 +550,66 @@ static void query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
/* A successful result overwrites any previous error */
|
||||
if(res->last_status != ARES_SUCCESS)
|
||||
res->last_status = status;
|
||||
|
||||
/* If there are responses still pending, we presume they must be the
|
||||
complementary IPv4 or IPv6 lookups that we started in parallel in
|
||||
Curl_resolver_getaddrinfo() (for Happy Eyeballs). If we've got a
|
||||
"definitive" response from one of a set of parallel queries, we need to
|
||||
think about how long we're willing to wait for more responses. */
|
||||
if(res->num_pending
|
||||
/* Only these c-ares status values count as "definitive" for these
|
||||
purposes. For example, ARES_ENODATA is what we expect when there is
|
||||
no IPv6 entry for a domain name, and that's not a reason to get more
|
||||
aggressive in our timeouts for the other response. Other errors are
|
||||
either a result of bad input (which should affect all parallel
|
||||
requests), local or network conditions, non-definitive server
|
||||
responses, or us cancelling the request. */
|
||||
&& (status == ARES_SUCCESS || status == ARES_ENOTFOUND)) {
|
||||
/* Right now, there can only be up to two parallel queries, so don't
|
||||
bother handling any other cases. */
|
||||
DEBUGASSERT(res->num_pending == 1);
|
||||
|
||||
/* It's possible that one of these parallel queries could succeed
|
||||
quickly, but the other could always fail or timeout (when we're
|
||||
talking to a pool of DNS servers that can only successfully resolve
|
||||
IPv4 address, for example).
|
||||
|
||||
It's also possible that the other request could always just take
|
||||
longer because it needs more time or only the second DNS server can
|
||||
fulfill it successfully. But, to align with the philosophy of Happy
|
||||
Eyeballs, we don't want to wait _too_ long or users will think
|
||||
requests are slow when IPv6 lookups don't actually work (but IPv4 ones
|
||||
do).
|
||||
|
||||
So, now that we have a usable answer (some IPv4 addresses, some IPv6
|
||||
addresses, or "no such domain"), we start a timeout for the remaining
|
||||
pending responses. Even though it is typical that this resolved
|
||||
request came back quickly, that needn't be the case. It might be that
|
||||
this completing request didn't get a result from the first DNS server
|
||||
or even the first round of the whole DNS server pool. So it could
|
||||
already be quite some time after we issued the DNS queries in the
|
||||
first place. Without modifying c-ares, we can't know exactly where in
|
||||
its retry cycle we are. We could guess based on how much time has
|
||||
gone by, but it doesn't really matter. Happy Eyeballs tells us that,
|
||||
given usable information in hand, we simply don't want to wait "too
|
||||
much longer" after we get a result.
|
||||
|
||||
We simply wait an additional amount of time equal to the default
|
||||
c-ares query timeout. That is enough time for a typical parallel
|
||||
response to arrive without being "too long". Even on a network
|
||||
where one of the two types of queries is failing or timing out
|
||||
constantly, this will usually mean we wait a total of the default
|
||||
c-ares timeout (5 seconds) plus the round trip time for the successful
|
||||
request, which seems bearable. The downside is that c-ares might race
|
||||
with us to issue one more retry just before we give up, but it seems
|
||||
better to "waste" that request instead of trying to guess the perfect
|
||||
timeout to prevent it. After all, we don't even know where in the
|
||||
c-ares retry cycle each request is.
|
||||
*/
|
||||
res->happy_eyeballs_dns_time = Curl_now();
|
||||
Curl_expire(
|
||||
conn->data, HAPPY_EYEBALLS_DNS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS_DNS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -108,8 +108,9 @@ void Curl_resolver_global_cleanup(void)
|
||||
* URL-state specific environment ('resolver' member of the UrlState
|
||||
* structure).
|
||||
*/
|
||||
CURLcode Curl_resolver_init(void **resolver)
|
||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver)
|
||||
{
|
||||
(void)easy;
|
||||
*resolver = calloc(1, sizeof(struct resdata));
|
||||
if(!*resolver)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -132,10 +133,10 @@ void Curl_resolver_cleanup(void *resolver)
|
||||
* Called from curl_easy_duphandle() to duplicate resolver URL state-specific
|
||||
* environment ('resolver' member of the UrlState structure).
|
||||
*/
|
||||
int Curl_resolver_duphandle(void **to, void *from)
|
||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from)
|
||||
{
|
||||
(void)from;
|
||||
return Curl_resolver_init(to);
|
||||
return Curl_resolver_init(easy, to);
|
||||
}
|
||||
|
||||
static void destroy_async_data(struct Curl_async *);
|
||||
@@ -276,7 +277,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
|
||||
char service[12];
|
||||
int rc;
|
||||
|
||||
snprintf(service, sizeof(service), "%d", tsd->port);
|
||||
msnprintf(service, sizeof(service), "%d", tsd->port);
|
||||
|
||||
rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
|
||||
|
||||
@@ -460,23 +461,15 @@ static CURLcode resolver_error(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* This is the version for resolves-in-a-thread.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
static CURLcode thread_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry,
|
||||
bool report)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(conn && td);
|
||||
DEBUGASSERT(td->thread_hnd != curl_thread_t_null);
|
||||
|
||||
/* wait for the thread to resolve the name */
|
||||
if(Curl_thread_join(&td->thread_hnd)) {
|
||||
@@ -491,18 +484,55 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
if(!conn->async.dns)
|
||||
if(!conn->async.dns && report)
|
||||
/* a name was not resolved, report error */
|
||||
result = resolver_error(conn);
|
||||
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
if(!conn->async.dns)
|
||||
if(!conn->async.dns && report)
|
||||
connclose(conn, "asynch resolve failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Until we gain a way to signal the resolver threads to stop early, we must
|
||||
* simply wait for them and ignore their results.
|
||||
*/
|
||||
void Curl_resolver_kill(struct connectdata *conn)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
|
||||
/* If we're still resolving, we must wait for the threads to fully clean up,
|
||||
unfortunately. Otherwise, we can simply cancel to clean up any resolver
|
||||
data. */
|
||||
if(td && td->thread_hnd != curl_thread_t_null)
|
||||
(void)thread_wait_resolv(conn, NULL, FALSE);
|
||||
else
|
||||
Curl_resolver_cancel(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
*
|
||||
* This is the version for resolves-in-a-thread.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
return thread_wait_resolv(conn, entry, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_resolver_is_resolved() is called repeatedly to check if a previous
|
||||
* name resolve request has completed. It should also make sure to time-out if
|
||||
@@ -678,7 +708,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = conn->socktype;
|
||||
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
msnprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
|
||||
reslv->start = Curl_now();
|
||||
/* fire up a new resolver thread! */
|
||||
|
||||
+26
-10
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -60,7 +60,7 @@ void Curl_resolver_global_cleanup(void);
|
||||
* Returning anything else than CURLE_OK fails curl_easy_init() with the
|
||||
* correspondent code.
|
||||
*/
|
||||
CURLcode Curl_resolver_init(void **resolver);
|
||||
CURLcode Curl_resolver_init(struct Curl_easy *easy, void **resolver);
|
||||
|
||||
/*
|
||||
* Curl_resolver_cleanup()
|
||||
@@ -79,17 +79,33 @@ void Curl_resolver_cleanup(void *resolver);
|
||||
* pointer. Returning anything else than CURLE_OK causes failed
|
||||
* curl_easy_duphandle() call.
|
||||
*/
|
||||
int Curl_resolver_duphandle(void **to, void *from);
|
||||
CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to,
|
||||
void *from);
|
||||
|
||||
/*
|
||||
* Curl_resolver_cancel().
|
||||
*
|
||||
* It is called from inside other functions to cancel currently performing
|
||||
* resolver request. Should also free any temporary resources allocated to
|
||||
* perform a request.
|
||||
* perform a request. This never waits for resolver threads to complete.
|
||||
*
|
||||
* It is safe to call this when conn is in any state.
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* Curl_resolver_kill().
|
||||
*
|
||||
* This acts like Curl_resolver_cancel() except it will block until any threads
|
||||
* associated with the resolver are complete. This never blocks for resolvers
|
||||
* that do not use threads. This is intended to be the "last chance" function
|
||||
* that cleans up an in-progress resolver completely (before its owner is about
|
||||
* to die).
|
||||
*
|
||||
* It is safe to call this when conn is in any state.
|
||||
*/
|
||||
void Curl_resolver_kill(struct connectdata *conn);
|
||||
|
||||
/* Curl_resolver_getsock()
|
||||
*
|
||||
* This function is called from the multi_getsock() function. 'sock' is a
|
||||
@@ -116,14 +132,13 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
/*
|
||||
* Curl_resolver_wait_resolv()
|
||||
*
|
||||
* waits for a resolve to finish. This function should be avoided since using
|
||||
* Waits for a resolve to finish. This function should be avoided since using
|
||||
* this risk getting the multi interface to "hang".
|
||||
*
|
||||
* If 'entry' is non-NULL, make it point to the resolved dns entry
|
||||
*
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred.
|
||||
|
||||
* Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved,
|
||||
* CURLE_OPERATION_TIMEDOUT if a time-out occurred, or other errors.
|
||||
*/
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
@@ -147,11 +162,12 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
#ifndef CURLRES_ASYNCH
|
||||
/* convert these functions if an asynch resolver isn't used */
|
||||
#define Curl_resolver_cancel(x) Curl_nop_stmt
|
||||
#define Curl_resolver_kill(x) Curl_nop_stmt
|
||||
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_getsock(x,y,z) 0
|
||||
#define Curl_resolver_duphandle(x,y) CURLE_OK
|
||||
#define Curl_resolver_init(x) CURLE_OK
|
||||
#define Curl_resolver_duphandle(x,y,z) CURLE_OK
|
||||
#define Curl_resolver_init(x,y) CURLE_OK
|
||||
#define Curl_resolver_global_init() CURLE_OK
|
||||
#define Curl_resolver_global_cleanup() Curl_nop_stmt
|
||||
#define Curl_resolver_cleanup(x) Curl_nop_stmt
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -23,6 +23,11 @@
|
||||
/* Base64 encoding/decoding */
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP_AUTH) || defined(USE_LIBSSH2) || \
|
||||
defined(USE_LIBSSH) || !defined(CURL_DISABLE_LDAP) || \
|
||||
!defined(CURL_DISABLE_DOH) || defined(USE_SSL)
|
||||
|
||||
#include "urldata.h" /* for the Curl_easy definition */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
@@ -233,24 +238,24 @@ static CURLcode base64_encode(const char *table64,
|
||||
|
||||
switch(inputparts) {
|
||||
case 1: /* only one byte read */
|
||||
snprintf(output, 5, "%c%c==",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]]);
|
||||
msnprintf(output, 5, "%c%c==",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]]);
|
||||
break;
|
||||
|
||||
case 2: /* two bytes read */
|
||||
snprintf(output, 5, "%c%c%c=",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]]);
|
||||
msnprintf(output, 5, "%c%c%c=",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]]);
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(output, 5, "%c%c%c%c",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]],
|
||||
table64[obuf[3]]);
|
||||
msnprintf(output, 5, "%c%c%c%c",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]],
|
||||
table64[obuf[3]]);
|
||||
break;
|
||||
}
|
||||
output += 4;
|
||||
@@ -317,3 +322,5 @@ CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
{
|
||||
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
|
||||
#endif /* no users so disabled */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2019, 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
|
||||
@@ -175,12 +175,12 @@ static void hashkey(struct connectdata *conn, char *buf,
|
||||
DEBUGASSERT(len > 32);
|
||||
|
||||
/* put the number first so that the hostname gets cut off if too long */
|
||||
snprintf(buf, len, "%ld%s", conn->port, hostname);
|
||||
msnprintf(buf, len, "%ld%s", conn->port, hostname);
|
||||
}
|
||||
|
||||
void Curl_conncache_unlock(struct connectdata *conn)
|
||||
void Curl_conncache_unlock(struct Curl_easy *data)
|
||||
{
|
||||
CONN_UNLOCK(conn->data);
|
||||
CONN_UNLOCK(data);
|
||||
}
|
||||
|
||||
/* Returns number of connections currently held in the connection cache.
|
||||
@@ -302,9 +302,14 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
|
||||
/*
|
||||
* Removes the connectdata object from the connection cache *and* clears the
|
||||
* ->data pointer association. Pass TRUE/FALSE in the 'lock' argument
|
||||
* depending on if the parent function already holds the lock or not.
|
||||
*/
|
||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn, bool lock)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct connectbundle *bundle = conn->bundle;
|
||||
struct conncache *connc = data->state.conn_cache;
|
||||
|
||||
@@ -323,6 +328,7 @@ void Curl_conncache_remove_conn(struct connectdata *conn, bool lock)
|
||||
DEBUGF(infof(data, "The cache now contains %zu members\n",
|
||||
connc->num_conn));
|
||||
}
|
||||
conn->data = NULL; /* clear the association */
|
||||
if(lock) {
|
||||
CONN_UNLOCK(data);
|
||||
}
|
||||
@@ -386,8 +392,8 @@ bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
NOTE: no locking is done here as this is presumably only done when cleaning
|
||||
up a cache!
|
||||
*/
|
||||
struct connectdata *
|
||||
Curl_conncache_find_first_connection(struct conncache *connc)
|
||||
static struct connectdata *
|
||||
conncache_find_first_connection(struct conncache *connc)
|
||||
{
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_hash_element *he;
|
||||
@@ -427,6 +433,8 @@ bool Curl_conncache_return_conn(struct connectdata *conn)
|
||||
data->multi->maxconnects;
|
||||
struct connectdata *conn_candidate = NULL;
|
||||
|
||||
conn->data = NULL; /* no owner anymore */
|
||||
conn->lastused = Curl_now(); /* it was used up until now */
|
||||
if(maxconnects > 0 &&
|
||||
Curl_conncache_size(data) > maxconnects) {
|
||||
infof(data, "Connection cache is full, closing the oldest one.\n");
|
||||
@@ -470,9 +478,9 @@ Curl_conncache_extract_bundle(struct Curl_easy *data,
|
||||
while(curr) {
|
||||
conn = curr->ptr;
|
||||
|
||||
if(!CONN_INUSE(conn)) {
|
||||
if(!CONN_INUSE(conn) && !conn->data) {
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = Curl_timediff(now, conn->now);
|
||||
score = Curl_timediff(now, conn->lastused);
|
||||
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
@@ -528,9 +536,9 @@ Curl_conncache_extract_oldest(struct Curl_easy *data)
|
||||
while(curr) {
|
||||
conn = curr->ptr;
|
||||
|
||||
if(!CONN_INUSE(conn)) {
|
||||
if(!CONN_INUSE(conn) && !conn->data) {
|
||||
/* Set higher score for the age passed since the connection was used */
|
||||
score = Curl_timediff(now, conn->now);
|
||||
score = Curl_timediff(now, conn->lastused);
|
||||
|
||||
if(score > highscore) {
|
||||
highscore = score;
|
||||
@@ -560,20 +568,18 @@ void Curl_conncache_close_all_connections(struct conncache *connc)
|
||||
{
|
||||
struct connectdata *conn;
|
||||
|
||||
conn = Curl_conncache_find_first_connection(connc);
|
||||
conn = conncache_find_first_connection(connc);
|
||||
while(conn) {
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
conn->data = connc->closure_handle;
|
||||
|
||||
sigpipe_ignore(conn->data, &pipe_st);
|
||||
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(connc->closure_handle, conn, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
conn = Curl_conncache_find_first_connection(connc);
|
||||
conn = conncache_find_first_connection(connc);
|
||||
}
|
||||
|
||||
if(connc->closure_handle) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2015 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -40,7 +40,6 @@ struct conncache {
|
||||
|
||||
#define BUNDLE_NO_MULTIUSE -1
|
||||
#define BUNDLE_UNKNOWN 0 /* initial value */
|
||||
#define BUNDLE_PIPELINING 1
|
||||
#define BUNDLE_MULTIPLEX 2
|
||||
|
||||
struct connectbundle {
|
||||
@@ -56,7 +55,7 @@ void Curl_conncache_destroy(struct conncache *connc);
|
||||
/* return the correct bundle, to a host or a proxy */
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
struct conncache *connc);
|
||||
void Curl_conncache_unlock(struct connectdata *conn);
|
||||
void Curl_conncache_unlock(struct Curl_easy *data);
|
||||
/* returns number of connections currently held in the connection cache */
|
||||
size_t Curl_conncache_size(struct Curl_easy *data);
|
||||
size_t Curl_conncache_bundle_size(struct connectdata *conn);
|
||||
@@ -64,7 +63,8 @@ size_t Curl_conncache_bundle_size(struct connectdata *conn);
|
||||
bool Curl_conncache_return_conn(struct connectdata *conn);
|
||||
CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
struct connectdata *conn) WARN_UNUSED_RESULT;
|
||||
void Curl_conncache_remove_conn(struct connectdata *conn,
|
||||
void Curl_conncache_remove_conn(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool lock);
|
||||
bool Curl_conncache_foreach(struct Curl_easy *data,
|
||||
struct conncache *connc,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -357,7 +357,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
conn->ip_version = CURL_IPRESOLVE_V6;
|
||||
#endif
|
||||
|
||||
rc = Curl_resolv(conn, dev, 0, &h);
|
||||
rc = Curl_resolv(conn, dev, 0, FALSE, &h);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
(void)Curl_resolver_wait_resolv(conn, &h);
|
||||
conn->ip_version = ipver;
|
||||
@@ -446,9 +446,10 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
curl_socklen_t size = sizeof(add);
|
||||
memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
|
||||
if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
infof(data, "Local port: %hu\n", port);
|
||||
@@ -470,10 +471,12 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "bind failed with errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
{
|
||||
char buffer[STRERROR_LEN];
|
||||
data->state.os_errno = error = SOCKERRNO;
|
||||
failf(data, "bind failed with errno %d: %s",
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
}
|
||||
|
||||
return CURLE_INTERFACE_FAILED;
|
||||
}
|
||||
@@ -522,7 +525,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
||||
err = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef __minix
|
||||
#if defined(EBADIOCTL) && defined(__minix)
|
||||
/* Minix 3.1.x doesn't support getsockopt on UDP sockets */
|
||||
if(EBADIOCTL == err) {
|
||||
SET_SOCKERRNO(0);
|
||||
@@ -617,12 +620,14 @@ void Curl_persistconninfo(struct connectdata *conn)
|
||||
conn->data->info.conn_local_port = conn->local_port;
|
||||
}
|
||||
|
||||
UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
long *port);
|
||||
|
||||
/* retrieves ip address and port from a sockaddr structure.
|
||||
note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
|
||||
bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
long *port)
|
||||
UNITTEST bool getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
long *port)
|
||||
{
|
||||
unsigned short us_port;
|
||||
struct sockaddr_in *si = NULL;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *si6 = NULL;
|
||||
@@ -636,7 +641,7 @@ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
si = (struct sockaddr_in *)(void *) sa;
|
||||
if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
|
||||
addr, MAX_IPADR_LEN)) {
|
||||
us_port = ntohs(si->sin_port);
|
||||
unsigned short us_port = ntohs(si->sin_port);
|
||||
*port = us_port;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -646,7 +651,7 @@ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
si6 = (struct sockaddr_in6 *)(void *) sa;
|
||||
if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
|
||||
addr, MAX_IPADR_LEN)) {
|
||||
us_port = ntohs(si6->sin6_port);
|
||||
unsigned short us_port = ntohs(si6->sin6_port);
|
||||
*port = us_port;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -655,7 +660,7 @@ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
|
||||
case AF_UNIX:
|
||||
su = (struct sockaddr_un*)sa;
|
||||
snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
|
||||
*port = 0;
|
||||
return TRUE;
|
||||
#endif
|
||||
@@ -673,49 +678,57 @@ bool Curl_getaddressinfo(struct sockaddr *sa, char *addr,
|
||||
connection */
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
curl_socklen_t len;
|
||||
struct Curl_sockaddr_storage ssrem;
|
||||
struct Curl_sockaddr_storage ssloc;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(conn->socktype == SOCK_DGRAM)
|
||||
/* there's no connection! */
|
||||
return;
|
||||
|
||||
#if defined(HAVE_GETPEERNAME) || defined(HAVE_GETSOCKNAME)
|
||||
if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
|
||||
struct Curl_easy *data = conn->data;
|
||||
char buffer[STRERROR_LEN];
|
||||
struct Curl_sockaddr_storage ssrem;
|
||||
struct Curl_sockaddr_storage ssloc;
|
||||
curl_socklen_t len;
|
||||
#ifdef HAVE_GETPEERNAME
|
||||
len = sizeof(struct Curl_sockaddr_storage);
|
||||
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getpeername() failed with errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
len = sizeof(struct Curl_sockaddr_storage);
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
|
||||
int error = SOCKERRNO;
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
error, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Curl_getaddressinfo((struct sockaddr*)&ssrem,
|
||||
conn->primary_ip, &conn->primary_port)) {
|
||||
#endif
|
||||
#ifdef HAVE_GETPEERNAME
|
||||
if(!getaddressinfo((struct sockaddr*)&ssrem,
|
||||
conn->primary_ip, &conn->primary_port)) {
|
||||
failf(data, "ssrem inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||
|
||||
if(!Curl_getaddressinfo((struct sockaddr*)&ssloc,
|
||||
conn->local_ip, &conn->local_port)) {
|
||||
#endif
|
||||
#ifdef HAVE_GETSOCKNAME
|
||||
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
||||
conn->local_ip, &conn->local_port)) {
|
||||
failf(data, "ssloc inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
#else /* !HAVE_GETSOCKNAME && !HAVE_GETPEERNAME */
|
||||
(void)sockfd; /* unused */
|
||||
#endif
|
||||
|
||||
/* persist connection info in session handle */
|
||||
Curl_persistconninfo(conn);
|
||||
@@ -836,9 +849,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
if(conn->tempaddr[i]) {
|
||||
CURLcode status;
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
char buffer[STRERROR_LEN];
|
||||
Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
|
||||
infof(data, "connect to %s port %ld failed: %s\n",
|
||||
ipaddress, conn->port, Curl_strerror(conn, error));
|
||||
ipaddress, conn->port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
|
||||
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
|
||||
allow : allow / 2;
|
||||
@@ -854,8 +869,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
if(result) {
|
||||
/* no more addresses to try */
|
||||
|
||||
const char *hostname;
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
/* if the first address family runs out of addresses to try before
|
||||
the happy eyeball timeout, go ahead and try the next family now */
|
||||
@@ -875,13 +890,14 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
hostname = conn->host.name;
|
||||
|
||||
failf(data, "Failed to connect to %s port %ld: %s",
|
||||
hostname, conn->port, Curl_strerror(conn, error));
|
||||
hostname, conn->port,
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
#if defined(TCP_NODELAY)
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
@@ -889,6 +905,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
#endif
|
||||
curl_socklen_t onoff = (curl_socklen_t) 1;
|
||||
int level = IPPROTO_TCP;
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) conn;
|
||||
@@ -897,7 +914,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
|
||||
sizeof(onoff)) < 0)
|
||||
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||
Curl_strerror(conn, SOCKERRNO));
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
else
|
||||
infof(data, "TCP_NODELAY set\n");
|
||||
#else
|
||||
@@ -917,9 +934,11 @@ static void nosigpipe(struct connectdata *conn,
|
||||
struct Curl_easy *data = conn->data;
|
||||
int onoff = 1;
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
|
||||
sizeof(onoff)) < 0)
|
||||
sizeof(onoff)) < 0) {
|
||||
char buffer[STRERROR_LEN];
|
||||
infof(data, "Could not set SO_NOSIGPIPE: %s\n",
|
||||
Curl_strerror(conn, SOCKERRNO));
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define nosigpipe(x,y) Curl_nop_stmt
|
||||
@@ -995,6 +1014,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
#ifdef TCP_FASTOPEN_CONNECT
|
||||
int optval = 1;
|
||||
#endif
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
*sockp = CURL_SOCKET_BAD;
|
||||
|
||||
@@ -1006,15 +1026,15 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
|
||||
/* store remote address and port used in this connection attempt */
|
||||
if(!Curl_getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
||||
ipaddress, &port)) {
|
||||
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
||||
ipaddress, &port)) {
|
||||
/* malformed address or bug in inet_ntop, try next address */
|
||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
Curl_closesocket(conn, sockfd);
|
||||
return CURLE_OK;
|
||||
}
|
||||
infof(data, " Trying %s...\n", ipaddress);
|
||||
infof(data, " Trying %s:%ld...\n", ipaddress, port);
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
|
||||
@@ -1023,7 +1043,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
|
||||
#endif
|
||||
if(is_tcp && data->set.tcp_nodelay)
|
||||
Curl_tcpnodelay(conn, sockfd);
|
||||
tcpnodelay(conn, sockfd);
|
||||
|
||||
nosigpipe(conn, sockfd);
|
||||
|
||||
@@ -1146,7 +1166,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
infof(data, "Immediate connect fail for %s: %s\n",
|
||||
ipaddress, Curl_strerror(conn, error));
|
||||
ipaddress, Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
data->state.os_errno = error;
|
||||
|
||||
/* connect failed */
|
||||
@@ -1314,7 +1334,7 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
conn->sock_accepted[SECONDARYSOCKET] = FALSE;
|
||||
else {
|
||||
int rc;
|
||||
Curl_multi_closed(conn, sock);
|
||||
Curl_multi_closed(conn->data, sock);
|
||||
Curl_set_in_callback(conn->data, true);
|
||||
rc = conn->fclosesocket(conn->closesocket_client, sock);
|
||||
Curl_set_in_callback(conn->data, false);
|
||||
@@ -1324,7 +1344,7 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
|
||||
if(conn)
|
||||
/* tell the multi-socket code about this */
|
||||
Curl_multi_closed(conn, sock);
|
||||
Curl_multi_closed(conn->data, sock);
|
||||
|
||||
sclose(sock);
|
||||
|
||||
@@ -1420,7 +1440,7 @@ void Curl_conncontrol(struct connectdata *conn,
|
||||
if((ctrl == CONNCTRL_STREAM) &&
|
||||
(conn->handler->flags & PROTOPT_STREAM))
|
||||
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
|
||||
else if(closeit != conn->bits.close) {
|
||||
else if((bit)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
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,11 +75,6 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||
void Curl_persistconninfo(struct connectdata *conn);
|
||||
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||
|
||||
/*
|
||||
* Get presentation format IP address and port from a sockaddr.
|
||||
*/
|
||||
bool Curl_getaddressinfo(struct sockaddr *sa, char *addr, long *port);
|
||||
|
||||
/*
|
||||
* The Curl_sockaddr_ex structure is basically libcurl's external API
|
||||
* curl_sockaddr structure with enough space available to directly hold any
|
||||
@@ -111,8 +106,6 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd);
|
||||
|
||||
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
|
||||
|
||||
/*
|
||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
||||
* argument specifies if it is the end of a connection or a stream.
|
||||
|
||||
+130
-74
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -93,6 +93,7 @@ Example set of cookies:
|
||||
#include "share.h"
|
||||
#include "strtoofft.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
@@ -223,7 +224,7 @@ static bool pathmatch(const char *cookie_path, const char *request_uri)
|
||||
goto pathmatched;
|
||||
}
|
||||
|
||||
/* here, cookie_path_len < url_path_len */
|
||||
/* here, cookie_path_len < uri_path_len */
|
||||
if(uri_path[cookie_path_len] == '/') {
|
||||
ret = TRUE;
|
||||
goto pathmatched;
|
||||
@@ -433,9 +434,10 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
bool noexpire, /* if TRUE, skip remove_expired() */
|
||||
char *lineptr, /* first character of the line */
|
||||
const char *domain, /* default domain */
|
||||
const char *path) /* full path used when this cookie is set,
|
||||
const char *path, /* full path used when this cookie is set,
|
||||
used to get default path for the cookie
|
||||
unless set */
|
||||
bool secure) /* TRUE if connection is over secure origin */
|
||||
{
|
||||
struct Cookie *clist;
|
||||
struct Cookie *co;
|
||||
@@ -527,6 +529,19 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
while(*whatptr && ISBLANK(*whatptr))
|
||||
whatptr++;
|
||||
|
||||
/*
|
||||
* Check if we have a reserved prefix set before anything else, as we
|
||||
* otherwise have to test for the prefix in both the cookie name and
|
||||
* "the rest". Prefixes must start with '__' and end with a '-', so
|
||||
* only test for names where that can possibly be true.
|
||||
*/
|
||||
if(nlen > 3 && name[0] == '_' && name[1] == '_') {
|
||||
if(strncasecompare("__Secure-", name, 9))
|
||||
co->prefix |= COOKIE_PREFIX__SECURE;
|
||||
else if(strncasecompare("__Host-", name, 7))
|
||||
co->prefix |= COOKIE_PREFIX__HOST;
|
||||
}
|
||||
|
||||
if(!co->name) {
|
||||
/* The very first name/value pair is the actual cookie name */
|
||||
if(!sep) {
|
||||
@@ -546,8 +561,20 @@ 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(strcasecompare("secure", name))
|
||||
co->secure = TRUE;
|
||||
/*
|
||||
* secure cookies are only allowed to be set when the connection is
|
||||
* using a secure protocol, or when the cookie is being set by
|
||||
* reading from file
|
||||
*/
|
||||
if(strcasecompare("secure", name)) {
|
||||
if(secure || !c->running) {
|
||||
co->secure = TRUE;
|
||||
}
|
||||
else {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(strcasecompare("httponly", name))
|
||||
co->httponly = TRUE;
|
||||
else if(sep)
|
||||
@@ -675,7 +702,10 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
/* overflow, used max value */
|
||||
co->expires = CURL_OFF_T_MAX;
|
||||
else if(!offt) {
|
||||
if(CURL_OFF_T_MAX - now < co->expires)
|
||||
if(!co->expires)
|
||||
/* already expired */
|
||||
co->expires = 1;
|
||||
else if(CURL_OFF_T_MAX - now < co->expires)
|
||||
/* would overflow */
|
||||
co->expires = CURL_OFF_T_MAX;
|
||||
else
|
||||
@@ -828,7 +858,13 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
fields++; /* add a field and fall down to secure */
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
co->secure = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
|
||||
co->secure = FALSE;
|
||||
if(strcasecompare(ptr, "TRUE")) {
|
||||
if(secure || c->running)
|
||||
co->secure = TRUE;
|
||||
else
|
||||
badcookie = TRUE;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(curlx_strtoofft(ptr, NULL, 10, &co->expires))
|
||||
@@ -838,6 +874,13 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
co->name = strdup(ptr);
|
||||
if(!co->name)
|
||||
badcookie = TRUE;
|
||||
else {
|
||||
/* For Netscape file format cookies we check prefix on the name */
|
||||
if(strncasecompare("__Secure-", co->name, 9))
|
||||
co->prefix |= COOKIE_PREFIX__SECURE;
|
||||
else if(strncasecompare("__Host-", co->name, 7))
|
||||
co->prefix |= COOKIE_PREFIX__HOST;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
co->value = strdup(ptr);
|
||||
@@ -866,6 +909,26 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
|
||||
}
|
||||
|
||||
if(co->prefix & COOKIE_PREFIX__SECURE) {
|
||||
/* The __Secure- prefix only requires that the cookie be set secure */
|
||||
if(!co->secure) {
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(co->prefix & COOKIE_PREFIX__HOST) {
|
||||
/*
|
||||
* The __Host- prefix requires the cookie to be secure, have a "/" path
|
||||
* and not have a domain set.
|
||||
*/
|
||||
if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch)
|
||||
;
|
||||
else {
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(!c->running && /* read from a file */
|
||||
c->newsession && /* clean session cookies */
|
||||
!co->expires) { /* this is a session cookie since it doesn't expire! */
|
||||
@@ -926,9 +989,31 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
/* the domains were identical */
|
||||
|
||||
if(clist->spath && co->spath) {
|
||||
if(strcasecompare(clist->spath, co->spath)) {
|
||||
replace_old = TRUE;
|
||||
if(clist->secure && !co->secure && !secure) {
|
||||
size_t cllen;
|
||||
const char *sep;
|
||||
|
||||
/*
|
||||
* A non-secure cookie may not overlay an existing secure cookie.
|
||||
* For an existing cookie "a" with path "/login", refuse a new
|
||||
* cookie "a" with for example path "/login/en", while the path
|
||||
* "/loginhelper" is ok.
|
||||
*/
|
||||
|
||||
sep = strchr(clist->spath + 1, '/');
|
||||
|
||||
if(sep)
|
||||
cllen = sep - clist->spath;
|
||||
else
|
||||
cllen = strlen(clist->spath);
|
||||
|
||||
if(strncasecompare(clist->spath, co->spath, cllen)) {
|
||||
freecookie(co);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if(strcasecompare(clist->spath, co->spath))
|
||||
replace_old = TRUE;
|
||||
else
|
||||
replace_old = FALSE;
|
||||
}
|
||||
@@ -1003,33 +1088,6 @@ 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;
|
||||
}
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -1087,7 +1145,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
line = malloc(MAX_COOKIE_LINE);
|
||||
if(!line)
|
||||
goto fail;
|
||||
while(get_line(line, MAX_COOKIE_LINE, fp)) {
|
||||
while(Curl_get_line(line, MAX_COOKIE_LINE, fp)) {
|
||||
if(checkprefix("Set-Cookie:", line)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr = &line[11];
|
||||
@@ -1100,7 +1158,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
while(*lineptr && ISBLANK(*lineptr))
|
||||
lineptr++;
|
||||
|
||||
Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL);
|
||||
Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE);
|
||||
}
|
||||
free(line); /* free the line buffer */
|
||||
remove_expired(c); /* run this once, not on every cookie */
|
||||
@@ -1451,27 +1509,14 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
struct Cookie *co;
|
||||
FILE *out;
|
||||
bool use_stdout = FALSE;
|
||||
char *format_ptr;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
struct Cookie **array;
|
||||
|
||||
if((NULL == c) || (0 == c->numcookies))
|
||||
/* If there are no known cookies, we don't write or even create any
|
||||
destination file */
|
||||
if(!c)
|
||||
/* no cookie engine alive */
|
||||
return 0;
|
||||
|
||||
/* at first, remove expired cookies */
|
||||
remove_expired(c);
|
||||
|
||||
/* make sure we still have cookies after expiration */
|
||||
if(0 == c->numcookies)
|
||||
return 0;
|
||||
|
||||
array = malloc(sizeof(struct Cookie *) * c->numcookies);
|
||||
if(!array)
|
||||
return 1;
|
||||
|
||||
if(!strcmp("-", dumphere)) {
|
||||
/* use stdout */
|
||||
out = stdout;
|
||||
@@ -1480,7 +1525,6 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
else {
|
||||
out = fopen(dumphere, FOPEN_WRITETEXT);
|
||||
if(!out) {
|
||||
free(array);
|
||||
return 1; /* failure */
|
||||
}
|
||||
}
|
||||
@@ -1490,32 +1534,44 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n\n",
|
||||
out);
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
|
||||
for(co = c->cookies[i]; co; co = co->next) {
|
||||
if(!co->domain)
|
||||
continue;
|
||||
array[j++] = co;
|
||||
}
|
||||
}
|
||||
if(c->numcookies) {
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
struct Cookie **array;
|
||||
|
||||
qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
|
||||
|
||||
for(i = 0; i < j; i++) {
|
||||
format_ptr = get_netscape_format(array[i]);
|
||||
if(format_ptr == NULL) {
|
||||
fprintf(out, "#\n# Fatal libcurl error\n");
|
||||
free(array);
|
||||
array = malloc(sizeof(struct Cookie *) * c->numcookies);
|
||||
if(!array) {
|
||||
if(!use_stdout)
|
||||
fclose(out);
|
||||
return 1;
|
||||
}
|
||||
fprintf(out, "%s\n", format_ptr);
|
||||
free(format_ptr);
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < COOKIE_HASH_SIZE; i++) {
|
||||
for(co = c->cookies[i]; co; co = co->next) {
|
||||
if(!co->domain)
|
||||
continue;
|
||||
array[j++] = co;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct);
|
||||
|
||||
for(i = 0; i < j; i++) {
|
||||
char *format_ptr = get_netscape_format(array[i]);
|
||||
if(format_ptr == NULL) {
|
||||
fprintf(out, "#\n# Fatal libcurl error\n");
|
||||
free(array);
|
||||
if(!use_stdout)
|
||||
fclose(out);
|
||||
return 1;
|
||||
}
|
||||
fprintf(out, "%s\n", format_ptr);
|
||||
free(format_ptr);
|
||||
}
|
||||
|
||||
free(array);
|
||||
}
|
||||
|
||||
free(array);
|
||||
|
||||
if(!use_stdout)
|
||||
fclose(out);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,8 +44,16 @@ struct Cookie {
|
||||
bool livecookie; /* updated from a server, not a stored file */
|
||||
bool httponly; /* true if the httponly directive is present */
|
||||
int creationtime; /* time when the cookie was written */
|
||||
unsigned char prefix; /* bitmap fields indicating which prefix are set */
|
||||
};
|
||||
|
||||
/*
|
||||
* Available cookie prefixes, as defined in
|
||||
* draft-ietf-httpbis-rfc6265bis-02
|
||||
*/
|
||||
#define COOKIE_PREFIX__SECURE (1<<0)
|
||||
#define COOKIE_PREFIX__HOST (1<<1)
|
||||
|
||||
#define COOKIE_HASH_SIZE 256
|
||||
|
||||
struct CookieInfo {
|
||||
@@ -85,7 +93,8 @@ struct Curl_easy;
|
||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *, bool header, bool noexpiry,
|
||||
char *lineptr,
|
||||
const char *domain, const char *path);
|
||||
const char *domain, const char *path,
|
||||
bool secure);
|
||||
|
||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
|
||||
const char *, bool);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -539,7 +539,7 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
/*
|
||||
* curl_dofreeaddrinfo()
|
||||
* curl_dbg_freeaddrinfo()
|
||||
*
|
||||
* This is strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
@@ -547,23 +547,23 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
*/
|
||||
|
||||
void
|
||||
curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source)
|
||||
{
|
||||
curl_dbg_log("ADDR %s:%d freeaddrinfo(%p)\n",
|
||||
source, line, (void *)freethis);
|
||||
#ifdef USE_LWIPSOCK
|
||||
lwip_freeaddrinfo(freethis);
|
||||
#else
|
||||
(freeaddrinfo)(freethis);
|
||||
#endif
|
||||
curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
|
||||
source, line, (void *)freethis);
|
||||
}
|
||||
#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
|
||||
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
/*
|
||||
* curl_dogetaddrinfo()
|
||||
* curl_dbg_getaddrinfo()
|
||||
*
|
||||
* This is strictly for memory tracing and are using the same style as the
|
||||
* family otherwise present in memdebug.c. I put these ones here since they
|
||||
@@ -571,11 +571,11 @@ curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
*/
|
||||
|
||||
int
|
||||
curl_dogetaddrinfo(const char *hostname,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source)
|
||||
curl_dbg_getaddrinfo(const char *hostname,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source)
|
||||
{
|
||||
#ifdef USE_LWIPSOCK
|
||||
int res = lwip_getaddrinfo(hostname, service, hints, result);
|
||||
@@ -584,11 +584,11 @@ curl_dogetaddrinfo(const char *hostname,
|
||||
#endif
|
||||
if(0 == res)
|
||||
/* success */
|
||||
curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, (void *)*result);
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() = %p\n",
|
||||
source, line, (void *)*result);
|
||||
else
|
||||
curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
|
||||
source, line);
|
||||
curl_dbg_log("ADDR %s:%d getaddrinfo() failed\n",
|
||||
source, line);
|
||||
return res;
|
||||
}
|
||||
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -86,17 +86,14 @@ Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
void
|
||||
curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source);
|
||||
curl_dbg_freeaddrinfo(struct addrinfo *freethis, int line, const char *source);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
|
||||
int
|
||||
curl_dogetaddrinfo(const char *hostname,
|
||||
const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **result,
|
||||
int line, const char *source);
|
||||
curl_dbg_getaddrinfo(const char *hostname, const char *service,
|
||||
const struct addrinfo *hints, struct addrinfo **result,
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
|
||||
@@ -226,6 +226,12 @@
|
||||
/* Define to 1 if you have the `getprotobyname' function. */
|
||||
#cmakedefine HAVE_GETPROTOBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `getpeername' function. */
|
||||
#cmakedefine HAVE_GETPEERNAME 1
|
||||
|
||||
/* Define to 1 if you have the `getsockname' function. */
|
||||
#cmakedefine HAVE_GETSOCKNAME 1
|
||||
|
||||
/* Define to 1 if you have the `getpwuid' function. */
|
||||
#cmakedefine HAVE_GETPWUID 1
|
||||
|
||||
@@ -930,8 +936,8 @@
|
||||
/* if PolarSSL is enabled */
|
||||
#cmakedefine USE_POLARSSL 1
|
||||
|
||||
/* if DarwinSSL is enabled */
|
||||
#cmakedefine USE_DARWINSSL 1
|
||||
/* if Secure Transport is enabled */
|
||||
#cmakedefine USE_SECTRANSP 1
|
||||
|
||||
/* if mbedTLS is enabled */
|
||||
#cmakedefine USE_MBEDTLS 1
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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 @@ unsigned short Curl_read16_be(const unsigned char *buf)
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_write32_le()
|
||||
* write32_le()
|
||||
*
|
||||
* This function converts a 32-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
@@ -92,7 +92,7 @@ unsigned short Curl_read16_be(const unsigned char *buf)
|
||||
* value [in] - The 32-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
void Curl_write32_le(const int value, unsigned char *buffer)
|
||||
static void write32_le(const int value, unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (char)(value & 0x000000FF);
|
||||
buffer[1] = (char)((value & 0x0000FF00) >> 8);
|
||||
@@ -118,7 +118,7 @@ void Curl_write64_le(const long long value, unsigned char *buffer)
|
||||
void Curl_write64_le(const __int64 value, unsigned char *buffer)
|
||||
#endif
|
||||
{
|
||||
Curl_write32_le((int)value, buffer);
|
||||
Curl_write32_le((int)(value >> 32), buffer + 4);
|
||||
write32_le((int)value, buffer);
|
||||
write32_le((int)(value >> 32), buffer + 4);
|
||||
}
|
||||
#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -21,7 +21,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_fnmatch.h"
|
||||
@@ -32,15 +32,6 @@
|
||||
|
||||
#ifndef HAVE_FNMATCH
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Make this function match POSIX. Test 1307 includes a set of test patterns
|
||||
* that returns different results with a POSIX fnmatch() than with this
|
||||
* implementation and this is considered a bug where POSIX is the guiding
|
||||
* light.
|
||||
*/
|
||||
|
||||
#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
|
||||
#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
|
||||
|
||||
@@ -394,3 +385,5 @@ int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* if FTP is disabled */
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_get_line.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* get_line() makes sure to only return complete whole lines that fit in 'len'
|
||||
* bytes and end with a newline.
|
||||
*/
|
||||
char *Curl_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;
|
||||
}
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef HEADER_CURL_AXTLS_H
|
||||
#define HEADER_CURL_AXTLS_H
|
||||
#ifndef HEADER_CURL_GET_LINE_H
|
||||
#define HEADER_CURL_GET_LINE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -7,8 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
|
||||
* Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -23,11 +22,8 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef USE_AXTLS
|
||||
#include "curl/curl.h"
|
||||
#include "urldata.h"
|
||||
/* get_line() makes sure to only return complete whole lines that fit in 'len'
|
||||
* bytes and end with a newline. */
|
||||
char *Curl_get_line(char *buf, int len, FILE *input);
|
||||
|
||||
extern const struct Curl_ssl Curl_ssl_axtls;
|
||||
|
||||
#endif /* USE_AXTLS */
|
||||
#endif /* HEADER_CURL_AXTLS_H */
|
||||
#endif /* HEADER_CURL_GET_LINE_H */
|
||||
@@ -97,9 +97,9 @@ static size_t display_gss_error(OM_uint32 status, int type,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
|
||||
len += snprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
|
||||
"%.*s. ", (int)status_string.length,
|
||||
(char *)status_string.value);
|
||||
len += msnprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
|
||||
"%.*s. ", (int)status_string.length,
|
||||
(char *)status_string.value);
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2019, 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,19 +26,6 @@
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#ifdef HAVE_GSSGNU
|
||||
# include <gss.h>
|
||||
#elif defined HAVE_GSSMIT
|
||||
/* MIT style */
|
||||
# include <gssapi/gssapi.h>
|
||||
# include <gssapi/gssapi_generic.h>
|
||||
# include <gssapi/gssapi_krb5.h>
|
||||
#else
|
||||
/* Heimdal-style */
|
||||
# include <gssapi.h>
|
||||
#endif
|
||||
|
||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
@@ -71,5 +58,4 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
#define GSSAUTH_P_PRIVACY 4
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
#endif /* HEADER_CURL_GSSAPI_H */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,11 +25,13 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
|
||||
(defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
|
||||
(defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
|
||||
|
||||
void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
|
||||
|
||||
#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
|
||||
(defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
|
||||
(defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
|
||||
|
||||
#endif /* HEADER_CURL_MD4_H */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -53,10 +53,10 @@ void Curl_md5it(unsigned char *output,
|
||||
const unsigned char *input);
|
||||
|
||||
MD5_context * Curl_MD5_init(const MD5_params *md5params);
|
||||
int Curl_MD5_update(MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
int Curl_MD5_final(MD5_context *context, unsigned char *result);
|
||||
CURLcode Curl_MD5_update(MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len);
|
||||
CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -39,7 +39,7 @@
|
||||
*
|
||||
* File lib/strdup.c is an exception, given that it provides a strdup
|
||||
* clone implementation while using malloc. Extra care needed inside
|
||||
* this one. TODO: revisit this paragraph and related code.
|
||||
* this one.
|
||||
*
|
||||
* The need for curl_memory.h inclusion is due to libcurl's feature
|
||||
* of allowing library user to provide memory replacement functions,
|
||||
|
||||
@@ -64,13 +64,13 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
if(str_w) {
|
||||
int str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
||||
0, NULL, NULL);
|
||||
if(str_utf8_len > 0) {
|
||||
str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
|
||||
int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if(bytes > 0) {
|
||||
str_utf8 = malloc(bytes);
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
NULL, FALSE) == 0) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
|
||||
NULL, NULL) == 0) {
|
||||
free(str_utf8);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -38,7 +38,7 @@
|
||||
3. USE_GNUTLS
|
||||
4. USE_NSS
|
||||
5. USE_MBEDTLS
|
||||
6. USE_DARWINSSL
|
||||
6. USE_SECTRANSP
|
||||
7. USE_OS400CRYPTO
|
||||
8. USE_WIN32_CRYPTO
|
||||
|
||||
@@ -54,23 +54,15 @@
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
|
||||
# ifdef USE_OPENSSL
|
||||
# include <openssl/des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <openssl/md4.h>
|
||||
# endif
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# include <openssl/des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <openssl/md4.h>
|
||||
# else
|
||||
# include <des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <md4.h>
|
||||
# endif
|
||||
# include <md5.h>
|
||||
# include <ssl.h>
|
||||
# include <rand.h>
|
||||
# include "curl_md4.h"
|
||||
# endif
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
||||
# define DES_key_schedule des_key_schedule
|
||||
# define DES_cblock des_cblock
|
||||
@@ -111,7 +103,7 @@
|
||||
# include "curl_md4.h"
|
||||
# endif
|
||||
|
||||
#elif defined(USE_DARWINSSL)
|
||||
#elif defined(USE_SECTRANSP)
|
||||
|
||||
# include <CommonCrypto/CommonCryptor.h>
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
@@ -300,7 +292,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
|
||||
}
|
||||
|
||||
#elif defined(USE_DARWINSSL)
|
||||
#elif defined(USE_SECTRANSP)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
@@ -447,7 +439,7 @@ 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_MBEDTLS) || defined(USE_DARWINSSL) \
|
||||
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
@@ -511,7 +503,7 @@ 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_MBEDTLS) || defined(USE_DARWINSSL) \
|
||||
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
@@ -578,10 +570,14 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
{
|
||||
/* Create NT hashed password. */
|
||||
#ifdef USE_OPENSSL
|
||||
#if !defined(OPENSSL_NO_MD4)
|
||||
MD4_CTX MD4pw;
|
||||
MD4_Init(&MD4pw);
|
||||
MD4_Update(&MD4pw, pw, 2 * len);
|
||||
MD4_Final(ntbuffer, &MD4pw);
|
||||
#else
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#endif
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
struct md4_ctx MD4pw;
|
||||
md4_init(&MD4pw);
|
||||
@@ -601,7 +597,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
#else
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#endif
|
||||
#elif defined(USE_DARWINSSL)
|
||||
#elif defined(USE_SECTRANSP)
|
||||
(void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
@@ -631,9 +627,9 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/* This returns the HMAC MD5 digest */
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output)
|
||||
static CURLcode hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output)
|
||||
{
|
||||
HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
|
||||
|
||||
@@ -678,9 +674,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
||||
ascii_uppercase_to_unicode_le(identity, user, userlen);
|
||||
ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
|
||||
|
||||
result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
|
||||
ntlmv2hash);
|
||||
|
||||
result = hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
|
||||
ntlmv2hash);
|
||||
free(identity);
|
||||
|
||||
return result;
|
||||
@@ -753,12 +748,12 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Create the BLOB structure */
|
||||
snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c", /* Reserved = 0 */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0);
|
||||
msnprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c", /* Reserved = 0 */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0);
|
||||
|
||||
Curl_write64_le(tw, ptr + 24);
|
||||
memcpy(ptr + 32, challenge_client, 8);
|
||||
@@ -766,8 +761,8 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
|
||||
/* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
|
||||
memcpy(ptr + 8, &ntlm->nonce[0], 8);
|
||||
result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
|
||||
NTLMv2_BLOB_LEN + 8, hmac_output);
|
||||
result = hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
|
||||
NTLMv2_BLOB_LEN + 8, hmac_output);
|
||||
if(result) {
|
||||
free(ptr);
|
||||
return result;
|
||||
@@ -809,7 +804,7 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
memcpy(&data[0], challenge_server, 8);
|
||||
memcpy(&data[8], challenge_client, 8);
|
||||
|
||||
result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
|
||||
result = hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -43,9 +43,7 @@
|
||||
|
||||
/* Define USE_NTRESPONSES in order to make the type-3 message include
|
||||
* the NT response message. */
|
||||
#if !defined(USE_OPENSSL) || !defined(OPENSSL_NO_MD4)
|
||||
#define USE_NTRESPONSES
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM2SESSION in order to make the type-3 message include the
|
||||
NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -53,6 +53,8 @@
|
||||
#include "url.h"
|
||||
#include "strerror.h"
|
||||
#include "strdup.h"
|
||||
#include "strcase.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -74,7 +76,7 @@
|
||||
# define sclose_nolog(x) close((x))
|
||||
#endif
|
||||
|
||||
void Curl_ntlm_wb_cleanup(struct connectdata *conn)
|
||||
void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn)
|
||||
{
|
||||
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
|
||||
sclose(conn->ntlm_auth_hlpr_socket);
|
||||
@@ -124,6 +126,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
struct passwd pw, *pw_res;
|
||||
char pwbuf[1024];
|
||||
#endif
|
||||
char buffer[STRERROR_LEN];
|
||||
|
||||
/* Return if communication with ntlm_auth already set up */
|
||||
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
|
||||
@@ -179,13 +182,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
|
||||
if(access(ntlm_auth, X_OK) != 0) {
|
||||
failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
|
||||
ntlm_auth, errno, Curl_strerror(conn, errno));
|
||||
ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
|
||||
failf(conn->data, "Could not open socket pair. errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -194,7 +197,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
sclose(sockfds[0]);
|
||||
sclose(sockfds[1]);
|
||||
failf(conn->data, "Could not fork. errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
goto done;
|
||||
}
|
||||
else if(!child_pid) {
|
||||
@@ -206,13 +209,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
sclose_nolog(sockfds[0]);
|
||||
if(dup2(sockfds[1], STDIN_FILENO) == -1) {
|
||||
failf(conn->data, "Could not redirect child stdin. errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
|
||||
failf(conn->data, "Could not redirect child stdout. errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -232,7 +235,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
|
||||
sclose_nolog(sockfds[1]);
|
||||
failf(conn->data, "Could not execl(). errno %d: %s",
|
||||
errno, Curl_strerror(conn, errno));
|
||||
errno, Curl_strerror(errno, buffer, sizeof(buffer)));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -332,6 +335,48 @@ done:
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
|
||||
bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
curlntlm *state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
|
||||
|
||||
if(!checkprefix("NTLM", header))
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
header += strlen("NTLM");
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
if(*header) {
|
||||
conn->challenge_header = strdup(header);
|
||||
if(!conn->challenge_header)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
*state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(*state == NTLMSTATE_LAST) {
|
||||
infof(conn->data, "NTLM auth restarted\n");
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
}
|
||||
else if(*state == NTLMSTATE_TYPE3) {
|
||||
infof(conn->data, "NTLM handshake rejected\n");
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
*state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
else if(*state >= NTLMSTATE_TYPE1) {
|
||||
infof(conn->data, "NTLM handshake failure (internal error)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
*state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for creating ntlm header output by delegating challenge/response
|
||||
* to Samba's winbind daemon helper ntlm_auth.
|
||||
@@ -344,8 +389,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
char **allocuserpwd;
|
||||
/* point to the name and password for this */
|
||||
const char *userp;
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
curlntlm *state;
|
||||
struct auth *authp;
|
||||
|
||||
CURLcode res = CURLE_OK;
|
||||
@@ -357,13 +401,13 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
ntlm = &conn->proxyntlm;
|
||||
state = &conn->proxy_ntlm_state;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
ntlm = &conn->ntlm;
|
||||
state = &conn->http_ntlm_state;
|
||||
authp = &conn->data->state.authhost;
|
||||
}
|
||||
authp->done = FALSE;
|
||||
@@ -372,7 +416,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
switch(ntlm->state) {
|
||||
switch(*state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default:
|
||||
/* Use Samba's 'winbind' daemon to support NTLM authentication,
|
||||
@@ -391,7 +435,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
res = ntlm_wb_init(conn, userp);
|
||||
if(res)
|
||||
return res;
|
||||
res = ntlm_wb_response(conn, "YR\n", ntlm->state);
|
||||
res = ntlm_wb_response(conn, "YR\n", *state);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
@@ -405,11 +449,12 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
conn->response_header = NULL;
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE2:
|
||||
input = aprintf("TT %s\n", conn->challenge_header);
|
||||
if(!input)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
res = ntlm_wb_response(conn, input, ntlm->state);
|
||||
res = ntlm_wb_response(conn, input, *state);
|
||||
free(input);
|
||||
input = NULL;
|
||||
if(res)
|
||||
@@ -420,17 +465,20 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
*state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
authp->done = TRUE;
|
||||
Curl_ntlm_wb_cleanup(conn);
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = NULL;
|
||||
*state = NTLMSTATE_LAST;
|
||||
/* FALLTHROUGH */
|
||||
case NTLMSTATE_LAST:
|
||||
Curl_safefree(*allocuserpwd);
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -27,11 +27,14 @@
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
|
||||
defined(NTLM_WB_ENABLED)
|
||||
|
||||
/* this is for creating ntlm header output by delegating challenge/response
|
||||
to Samba's winbind daemon helper ntlm_auth */
|
||||
/* this is for ntlm header input */
|
||||
CURLcode Curl_input_ntlm_wb(struct connectdata *conn, bool proxy,
|
||||
const char *header);
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_ntlm_wb_cleanup(struct connectdata *conn);
|
||||
void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn);
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,6 +22,8 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_SSH)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_memory.h"
|
||||
#include "curl_path.h"
|
||||
@@ -193,3 +195,5 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir)
|
||||
Curl_safefree(*path);
|
||||
return CURLE_QUOTE_ERROR;
|
||||
}
|
||||
|
||||
#endif /* if SSH is used */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef snprintf
|
||||
# undef msnprintf
|
||||
# undef vprintf
|
||||
# undef vfprintf
|
||||
# undef vsnprintf
|
||||
@@ -39,18 +39,10 @@
|
||||
# undef vaprintf
|
||||
# define printf curl_mprintf
|
||||
# define fprintf curl_mfprintf
|
||||
# define snprintf curl_msnprintf
|
||||
# define msnprintf curl_msnprintf
|
||||
# define vprintf curl_mvprintf
|
||||
# define vfprintf curl_mvfprintf
|
||||
# define vsnprintf curl_mvsnprintf
|
||||
# define mvsnprintf curl_mvsnprintf
|
||||
# define aprintf curl_maprintf
|
||||
# define vaprintf curl_mvaprintf
|
||||
|
||||
/* We define away the sprintf functions unconditonally since we don't want
|
||||
internal code to be using them, intentionally or by mistake!*/
|
||||
# undef sprintf
|
||||
# undef vsprintf
|
||||
# define sprintf sprintf_was_used
|
||||
# define vsprintf vsprintf_was_used
|
||||
|
||||
#endif /* HEADER_CURL_PRINTF_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -239,17 +239,18 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
RTMP *r = conn->proto.generic;
|
||||
|
||||
if(!RTMP_ConnectStream(r, 0))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
if(conn->data->set.upload) {
|
||||
Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
||||
}
|
||||
else
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2019, 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,6 +31,9 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
|
||||
!defined(CURL_DISABLE_POP3)
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "urldata.h"
|
||||
|
||||
@@ -83,14 +86,14 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
|
||||
#if defined(USE_KERBEROS5)
|
||||
/* Cleanup the gssapi structure */
|
||||
if(authused == SASL_MECH_GSSAPI) {
|
||||
Curl_auth_gssapi_cleanup(&conn->krb5);
|
||||
Curl_auth_cleanup_gssapi(&conn->krb5);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_NTLM)
|
||||
/* Cleanup the NTLM structure */
|
||||
if(authused == SASL_MECH_NTLM) {
|
||||
Curl_auth_ntlm_cleanup(&conn->ntlm);
|
||||
Curl_auth_cleanup_ntlm(&conn->ntlm);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -290,7 +293,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
#if defined(USE_KERBEROS5)
|
||||
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 */
|
||||
sasl->mutual_auth = FALSE;
|
||||
mech = SASL_MECH_STRING_GSSAPI;
|
||||
state1 = SASL_GSSAPI;
|
||||
state2 = SASL_GSSAPI_TOKEN;
|
||||
@@ -300,8 +303,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
result = Curl_auth_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd,
|
||||
service,
|
||||
data->easy_conn->
|
||||
host.name,
|
||||
data->conn->host.name,
|
||||
sasl->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
&resp, &len);
|
||||
@@ -358,10 +360,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
sasl->authused = SASL_MECH_XOAUTH2;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
||||
NULL, 0,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_PLAIN) {
|
||||
mech = SASL_MECH_STRING_PLAIN;
|
||||
@@ -369,8 +370,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
sasl->authused = SASL_MECH_PLAIN;
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_plain_message(data, conn->user, conn->passwd,
|
||||
&resp, &len);
|
||||
result = Curl_auth_create_plain_message(data, NULL, conn->user,
|
||||
conn->passwd, &resp, &len);
|
||||
}
|
||||
else if(enabledmechs & SASL_MECH_LOGIN) {
|
||||
mech = SASL_MECH_STRING_LOGIN;
|
||||
@@ -452,9 +453,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
*progress = SASL_DONE;
|
||||
return result;
|
||||
case SASL_PLAIN:
|
||||
result = Curl_auth_create_plain_message(data, conn->user, conn->passwd,
|
||||
&resp,
|
||||
&len);
|
||||
result = Curl_auth_create_plain_message(data, NULL, conn->user,
|
||||
conn->passwd, &resp, &len);
|
||||
break;
|
||||
case SASL_LOGIN:
|
||||
result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
|
||||
@@ -517,7 +517,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
result = Curl_auth_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd,
|
||||
service,
|
||||
data->easy_conn->host.name,
|
||||
data->conn->host.name,
|
||||
sasl->mutual_auth, NULL,
|
||||
&conn->krb5,
|
||||
&resp, &len);
|
||||
@@ -563,10 +563,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
newstate = SASL_OAUTH2_RESP;
|
||||
}
|
||||
else
|
||||
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
||||
NULL, 0,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
break;
|
||||
|
||||
case SASL_OAUTH2_RESP:
|
||||
@@ -627,3 +626,4 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* protocols are enabled that use SASL */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -314,11 +314,12 @@
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# ifndef __ixemul__
|
||||
# include <exec/types.h>
|
||||
# include <exec/execbase.h>
|
||||
# include <proto/exec.h>
|
||||
# include <proto/dos.h>
|
||||
# include <exec/types.h>
|
||||
# include <exec/execbase.h>
|
||||
# include <proto/exec.h>
|
||||
# include <proto/dos.h>
|
||||
# ifdef HAVE_PROTO_BSDSOCKET_H
|
||||
# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */
|
||||
# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
|
||||
# endif
|
||||
#endif
|
||||
@@ -661,9 +662,9 @@ int netware_init(void);
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
|
||||
defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_POLARSSL) || defined(USE_MBEDTLS) || \
|
||||
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_DARWINSSL) || defined(USE_GSKIT) || defined(USE_MESALINK)
|
||||
defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
@@ -682,7 +683,7 @@ int netware_init(void);
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
|
||||
defined(USE_MBEDTLS)
|
||||
|
||||
@@ -700,6 +701,10 @@ int netware_init(void);
|
||||
#error "No longer supported. Set CURLOPT_CAINFO at runtime instead."
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) || defined(USE_WOLFSSH)
|
||||
#define USE_SSH
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide a mechanism to silence picky compilers, such as gcc 4.6+.
|
||||
* Parameters should of course normally not be unused, but for example when
|
||||
@@ -831,4 +836,10 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf,
|
||||
size_t buflen, struct passwd **result);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define UNITTEST
|
||||
#else
|
||||
#define UNITTEST static
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -81,22 +81,21 @@
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef sprintf
|
||||
# undef snprintf
|
||||
# undef msnprintf
|
||||
# undef vprintf
|
||||
# undef vfprintf
|
||||
# undef vsprintf
|
||||
# undef vsnprintf
|
||||
# undef mvsnprintf
|
||||
# undef aprintf
|
||||
# undef vaprintf
|
||||
|
||||
# define printf curlx_mprintf
|
||||
# define fprintf curlx_mfprintf
|
||||
# define sprintf curlx_msprintf
|
||||
# define snprintf curlx_msnprintf
|
||||
# define msnprintf curlx_msnprintf
|
||||
# define vprintf curlx_mvprintf
|
||||
# define vfprintf curlx_mvfprintf
|
||||
# define vsprintf curlx_mvsprintf
|
||||
# define vsnprintf curlx_mvsnprintf
|
||||
# define mvsnprintf curlx_mvsnprintf
|
||||
# define aprintf curlx_maprintf
|
||||
# define vaprintf curlx_mvaprintf
|
||||
#endif /* ENABLE_CURLX_PRINTF */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -137,7 +137,6 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
char *path = data->state.up.path;
|
||||
curl_off_t *bytecount = &data->req.bytecount;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@@ -200,8 +199,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
failf(data, "Failed sending DICT request");
|
||||
return result;
|
||||
}
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); /* no upload */
|
||||
}
|
||||
else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
@@ -247,8 +245,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
failf(data, "Failed sending DICT request");
|
||||
return result;
|
||||
}
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -270,7 +267,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+87
-40
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2019, 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,17 +22,19 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
|
||||
#include "urldata.h"
|
||||
#include "curl_addrinfo.h"
|
||||
#include "doh.h"
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
#include "sendf.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "share.h"
|
||||
#include "curl_base64.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -143,8 +145,8 @@ doh_write_cb(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
/* suspiciously much for us */
|
||||
return 0;
|
||||
|
||||
mem->memory = realloc(mem->memory, mem->size + realsize);
|
||||
if(mem->memory == NULL)
|
||||
mem->memory = Curl_saferealloc(mem->memory, mem->size + realsize);
|
||||
if(!mem->memory)
|
||||
/* out of memory! */
|
||||
return 0;
|
||||
|
||||
@@ -160,7 +162,7 @@ static int Curl_doh_done(struct Curl_easy *doh, CURLcode result)
|
||||
struct Curl_easy *data = doh->set.dohfor;
|
||||
/* so one of the DOH request done for the 'data' transfer is now complete! */
|
||||
data->req.doh.pending--;
|
||||
infof(data, "a DOH request is completed, %d to go\n", data->req.doh.pending);
|
||||
infof(data, "a DOH request is completed, %u to go\n", data->req.doh.pending);
|
||||
if(result)
|
||||
infof(data, "DOH request %s\n", curl_easy_strerror(result));
|
||||
|
||||
@@ -173,8 +175,12 @@ static int Curl_doh_done(struct Curl_easy *doh, CURLcode result)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ERROR_CHECK_SETOPT(x,y) result = curl_easy_setopt(doh, x, y); \
|
||||
if(result) goto error
|
||||
#define ERROR_CHECK_SETOPT(x,y) \
|
||||
do { \
|
||||
result = curl_easy_setopt(doh, x, y); \
|
||||
if(result) \
|
||||
goto error; \
|
||||
} WHILE_FALSE
|
||||
|
||||
static CURLcode dohprobe(struct Curl_easy *data,
|
||||
struct dnsprobe *p, DNStype dnstype,
|
||||
@@ -234,13 +240,76 @@ static CURLcode dohprobe(struct Curl_easy *data,
|
||||
ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDSIZE, (long)p->dohlen);
|
||||
}
|
||||
ERROR_CHECK_SETOPT(CURLOPT_HTTPHEADER, headers);
|
||||
#ifdef USE_NGHTTP2
|
||||
ERROR_CHECK_SETOPT(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||
#endif
|
||||
#ifndef CURLDEBUG
|
||||
/* enforce HTTPS if not debug */
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
|
||||
#endif
|
||||
ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms);
|
||||
ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L);
|
||||
if(data->set.verbose)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L);
|
||||
if(data->set.no_signal)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L);
|
||||
|
||||
/* Inherit *some* SSL options from the user's transfer. This is a
|
||||
best-guess as to which options are needed for compatibility. #3661 */
|
||||
if(data->set.ssl.falsestart)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L);
|
||||
if(data->set.ssl.primary.verifyhost)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L);
|
||||
if(data->set.proxy_ssl.primary.verifyhost)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L);
|
||||
if(data->set.ssl.primary.verifypeer)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
if(data->set.proxy_ssl.primary.verifypeer)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
|
||||
if(data->set.ssl.primary.verifystatus)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L);
|
||||
if(data->set.str[STRING_SSL_CAFILE_ORIG]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_CAINFO,
|
||||
data->set.str[STRING_SSL_CAFILE_ORIG]);
|
||||
}
|
||||
if(data->set.str[STRING_SSL_CAFILE_PROXY]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO,
|
||||
data->set.str[STRING_SSL_CAFILE_PROXY]);
|
||||
}
|
||||
if(data->set.str[STRING_SSL_CAPATH_ORIG]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_CAPATH,
|
||||
data->set.str[STRING_SSL_CAPATH_ORIG]);
|
||||
}
|
||||
if(data->set.str[STRING_SSL_CAPATH_PROXY]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH,
|
||||
data->set.str[STRING_SSL_CAPATH_PROXY]);
|
||||
}
|
||||
if(data->set.str[STRING_SSL_CRLFILE_ORIG]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_CRLFILE,
|
||||
data->set.str[STRING_SSL_CRLFILE_ORIG]);
|
||||
}
|
||||
if(data->set.str[STRING_SSL_CRLFILE_PROXY]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE,
|
||||
data->set.str[STRING_SSL_CRLFILE_PROXY]);
|
||||
}
|
||||
if(data->set.ssl.certinfo)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L);
|
||||
if(data->set.str[STRING_SSL_RANDOM_FILE]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE,
|
||||
data->set.str[STRING_SSL_RANDOM_FILE]);
|
||||
}
|
||||
if(data->set.str[STRING_SSL_EGDSOCKET]) {
|
||||
ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET,
|
||||
data->set.str[STRING_SSL_EGDSOCKET]);
|
||||
}
|
||||
if(data->set.ssl.no_revoke)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
|
||||
if(data->set.proxy_ssl.no_revoke)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
|
||||
if(data->set.ssl.fsslctx)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx);
|
||||
if(data->set.ssl.fsslctxp)
|
||||
ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp);
|
||||
|
||||
doh->set.fmultidone = Curl_doh_done;
|
||||
doh->set.dohfor = data; /* identify for which transfer this is done */
|
||||
p->easy = doh;
|
||||
@@ -515,7 +584,6 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
|
||||
unsigned short qdcount;
|
||||
unsigned short ancount;
|
||||
unsigned short type = 0;
|
||||
unsigned short class;
|
||||
unsigned short rdlength;
|
||||
unsigned short nscount;
|
||||
unsigned short arcount;
|
||||
@@ -524,7 +592,7 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
|
||||
|
||||
if(dohlen < 12)
|
||||
return DOH_TOO_SMALL_BUFFER; /* too small */
|
||||
if(doh[0] || doh[1])
|
||||
if(!doh || doh[0] || doh[1])
|
||||
return DOH_DNS_BAD_ID; /* bad ID */
|
||||
rcode = doh[3] & 0x0f;
|
||||
if(rcode)
|
||||
@@ -543,6 +611,7 @@ UNITTEST DOHcode doh_decode(unsigned char *doh,
|
||||
|
||||
ancount = get16bit(doh, 6);
|
||||
while(ancount) {
|
||||
unsigned short class;
|
||||
unsigned int ttl;
|
||||
|
||||
rc = skipqname(doh, dohlen, &index);
|
||||
@@ -660,13 +729,13 @@ static void showdoh(struct Curl_easy *data,
|
||||
char buffer[128];
|
||||
char *ptr;
|
||||
size_t len;
|
||||
snprintf(buffer, 128, "DOH AAAA: ");
|
||||
msnprintf(buffer, 128, "DOH AAAA: ");
|
||||
ptr = &buffer[10];
|
||||
len = 118;
|
||||
for(j = 0; j < 16; j += 2) {
|
||||
size_t l;
|
||||
snprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j],
|
||||
d->addr[i].ip.v6[j + 1]);
|
||||
msnprintf(ptr, len, "%s%02x%02x", j?":":"", d->addr[i].ip.v6[j],
|
||||
d->addr[i].ip.v6[j + 1]);
|
||||
l = strlen(ptr);
|
||||
len -= l;
|
||||
ptr += l;
|
||||
@@ -827,8 +896,6 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
DOHcode rc;
|
||||
DOHcode rc2;
|
||||
struct dohentry de;
|
||||
struct Curl_dns_entry *dns;
|
||||
struct Curl_addrinfo *ai;
|
||||
/* remove DOH handles from multi handle and close them */
|
||||
curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy);
|
||||
Curl_close(data->req.doh.probe[0].easy);
|
||||
@@ -853,11 +920,14 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
&de);
|
||||
free(data->req.doh.probe[1].serverdoh.memory);
|
||||
if(rc2) {
|
||||
infof(data, "DOG: %s type %s for %s\n", doh_strerror(rc2),
|
||||
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2),
|
||||
type2name(data->req.doh.probe[1].dnstype),
|
||||
data->req.doh.host);
|
||||
}
|
||||
if(!rc || !rc2) {
|
||||
struct Curl_dns_entry *dns;
|
||||
struct Curl_addrinfo *ai;
|
||||
|
||||
infof(data, "DOH Host name: %s\n", data->req.doh.host);
|
||||
showdoh(data, &de);
|
||||
|
||||
@@ -894,27 +964,4 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#else /* !USE_NGHTTP2 */
|
||||
/*
|
||||
*/
|
||||
Curl_addrinfo *Curl_doh(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *waitp)
|
||||
{
|
||||
(void)conn;
|
||||
(void)hostname;
|
||||
(void)port;
|
||||
(void)waitp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CURLcode Curl_doh_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dnsp)
|
||||
{
|
||||
(void)conn;
|
||||
(void)dnsp;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
#endif /* USE_NGHTTP2 */
|
||||
#endif /* CURL_DISABLE_DOH */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2018 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "urldata.h"
|
||||
#include "curl_addrinfo.h"
|
||||
|
||||
#ifndef CURL_DISABLE_DOH
|
||||
|
||||
/*
|
||||
* Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name
|
||||
* and returns a 'Curl_addrinfo *' with the address information.
|
||||
@@ -102,4 +104,10 @@ DOHcode doh_decode(unsigned char *doh,
|
||||
struct dohentry *d);
|
||||
void de_cleanup(struct dohentry *d);
|
||||
#endif
|
||||
|
||||
#else /* if DOH is disabled */
|
||||
#define Curl_doh(a,b,c,d) NULL
|
||||
#define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_DOH_H */
|
||||
|
||||
+27
-84
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,6 +75,7 @@
|
||||
#include "ssh.h"
|
||||
#include "setopt.h"
|
||||
#include "http_digest.h"
|
||||
#include "system_win32.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -83,70 +84,6 @@
|
||||
|
||||
void Curl_version_init(void);
|
||||
|
||||
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
|
||||
of win32_init() */
|
||||
static void win32_cleanup(void)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
Curl_sspi_global_cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* win32_init() performs win32 socket initialization to properly setup the
|
||||
stack to allow networking */
|
||||
static CURLcode win32_init(void)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int res;
|
||||
|
||||
#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
|
||||
Error IPV6_requires_winsock2
|
||||
#endif
|
||||
|
||||
wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
|
||||
|
||||
res = WSAStartup(wVersionRequested, &wsaData);
|
||||
|
||||
if(res != 0)
|
||||
/* Tell the user that we couldn't find a usable */
|
||||
/* winsock.dll. */
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Confirm that the Windows Sockets DLL supports what we need.*/
|
||||
/* Note that if the DLL supports versions greater */
|
||||
/* than wVersionRequested, it will still return */
|
||||
/* wVersionRequested in wVersion. wHighVersion contains the */
|
||||
/* highest supported version. */
|
||||
|
||||
if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
|
||||
HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
|
||||
/* Tell the user that we couldn't find a usable */
|
||||
|
||||
/* winsock.dll. */
|
||||
WSACleanup();
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
/* The Windows Sockets DLL is acceptable. Proceed. */
|
||||
#elif defined(USE_LWIPSOCK)
|
||||
lwip_init();
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
{
|
||||
CURLcode result = Curl_sspi_global_init();
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||
static unsigned int initialized;
|
||||
static long init_flags;
|
||||
@@ -223,11 +160,12 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
if(flags & CURL_GLOBAL_WIN32)
|
||||
if(win32_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#ifdef WIN32
|
||||
if(Curl_win32_init(flags)) {
|
||||
DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
if(!Curl_amiga_init()) {
|
||||
@@ -327,12 +265,12 @@ void curl_global_cleanup(void)
|
||||
if(--initialized)
|
||||
return;
|
||||
|
||||
Curl_global_host_cache_dtor();
|
||||
Curl_ssl_cleanup();
|
||||
Curl_resolver_global_cleanup();
|
||||
|
||||
if(init_flags & CURL_GLOBAL_WIN32)
|
||||
win32_cleanup();
|
||||
#ifdef WIN32
|
||||
Curl_win32_cleanup(init_flags);
|
||||
#endif
|
||||
|
||||
Curl_amiga_cleanup();
|
||||
|
||||
@@ -489,8 +427,8 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
|
||||
mask. Convert from libcurl bitmask to the poll one. */
|
||||
m->socket.events = socketcb2poll(what);
|
||||
infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
|
||||
what&CURL_POLL_IN?"IN":"",
|
||||
what&CURL_POLL_OUT?"OUT":"");
|
||||
(what&CURL_POLL_IN)?"IN":"",
|
||||
(what&CURL_POLL_OUT)?"OUT":"");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -513,8 +451,8 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */
|
||||
m->socket.revents = 0;
|
||||
ev->list = m;
|
||||
infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
|
||||
what&CURL_POLL_IN?"IN":"",
|
||||
what&CURL_POLL_OUT?"OUT":"");
|
||||
(what&CURL_POLL_IN)?"IN":"",
|
||||
(what&CURL_POLL_OUT)?"OUT":"");
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -621,7 +559,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
if(mcode)
|
||||
return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
/* we don't really care about the "msgs_in_queue" value returned in the
|
||||
second argument */
|
||||
@@ -664,12 +602,12 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
|
||||
|
||||
while(!done && !mcode) {
|
||||
int still_running = 0;
|
||||
int rc;
|
||||
bool gotsocket = FALSE;
|
||||
|
||||
mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
|
||||
mcode = Curl_multi_wait(multi, NULL, 0, 1000, NULL, &gotsocket);
|
||||
|
||||
if(!mcode) {
|
||||
if(!rc) {
|
||||
if(!gotsocket) {
|
||||
long sleep_ms;
|
||||
|
||||
/* If it returns without any filedescriptor instantly, we need to
|
||||
@@ -688,6 +626,7 @@ static CURLcode easy_transfer(struct Curl_multi *multi)
|
||||
|
||||
/* only read 'still_running' if curl_multi_perform() return OK */
|
||||
if(!mcode && !still_running) {
|
||||
int rc;
|
||||
CURLMsg *msg = curl_multi_info_read(multi, &rc);
|
||||
if(msg) {
|
||||
result = msg->data.result;
|
||||
@@ -966,7 +905,8 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
}
|
||||
|
||||
/* Clone the resolver handle, if present, for the new handle */
|
||||
if(Curl_resolver_duphandle(&outcurl->state.resolver,
|
||||
if(Curl_resolver_duphandle(outcurl,
|
||||
&outcurl->state.resolver,
|
||||
data->state.resolver))
|
||||
goto fail;
|
||||
|
||||
@@ -1021,7 +961,10 @@ void curl_easy_reset(struct Curl_easy *data)
|
||||
/* zero out authentication data: */
|
||||
memset(&data->state.authhost, 0, sizeof(struct auth));
|
||||
memset(&data->state.authproxy, 0, sizeof(struct auth));
|
||||
Curl_digest_cleanup(data);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
Curl_http_auth_cleanup_digest(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1058,7 +1001,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
unsigned int i;
|
||||
unsigned int count = data->state.tempcount;
|
||||
struct tempbuf writebuf[3]; /* there can only be three */
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct Curl_easy *saved_data = NULL;
|
||||
|
||||
/* copy the structs to allow for immediate re-pausing */
|
||||
|
||||
@@ -122,7 +122,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(&ns[strindex], 4, "%%%02X", in);
|
||||
msnprintf(&ns[strindex], 4, "%%%02X", in);
|
||||
|
||||
strindex += 3;
|
||||
}
|
||||
|
||||
+15
-14
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -311,7 +311,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(readcount <= 0) /* fix questionable compare error. curlvms */
|
||||
if(!readcount)
|
||||
break;
|
||||
|
||||
nread = readcount;
|
||||
@@ -417,8 +417,9 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
struct tm buffer;
|
||||
const struct tm *tm = &buffer;
|
||||
char header[80];
|
||||
snprintf(header, sizeof(header),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
|
||||
msnprintf(header, sizeof(header),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n",
|
||||
expected_size);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -434,16 +435,16 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
snprintf(header, sizeof(header),
|
||||
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s",
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec,
|
||||
data->set.opt_no_body ? "": "\r\n");
|
||||
msnprintf(header, sizeof(header),
|
||||
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s",
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec,
|
||||
data->set.opt_no_body ? "": "\r\n");
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2019, 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
|
||||
@@ -21,7 +21,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#include "strdup.h"
|
||||
#include "fileinfo.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -41,3 +41,4 @@ void Curl_fileinfo_cleanup(struct fileinfo *finfo)
|
||||
Curl_safefree(finfo->info.b_data);
|
||||
free(finfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -24,14 +24,14 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
#include "formdata.h"
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)
|
||||
|
||||
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h" /* for struct Curl_easy */
|
||||
#include "formdata.h"
|
||||
#include "mime.h"
|
||||
#include "non-ascii.h"
|
||||
#include "vtls/vtls.h"
|
||||
@@ -569,7 +569,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
if(((form->flags & HTTPPOST_FILENAME) ||
|
||||
(form->flags & HTTPPOST_BUFFER)) &&
|
||||
!form->contenttype) {
|
||||
char *f = form->flags & HTTPPOST_BUFFER?
|
||||
char *f = (form->flags & HTTPPOST_BUFFER)?
|
||||
form->showfilename : form->value;
|
||||
char const *type;
|
||||
type = Curl_mime_contenttype(f);
|
||||
@@ -921,7 +921,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
#else
|
||||
/* if disabled */
|
||||
CURLFORMcode curl_formadd(struct curl_httppost **httppost,
|
||||
struct curl_httppost **last_post,
|
||||
...)
|
||||
@@ -946,5 +947,4 @@ void curl_formfree(struct curl_httppost *form)
|
||||
/* does nothing HTTP is disabled */
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) */
|
||||
#endif /* if disabled */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,6 +22,10 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_MIME
|
||||
|
||||
/* used by FormAdd for temporary storage */
|
||||
typedef struct FormInfo {
|
||||
char *name;
|
||||
@@ -47,5 +51,10 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
curl_mimepart *,
|
||||
struct curl_httppost *post,
|
||||
curl_read_callback fread_func);
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_getformdata(a,b,c,d) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_FORMDATA_H */
|
||||
|
||||
+47
-56
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -448,7 +448,6 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
static CURLcode InitiateTransfer(struct connectdata *conn)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->bits.ftp_use_data_ssl) {
|
||||
@@ -461,24 +460,19 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(conn->proto.ftpc.state_saved == FTP_STOR) {
|
||||
*(ftp->bytecountp) = 0;
|
||||
|
||||
/* When we know we're uploading a specified file, we can get the file
|
||||
size prior to the actual upload. */
|
||||
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
|
||||
/* set the SO_SNDBUF for the secondary socket for those who need it */
|
||||
Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
|
||||
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
|
||||
SECONDARYSOCKET, ftp->bytecountp);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, SECONDARYSOCKET);
|
||||
}
|
||||
else {
|
||||
/* FTP download: */
|
||||
Curl_setup_transfer(conn, SECONDARYSOCKET,
|
||||
conn->proto.ftpc.retr_size_saved, FALSE,
|
||||
ftp->bytecountp, -1, NULL); /* no upload here */
|
||||
Curl_setup_transfer(data, SECONDARYSOCKET,
|
||||
conn->proto.ftpc.retr_size_saved, FALSE, -1);
|
||||
}
|
||||
|
||||
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
|
||||
@@ -578,7 +572,6 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
|
||||
#if defined(HAVE_GSSAPI)
|
||||
/* handle the security-oriented responses 6xx ***/
|
||||
/* FIXME: some errorchecking perhaps... ***/
|
||||
switch(code) {
|
||||
case 631:
|
||||
code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
|
||||
@@ -655,7 +648,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
|
||||
while(!*ftpcode && !result) {
|
||||
/* check and reset timeout value every lap */
|
||||
time_t timeout = Curl_pp_state_timeout(pp); /* timeout in milliseconds */
|
||||
time_t timeout = Curl_pp_state_timeout(pp, FALSE);
|
||||
time_t interval_ms;
|
||||
|
||||
if(timeout <= 0) {
|
||||
@@ -955,7 +948,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
unsigned short port_max = 0;
|
||||
unsigned short port;
|
||||
bool possibly_non_local = TRUE;
|
||||
|
||||
char buffer[STRERROR_LEN];
|
||||
char *addr = NULL;
|
||||
|
||||
/* Step 1, figure out what is requested,
|
||||
@@ -1064,11 +1057,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(!host) {
|
||||
/* not an interface and not a host name, get default by extracting
|
||||
the IP from the control connection */
|
||||
|
||||
sslen = sizeof(ss);
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
free(addr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1087,7 +1079,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* resolv ip/host to ip */
|
||||
rc = Curl_resolv(conn, host, 0, &h);
|
||||
rc = Curl_resolv(conn, host, 0, FALSE, &h);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
(void)Curl_resolver_wait_resolv(conn, &h);
|
||||
if(h) {
|
||||
@@ -1121,7 +1113,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
if(!ai) {
|
||||
failf(data, "socket failure: %s", Curl_strerror(conn, error));
|
||||
failf(data, "socket failure: %s",
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
@@ -1145,14 +1138,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
/* The requested bind address is not local. Use the address used for
|
||||
* the control connection instead and restart the port loop
|
||||
*/
|
||||
|
||||
infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
|
||||
Curl_strerror(conn, error) );
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
|
||||
sslen = sizeof(ss);
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1162,7 +1154,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
}
|
||||
if(error != EADDRINUSE && error != EACCES) {
|
||||
failf(data, "bind(port=%hu) failed: %s", port,
|
||||
Curl_strerror(conn, error) );
|
||||
Curl_strerror(error, buffer, sizeof(buffer)));
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1185,7 +1177,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
sslen = sizeof(ss);
|
||||
if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1193,7 +1185,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
/* step 4, listen on the socket */
|
||||
|
||||
if(listen(portsock, 1)) {
|
||||
failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
|
||||
failf(data, "socket failure: %s",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
Curl_closesocket(conn, portsock);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
@@ -1272,7 +1265,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
source++;
|
||||
}
|
||||
*dest = 0;
|
||||
snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
|
||||
msnprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
|
||||
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
|
||||
if(result) {
|
||||
@@ -1658,7 +1651,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
|
||||
infof(data, "File already completely uploaded\n");
|
||||
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
|
||||
/* Set ->transfer so that we won't get any error in
|
||||
* ftp_done() because we didn't transfer anything! */
|
||||
@@ -1940,7 +1933,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
*/
|
||||
const char * const host_name = conn->bits.socksproxy ?
|
||||
conn->socks_proxy.host.name : conn->http_proxy.host.name;
|
||||
rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
|
||||
rc = Curl_resolv(conn, host_name, (int)conn->port, FALSE, &addr);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
||||
case of failure */
|
||||
@@ -1956,7 +1949,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
/* normal, direct, ftp connection */
|
||||
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
|
||||
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, FALSE, &addr);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING */
|
||||
(void)Curl_resolver_wait_resolv(conn, &addr);
|
||||
@@ -2061,9 +2054,9 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
char timebuf[24];
|
||||
time_t secs = time(NULL);
|
||||
|
||||
snprintf(timebuf, sizeof(timebuf),
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
msnprintf(timebuf, sizeof(timebuf),
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
/* now, convert this into a time() value: */
|
||||
data->info.filetime = curl_getdate(timebuf, &secs);
|
||||
}
|
||||
@@ -2086,15 +2079,15 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
return result;
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26" */
|
||||
snprintf(headerbuf, sizeof(headerbuf),
|
||||
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec);
|
||||
msnprintf(headerbuf, sizeof(headerbuf),
|
||||
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -2230,7 +2223,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
|
||||
|
||||
if(ftp->downloadsize == 0) {
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
infof(data, "File already completely downloaded\n");
|
||||
|
||||
/* Set ->transfer so that we won't get any error in ftp_done()
|
||||
@@ -2276,8 +2269,8 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||||
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||||
if(-1 != filesize) {
|
||||
char clbuf[128];
|
||||
snprintf(clbuf, sizeof(clbuf),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
|
||||
msnprintf(clbuf, sizeof(clbuf),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -3054,7 +3047,7 @@ static CURLcode ftp_multi_statemach(struct connectdata *conn,
|
||||
bool *done)
|
||||
{
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
|
||||
CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE, FALSE);
|
||||
|
||||
/* 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
|
||||
@@ -3071,7 +3064,7 @@ static CURLcode ftp_block_statemach(struct connectdata *conn)
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
while(ftpc->state != FTP_STOP) {
|
||||
result = Curl_pp_statemach(pp, TRUE);
|
||||
result = Curl_pp_statemach(pp, TRUE, TRUE /* disconnecting */);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
@@ -3308,33 +3301,33 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
;
|
||||
else if(data->set.upload) {
|
||||
if((-1 != data->state.infilesize) &&
|
||||
(data->state.infilesize != *ftp->bytecountp) &&
|
||||
(data->state.infilesize != data->req.writebytecount) &&
|
||||
!data->set.crlf &&
|
||||
(ftp->transfer == FTPTRANSFER_BODY)) {
|
||||
failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
|
||||
" out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
|
||||
*ftp->bytecountp, data->state.infilesize);
|
||||
data->req.bytecount, data->state.infilesize);
|
||||
result = CURLE_PARTIAL_FILE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if((-1 != data->req.size) &&
|
||||
(data->req.size != *ftp->bytecountp) &&
|
||||
(data->req.size != data->req.bytecount) &&
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
/* Most FTP servers don't adjust their file SIZE response for CRLFs, so
|
||||
* we'll check to see if the discrepancy can be explained by the number
|
||||
* of CRLFs we've changed to LFs.
|
||||
*/
|
||||
((data->req.size + data->state.crlf_conversions) !=
|
||||
*ftp->bytecountp) &&
|
||||
data->req.bytecount) &&
|
||||
#endif /* CURL_DO_LINEEND_CONV */
|
||||
(data->req.maxdownload != *ftp->bytecountp)) {
|
||||
(data->req.maxdownload != data->req.bytecount)) {
|
||||
failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes", *ftp->bytecountp);
|
||||
" bytes", data->req.bytecount);
|
||||
result = CURLE_PARTIAL_FILE;
|
||||
}
|
||||
else if(!ftpc->dont_check &&
|
||||
!*ftp->bytecountp &&
|
||||
!data->req.bytecount &&
|
||||
(data->req.size>0)) {
|
||||
failf(data, "No data was received!");
|
||||
result = CURLE_FTP_COULDNT_RETR_FILE;
|
||||
@@ -3496,7 +3489,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
|
||||
if(Curl_connect_ongoing(conn)) {
|
||||
/* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
|
||||
aren't used so we blank their arguments. TODO: make this nicer */
|
||||
aren't used so we blank their arguments. */
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0);
|
||||
|
||||
return result;
|
||||
@@ -3629,7 +3622,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
if(!result && (ftp->transfer != FTPTRANSFER_BODY))
|
||||
/* no data to transfer. FIX: it feels like a kludge to have this here
|
||||
too! */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
|
||||
if(!ftpc->wait_data_conn) {
|
||||
/* no waiting for the data connection so this is now complete */
|
||||
@@ -4309,7 +4302,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
|
||||
if(ftp->transfer != FTPTRANSFER_BODY)
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
|
||||
else if(!connected)
|
||||
/* since we didn't connect now, we want do_more to get called */
|
||||
conn->bits.do_more = TRUE;
|
||||
@@ -4396,7 +4389,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ftp->path = &data->state.up.path[1]; /* don't include the initial slash */
|
||||
data->state.slash_removed = TRUE; /* we've skipped the slash */
|
||||
|
||||
/* FTP URLs support an extension like ";type=<typecode>" that
|
||||
* we'll try to get now! */
|
||||
@@ -4429,7 +4421,6 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* get some initial data into the ftp struct */
|
||||
ftp->bytecountp = &conn->data->req.bytecount;
|
||||
ftp->transfer = FTPTRANSFER_BODY;
|
||||
ftp->downloadsize = 0;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -102,7 +102,6 @@ typedef enum {
|
||||
perhaps the Curl_easy is changed between the times the connection is
|
||||
used. */
|
||||
struct FTP {
|
||||
curl_off_t *bytecountp;
|
||||
char *user; /* user name string */
|
||||
char *passwd; /* password string */
|
||||
char *path; /* points to the urlpieces struct field */
|
||||
|
||||
@@ -405,7 +405,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
/* start FSM again not considering size of directory */
|
||||
finfo->b_used = 0;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case PL_UNIX_TOTALSIZE_READING:
|
||||
@@ -914,10 +914,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
case PL_WINNT_DIRORSIZE:
|
||||
switch(parser->state.NT.sub.dirorsize) {
|
||||
case PL_WINNT_DIRORSIZE_PRESPACE:
|
||||
if(c == ' ') {
|
||||
|
||||
}
|
||||
else {
|
||||
if(c != ' ') {
|
||||
parser->item_offset = finfo->b_used - 1;
|
||||
parser->item_length = 1;
|
||||
parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -163,10 +163,10 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
*param_longp = (long)data->info.filetime;
|
||||
break;
|
||||
case CURLINFO_HEADER_SIZE:
|
||||
*param_longp = data->info.header_size;
|
||||
*param_longp = (long)data->info.header_size;
|
||||
break;
|
||||
case CURLINFO_REQUEST_SIZE:
|
||||
*param_longp = data->info.request_size;
|
||||
*param_longp = (long)data->info.request_size;
|
||||
break;
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.ssl.certverifyresult;
|
||||
@@ -390,7 +390,7 @@ static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
|
||||
param_slistp;
|
||||
struct curl_tlssessioninfo *tsi = &data->tsi;
|
||||
#ifdef USE_SSL
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
struct connectdata *conn = data->conn;
|
||||
#endif
|
||||
|
||||
*tsip = tsi;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,9 +31,11 @@
|
||||
#include "progress.h"
|
||||
#include "gopher.h"
|
||||
#include "select.h"
|
||||
#include "strdup.h"
|
||||
#include "url.h"
|
||||
#include "escape.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@@ -76,9 +78,9 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
CURLcode result = CURLE_OK;
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
curl_off_t *bytecount = &data->req.bytecount;
|
||||
char *gopherpath;
|
||||
char *path = data->state.up.path;
|
||||
char *query = data->state.up.query;
|
||||
char *sel = NULL;
|
||||
char *sel_org = NULL;
|
||||
ssize_t amount, k;
|
||||
@@ -86,20 +88,33 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
/* path is guaranteed non-NULL */
|
||||
DEBUGASSERT(path);
|
||||
|
||||
if(query)
|
||||
gopherpath = aprintf("%s?%s", path, query);
|
||||
else
|
||||
gopherpath = strdup(path);
|
||||
|
||||
if(!gopherpath)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Create selector. Degenerate cases: / and /1 => convert to "" */
|
||||
if(strlen(path) <= 2) {
|
||||
if(strlen(gopherpath) <= 2) {
|
||||
sel = (char *)"";
|
||||
len = strlen(sel);
|
||||
free(gopherpath);
|
||||
}
|
||||
else {
|
||||
char *newp;
|
||||
|
||||
/* Otherwise, drop / and the first character (i.e., item type) ... */
|
||||
newp = path;
|
||||
newp = gopherpath;
|
||||
newp += 2;
|
||||
|
||||
/* ... and finally unescape */
|
||||
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
|
||||
free(gopherpath);
|
||||
if(result)
|
||||
return result;
|
||||
sel_org = sel;
|
||||
@@ -153,8 +168,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif /*CURL_DISABLE_GOPHER*/
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -85,14 +85,14 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
dns = Curl_cache_addr(data, ai,
|
||||
conn->async.hostname,
|
||||
conn->async.port);
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
if(!dns) {
|
||||
/* failed to store, cleanup and return error */
|
||||
Curl_freeaddrinfo(ai);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
else {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_OPENSSL) \
|
||||
|| defined(USE_AXTLS) \
|
||||
|| defined(USE_GSKIT) \
|
||||
|| defined(USE_SCHANNEL)
|
||||
/* these backends use functions from this file */
|
||||
@@ -128,16 +127,14 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
{
|
||||
char *matchp;
|
||||
char *hostp;
|
||||
int res = 0;
|
||||
if(!match_pattern || !*match_pattern ||
|
||||
!hostname || !*hostname) /* sanity check */
|
||||
;
|
||||
else {
|
||||
matchp = strdup(match_pattern);
|
||||
char *matchp = strdup(match_pattern);
|
||||
if(matchp) {
|
||||
hostp = strdup(hostname);
|
||||
char *hostp = strdup(hostname);
|
||||
if(hostp) {
|
||||
if(hostmatch(hostp, matchp) == CURL_HOST_MATCH)
|
||||
res = 1;
|
||||
@@ -150,4 +147,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL, AXTLS, GSKIT or schannel+wince */
|
||||
#endif /* OPENSSL, GSKIT or schannel+wince */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -73,6 +73,8 @@
|
||||
#define USE_ALARM_TIMEOUT
|
||||
#endif
|
||||
|
||||
#define MAX_HOSTCACHE_LEN (255 + 7) /* max FQDN + colon + port number + zero */
|
||||
|
||||
/*
|
||||
* hostip.c explained
|
||||
* ==================
|
||||
@@ -112,42 +114,8 @@
|
||||
* CURLRES_* defines based on the config*.h and curl_setup.h defines.
|
||||
*/
|
||||
|
||||
/* These two symbols are for the global DNS cache */
|
||||
static struct curl_hash hostname_cache;
|
||||
static int host_cache_initialized;
|
||||
|
||||
static void freednsentry(void *freethis);
|
||||
|
||||
/*
|
||||
* Curl_global_host_cache_init() initializes and sets up a global DNS cache.
|
||||
* Global DNS cache is general badness. Do not use. This will be removed in
|
||||
* a future version. Use the share interface instead!
|
||||
*
|
||||
* Returns a struct curl_hash pointer on success, NULL on failure.
|
||||
*/
|
||||
struct curl_hash *Curl_global_host_cache_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
if(!host_cache_initialized) {
|
||||
rc = Curl_hash_init(&hostname_cache, 7, Curl_hash_str,
|
||||
Curl_str_key_compare, freednsentry);
|
||||
if(!rc)
|
||||
host_cache_initialized = 1;
|
||||
}
|
||||
return rc?NULL:&hostname_cache;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy and cleanup the global DNS cache
|
||||
*/
|
||||
void Curl_global_host_cache_dtor(void)
|
||||
{
|
||||
if(host_cache_initialized) {
|
||||
Curl_hash_destroy(&hostname_cache);
|
||||
host_cache_initialized = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return # of addresses in a Curl_addrinfo struct
|
||||
*/
|
||||
@@ -198,23 +166,19 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a hostcache id string for the provided host + port, to be used by
|
||||
* the DNS caching.
|
||||
* Create a hostcache id string for the provided host + port, to be used by
|
||||
* the DNS caching. Without alloc.
|
||||
*/
|
||||
static char *
|
||||
create_hostcache_id(const char *name, int port)
|
||||
static void
|
||||
create_hostcache_id(const char *name, int port, char *ptr, size_t buflen)
|
||||
{
|
||||
/* create and return the new allocated entry */
|
||||
char *id = aprintf("%s:%d", name, port);
|
||||
char *ptr = id;
|
||||
if(ptr) {
|
||||
/* lower case the name part */
|
||||
while(*ptr && (*ptr != ':')) {
|
||||
*ptr = (char)TOLOWER(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
size_t len = strlen(name);
|
||||
if(len > (buflen - 7))
|
||||
len = buflen - 7;
|
||||
/* store and lower case the name */
|
||||
while(len--)
|
||||
*ptr++ = (char)TOLOWER(*name++);
|
||||
msnprintf(ptr, 7, ":%u", port);
|
||||
}
|
||||
|
||||
struct hostcache_prune_data {
|
||||
@@ -296,22 +260,27 @@ fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port)
|
||||
{
|
||||
char *entry_id = NULL;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
size_t entry_len;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char entry_id[MAX_HOSTCACHE_LEN];
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id)
|
||||
return dns;
|
||||
|
||||
create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
|
||||
|
||||
/* No entry found in cache, check if we might have a wildcard entry */
|
||||
if(!dns && data->change.wildcard_resolve) {
|
||||
create_hostcache_id("*", port, entry_id, sizeof(entry_id));
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
/* See if it's already in our dns cache */
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
|
||||
}
|
||||
|
||||
if(dns && (data->set.dns_cache_timeout != -1)) {
|
||||
/* See whether the returned entry is stale. Done before we release lock */
|
||||
struct hostcache_prune_data user;
|
||||
@@ -326,9 +295,6 @@ fetch_addr(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
return dns;
|
||||
}
|
||||
|
||||
@@ -368,6 +334,9 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
return dns;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_SHUFFLE_DNS
|
||||
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
Curl_addrinfo **addr);
|
||||
/*
|
||||
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
|
||||
* struct by re-linking its linked list.
|
||||
@@ -380,7 +349,8 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
*
|
||||
* @unittest: 1608
|
||||
*/
|
||||
CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr)
|
||||
UNITTEST CURLcode Curl_shuffle_addr(struct Curl_easy *data,
|
||||
Curl_addrinfo **addr)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
const int num_addrs = Curl_num_addresses(*addr);
|
||||
@@ -431,6 +401,7 @@ CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
@@ -447,32 +418,30 @@ Curl_cache_addr(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
int port)
|
||||
{
|
||||
char *entry_id;
|
||||
char entry_id[MAX_HOSTCACHE_LEN];
|
||||
size_t entry_len;
|
||||
struct Curl_dns_entry *dns;
|
||||
struct Curl_dns_entry *dns2;
|
||||
|
||||
#ifndef CURL_DISABLE_SHUFFLE_DNS
|
||||
/* shuffle addresses if requested */
|
||||
if(data->set.dns_shuffle_addresses) {
|
||||
CURLcode result = Curl_shuffle_addr(data, &addr);
|
||||
if(result)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id)
|
||||
return NULL;
|
||||
entry_len = strlen(entry_id);
|
||||
#endif
|
||||
|
||||
/* Create a new cache entry */
|
||||
dns = calloc(1, sizeof(struct Curl_dns_entry));
|
||||
if(!dns) {
|
||||
free(entry_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
dns->inuse = 1; /* the cache has the first reference */
|
||||
dns->addr = addr; /* this is the address(es) */
|
||||
time(&dns->timestamp);
|
||||
@@ -484,16 +453,11 @@ Curl_cache_addr(struct Curl_easy *data,
|
||||
(void *)dns);
|
||||
if(!dns2) {
|
||||
free(dns);
|
||||
free(entry_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dns = dns2;
|
||||
dns->inuse++; /* mark entry as in-use */
|
||||
|
||||
/* free the allocated entry_id */
|
||||
free(entry_id);
|
||||
|
||||
return dns;
|
||||
}
|
||||
|
||||
@@ -521,6 +485,7 @@ Curl_cache_addr(struct Curl_easy *data,
|
||||
int Curl_resolv(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
bool allowDOH,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
@@ -548,7 +513,7 @@ int Curl_resolv(struct connectdata *conn,
|
||||
/* The entry was not in the cache. Resolve it to IP address */
|
||||
|
||||
Curl_addrinfo *addr;
|
||||
int respwait;
|
||||
int respwait = 0;
|
||||
|
||||
/* Check what IP specifics the app has requested and if we can provide it.
|
||||
* If not, bail out. */
|
||||
@@ -566,7 +531,7 @@ int Curl_resolv(struct connectdata *conn,
|
||||
return CURLRESOLV_ERROR;
|
||||
}
|
||||
|
||||
if(data->set.doh) {
|
||||
if(allowDOH && data->set.doh) {
|
||||
addr = Curl_doh(conn, hostname, port, &respwait);
|
||||
}
|
||||
else {
|
||||
@@ -692,7 +657,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
|
||||
if(!timeout)
|
||||
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
|
||||
return Curl_resolv(conn, hostname, port, entry);
|
||||
return Curl_resolv(conn, hostname, port, TRUE, entry);
|
||||
|
||||
if(timeout < 1000) {
|
||||
/* The alarm() function only provides integer second resolution, so if
|
||||
@@ -754,7 +719,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
/* Perform the actual name resolution. This might be interrupted by an
|
||||
* alarm if it takes too long.
|
||||
*/
|
||||
rc = Curl_resolv(conn, hostname, port, entry);
|
||||
rc = Curl_resolv(conn, hostname, port, TRUE, entry);
|
||||
|
||||
#ifdef USE_ALARM_TIMEOUT
|
||||
clean_up:
|
||||
@@ -872,11 +837,14 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
char hostname[256];
|
||||
int port = 0;
|
||||
|
||||
/* Default is no wildcard found */
|
||||
data->change.wildcard_resolve = false;
|
||||
|
||||
for(hostp = data->change.resolve; hostp; hostp = hostp->next) {
|
||||
char entry_id[MAX_HOSTCACHE_LEN];
|
||||
if(!hostp->data)
|
||||
continue;
|
||||
if(hostp->data[0] == '-') {
|
||||
char *entry_id;
|
||||
size_t entry_len;
|
||||
|
||||
if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
|
||||
@@ -886,12 +854,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
}
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
if(data->share)
|
||||
@@ -902,14 +865,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
}
|
||||
else {
|
||||
struct Curl_dns_entry *dns;
|
||||
Curl_addrinfo *head = NULL, *tail = NULL;
|
||||
char *entry_id;
|
||||
size_t entry_len;
|
||||
char address[64];
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
@@ -1005,12 +964,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
}
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id) {
|
||||
Curl_freeaddrinfo(head);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
create_hostcache_id(hostname, port, entry_id, sizeof(entry_id));
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
if(data->share)
|
||||
@@ -1031,8 +985,6 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
|
||||
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
|
||||
}
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
/* put this new host in the cache */
|
||||
dns = Curl_cache_addr(data, head, hostname, port);
|
||||
@@ -1052,6 +1004,13 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
}
|
||||
infof(data, "Added %s:%d:%s to DNS cache\n",
|
||||
hostname, port, addresses);
|
||||
|
||||
/* Wildcard hostname */
|
||||
if(hostname[0] == '*' && hostname[1] == '\0') {
|
||||
infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n",
|
||||
hostname, port);
|
||||
data->change.wildcard_resolve = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
data->change.resolve = NULL; /* dealt with now */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -83,8 +83,11 @@ struct Curl_dns_entry {
|
||||
#define CURLRESOLV_ERROR -1
|
||||
#define CURLRESOLV_RESOLVED 0
|
||||
#define CURLRESOLV_PENDING 1
|
||||
int Curl_resolv(struct connectdata *conn, const char *hostname,
|
||||
int port, struct Curl_dns_entry **dnsentry);
|
||||
int Curl_resolv(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
bool allowDOH,
|
||||
struct Curl_dns_entry **dnsentry);
|
||||
int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
|
||||
int port, struct Curl_dns_entry **dnsentry,
|
||||
time_t timeoutms);
|
||||
@@ -178,16 +181,6 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port);
|
||||
|
||||
/*
|
||||
* Curl_shuffle_addr() shuffles the order of addresses in a 'Curl_addrinfo'
|
||||
* struct by re-linking its linked list.
|
||||
*
|
||||
* The addr argument should be the address of a pointer to the head node of a
|
||||
* `Curl_addrinfo` list and it will be modified to point to the new head after
|
||||
* shuffling.
|
||||
*/
|
||||
CURLcode Curl_shuffle_addr(struct Curl_easy *data, Curl_addrinfo **addr);
|
||||
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -145,7 +145,7 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
|
||||
hints.ai_family = PF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if(port) {
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
msnprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
sbufptr = sbuf;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -101,14 +101,16 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
{
|
||||
printf("dump_addrinfo:\n");
|
||||
for(; ai; ai = ai->ai_next) {
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
printf(" fam %2d, CNAME %s, ",
|
||||
ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
|
||||
if(Curl_printable_address(ai, buf, sizeof(buf)))
|
||||
printf("%s\n", buf);
|
||||
else
|
||||
printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
|
||||
else {
|
||||
char buffer[STRERROR_LEN];
|
||||
printf("failed; %s\n",
|
||||
Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -178,7 +180,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
if(port) {
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
msnprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
sbufptr = sbuf;
|
||||
}
|
||||
|
||||
|
||||
+318
-174
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -73,10 +73,10 @@
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "pipeline.h"
|
||||
#include "http2.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
#include "altsvc.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@@ -92,7 +92,9 @@ static int http_getsock_do(struct connectdata *conn,
|
||||
int numsocks);
|
||||
static int http_should_fail(struct connectdata *conn);
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done);
|
||||
@@ -102,13 +104,14 @@ static int https_getsock(struct connectdata *conn,
|
||||
#else
|
||||
#define https_connecting(x,y) CURLE_COULDNT_CONNECT
|
||||
#endif
|
||||
static CURLcode http_setup_conn(struct connectdata *conn);
|
||||
|
||||
/*
|
||||
* HTTP handler interface.
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_http = {
|
||||
"HTTP", /* scheme */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@@ -133,7 +136,7 @@ const struct Curl_handler Curl_handler_http = {
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_https = {
|
||||
"HTTPS", /* scheme */
|
||||
Curl_http_setup_conn, /* setup_connection */
|
||||
http_setup_conn, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@@ -153,7 +156,7 @@ const struct Curl_handler Curl_handler_https = {
|
||||
};
|
||||
#endif
|
||||
|
||||
CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
static CURLcode http_setup_conn(struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
|
||||
during this request */
|
||||
@@ -175,7 +178,7 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/*
|
||||
* checkProxyHeaders() checks the linked list of custom proxy headers
|
||||
* if proxy headers are not available, then it will lookup into http header
|
||||
@@ -202,6 +205,10 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_checkProxyheaders(x,y) NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Strip off leading and trailing whitespace from the value in the
|
||||
@@ -256,6 +263,7 @@ char *Curl_copy_header_value(const char *header)
|
||||
return value;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP_AUTH
|
||||
/*
|
||||
* http_output_basic() sets up an Authorization: header (or the proxy version)
|
||||
* for HTTP Basic authentication.
|
||||
@@ -337,6 +345,8 @@ static CURLcode http_output_bearer(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* pickoneauth() selects the most favourable authentication method from the
|
||||
* ones available and the ones we want.
|
||||
*
|
||||
@@ -415,7 +425,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
break;
|
||||
}
|
||||
|
||||
bytessent = http->writebytecount;
|
||||
bytessent = data->req.writebytecount;
|
||||
|
||||
if(conn->bits.authneg) {
|
||||
/* This is a state where we are known to be negotiating and we don't send
|
||||
@@ -456,8 +466,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
(data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
|
||||
if(((expectsend - bytessent) < 2000) ||
|
||||
(conn->ntlm.state != NTLMSTATE_NONE) ||
|
||||
(conn->proxyntlm.state != NTLMSTATE_NONE)) {
|
||||
(conn->http_ntlm_state != NTLMSTATE_NONE) ||
|
||||
(conn->proxy_ntlm_state != NTLMSTATE_NONE)) {
|
||||
/* The NTLM-negotiation has started *OR* there is just a little (<2K)
|
||||
data left to send, keep on sending. */
|
||||
|
||||
@@ -479,8 +489,36 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_SPNEGO)
|
||||
/* There is still data left to send */
|
||||
if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
|
||||
if(((expectsend - bytessent) < 2000) ||
|
||||
(conn->http_negotiate_state != GSS_AUTHNONE) ||
|
||||
(conn->proxy_negotiate_state != GSS_AUTHNONE)) {
|
||||
/* The NEGOTIATE-negotiation has started *OR*
|
||||
there is just a little (<2K) data left to send, keep on sending. */
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(conn->bits.close)
|
||||
/* this is already marked to get closed */
|
||||
return CURLE_OK;
|
||||
|
||||
infof(data, "NEGOTIATE send, close instead of sending %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is not NEGOTIATE/NTLM or many bytes left to send: close */
|
||||
streamclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
@@ -526,6 +564,12 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
pickhost = pickoneauth(&data->state.authhost, authmask);
|
||||
if(!pickhost)
|
||||
data->state.authproblem = TRUE;
|
||||
if(data->state.authhost.picked == CURLAUTH_NTLM &&
|
||||
conn->httpversion > 11) {
|
||||
infof(data, "Forcing HTTP/1.1 for NTLM");
|
||||
connclose(conn, "Force HTTP/1.1 connection");
|
||||
conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
|
||||
}
|
||||
}
|
||||
if(conn->bits.proxy_user_passwd &&
|
||||
((data->req.httpcode == 407) ||
|
||||
@@ -576,6 +620,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP_AUTH
|
||||
/*
|
||||
* Output the correct authentication header depending on the auth type
|
||||
* and whether or not it is to a proxy.
|
||||
@@ -592,10 +637,6 @@ output_auth_headers(struct connectdata *conn,
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy ?
|
||||
&data->state.proxyneg : &data->state.negotiate;
|
||||
#endif
|
||||
|
||||
#ifdef CURL_DISABLE_CRYPTO_AUTH
|
||||
(void)request;
|
||||
@@ -603,15 +644,11 @@ output_auth_headers(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
negdata->state = GSS_AUTHNONE;
|
||||
if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
|
||||
negdata->context && !GSS_ERROR(negdata->status)) {
|
||||
if((authstatus->picked == CURLAUTH_NEGOTIATE)) {
|
||||
auth = "Negotiate";
|
||||
result = Curl_output_negotiate(conn, proxy);
|
||||
if(result)
|
||||
return result;
|
||||
authstatus->done = TRUE;
|
||||
negdata->state = GSS_AUTHSENT;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -697,7 +734,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
*
|
||||
* @param conn all information about the current connection
|
||||
* @param request pointer to the request keyword
|
||||
* @param path pointer to the requested path
|
||||
* @param path pointer to the requested path; should include query part
|
||||
* @param proxytunnel boolean if this is the request setting up a "proxy
|
||||
* tunnel"
|
||||
*
|
||||
@@ -744,7 +781,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/* Send proxy authentication header if needed */
|
||||
if(conn->bits.httpproxy &&
|
||||
(conn->bits.tunnel_proxy == proxytunnel)) {
|
||||
(conn->bits.tunnel_proxy == (bit)proxytunnel)) {
|
||||
result = output_auth_headers(conn, authproxy, request, path, TRUE);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -772,6 +809,22 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
/* when disabled */
|
||||
CURLcode
|
||||
Curl_http_output_auth(struct connectdata *conn,
|
||||
const char *request,
|
||||
const char *path,
|
||||
bool proxytunnel)
|
||||
{
|
||||
(void)conn;
|
||||
(void)request;
|
||||
(void)path;
|
||||
(void)proxytunnel;
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
|
||||
* headers. They are dealt with both in the transfer.c main loop and in the
|
||||
@@ -787,8 +840,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy?
|
||||
&data->state.proxyneg:&data->state.negotiate;
|
||||
curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
|
||||
&conn->http_negotiate_state;
|
||||
#endif
|
||||
unsigned long *availp;
|
||||
struct auth *authp;
|
||||
@@ -827,21 +880,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
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;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
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 */
|
||||
*negstate = GSS_AUTHRECV;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -869,19 +919,10 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
*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(checkprefix("NTLM", auth)) {
|
||||
auth += strlen("NTLM");
|
||||
while(*auth && ISSPACE(*auth))
|
||||
auth++;
|
||||
if(*auth) {
|
||||
conn->challenge_header = strdup(auth);
|
||||
if(!conn->challenge_header)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = Curl_input_ntlm_wb(conn, proxy, auth);
|
||||
if(result) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1111,14 +1152,13 @@ void Curl_add_buffer_free(Curl_send_buffer **inp)
|
||||
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
|
||||
struct connectdata *conn,
|
||||
|
||||
/* add the number of sent bytes to this
|
||||
counter */
|
||||
long *bytes_written,
|
||||
/* add the number of sent bytes to this
|
||||
counter */
|
||||
curl_off_t *bytes_written,
|
||||
|
||||
/* how much of the buffer contains body data */
|
||||
/* how much of the buffer contains body data */
|
||||
size_t included_body_bytes,
|
||||
int socketindex)
|
||||
|
||||
{
|
||||
ssize_t amount;
|
||||
CURLcode result;
|
||||
@@ -1214,7 +1254,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
|
||||
if(http) {
|
||||
/* if we sent a piece of the body here, up the byte counter for it
|
||||
accordingly */
|
||||
http->writebytecount += bodylen;
|
||||
data->req.writebytecount += bodylen;
|
||||
Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
|
||||
|
||||
if((size_t)amount != size) {
|
||||
/* The whole request could not be sent in one system call. We must
|
||||
@@ -1255,7 +1296,6 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
|
||||
This needs FIXing.
|
||||
*/
|
||||
return CURLE_SEND_ERROR;
|
||||
Curl_pipeline_leave_write(conn);
|
||||
}
|
||||
}
|
||||
Curl_add_buffer_free(&in);
|
||||
@@ -1432,12 +1472,14 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
/* nothing else to do except wait right now - we're not done here. */
|
||||
return CURLE_OK;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->data->set.haproxyprotocol) {
|
||||
/* add HAProxy PROXY protocol header */
|
||||
result = add_haproxy_protocol_header(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(conn->given->protocol & CURLPROTO_HTTPS) {
|
||||
/* perform SSL initialization */
|
||||
@@ -1464,6 +1506,7 @@ static int http_getsock_do(struct connectdata *conn,
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
{
|
||||
char proxy_header[128];
|
||||
@@ -1479,14 +1522,14 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
strcpy(tcp_version, "TCP4");
|
||||
}
|
||||
|
||||
snprintf(proxy_header,
|
||||
sizeof(proxy_header),
|
||||
"PROXY %s %s %s %li %li\r\n",
|
||||
tcp_version,
|
||||
conn->data->info.conn_local_ip,
|
||||
conn->data->info.conn_primary_ip,
|
||||
conn->data->info.conn_local_port,
|
||||
conn->data->info.conn_primary_port);
|
||||
msnprintf(proxy_header,
|
||||
sizeof(proxy_header),
|
||||
"PROXY %s %s %s %li %li\r\n",
|
||||
tcp_version,
|
||||
conn->data->info.conn_local_ip,
|
||||
conn->data->info.conn_primary_ip,
|
||||
conn->data->info.conn_local_port,
|
||||
conn->data->info.conn_primary_port);
|
||||
|
||||
req_buffer = Curl_add_buffer_init();
|
||||
if(!req_buffer)
|
||||
@@ -1504,6 +1547,7 @@ static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSL
|
||||
static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
@@ -1547,20 +1591,6 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
if(data->state.proxyneg.state == GSS_AUTHSENT ||
|
||||
data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* add forbid re-use if http-code != 401/407 as a WA only needed for
|
||||
* 401/407 that signal auth failure (empty) otherwise state will be RECV
|
||||
* with current code.
|
||||
* Do not close CONNECT_ONLY connections. */
|
||||
if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
|
||||
!data->set.connect_only)
|
||||
streamclose(conn, "Negotiate transfer completed");
|
||||
Curl_cleanup_negotiate(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set the proper values (possibly modified on POST) */
|
||||
conn->seek_func = data->set.seek_func; /* restore */
|
||||
conn->seek_client = data->set.seek_client; /* restore */
|
||||
@@ -1576,16 +1606,6 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
|
||||
Curl_mime_cleanpart(&http->form);
|
||||
|
||||
switch(data->set.httpreq) {
|
||||
case HTTPREQ_PUT:
|
||||
case HTTPREQ_POST_FORM:
|
||||
case HTTPREQ_POST_MIME:
|
||||
data->req.bytecount = http->readbytecount + http->writebytecount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(status)
|
||||
return status;
|
||||
|
||||
@@ -1593,7 +1613,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
entire operation is complete */
|
||||
!conn->bits.retry &&
|
||||
!data->set.connect_only &&
|
||||
(http->readbytecount +
|
||||
(data->req.bytecount +
|
||||
data->req.headerbytecount -
|
||||
data->req.deductheadercount) <= 0) {
|
||||
/* If this connection isn't simply closed to be retried, AND nothing was
|
||||
@@ -1676,6 +1696,50 @@ enum proxy_use {
|
||||
HEADER_CONNECT /* sending CONNECT to a proxy */
|
||||
};
|
||||
|
||||
/* used to compile the provided trailers into one buffer
|
||||
will return an error code if one of the headers is
|
||||
not formatted correctly */
|
||||
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
|
||||
Curl_send_buffer *buffer,
|
||||
struct Curl_easy *handle)
|
||||
{
|
||||
char *ptr = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
const char *endofline_native = NULL;
|
||||
const char *endofline_network = NULL;
|
||||
|
||||
if(
|
||||
#ifdef CURL_DO_LINEEND_CONV
|
||||
(handle->set.prefer_ascii) ||
|
||||
#endif
|
||||
(handle->set.crlf)) {
|
||||
/* \n will become \r\n later on */
|
||||
endofline_native = "\n";
|
||||
endofline_network = "\x0a";
|
||||
}
|
||||
else {
|
||||
endofline_native = "\r\n";
|
||||
endofline_network = "\x0d\x0a";
|
||||
}
|
||||
|
||||
while(trailers) {
|
||||
/* only add correctly formatted trailers */
|
||||
ptr = strchr(trailers->data, ':');
|
||||
if(ptr && *(ptr + 1) == ' ') {
|
||||
result = Curl_add_bufferf(&buffer, "%s%s", trailers->data,
|
||||
endofline_native);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
infof(handle, "Malformatted trailing header ! Skipping trailer.");
|
||||
trailers = trailers->next;
|
||||
}
|
||||
result = Curl_add_buffer(&buffer, endofline_network,
|
||||
strlen(endofline_network));
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_connect,
|
||||
Curl_send_buffer *req_buffer)
|
||||
@@ -1737,9 +1801,16 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
if(*(--ptr) == ';') {
|
||||
/* send no-value custom header if terminated by semicolon */
|
||||
*ptr = ':';
|
||||
semicolonp = ptr;
|
||||
/* copy the source */
|
||||
semicolonp = strdup(headers->data);
|
||||
if(!semicolonp) {
|
||||
Curl_add_buffer_free(&req_buffer);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
/* put a colon where the semicolon is */
|
||||
semicolonp[ptr - headers->data] = ':';
|
||||
/* point at the colon */
|
||||
optr = &semicolonp [ptr - headers->data];
|
||||
}
|
||||
}
|
||||
ptr = optr;
|
||||
@@ -1755,35 +1826,37 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
if(*ptr || semicolonp) {
|
||||
/* only send this if the contents was non-blank or done special */
|
||||
CURLcode result = CURLE_OK;
|
||||
char *compare = semicolonp ? semicolonp : headers->data;
|
||||
|
||||
if(conn->allocptr.host &&
|
||||
/* a Host: header was sent already, don't pass on any custom Host:
|
||||
header as that will produce *two* in the same request! */
|
||||
checkprefix("Host:", headers->data))
|
||||
checkprefix("Host:", compare))
|
||||
;
|
||||
else if(data->set.httpreq == HTTPREQ_POST_FORM &&
|
||||
/* this header (extended by formdata.c) is sent later */
|
||||
checkprefix("Content-Type:", headers->data))
|
||||
checkprefix("Content-Type:", compare))
|
||||
;
|
||||
else if(data->set.httpreq == HTTPREQ_POST_MIME &&
|
||||
/* this header is sent later */
|
||||
checkprefix("Content-Type:", headers->data))
|
||||
checkprefix("Content-Type:", compare))
|
||||
;
|
||||
else if(conn->bits.authneg &&
|
||||
/* while doing auth neg, don't allow the custom length since
|
||||
we will force length zero then */
|
||||
checkprefix("Content-Length:", headers->data))
|
||||
checkprefix("Content-Length:", compare))
|
||||
;
|
||||
else if(conn->allocptr.te &&
|
||||
/* when asking for Transfer-Encoding, don't pass on a custom
|
||||
Connection: */
|
||||
checkprefix("Connection:", headers->data))
|
||||
checkprefix("Connection:", compare))
|
||||
;
|
||||
else if((conn->httpversion == 20) &&
|
||||
checkprefix("Transfer-Encoding:", headers->data))
|
||||
checkprefix("Transfer-Encoding:", compare))
|
||||
/* HTTP/2 doesn't support chunked requests */
|
||||
;
|
||||
else if(checkprefix("Authorization:", headers->data) &&
|
||||
else if((checkprefix("Authorization:", compare) ||
|
||||
checkprefix("Cookie:", compare)) &&
|
||||
/* be careful of sending this potentially sensitive header to
|
||||
other hosts */
|
||||
(data->state.this_is_a_follow &&
|
||||
@@ -1792,10 +1865,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
!strcasecompare(data->state.first_host, conn->host.name)))
|
||||
;
|
||||
else {
|
||||
result = Curl_add_bufferf(&req_buffer, "%s\r\n", headers->data);
|
||||
result = Curl_add_bufferf(&req_buffer, "%s\r\n", compare);
|
||||
}
|
||||
if(semicolonp)
|
||||
*semicolonp = ';'; /* put back the semicolon */
|
||||
free(semicolonp);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -1807,6 +1880,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_PARSEDATE
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
Curl_send_buffer *req_buffer)
|
||||
{
|
||||
@@ -1850,21 +1924,31 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
*/
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
snprintf(datestr, sizeof(datestr),
|
||||
"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
condp,
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec);
|
||||
msnprintf(datestr, sizeof(datestr),
|
||||
"%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
condp,
|
||||
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||||
tm->tm_mday,
|
||||
Curl_month[tm->tm_mon],
|
||||
tm->tm_year + 1900,
|
||||
tm->tm_hour,
|
||||
tm->tm_min,
|
||||
tm->tm_sec);
|
||||
|
||||
result = Curl_add_buffer(&req_buffer, datestr, strlen(datestr));
|
||||
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
/* disabled */
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
Curl_send_buffer *req_buffer)
|
||||
{
|
||||
(void)data;
|
||||
(void)req_buffer;
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_http() gets called from the generic multi_do() function when a HTTP
|
||||
@@ -1916,6 +2000,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
#ifdef USE_NGHTTP2
|
||||
if(conn->data->set.httpversion ==
|
||||
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
||||
/* We don't support HTTP/2 proxies yet. Also it's debatable whether
|
||||
or not this setting should apply to HTTP/2 proxies. */
|
||||
infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
|
||||
conn->httpversion = 20;
|
||||
|
||||
@@ -1947,7 +2038,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
data->state.first_remote_port = conn->remote_port;
|
||||
}
|
||||
http->writebytecount = http->readbytecount = 0;
|
||||
|
||||
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
|
||||
data->set.upload) {
|
||||
@@ -1995,11 +2085,21 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
/* setup the authentication headers */
|
||||
result = Curl_http_output_auth(conn, request, path, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
{
|
||||
char *pq = NULL;
|
||||
if(query && *query) {
|
||||
pq = aprintf("%s?%s", path, query);
|
||||
if(!pq)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = Curl_http_output_auth(conn, request, (pq ? pq : path), FALSE);
|
||||
free(pq);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
|
||||
if(((data->state.authhost.multipass && !data->state.authhost.done)
|
||||
|| (data->state.authproxy.multipass && !data->state.authproxy.done)) &&
|
||||
(httpreq != HTTPREQ_GET) &&
|
||||
(httpreq != HTTPREQ_HEAD)) {
|
||||
/* Auth is required and we are not authenticated yet. Make a PUT or POST
|
||||
@@ -2084,6 +2184,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
http->sendit = NULL;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_MIME
|
||||
if(http->sendit) {
|
||||
const char *cthdr = Curl_checkheaders(conn, "Content-Type");
|
||||
|
||||
@@ -2108,6 +2209,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
http->postsize = Curl_mime_size(http->sendit);
|
||||
}
|
||||
#endif
|
||||
|
||||
ptr = Curl_checkheaders(conn, "Transfer-Encoding");
|
||||
if(ptr) {
|
||||
@@ -2293,8 +2395,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(!*data->state.up.path && path[strlen(path) - 1] != '/') {
|
||||
*p++ = '/';
|
||||
}
|
||||
snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
|
||||
data->set.prefer_ascii ? 'a' : 'i');
|
||||
msnprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
|
||||
data->set.prefer_ascii ? 'a' : 'i');
|
||||
}
|
||||
}
|
||||
if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
|
||||
@@ -2635,9 +2737,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
failf(data, "Failed sending PUT request");
|
||||
else
|
||||
/* prepare for transfer */
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||
&http->readbytecount, postsize?FIRSTSOCKET:-1,
|
||||
postsize?&http->writebytecount:NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
|
||||
postsize?FIRSTSOCKET:-1);
|
||||
if(result)
|
||||
return result;
|
||||
break;
|
||||
@@ -2657,12 +2758,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
failf(data, "Failed sending POST request");
|
||||
else
|
||||
/* setup variables for the upcoming transfer */
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
|
||||
-1, NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
postsize = http->postsize;
|
||||
data->state.infilesize = postsize = http->postsize;
|
||||
|
||||
/* We only set Content-Length and allow a custom Content-Length if
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
@@ -2678,6 +2778,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef CURL_DISABLE_MIME
|
||||
/* Output mime-generated headers. */
|
||||
{
|
||||
struct curl_slist *hdr;
|
||||
@@ -2688,6 +2789,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For really small posts we don't use Expect: headers at all, and for
|
||||
the somewhat bigger ones we allow the app to disable it. Just make
|
||||
@@ -2726,9 +2828,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
failf(data, "Failed sending POST request");
|
||||
else
|
||||
/* prepare for transfer */
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||
&http->readbytecount, postsize?FIRSTSOCKET:-1,
|
||||
postsize?&http->writebytecount:NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
|
||||
postsize?FIRSTSOCKET:-1);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -2882,9 +2983,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
failf(data, "Failed sending HTTP POST request");
|
||||
else
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
|
||||
&http->readbytecount, http->postdata?FIRSTSOCKET:-1,
|
||||
http->postdata?&http->writebytecount:NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
|
||||
http->postdata?FIRSTSOCKET:-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2900,33 +3000,30 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
failf(data, "Failed sending HTTP request");
|
||||
else
|
||||
/* HTTP GET/HEAD download: */
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
|
||||
http->postdata?FIRSTSOCKET:-1,
|
||||
http->postdata?&http->writebytecount:NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
|
||||
http->postdata?FIRSTSOCKET:-1);
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(http->writebytecount) {
|
||||
if(data->req.writebytecount) {
|
||||
/* if a request-body has been sent off, we make sure this progress is noted
|
||||
properly */
|
||||
Curl_pgrsSetUploadCounter(data, http->writebytecount);
|
||||
Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
if(http->writebytecount >= postsize) {
|
||||
if(data->req.writebytecount >= postsize) {
|
||||
/* already sent the entire request body, mark the "upload" as
|
||||
complete */
|
||||
infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
|
||||
" out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
http->writebytecount, postsize);
|
||||
data->req.writebytecount, postsize);
|
||||
data->req.upload_done = TRUE;
|
||||
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
|
||||
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
|
||||
Curl_expire_done(data, EXPIRE_100_TIMEOUT);
|
||||
}
|
||||
else
|
||||
data->req.writebytecount = http->writebytecount;
|
||||
}
|
||||
|
||||
if((conn->httpversion == 20) && data->req.upload_chunky)
|
||||
@@ -3161,6 +3258,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
k->header = FALSE;
|
||||
k->badheader = HEADER_ALLBAD;
|
||||
streamclose(conn, "bad HTTP: No end-of-message indicator");
|
||||
if(!data->set.http09_allowed) {
|
||||
failf(data, "Received HTTP/0.9 when not allowed\n");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3194,6 +3295,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if(st == STATUS_BAD) {
|
||||
streamclose(conn, "bad HTTP: No end-of-message indicator");
|
||||
/* this is not the beginning of a protocol first header line */
|
||||
if(!data->set.http09_allowed) {
|
||||
failf(data, "Received HTTP/0.9 when not allowed\n");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
k->header = FALSE;
|
||||
if(*nread)
|
||||
/* since there's more, this is a partial bad header */
|
||||
@@ -3306,14 +3411,31 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
#if defined(USE_NTLM)
|
||||
if(conn->bits.close &&
|
||||
(((data->req.httpcode == 401) &&
|
||||
(conn->ntlm.state == NTLMSTATE_TYPE2)) ||
|
||||
(conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
|
||||
(conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPNEGO)
|
||||
if(conn->bits.close &&
|
||||
(((data->req.httpcode == 401) &&
|
||||
(conn->http_negotiate_state == GSS_AUTHRECV)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
if((conn->http_negotiate_state == GSS_AUTHDONE) &&
|
||||
(data->req.httpcode != 401)) {
|
||||
conn->http_negotiate_state = GSS_AUTHSUCC;
|
||||
}
|
||||
if((conn->proxy_negotiate_state == GSS_AUTHDONE) &&
|
||||
(data->req.httpcode != 407)) {
|
||||
conn->proxy_negotiate_state = GSS_AUTHSUCC;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* When all the headers have been parsed, see if we should give
|
||||
* up and return an error.
|
||||
@@ -3549,6 +3671,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if(conn->httpversion != 20)
|
||||
infof(data, "Lying server, not serving HTTP/2\n");
|
||||
}
|
||||
if(conn->httpversion < 20) {
|
||||
conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
|
||||
infof(data, "Mark bundle as not supporting multiuse\n");
|
||||
}
|
||||
}
|
||||
else if(!nc) {
|
||||
/* this is the real world, not a Nirvana
|
||||
@@ -3586,7 +3712,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
|
||||
}
|
||||
else {
|
||||
/* TODO: do we care about the other cases here? */
|
||||
nc = 0;
|
||||
}
|
||||
}
|
||||
@@ -3639,26 +3764,12 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
}
|
||||
else if(conn->httpversion >= 11 &&
|
||||
!conn->bits.close) {
|
||||
/* If HTTP version is >= 1.1 and connection is persistent
|
||||
server supports pipelining. */
|
||||
/* If HTTP version is >= 1.1 and connection is persistent */
|
||||
DEBUGF(infof(data,
|
||||
"HTTP 1.1 or later with persistent connection, "
|
||||
"pipelining supported\n"));
|
||||
/* Activate pipelining if needed */
|
||||
if(conn->bundle) {
|
||||
if(!Curl_pipeline_site_blacklisted(data, conn))
|
||||
conn->bundle->multiuse = BUNDLE_PIPELINING;
|
||||
}
|
||||
"HTTP 1.1 or later with persistent connection\n"));
|
||||
}
|
||||
|
||||
switch(k->httpcode) {
|
||||
case 204:
|
||||
/* (quote from RFC2616, section 10.2.5): The server has
|
||||
* fulfilled the request but does not need to return an
|
||||
* entity-body ... The 204 response MUST NOT include a
|
||||
* message-body, and thus is always terminated by the first
|
||||
* empty line after the header fields. */
|
||||
/* FALLTHROUGH */
|
||||
case 304:
|
||||
/* (quote from RFC2616, section 10.3.5): The 304 response
|
||||
* MUST NOT contain a message-body, and thus is always
|
||||
@@ -3666,6 +3777,13 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
* fields. */
|
||||
if(data->set.timecondition)
|
||||
data->info.timecond = TRUE;
|
||||
/* FALLTHROUGH */
|
||||
case 204:
|
||||
/* (quote from RFC2616, section 10.2.5): The server has
|
||||
* fulfilled the request but does not need to return an
|
||||
* entity-body ... The 204 response MUST NOT include a
|
||||
* message-body, and thus is always terminated by the first
|
||||
* empty line after the header fields. */
|
||||
k->size = 0;
|
||||
k->maxdownload = 0;
|
||||
k->ignorecl = TRUE; /* ignore Content-Length headers */
|
||||
@@ -3733,19 +3851,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
data->info.contenttype = contenttype;
|
||||
}
|
||||
}
|
||||
else if(checkprefix("Server:", k->p)) {
|
||||
if(conn->httpversion < 20) {
|
||||
/* only do this for non-h2 servers */
|
||||
char *server_name = Curl_copy_header_value(k->p);
|
||||
|
||||
/* Turn off pipelining if the server version is blacklisted */
|
||||
if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
|
||||
if(Curl_pipeline_server_blacklisted(data, server_name))
|
||||
conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
|
||||
}
|
||||
free(server_name);
|
||||
}
|
||||
}
|
||||
else if((conn->httpversion == 10) &&
|
||||
conn->bits.httpproxy &&
|
||||
Curl_compareheader(k->p,
|
||||
@@ -3859,7 +3964,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
here, or else use real peer host name. */
|
||||
conn->allocptr.cookiehost?
|
||||
conn->allocptr.cookiehost:conn->host.name,
|
||||
data->state.up.path);
|
||||
data->state.up.path,
|
||||
(conn->handler->protocol&CURLPROTO_HTTPS)?
|
||||
TRUE:FALSE);
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
#endif
|
||||
@@ -3888,6 +3995,22 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#ifdef USE_SPNEGO
|
||||
else if(checkprefix("Persistent-Auth", k->p)) {
|
||||
struct negotiatedata *negdata = &conn->negotiate;
|
||||
struct auth *authp = &data->state.authhost;
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
char *persistentauth = Curl_copy_header_value(k->p);
|
||||
if(!persistentauth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
negdata->noauthpersist = checkprefix("false", persistentauth);
|
||||
negdata->havenoauthpersist = TRUE;
|
||||
infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
|
||||
negdata->noauthpersist, persistentauth);
|
||||
free(persistentauth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if((k->httpcode >= 300 && k->httpcode < 400) &&
|
||||
checkprefix("Location:", k->p) &&
|
||||
!data->req.location) {
|
||||
@@ -3915,6 +4038,27 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef USE_ALTSVC
|
||||
/* If enabled, the header is incoming and this is over HTTPS */
|
||||
else if(data->asi && checkprefix("Alt-Svc:", k->p) &&
|
||||
((conn->handler->flags & PROTOPT_SSL) ||
|
||||
#ifdef CURLDEBUG
|
||||
/* allow debug builds to circumvent the HTTPS restriction */
|
||||
getenv("CURL_ALTSVC_HTTP")
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
)) {
|
||||
/* the ALPN of the current request */
|
||||
enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
|
||||
result = Curl_altsvc_parse(data, data->asi,
|
||||
&k->p[ strlen("Alt-Svc:") ],
|
||||
id, conn->host.name,
|
||||
curlx_uitous(conn->remote_port));
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
else if(conn->handler->protocol & CURLPROTO_RTSP) {
|
||||
result = Curl_rtsp_parseheader(conn, k->p);
|
||||
if(result)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -65,7 +65,7 @@ CURLcode Curl_add_buffer(Curl_send_buffer **inp, const void *inptr,
|
||||
size_t size) WARN_UNUSED_RESULT;
|
||||
CURLcode Curl_add_buffer_send(Curl_send_buffer **inp,
|
||||
struct connectdata *conn,
|
||||
long *bytes_written,
|
||||
curl_off_t *bytes_written,
|
||||
size_t included_body_bytes,
|
||||
int socketindex);
|
||||
|
||||
@@ -74,6 +74,9 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_connect,
|
||||
Curl_send_buffer *req_buffer);
|
||||
CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
|
||||
Curl_send_buffer *buffer,
|
||||
struct Curl_easy *handle);
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
||||
@@ -136,8 +139,6 @@ struct HTTP {
|
||||
|
||||
const char *p_pragma; /* Pragma: string */
|
||||
const char *p_accept; /* Accept: string */
|
||||
curl_off_t readbytecount;
|
||||
curl_off_t writebytecount;
|
||||
|
||||
/* For FORM posting */
|
||||
curl_mimepart form;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -111,8 +111,6 @@ static int http2_perform_getsock(const struct connectdata *conn,
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
(void)numsocks;
|
||||
|
||||
/* TODO We should check underlying socket state if it is SSL socket
|
||||
because of renegotiation. */
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
/* in a HTTP/2 connection we can basically always get a frame so we should
|
||||
@@ -350,14 +348,14 @@ static const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
int Curl_http2_ver(char *p, size_t len)
|
||||
{
|
||||
nghttp2_info *h2 = nghttp2_version(0);
|
||||
return snprintf(p, len, " nghttp2/%s", h2->version_str);
|
||||
return msnprintf(p, len, " nghttp2/%s", h2->version_str);
|
||||
}
|
||||
|
||||
/* HTTP/2 error code to name based on the Error Code Registry.
|
||||
https://tools.ietf.org/html/rfc7540#page-77
|
||||
nghttp2_error_code enums are identical.
|
||||
*/
|
||||
const char *Curl_http2_strerror(uint32_t err)
|
||||
static const char *http2_strerror(uint32_t err)
|
||||
{
|
||||
#ifndef NGHTTP2_HAS_HTTP2_STRERROR
|
||||
const char *str[] = {
|
||||
@@ -618,6 +616,18 @@ static int push_promise(struct Curl_easy *data,
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* multi_connchanged() is called to tell that there is a connection in
|
||||
* this multi handle that has changed state (multiplexing become possible, the
|
||||
* number of allowed streams changed or similar), and a subsequent use of this
|
||||
* multi handle should move CONNECT_PEND handles back to CONNECT to have them
|
||||
* retry.
|
||||
*/
|
||||
static void multi_connchanged(struct Curl_multi *multi)
|
||||
{
|
||||
multi->recheckstate = TRUE;
|
||||
}
|
||||
|
||||
static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
@@ -650,7 +660,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
infof(conn->data,
|
||||
"Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n",
|
||||
httpc->settings.max_concurrent_streams);
|
||||
Curl_multi_connchanged(conn->data->multi);
|
||||
multi_connchanged(conn->data->multi);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -800,7 +810,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
|
||||
", stream %u\n",
|
||||
len - nread, stream_id));
|
||||
data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
|
||||
data_s->conn->proto.httpc.pause_stream_id = stream_id;
|
||||
|
||||
return NGHTTP2_ERR_PAUSE;
|
||||
}
|
||||
@@ -808,7 +818,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
/* pause execution of nghttp2 if we received data for another handle
|
||||
in order to process them first. */
|
||||
if(conn->data != data_s) {
|
||||
data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
|
||||
data_s->conn->proto.httpc.pause_stream_id = stream_id;
|
||||
|
||||
return NGHTTP2_ERR_PAUSE;
|
||||
}
|
||||
@@ -837,7 +847,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
|
||||
Curl_http2_strerror(error_code), error_code, stream_id));
|
||||
http2_strerror(error_code), error_code, stream_id));
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
@@ -854,6 +864,10 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
stream_id);
|
||||
DEBUGASSERT(0);
|
||||
}
|
||||
if(stream_id == httpc->pause_stream_id) {
|
||||
H2BUGF(infof(data_s, "Stopped the pause stream!\n"));
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
|
||||
stream->stream_id = 0; /* cleared */
|
||||
}
|
||||
@@ -953,6 +967,28 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||
char *h;
|
||||
|
||||
if(!strcmp(":authority", (const char *)name)) {
|
||||
/* pseudo headers are lower case */
|
||||
int rc = 0;
|
||||
char *check = aprintf("%s:%d", conn->host.name, conn->remote_port);
|
||||
if(!check)
|
||||
/* no memory */
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
if(!Curl_strcasecompare(check, (const char *)value)) {
|
||||
/* This is push is not for the same authority that was asked for in
|
||||
* the URL. RFC 7540 section 8.2 says: "A client MUST treat a
|
||||
* PUSH_PROMISE for which the server is not authoritative as a stream
|
||||
* error of type PROTOCOL_ERROR."
|
||||
*/
|
||||
(void)nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
stream_id, NGHTTP2_PROTOCOL_ERROR);
|
||||
rc = NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
free(check);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if(!stream->push_headers) {
|
||||
stream->push_headers_alloc = 10;
|
||||
stream->push_headers = malloc(stream->push_headers_alloc *
|
||||
@@ -1193,7 +1229,7 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
|
||||
/*
|
||||
* Initialize nghttp2 for a Curl connection
|
||||
*/
|
||||
CURLcode Curl_http2_init(struct connectdata *conn)
|
||||
static CURLcode http2_init(struct connectdata *conn)
|
||||
{
|
||||
if(!conn->proto.httpc.h2) {
|
||||
int rc;
|
||||
@@ -1427,7 +1463,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
}
|
||||
else if(httpc->error_code != NGHTTP2_NO_ERROR) {
|
||||
failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)",
|
||||
stream->stream_id, Curl_http2_strerror(httpc->error_code),
|
||||
stream->stream_id, http2_strerror(httpc->error_code),
|
||||
httpc->error_code);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
@@ -1809,9 +1845,9 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
/*
|
||||
* BIG TODO: Currently, we send request in this function, but this
|
||||
* function is also used to send request body. It would be nice to
|
||||
* add dedicated function for request.
|
||||
* Currently, we send request in this function, but this function is also
|
||||
* used to send request body. It would be nice to add dedicated function for
|
||||
* request.
|
||||
*/
|
||||
int rv;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
@@ -2137,7 +2173,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
else
|
||||
conn->handler = &Curl_handler_http2;
|
||||
|
||||
result = Curl_http2_init(conn);
|
||||
result = http2_init(conn);
|
||||
if(result) {
|
||||
Curl_add_buffer_free(&stream->header_recvbuf);
|
||||
return result;
|
||||
@@ -2159,7 +2195,7 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
|
||||
|
||||
infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
|
||||
Curl_multi_connchanged(conn->data->multi);
|
||||
multi_connchanged(conn->data->multi);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -2367,6 +2403,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
|
||||
Curl_http2_remove_child(data->set.stream_depends_on, data);
|
||||
}
|
||||
|
||||
/* Only call this function for a transfer that already got a HTTP/2
|
||||
CURLE_HTTP2_STREAM error! */
|
||||
bool Curl_h2_http_1_1_error(struct connectdata *conn)
|
||||
{
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED);
|
||||
}
|
||||
|
||||
#else /* !USE_NGHTTP2 */
|
||||
|
||||
/* Satisfy external references even if http2 is not compiled in. */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -59,8 +59,10 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent,
|
||||
void Curl_http2_remove_child(struct Curl_easy *parent,
|
||||
struct Curl_easy *child);
|
||||
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
|
||||
|
||||
/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
|
||||
bool Curl_h2_http_1_1_error(struct connectdata *conn);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
@@ -74,6 +76,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
|
||||
#define Curl_http2_add_child(x, y, z)
|
||||
#define Curl_http2_remove_child(x, y)
|
||||
#define Curl_http2_cleanup_dependencies(x)
|
||||
#define Curl_h2_http_1_1_error(x) 0
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "strcase.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "http_digest.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@@ -171,7 +172,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_digest_cleanup(struct Curl_easy *data)
|
||||
void Curl_http_auth_cleanup_digest(struct Curl_easy *data)
|
||||
{
|
||||
Curl_auth_digest_cleanup(&data->state.digest);
|
||||
Curl_auth_digest_cleanup(&data->state.proxydigest);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -23,6 +23,8 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
|
||||
/* this is for digest header input */
|
||||
CURLcode Curl_input_digest(struct connectdata *conn,
|
||||
bool proxy, const char *header);
|
||||
@@ -33,10 +35,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
void Curl_digest_cleanup(struct Curl_easy *data);
|
||||
#else
|
||||
#define Curl_digest_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
void Curl_http_auth_cleanup_digest(struct Curl_easy *data);
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_DIGEST_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -49,6 +49,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
/* Point to the correct struct with this */
|
||||
struct negotiatedata *neg_ctx;
|
||||
curlnegotiate state;
|
||||
|
||||
if(proxy) {
|
||||
userp = conn->http_proxy.user;
|
||||
@@ -56,7 +57,8 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||
host = conn->http_proxy.host.name;
|
||||
neg_ctx = &data->state.proxyneg;
|
||||
neg_ctx = &conn->proxyneg;
|
||||
state = conn->proxy_negotiate_state;
|
||||
}
|
||||
else {
|
||||
userp = conn->user;
|
||||
@@ -64,7 +66,8 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||
host = conn->host.name;
|
||||
neg_ctx = &data->state.negotiate;
|
||||
neg_ctx = &conn->negotiate;
|
||||
state = conn->http_negotiate_state;
|
||||
}
|
||||
|
||||
/* Not set means empty */
|
||||
@@ -80,59 +83,138 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
header++;
|
||||
|
||||
len = strlen(header);
|
||||
neg_ctx->havenegdata = len != 0;
|
||||
if(!len) {
|
||||
/* Is this the first call in a new negotiation? */
|
||||
if(neg_ctx->context) {
|
||||
/* The server rejected our authentication and hasn't suppled any more
|
||||
if(state == GSS_AUTHSUCC) {
|
||||
infof(conn->data, "Negotiate auth restarted\n");
|
||||
Curl_http_auth_cleanup_negotiate(conn);
|
||||
}
|
||||
else if(state != GSS_AUTHNONE) {
|
||||
/* The server rejected our authentication and hasn't supplied any more
|
||||
negotiation mechanisms */
|
||||
Curl_http_auth_cleanup_negotiate(conn);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Supports SSL channel binding for Windows ISS extended protection */
|
||||
#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS)
|
||||
neg_ctx->sslContext = conn->sslContext;
|
||||
#endif
|
||||
|
||||
/* Initialize the security context and decode our challenge */
|
||||
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
|
||||
host, header, neg_ctx);
|
||||
|
||||
if(result)
|
||||
Curl_auth_spnego_cleanup(neg_ctx);
|
||||
Curl_http_auth_cleanup_negotiate(conn);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg :
|
||||
&conn->data->state.negotiate;
|
||||
struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg :
|
||||
&conn->negotiate;
|
||||
struct auth *authp = proxy ? &conn->data->state.authproxy :
|
||||
&conn->data->state.authhost;
|
||||
curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
|
||||
&conn->http_negotiate_state;
|
||||
char *base64 = NULL;
|
||||
size_t len = 0;
|
||||
char *userp;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len);
|
||||
if(result)
|
||||
return result;
|
||||
authp->done = FALSE;
|
||||
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
if(*state == GSS_AUTHRECV) {
|
||||
if(neg_ctx->havenegdata) {
|
||||
neg_ctx->havemultiplerequests = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = userp;
|
||||
else if(*state == GSS_AUTHSUCC) {
|
||||
if(!neg_ctx->havenoauthpersist) {
|
||||
neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests;
|
||||
}
|
||||
}
|
||||
|
||||
free(base64);
|
||||
if(neg_ctx->noauthpersist ||
|
||||
(*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) {
|
||||
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) {
|
||||
infof(conn->data, "Curl_output_negotiate, "
|
||||
"no persistent authentication: cleanup existing context");
|
||||
Curl_http_auth_cleanup_negotiate(conn);
|
||||
}
|
||||
if(!neg_ctx->context) {
|
||||
result = Curl_input_negotiate(conn, proxy, "Negotiate");
|
||||
if(result == CURLE_LOGIN_DENIED) {
|
||||
/* negotiate auth failed, let's continue unauthenticated to stay
|
||||
* compatible with the behavior before curl-7_64_0-158-g6c6035532 */
|
||||
conn->data->state.authproblem = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_auth_create_spnego_message(conn->data,
|
||||
neg_ctx, &base64, &len);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
}
|
||||
else {
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = userp;
|
||||
}
|
||||
|
||||
free(base64);
|
||||
|
||||
if(userp == NULL) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*state = GSS_AUTHSENT;
|
||||
#ifdef HAVE_GSSAPI
|
||||
if(neg_ctx->status == GSS_S_COMPLETE ||
|
||||
neg_ctx->status == GSS_S_CONTINUE_NEEDED) {
|
||||
*state = GSS_AUTHDONE;
|
||||
}
|
||||
#else
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
if(neg_ctx->status == SEC_E_OK ||
|
||||
neg_ctx->status == SEC_I_CONTINUE_NEEDED) {
|
||||
*state = GSS_AUTHDONE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if(*state == GSS_AUTHDONE || *state == GSS_AUTHSUCC) {
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
authp->done = TRUE;
|
||||
}
|
||||
|
||||
neg_ctx->havenegdata = FALSE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data)
|
||||
void Curl_http_auth_cleanup_negotiate(struct connectdata *conn)
|
||||
{
|
||||
Curl_auth_spnego_cleanup(&data->state.negotiate);
|
||||
Curl_auth_spnego_cleanup(&data->state.proxyneg);
|
||||
conn->http_negotiate_state = GSS_AUTHNONE;
|
||||
conn->proxy_negotiate_state = GSS_AUTHNONE;
|
||||
|
||||
Curl_auth_cleanup_spnego(&conn->negotiate);
|
||||
Curl_auth_cleanup_spnego(&conn->proxyneg);
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
|
||||
|
||||
/* this is for Negotiate header input */
|
||||
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
@@ -31,8 +31,8 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
/* this is for creating Negotiate header output */
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data);
|
||||
void Curl_http_auth_cleanup_negotiate(struct connectdata *conn);
|
||||
|
||||
#endif /* USE_SPNEGO */
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -68,9 +68,11 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
{
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
curlntlm *state;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
||||
state = proxy ? &conn->proxy_ntlm_state : &conn->http_ntlm_state;
|
||||
|
||||
if(checkprefix("NTLM", header)) {
|
||||
header += strlen("NTLM");
|
||||
@@ -83,25 +85,25 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
*state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(ntlm->state == NTLMSTATE_LAST) {
|
||||
if(*state == NTLMSTATE_LAST) {
|
||||
infof(conn->data, "NTLM auth restarted\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
Curl_http_auth_cleanup_ntlm(conn);
|
||||
}
|
||||
else if(ntlm->state == NTLMSTATE_TYPE3) {
|
||||
else if(*state == NTLMSTATE_TYPE3) {
|
||||
infof(conn->data, "NTLM handshake rejected\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
ntlm->state = NTLMSTATE_NONE;
|
||||
Curl_http_auth_cleanup_ntlm(conn);
|
||||
*state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
else if(ntlm->state >= NTLMSTATE_TYPE1) {
|
||||
else if(*state >= NTLMSTATE_TYPE1) {
|
||||
infof(conn->data, "NTLM handshake failure (internal error)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
|
||||
*state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +131,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
curlntlm *state;
|
||||
struct auth *authp;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
@@ -147,6 +150,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||
hostname = conn->http_proxy.host.name;
|
||||
ntlm = &conn->proxyntlm;
|
||||
state = &conn->proxy_ntlm_state;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
@@ -157,6 +161,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
conn->data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||
hostname = conn->host.name;
|
||||
ntlm = &conn->ntlm;
|
||||
state = &conn->http_ntlm_state;
|
||||
authp = &conn->data->state.authhost;
|
||||
}
|
||||
authp->done = FALSE;
|
||||
@@ -175,9 +180,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
if(s_hSecDll == NULL)
|
||||
return err;
|
||||
}
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
ntlm->sslContext = conn->sslContext;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
switch(ntlm->state) {
|
||||
switch(*state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
/* Create a type-1 message */
|
||||
@@ -219,7 +227,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
|
||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
|
||||
*state = NTLMSTATE_TYPE3; /* we send a type-3 */
|
||||
authp->done = TRUE;
|
||||
}
|
||||
break;
|
||||
@@ -227,7 +235,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
ntlm->state = NTLMSTATE_LAST;
|
||||
*state = NTLMSTATE_LAST;
|
||||
/* FALLTHROUGH */
|
||||
case NTLMSTATE_LAST:
|
||||
Curl_safefree(*allocuserpwd);
|
||||
@@ -238,13 +246,13 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_http_ntlm_cleanup(struct connectdata *conn)
|
||||
void Curl_http_auth_cleanup_ntlm(struct connectdata *conn)
|
||||
{
|
||||
Curl_auth_ntlm_cleanup(&conn->ntlm);
|
||||
Curl_auth_ntlm_cleanup(&conn->proxyntlm);
|
||||
Curl_auth_cleanup_ntlm(&conn->ntlm);
|
||||
Curl_auth_cleanup_ntlm(&conn->proxyntlm);
|
||||
|
||||
#if defined(NTLM_WB_ENABLED)
|
||||
Curl_ntlm_wb_cleanup(conn);
|
||||
Curl_http_auth_cleanup_ntlm_wb(conn);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef HEADER_CURL_NTLM_H
|
||||
#define HEADER_CURL_NTLM_H
|
||||
#ifndef HEADER_CURL_HTTP_NTLM_H
|
||||
#define HEADER_CURL_HTTP_NTLM_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -33,8 +33,8 @@ CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_http_ntlm_cleanup(struct connectdata *conn);
|
||||
void Curl_http_auth_cleanup_ntlm(struct connectdata *conn);
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_H */
|
||||
#endif /* HEADER_CURL_HTTP_NTLM_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -643,7 +643,7 @@ static CURLcode CONNECT(struct connectdata *conn,
|
||||
|
||||
void Curl_connect_free(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
struct connectdata *conn = data->conn;
|
||||
struct http_connect_state *s = conn->connect_state;
|
||||
if(s) {
|
||||
free(s);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -96,26 +96,8 @@ unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
|
||||
|
||||
#if defined(HAVE_GETIFADDRS)
|
||||
|
||||
bool Curl_if_is_interface_name(const char *interf)
|
||||
{
|
||||
bool result = FALSE;
|
||||
|
||||
struct ifaddrs *iface, *head;
|
||||
|
||||
if(getifaddrs(&head) >= 0) {
|
||||
for(iface = head; iface != NULL; iface = iface->ifa_next) {
|
||||
if(strcasecompare(iface->ifa_name, interf)) {
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeifaddrs(head);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
struct ifaddrs *iface, *head;
|
||||
@@ -127,7 +109,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
|
||||
#if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \
|
||||
!defined(ENABLE_IPV6)
|
||||
(void) remote_scope_id;
|
||||
(void) local_scope_id;
|
||||
#endif
|
||||
|
||||
if(getifaddrs(&head) >= 0) {
|
||||
@@ -141,7 +123,9 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
char ipstr[64];
|
||||
#ifdef ENABLE_IPV6
|
||||
if(af == AF_INET6) {
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
unsigned int scopeid = 0;
|
||||
#endif
|
||||
unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
|
||||
|
||||
if(ifscope != remote_scope) {
|
||||
@@ -161,15 +145,16 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
->sin6_scope_id;
|
||||
|
||||
/* If given, scope id should match. */
|
||||
if(remote_scope_id && scopeid != remote_scope_id) {
|
||||
if(local_scope_id && scopeid != local_scope_id) {
|
||||
if(res == IF2IP_NOT_FOUND)
|
||||
res = IF2IP_AF_NOT_SUPPORTED;
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(scopeid)
|
||||
snprintf(scope, sizeof(scope), "%%%u", scopeid);
|
||||
msnprintf(scope, sizeof(scope), "%%%u", scopeid);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -177,7 +162,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
&((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
|
||||
res = IF2IP_FOUND;
|
||||
ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
|
||||
snprintf(buf, buf_size, "%s%s", ip, scope);
|
||||
msnprintf(buf, buf_size, "%s%s", ip, scope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -196,17 +181,8 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
|
||||
#elif defined(HAVE_IOCTL_SIOCGIFADDR)
|
||||
|
||||
bool Curl_if_is_interface_name(const char *interf)
|
||||
{
|
||||
/* This is here just to support the old interfaces */
|
||||
char buf[256];
|
||||
|
||||
return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) ==
|
||||
IF2IP_NOT_FOUND) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
struct ifreq req;
|
||||
@@ -216,7 +192,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
size_t len;
|
||||
|
||||
(void)remote_scope;
|
||||
(void)remote_scope_id;
|
||||
(void)local_scope_id;
|
||||
|
||||
if(!interf || (af != AF_INET))
|
||||
return IF2IP_NOT_FOUND;
|
||||
@@ -251,20 +227,13 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
|
||||
#else
|
||||
|
||||
bool Curl_if_is_interface_name(const char *interf)
|
||||
{
|
||||
(void) interf;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
(void) af;
|
||||
(void) remote_scope;
|
||||
(void) remote_scope_id;
|
||||
(void) local_scope_id;
|
||||
(void) interf;
|
||||
(void) buf;
|
||||
(void) buf_size;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -32,8 +32,6 @@
|
||||
|
||||
unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
|
||||
|
||||
bool Curl_if_is_interface_name(const char *interf);
|
||||
|
||||
typedef enum {
|
||||
IF2IP_NOT_FOUND = 0, /* Interface not found */
|
||||
IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */
|
||||
@@ -41,7 +39,7 @@ typedef enum {
|
||||
} if2ip_result_t;
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
unsigned int local_scope_id, const char *interf,
|
||||
char *buf, int buf_size);
|
||||
|
||||
#ifdef __INTERIX
|
||||
|
||||
+19
-22
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -28,6 +28,7 @@
|
||||
* RFC4959 IMAP Extension for SASL Initial Client Response
|
||||
* RFC5092 IMAP URL Scheme
|
||||
* RFC6749 OAuth 2.0 Authorization Framework
|
||||
* RFC8314 Use of TLS for Email Submission and Access
|
||||
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||
*
|
||||
***************************************************************************/
|
||||
@@ -316,7 +317,7 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
|
||||
a space and optionally some text as per RFC-3501 for the AUTHENTICATE and
|
||||
APPEND commands and as outlined in Section 4. Examples of RFC-4959 but
|
||||
some e-mail servers ignore this and only send a single + instead. */
|
||||
if(imap && !imap->custom && ((len == 3 && !memcmp("+", line, 1)) ||
|
||||
if(imap && !imap->custom && ((len == 3 && line[0] == '+') ||
|
||||
(len >= 2 && !memcmp("+ ", line, 2)))) {
|
||||
switch(imapc->state) {
|
||||
/* States which are interested in continuation responses */
|
||||
@@ -1042,7 +1043,7 @@ static CURLcode imap_state_listsearch_resp(struct connectdata *conn,
|
||||
line[len] = '\0';
|
||||
}
|
||||
else if(imapcode != IMAP_RESP_OK)
|
||||
result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
|
||||
result = CURLE_QUOTE_ERROR;
|
||||
else
|
||||
/* End of DO phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@@ -1114,7 +1115,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
if(imapcode != '*') {
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
state(conn, IMAP_STOP);
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse
|
||||
@@ -1177,11 +1178,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
|
||||
if(data->req.bytecount == size)
|
||||
/* The entire data is already transferred! */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
else {
|
||||
/* IMAP download */
|
||||
data->req.maxdownload = size;
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, size, FALSE, -1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1231,7 +1232,7 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
|
||||
Curl_pgrsSetUploadSize(data, data->state.infilesize);
|
||||
|
||||
/* IMAP upload */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
||||
|
||||
/* End of DO phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@@ -1362,19 +1363,20 @@ static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_pp_statemach(&imapc->pp, FALSE);
|
||||
result = Curl_pp_statemach(&imapc->pp, FALSE, FALSE);
|
||||
*done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode imap_block_statemach(struct connectdata *conn)
|
||||
static CURLcode imap_block_statemach(struct connectdata *conn,
|
||||
bool disconnecting)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
|
||||
while(imapc->state != IMAP_STOP && !result)
|
||||
result = Curl_pp_statemach(&imapc->pp, TRUE);
|
||||
result = Curl_pp_statemach(&imapc->pp, TRUE, disconnecting);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1490,14 +1492,9 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
|
||||
state(conn, IMAP_APPEND_FINAL);
|
||||
}
|
||||
|
||||
/* Run the state-machine
|
||||
|
||||
TODO: when the multi interface is used, this _really_ should be using
|
||||
the imap_multi_statemach function but we have no general support for
|
||||
non-blocking DONE operations!
|
||||
*/
|
||||
/* Run the state-machine */
|
||||
if(!result)
|
||||
result = imap_block_statemach(conn);
|
||||
result = imap_block_statemach(conn, FALSE);
|
||||
}
|
||||
|
||||
/* Cleanup our per-request based variables */
|
||||
@@ -1635,7 +1632,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
point! */
|
||||
if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
|
||||
if(!imap_perform_logout(conn))
|
||||
(void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
|
||||
(void)imap_block_statemach(conn, TRUE); /* ignore errors on LOGOUT */
|
||||
|
||||
/* Disconnect from the server */
|
||||
Curl_pp_disconnect(&imapc->pp);
|
||||
@@ -1659,7 +1656,7 @@ static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
|
||||
|
||||
if(imap->transfer != FTPTRANSFER_BODY)
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(conn->data, -1, -1, FALSE, -1);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -1749,8 +1746,8 @@ static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
|
||||
imapc->cmdid = (imapc->cmdid + 1) % 1000;
|
||||
|
||||
/* Calculate the tag based on the connection ID and command ID */
|
||||
snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
|
||||
'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
|
||||
msnprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
|
||||
'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
|
||||
|
||||
/* Prefix the format with the tag */
|
||||
taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
|
||||
@@ -1793,7 +1790,7 @@ static char *imap_atom(const char *str, bool escape_only)
|
||||
return NULL;
|
||||
|
||||
/* Look for "atom-specials", counting the backslash and quote characters as
|
||||
these will need escapping */
|
||||
these will need escaping */
|
||||
p1 = str;
|
||||
while(*p1) {
|
||||
if(*p1 == '\\')
|
||||
|
||||
@@ -55,11 +55,11 @@ static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
|
||||
DEBUGASSERT(size >= 16);
|
||||
|
||||
tmp[0] = '\0';
|
||||
(void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
|
||||
((int)((unsigned char)src[0])) & 0xff,
|
||||
((int)((unsigned char)src[1])) & 0xff,
|
||||
((int)((unsigned char)src[2])) & 0xff,
|
||||
((int)((unsigned char)src[3])) & 0xff);
|
||||
(void)msnprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
|
||||
((int)((unsigned char)src[0])) & 0xff,
|
||||
((int)((unsigned char)src[1])) & 0xff,
|
||||
((int)((unsigned char)src[2])) & 0xff,
|
||||
((int)((unsigned char)src[3])) & 0xff);
|
||||
|
||||
len = strlen(tmp);
|
||||
if(len == 0 || len >= size) {
|
||||
@@ -148,7 +148,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += snprintf(tp, 5, "%lx", words[i]);
|
||||
tp += msnprintf(tp, 5, "%lx", words[i]);
|
||||
}
|
||||
|
||||
/* Was it a trailing run of 0x00's?
|
||||
|
||||
@@ -153,7 +153,7 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
const char *curtok;
|
||||
int ch, saw_xdigit;
|
||||
size_t val;
|
||||
|
||||
@@ -168,6 +168,7 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while((ch = *src++) != '\0') {
|
||||
const char *xdigits;
|
||||
const char *pch;
|
||||
|
||||
pch = strchr((xdigits = xdigits_l), ch);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -744,7 +744,7 @@ quit:
|
||||
#endif
|
||||
|
||||
/* no data to transfer */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, -1, -1, FALSE, -1);
|
||||
connclose(conn, "LDAP connection always disable re-use");
|
||||
|
||||
return result;
|
||||
@@ -839,6 +839,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
{
|
||||
int rc = LDAP_SUCCESS;
|
||||
char *path;
|
||||
char *query;
|
||||
char *p;
|
||||
char *q;
|
||||
size_t i;
|
||||
@@ -846,7 +847,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(!conn->data ||
|
||||
!conn->data->state.up.path ||
|
||||
conn->data->state.up.path[0] != '/' ||
|
||||
!strcasecompare("LDAP", conn->data->state.up.scheme))
|
||||
!strncasecompare("LDAP", conn->data->state.up.scheme, 4))
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
|
||||
ludp->lud_scope = LDAP_SCOPE_BASE;
|
||||
@@ -858,11 +859,14 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(!path)
|
||||
return LDAP_NO_MEMORY;
|
||||
|
||||
/* Parse the DN (Distinguished Name) */
|
||||
q = strchr(p, '?');
|
||||
if(q)
|
||||
*q++ = '\0';
|
||||
/* Duplicate the query */
|
||||
q = query = strdup(conn->data->state.up.query);
|
||||
if(!query) {
|
||||
free(path);
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Parse the DN (Distinguished Name) */
|
||||
if(*p) {
|
||||
char *dn = p;
|
||||
char *unescaped;
|
||||
@@ -1039,6 +1043,7 @@ static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
|
||||
quit:
|
||||
free(path);
|
||||
free(query);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1064,8 +1069,6 @@ static int _ldap_url_parse(const struct connectdata *conn,
|
||||
|
||||
static void _ldap_free_urldesc(LDAPURLDesc *ludp)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if(!ludp)
|
||||
return;
|
||||
|
||||
@@ -1073,6 +1076,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp)
|
||||
free(ludp->lud_filter);
|
||||
|
||||
if(ludp->lud_attrs) {
|
||||
size_t i;
|
||||
for(i = 0; i < ludp->lud_attrs_dups; i++)
|
||||
free(ludp->lud_attrs[i]);
|
||||
free(ludp->lud_attrs);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,22 +22,22 @@
|
||||
#include <winver.h>
|
||||
#include "../include/curl/curlver.h"
|
||||
|
||||
LANGUAGE 0x09,0x01
|
||||
LANGUAGE 0, 0
|
||||
|
||||
#define RC_VERSION LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RC_VERSION
|
||||
PRODUCTVERSION RC_VERSION
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#if defined(DEBUGBUILD) || defined(_DEBUG)
|
||||
FILEFLAGS 1
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0
|
||||
FILEFLAGS 0L
|
||||
#endif
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L
|
||||
FILESUBTYPE 0L
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
|
||||
+59
-53
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* !checksrc! disable COPYRIGHT
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD4 Message-Digest Algorithm (RFC 1320).
|
||||
*
|
||||
@@ -37,9 +38,11 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
/* The NSS, OS/400 and sometimes mbed TLS crypto libraries do not provide the
|
||||
* MD4 hash algorithm, so we have a local implementation of it */
|
||||
/* The NSS, OS/400, and when not included, OpenSSL and mbed TLS crypto
|
||||
* libraries do not provide the MD4 hash algorithm, so we use this
|
||||
* implementation of it */
|
||||
#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
|
||||
(defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) || \
|
||||
(defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
|
||||
|
||||
#include "curl_md4.h"
|
||||
@@ -112,7 +115,6 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
MD4_u32plus a, b, c, d;
|
||||
MD4_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ptr = (const unsigned char *)data;
|
||||
|
||||
@@ -122,6 +124,8 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
d = ctx->d;
|
||||
|
||||
do {
|
||||
MD4_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
@@ -129,59 +133,59 @@ static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 3)
|
||||
STEP(F, d, a, b, c, SET(1), 7)
|
||||
STEP(F, c, d, a, b, SET(2), 11)
|
||||
STEP(F, b, c, d, a, SET(3), 19)
|
||||
STEP(F, a, b, c, d, SET(4), 3)
|
||||
STEP(F, d, a, b, c, SET(5), 7)
|
||||
STEP(F, c, d, a, b, SET(6), 11)
|
||||
STEP(F, b, c, d, a, SET(7), 19)
|
||||
STEP(F, a, b, c, d, SET(8), 3)
|
||||
STEP(F, d, a, b, c, SET(9), 7)
|
||||
STEP(F, c, d, a, b, SET(10), 11)
|
||||
STEP(F, b, c, d, a, SET(11), 19)
|
||||
STEP(F, a, b, c, d, SET(12), 3)
|
||||
STEP(F, d, a, b, c, SET(13), 7)
|
||||
STEP(F, c, d, a, b, SET(14), 11)
|
||||
STEP(F, b, c, d, a, SET(15), 19)
|
||||
STEP(F, d, a, b, c, SET(1), 7)
|
||||
STEP(F, c, d, a, b, SET(2), 11)
|
||||
STEP(F, b, c, d, a, SET(3), 19)
|
||||
STEP(F, a, b, c, d, SET(4), 3)
|
||||
STEP(F, d, a, b, c, SET(5), 7)
|
||||
STEP(F, c, d, a, b, SET(6), 11)
|
||||
STEP(F, b, c, d, a, SET(7), 19)
|
||||
STEP(F, a, b, c, d, SET(8), 3)
|
||||
STEP(F, d, a, b, c, SET(9), 7)
|
||||
STEP(F, c, d, a, b, SET(10), 11)
|
||||
STEP(F, b, c, d, a, SET(11), 19)
|
||||
STEP(F, a, b, c, d, SET(12), 3)
|
||||
STEP(F, d, a, b, c, SET(13), 7)
|
||||
STEP(F, c, d, a, b, SET(14), 11)
|
||||
STEP(F, b, c, d, a, SET(15), 19)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
|
||||
STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
|
||||
STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
|
||||
STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
|
||||
STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
|
||||
STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
|
||||
STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
|
||||
STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
|
||||
STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
|
||||
|
||||
a += saved_a;
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
@@ -211,7 +215,7 @@ static void MD4_Init(MD4_CTX *ctx)
|
||||
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
MD4_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
unsigned long used;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
@@ -222,7 +226,7 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if(used) {
|
||||
available = 64 - used;
|
||||
unsigned long available = 64 - used;
|
||||
|
||||
if(size < available) {
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
@@ -303,5 +307,7 @@ void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
|
||||
MD4_Update(&ctx, input, curlx_uztoui(len));
|
||||
MD4_Final(output, &ctx);
|
||||
}
|
||||
|
||||
#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
|
||||
(defined(USE_OPENSSL) && defined(OPENSSL_NO_MD4)) ||
|
||||
(defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
|
||||
|
||||
+83
-89
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -39,19 +39,19 @@
|
||||
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX * ctx)
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
md5_init(ctx);
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX * ctx,
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
md5_update(ctx, inputLen, input);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
{
|
||||
md5_digest(ctx, 16, digest);
|
||||
}
|
||||
@@ -65,25 +65,25 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
|
||||
typedef gcry_md_hd_t MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX * ctx)
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
gcry_md_open(ctx, GCRY_MD_MD5, 0);
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX * ctx,
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
gcry_md_write(*ctx, input, inputLen);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
{
|
||||
memcpy(digest, gcry_md_read(*ctx, 0), 16);
|
||||
gcry_md_close(*ctx);
|
||||
}
|
||||
|
||||
#elif defined(USE_OPENSSL)
|
||||
#elif defined(USE_OPENSSL) && !defined(USE_AMISSL)
|
||||
/* When OpenSSL is available we use the MD5-function from OpenSSL */
|
||||
#include <openssl/md5.h>
|
||||
#include "curl_memory.h"
|
||||
@@ -124,7 +124,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
CC_MD5_Final(digest, ctx);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
|
||||
#elif defined(WIN32) && !defined(CURL_WINDOWS_APP)
|
||||
|
||||
#include <wincrypt.h>
|
||||
#include "curl_memory.h"
|
||||
@@ -163,13 +163,6 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
CryptReleaseContext(ctx->hCryptProv, 0);
|
||||
}
|
||||
|
||||
#elif defined(USE_AXTLS)
|
||||
#include <axTLS/config.h>
|
||||
#include <axTLS/os_int.h>
|
||||
#include <axTLS/crypto.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
#else
|
||||
/* When no other crypto library is available we use this code segment */
|
||||
/*
|
||||
@@ -282,7 +275,6 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
const unsigned char *ptr;
|
||||
MD5_u32plus a, b, c, d;
|
||||
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ptr = (const unsigned char *)data;
|
||||
|
||||
@@ -292,6 +284,8 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
d = ctx->d;
|
||||
|
||||
do {
|
||||
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
saved_a = a;
|
||||
saved_b = b;
|
||||
saved_c = c;
|
||||
@@ -299,77 +293,77 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
|
||||
/* Round 1 */
|
||||
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
|
||||
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
|
||||
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
|
||||
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
|
||||
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
|
||||
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
|
||||
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
|
||||
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
|
||||
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
|
||||
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
|
||||
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
|
||||
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
|
||||
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
|
||||
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
|
||||
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
|
||||
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
|
||||
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
|
||||
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
|
||||
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
|
||||
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
|
||||
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
|
||||
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
|
||||
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
|
||||
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
|
||||
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
|
||||
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
|
||||
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
|
||||
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
|
||||
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
|
||||
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
|
||||
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
|
||||
|
||||
/* Round 2 */
|
||||
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
|
||||
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
|
||||
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
|
||||
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
|
||||
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
|
||||
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
|
||||
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
|
||||
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
|
||||
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
|
||||
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
|
||||
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
|
||||
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
|
||||
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
|
||||
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
|
||||
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
|
||||
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
|
||||
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
|
||||
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
|
||||
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
|
||||
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
|
||||
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
|
||||
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
|
||||
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
|
||||
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
|
||||
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
|
||||
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
|
||||
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
|
||||
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
|
||||
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
|
||||
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
|
||||
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
|
||||
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
|
||||
|
||||
/* Round 3 */
|
||||
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
|
||||
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
|
||||
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
|
||||
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
|
||||
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
|
||||
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
|
||||
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
|
||||
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
|
||||
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
|
||||
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
|
||||
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
|
||||
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
|
||||
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
|
||||
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
|
||||
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
|
||||
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
|
||||
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
|
||||
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
|
||||
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
|
||||
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
|
||||
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
|
||||
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
|
||||
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
|
||||
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
|
||||
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
|
||||
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
|
||||
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
|
||||
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
|
||||
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
|
||||
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
|
||||
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
|
||||
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
|
||||
|
||||
/* Round 4 */
|
||||
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
|
||||
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
|
||||
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
|
||||
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
|
||||
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
|
||||
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
|
||||
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
|
||||
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
|
||||
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
|
||||
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
|
||||
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
|
||||
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
|
||||
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
|
||||
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
|
||||
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
|
||||
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
|
||||
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
|
||||
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
|
||||
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
|
||||
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
|
||||
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
|
||||
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
|
||||
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
|
||||
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
|
||||
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
|
||||
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
|
||||
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
|
||||
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
|
||||
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
|
||||
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
|
||||
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
|
||||
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
|
||||
|
||||
a += saved_a;
|
||||
a += saved_a;
|
||||
b += saved_b;
|
||||
c += saved_c;
|
||||
d += saved_d;
|
||||
@@ -399,7 +393,7 @@ static void MD5_Init(MD5_CTX *ctx)
|
||||
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
MD5_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
unsigned long used;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
@@ -410,7 +404,7 @@ static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
if(used) {
|
||||
available = 64 - used;
|
||||
unsigned long available = 64 - used;
|
||||
|
||||
if(size < available) {
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
@@ -552,23 +546,23 @@ MD5_context *Curl_MD5_init(const MD5_params *md5params)
|
||||
return ctxt;
|
||||
}
|
||||
|
||||
int Curl_MD5_update(MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len)
|
||||
CURLcode Curl_MD5_update(MD5_context *context,
|
||||
const unsigned char *data,
|
||||
unsigned int len)
|
||||
{
|
||||
(*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
|
||||
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
int Curl_MD5_final(MD5_context *context, unsigned char *result)
|
||||
CURLcode Curl_MD5_final(MD5_context *context, unsigned char *result)
|
||||
{
|
||||
(*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
|
||||
|
||||
free(context->md5_hashctx);
|
||||
free(context);
|
||||
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -100,30 +100,29 @@ struct memdebug {
|
||||
* Don't use these with multithreaded test programs!
|
||||
*/
|
||||
|
||||
#define logfile curl_debuglogfile
|
||||
FILE *curl_debuglogfile = NULL;
|
||||
FILE *curl_dbg_logfile = NULL;
|
||||
static bool memlimit = FALSE; /* enable memory limit */
|
||||
static long memsize = 0; /* set number of mallocs allowed */
|
||||
|
||||
/* this sets the log file name */
|
||||
void curl_memdebug(const char *logname)
|
||||
void curl_dbg_memdebug(const char *logname)
|
||||
{
|
||||
if(!logfile) {
|
||||
if(!curl_dbg_logfile) {
|
||||
if(logname && *logname)
|
||||
logfile = fopen(logname, FOPEN_WRITETEXT);
|
||||
curl_dbg_logfile = fopen(logname, FOPEN_WRITETEXT);
|
||||
else
|
||||
logfile = stderr;
|
||||
curl_dbg_logfile = stderr;
|
||||
#ifdef MEMDEBUG_LOG_SYNC
|
||||
/* Flush the log file after every line so the log isn't lost in a crash */
|
||||
if(logfile)
|
||||
setbuf(logfile, (char *)NULL);
|
||||
if(curl_dbg_logfile)
|
||||
setbuf(curl_dbg_logfile, (char *)NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* This function sets the number of malloc() calls that should return
|
||||
successfully! */
|
||||
void curl_memlimit(long limit)
|
||||
void curl_dbg_memlimit(long limit)
|
||||
{
|
||||
if(!memlimit) {
|
||||
memlimit = TRUE;
|
||||
@@ -140,12 +139,12 @@ static bool countcheck(const char *func, int line, const char *source)
|
||||
if(!memsize) {
|
||||
if(source) {
|
||||
/* log to file */
|
||||
curl_memlog("LIMIT %s:%d %s reached memlimit\n",
|
||||
source, line, func);
|
||||
curl_dbg_log("LIMIT %s:%d %s reached memlimit\n",
|
||||
source, line, func);
|
||||
/* log to stderr also */
|
||||
fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
|
||||
source, line, func);
|
||||
fflush(logfile); /* because it might crash now */
|
||||
fflush(curl_dbg_logfile); /* because it might crash now */
|
||||
}
|
||||
errno = ENOMEM;
|
||||
return TRUE; /* RETURN ERROR! */
|
||||
@@ -159,7 +158,7 @@ static bool countcheck(const char *func, int line, const char *source)
|
||||
return FALSE; /* allow this */
|
||||
}
|
||||
|
||||
void *curl_domalloc(size_t wantedsize, int line, const char *source)
|
||||
void *curl_dbg_malloc(size_t wantedsize, int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem;
|
||||
size_t size;
|
||||
@@ -180,15 +179,15 @@ void *curl_domalloc(size_t wantedsize, int line, const char *source)
|
||||
}
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
|
||||
source, line, wantedsize,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
curl_dbg_log("MEM %s:%d malloc(%zu) = %p\n",
|
||||
source, line, wantedsize,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
|
||||
return (mem ? mem->mem : NULL);
|
||||
}
|
||||
|
||||
void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
|
||||
int line, const char *source)
|
||||
void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size,
|
||||
int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem;
|
||||
size_t size, user_size;
|
||||
@@ -208,14 +207,14 @@ void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
|
||||
mem->size = user_size;
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
|
||||
source, line, wanted_elements, wanted_size,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
curl_dbg_log("MEM %s:%d calloc(%zu,%zu) = %p\n",
|
||||
source, line, wanted_elements, wanted_size,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
|
||||
return (mem ? mem->mem : NULL);
|
||||
}
|
||||
|
||||
char *curl_dostrdup(const char *str, int line, const char *source)
|
||||
char *curl_dbg_strdup(const char *str, int line, const char *source)
|
||||
{
|
||||
char *mem;
|
||||
size_t len;
|
||||
@@ -227,19 +226,19 @@ char *curl_dostrdup(const char *str, int line, const char *source)
|
||||
|
||||
len = strlen(str) + 1;
|
||||
|
||||
mem = curl_domalloc(len, 0, NULL); /* NULL prevents logging */
|
||||
mem = curl_dbg_malloc(len, 0, NULL); /* NULL prevents logging */
|
||||
if(mem)
|
||||
memcpy(mem, str, len);
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
|
||||
source, line, (const void *)str, len, (const void *)mem);
|
||||
curl_dbg_log("MEM %s:%d strdup(%p) (%zu) = %p\n",
|
||||
source, line, (const void *)str, len, (const void *)mem);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
|
||||
wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source)
|
||||
{
|
||||
wchar_t *mem;
|
||||
size_t wsiz, bsiz;
|
||||
@@ -252,12 +251,12 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
|
||||
wsiz = wcslen(str) + 1;
|
||||
bsiz = wsiz * sizeof(wchar_t);
|
||||
|
||||
mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */
|
||||
mem = curl_dbg_malloc(bsiz, 0, NULL); /* NULL prevents logging */
|
||||
if(mem)
|
||||
memcpy(mem, str, bsiz);
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
|
||||
curl_dbg_log("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
|
||||
source, line, (void *)str, bsiz, (void *)mem);
|
||||
|
||||
return mem;
|
||||
@@ -266,8 +265,8 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
|
||||
|
||||
/* We provide a realloc() that accepts a NULL as pointer, which then
|
||||
performs a malloc(). In order to work with ares. */
|
||||
void *curl_dorealloc(void *ptr, size_t wantedsize,
|
||||
int line, const char *source)
|
||||
void *curl_dbg_realloc(void *ptr, size_t wantedsize,
|
||||
int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem = NULL;
|
||||
|
||||
@@ -293,7 +292,7 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
|
||||
|
||||
mem = (Curl_crealloc)(mem, size);
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
|
||||
curl_dbg_log("MEM %s:%d realloc(%p, %zu) = %p\n",
|
||||
source, line, (void *)ptr, wantedsize,
|
||||
mem ? (void *)mem->mem : (void *)0);
|
||||
|
||||
@@ -305,11 +304,10 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void curl_dofree(void *ptr, int line, const char *source)
|
||||
void curl_dbg_free(void *ptr, int line, const char *source)
|
||||
{
|
||||
struct memdebug *mem;
|
||||
|
||||
if(ptr) {
|
||||
struct memdebug *mem;
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
# pragma warning(push)
|
||||
@@ -331,11 +329,11 @@ void curl_dofree(void *ptr, int line, const char *source)
|
||||
}
|
||||
|
||||
if(source)
|
||||
curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
|
||||
curl_dbg_log("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
|
||||
}
|
||||
|
||||
curl_socket_t curl_socket(int domain, int type, int protocol,
|
||||
int line, const char *source)
|
||||
curl_socket_t curl_dbg_socket(int domain, int type, int protocol,
|
||||
int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d socket() = %d\n" :
|
||||
@@ -351,44 +349,44 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
|
||||
sockfd = socket(domain, type, protocol);
|
||||
|
||||
if(source && (sockfd != CURL_SOCKET_BAD))
|
||||
curl_memlog(fmt, source, line, sockfd);
|
||||
curl_dbg_log(fmt, source, line, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd,
|
||||
SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
|
||||
SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line,
|
||||
const char *source)
|
||||
SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd,
|
||||
SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
|
||||
SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line,
|
||||
const char *source)
|
||||
{
|
||||
SEND_TYPE_RETV rc;
|
||||
if(countcheck("send", line, source))
|
||||
return -1;
|
||||
rc = send(sockfd, buf, len, flags);
|
||||
if(source)
|
||||
curl_memlog("SEND %s:%d send(%lu) = %ld\n",
|
||||
curl_dbg_log("SEND %s:%d send(%lu) = %ld\n",
|
||||
source, line, (unsigned long)len, (long)rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf,
|
||||
RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line,
|
||||
const char *source)
|
||||
RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf,
|
||||
RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line,
|
||||
const char *source)
|
||||
{
|
||||
RECV_TYPE_RETV rc;
|
||||
if(countcheck("recv", line, source))
|
||||
return -1;
|
||||
rc = recv(sockfd, buf, len, flags);
|
||||
if(source)
|
||||
curl_memlog("RECV %s:%d recv(%lu) = %ld\n",
|
||||
curl_dbg_log("RECV %s:%d recv(%lu) = %ld\n",
|
||||
source, line, (unsigned long)len, (long)rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
int curl_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
int line, const char *source)
|
||||
int curl_dbg_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d socketpair() = %d %d\n" :
|
||||
@@ -399,14 +397,14 @@ int curl_socketpair(int domain, int type, int protocol,
|
||||
int res = socketpair(domain, type, protocol, socket_vector);
|
||||
|
||||
if(source && (0 == res))
|
||||
curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
|
||||
curl_dbg_log(fmt, source, line, socket_vector[0], socket_vector[1]);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
|
||||
int line, const char *source)
|
||||
curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen,
|
||||
int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d accept() = %d\n" :
|
||||
@@ -420,13 +418,13 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
|
||||
curl_socket_t sockfd = accept(s, addr, addrlen);
|
||||
|
||||
if(source && (sockfd != CURL_SOCKET_BAD))
|
||||
curl_memlog(fmt, source, line, sockfd);
|
||||
curl_dbg_log(fmt, source, line, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/* separate function to allow libcurl to mark a "faked" close */
|
||||
void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
{
|
||||
const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
|
||||
"FD %s:%d sclose(%d)\n":
|
||||
@@ -435,54 +433,40 @@ void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
"FD %s:%d sclose(%zd)\n";
|
||||
|
||||
if(source)
|
||||
curl_memlog(fmt, source, line, sockfd);
|
||||
curl_dbg_log(fmt, source, line, sockfd);
|
||||
}
|
||||
|
||||
/* this is our own defined way to close sockets on *ALL* platforms */
|
||||
int curl_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
{
|
||||
int res = sclose(sockfd);
|
||||
curl_mark_sclose(sockfd, line, source);
|
||||
curl_dbg_mark_sclose(sockfd, line, source);
|
||||
return res;
|
||||
}
|
||||
|
||||
FILE *curl_fopen(const char *file, const char *mode,
|
||||
int line, const char *source)
|
||||
FILE *curl_dbg_fopen(const char *file, const char *mode,
|
||||
int line, const char *source)
|
||||
{
|
||||
FILE *res = fopen(file, mode);
|
||||
|
||||
if(source)
|
||||
curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
|
||||
curl_dbg_log("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
|
||||
source, line, file, mode, (void *)res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FDOPEN
|
||||
FILE *curl_fdopen(int filedes, const char *mode,
|
||||
int line, const char *source)
|
||||
{
|
||||
FILE *res = fdopen(filedes, mode);
|
||||
|
||||
if(source)
|
||||
curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
|
||||
source, line, filedes, mode, (void *)res);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
int curl_fclose(FILE *file, int line, const char *source)
|
||||
int curl_dbg_fclose(FILE *file, int line, const char *source)
|
||||
{
|
||||
int res;
|
||||
|
||||
DEBUGASSERT(file != NULL);
|
||||
|
||||
res = fclose(file);
|
||||
|
||||
if(source)
|
||||
curl_memlog("FILE %s:%d fclose(%p)\n",
|
||||
source, line, (void *)file);
|
||||
curl_dbg_log("FILE %s:%d fclose(%p)\n",
|
||||
source, line, (void *)file);
|
||||
|
||||
res = fclose(file);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -490,13 +474,13 @@ int curl_fclose(FILE *file, int line, const char *source)
|
||||
#define LOGLINE_BUFSIZE 1024
|
||||
|
||||
/* this does the writing to the memory tracking log file */
|
||||
void curl_memlog(const char *format, ...)
|
||||
void curl_dbg_log(const char *format, ...)
|
||||
{
|
||||
char *buf;
|
||||
int nchars;
|
||||
va_list ap;
|
||||
|
||||
if(!logfile)
|
||||
if(!curl_dbg_logfile)
|
||||
return;
|
||||
|
||||
buf = (Curl_cmalloc)(LOGLINE_BUFSIZE);
|
||||
@@ -504,14 +488,14 @@ void curl_memlog(const char *format, ...)
|
||||
return;
|
||||
|
||||
va_start(ap, format);
|
||||
nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
|
||||
nchars = mvsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(nchars > LOGLINE_BUFSIZE - 1)
|
||||
nchars = LOGLINE_BUFSIZE - 1;
|
||||
|
||||
if(nchars > 0)
|
||||
fwrite(buf, 1, (size_t)nchars, logfile);
|
||||
fwrite(buf, 1, (size_t)nchars, curl_dbg_logfile);
|
||||
|
||||
(Curl_cfree)(buf);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -30,97 +30,92 @@
|
||||
|
||||
#define CURL_MT_LOGFNAME_BUFSIZE 512
|
||||
|
||||
#define logfile curl_debuglogfile
|
||||
|
||||
extern FILE *logfile;
|
||||
extern FILE *curl_dbg_logfile;
|
||||
|
||||
/* memory functions */
|
||||
CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
|
||||
CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
|
||||
CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
|
||||
CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source);
|
||||
CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source);
|
||||
CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src);
|
||||
#if defined(WIN32) && defined(UNICODE)
|
||||
CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line,
|
||||
const char *source);
|
||||
#endif
|
||||
|
||||
CURL_EXTERN void curl_memdebug(const char *logname);
|
||||
CURL_EXTERN void curl_memlimit(long limit);
|
||||
CURL_EXTERN void curl_memlog(const char *format, ...);
|
||||
CURL_EXTERN void curl_dbg_memdebug(const char *logname);
|
||||
CURL_EXTERN void curl_dbg_memlimit(long limit);
|
||||
CURL_EXTERN void curl_dbg_log(const char *format, ...);
|
||||
|
||||
/* file descriptor manipulators */
|
||||
CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol,
|
||||
CURL_EXTERN curl_socket_t curl_dbg_socket(int domain, int type, int protocol,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN void curl_dbg_mark_sclose(curl_socket_t sockfd,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN int curl_sclose(curl_socket_t sockfd,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen,
|
||||
int line, const char *source);
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd,
|
||||
int line, const char *source);
|
||||
CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen,
|
||||
int line, const char *source);
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
/* send/receive sockets */
|
||||
CURL_EXTERN SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd,
|
||||
SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
|
||||
SEND_TYPE_ARG3 len,
|
||||
SEND_TYPE_ARG4 flags, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd,
|
||||
RECV_TYPE_ARG2 buf, RECV_TYPE_ARG3 len,
|
||||
RECV_TYPE_ARG4 flags, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN SEND_TYPE_RETV curl_dbg_send(SEND_TYPE_ARG1 sockfd,
|
||||
SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
|
||||
SEND_TYPE_ARG3 len,
|
||||
SEND_TYPE_ARG4 flags, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd,
|
||||
RECV_TYPE_ARG2 buf,
|
||||
RECV_TYPE_ARG3 len,
|
||||
RECV_TYPE_ARG4 flags, int line,
|
||||
const char *source);
|
||||
|
||||
/* FILE functions */
|
||||
CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
|
||||
const char *source);
|
||||
#ifdef HAVE_FDOPEN
|
||||
CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line,
|
||||
const char *source);
|
||||
#endif
|
||||
CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
|
||||
CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line,
|
||||
const char *source);
|
||||
CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source);
|
||||
|
||||
#ifndef MEMDEBUG_NODEFINES
|
||||
|
||||
/* Set this symbol on the command-line, recompile all lib-sources */
|
||||
#undef strdup
|
||||
#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
|
||||
#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
|
||||
#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
|
||||
#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
|
||||
#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
|
||||
#define send(a,b,c,d) curl_dosend(a,b,c,d, __LINE__, __FILE__)
|
||||
#define recv(a,b,c,d) curl_dorecv(a,b,c,d, __LINE__, __FILE__)
|
||||
#define strdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__)
|
||||
#define malloc(size) curl_dbg_malloc(size, __LINE__, __FILE__)
|
||||
#define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__)
|
||||
#define realloc(ptr,size) curl_dbg_realloc(ptr, size, __LINE__, __FILE__)
|
||||
#define free(ptr) curl_dbg_free(ptr, __LINE__, __FILE__)
|
||||
#define send(a,b,c,d) curl_dbg_send(a,b,c,d, __LINE__, __FILE__)
|
||||
#define recv(a,b,c,d) curl_dbg_recv(a,b,c,d, __LINE__, __FILE__)
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef UNICODE
|
||||
# undef wcsdup
|
||||
# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
|
||||
# define wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
|
||||
# undef _wcsdup
|
||||
# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
|
||||
# define _wcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
|
||||
# undef _tcsdup
|
||||
# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
|
||||
# define _tcsdup(ptr) curl_dbg_wcsdup(ptr, __LINE__, __FILE__)
|
||||
# else
|
||||
# undef _tcsdup
|
||||
# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
|
||||
# define _tcsdup(ptr) curl_dbg_strdup(ptr, __LINE__, __FILE__)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef socket
|
||||
#define socket(domain,type,protocol)\
|
||||
curl_socket(domain, type, protocol, __LINE__, __FILE__)
|
||||
curl_dbg_socket(domain, type, protocol, __LINE__, __FILE__)
|
||||
#undef accept /* for those with accept as a macro */
|
||||
#define accept(sock,addr,len)\
|
||||
curl_accept(sock, addr, len, __LINE__, __FILE__)
|
||||
curl_dbg_accept(sock, addr, len, __LINE__, __FILE__)
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#define socketpair(domain,type,protocol,socket_vector)\
|
||||
curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
|
||||
curl_dbg_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
@@ -129,31 +124,31 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
|
||||
our macro as for other platforms. Instead, we redefine the new name they
|
||||
define getaddrinfo to become! */
|
||||
#define ogetaddrinfo(host,serv,hint,res) \
|
||||
curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
#else
|
||||
#undef getaddrinfo
|
||||
#define getaddrinfo(host,serv,hint,res) \
|
||||
curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
curl_dbg_getaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
|
||||
#endif
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
|
||||
#ifdef HAVE_FREEADDRINFO
|
||||
#undef freeaddrinfo
|
||||
#define freeaddrinfo(data) \
|
||||
curl_dofreeaddrinfo(data, __LINE__, __FILE__)
|
||||
curl_dbg_freeaddrinfo(data, __LINE__, __FILE__)
|
||||
#endif /* HAVE_FREEADDRINFO */
|
||||
|
||||
/* sclose is probably already defined, redefine it! */
|
||||
#undef sclose
|
||||
#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
|
||||
#define sclose(sockfd) curl_dbg_sclose(sockfd,__LINE__,__FILE__)
|
||||
|
||||
#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__)
|
||||
#define fake_sclose(sockfd) curl_dbg_mark_sclose(sockfd,__LINE__,__FILE__)
|
||||
|
||||
#undef fopen
|
||||
#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
|
||||
#define fopen(file,mode) curl_dbg_fopen(file,mode,__LINE__,__FILE__)
|
||||
#undef fdopen
|
||||
#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__)
|
||||
#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
|
||||
#define fdopen(file,mode) curl_dbg_fdopen(file,mode,__LINE__,__FILE__)
|
||||
#define fclose(file) curl_dbg_fclose(file,__LINE__,__FILE__)
|
||||
|
||||
#endif /* MEMDEBUG_NODEFINES */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -29,8 +29,8 @@
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
|
||||
!defined(CURL_DISABLE_IMAP)
|
||||
#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
|
||||
!defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
|
||||
|
||||
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
||||
#include <libgen.h>
|
||||
@@ -821,8 +821,10 @@ static size_t readback_part(curl_mimepart *part,
|
||||
struct curl_slist *hdr = (struct curl_slist *) part->state.ptr;
|
||||
switch(part->state.state) {
|
||||
case MIMESTATE_BEGIN:
|
||||
mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
|
||||
MIMESTATE_CURLHEADERS, part->curlheaders);
|
||||
mimesetstate(&part->state,
|
||||
(part->flags & MIME_BODY_ONLY)?
|
||||
MIMESTATE_BODY: MIMESTATE_CURLHEADERS,
|
||||
part->curlheaders);
|
||||
break;
|
||||
case MIMESTATE_USERHEADERS:
|
||||
if(!hdr) {
|
||||
@@ -1122,8 +1124,6 @@ void curl_mime_free(curl_mime *mime)
|
||||
Curl_mime_cleanpart(part);
|
||||
free(part);
|
||||
}
|
||||
|
||||
free(mime->boundary);
|
||||
free(mime);
|
||||
}
|
||||
}
|
||||
@@ -1220,18 +1220,10 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
|
||||
mime->firstpart = NULL;
|
||||
mime->lastpart = NULL;
|
||||
|
||||
/* Get a part boundary. */
|
||||
mime->boundary = malloc(24 + MIME_RAND_BOUNDARY_CHARS + 1);
|
||||
if(!mime->boundary) {
|
||||
free(mime);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(mime->boundary, '-', 24);
|
||||
if(Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
|
||||
if(Curl_rand_hex(easy, (unsigned char *) &mime->boundary[24],
|
||||
MIME_RAND_BOUNDARY_CHARS + 1)) {
|
||||
/* failed to get random separator, bail out */
|
||||
free(mime->boundary);
|
||||
free(mime);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1909,72 +1901,4 @@ CURLcode curl_mime_headers(curl_mimepart *part,
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
|
||||
{
|
||||
(void) part;
|
||||
(void) easy;
|
||||
}
|
||||
|
||||
void Curl_mime_cleanpart(curl_mimepart *part)
|
||||
{
|
||||
(void) part;
|
||||
}
|
||||
|
||||
CURLcode Curl_mime_duppart(curl_mimepart *dst, const curl_mimepart *src)
|
||||
{
|
||||
(void) dst;
|
||||
(void) src;
|
||||
return CURLE_OK; /* Nothing to duplicate: always succeed. */
|
||||
}
|
||||
|
||||
CURLcode Curl_mime_set_subparts(curl_mimepart *part,
|
||||
curl_mime *subparts, int take_ownership)
|
||||
{
|
||||
(void) part;
|
||||
(void) subparts;
|
||||
(void) take_ownership;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
const char *contenttype,
|
||||
const char *disposition,
|
||||
enum mimestrategy strategy)
|
||||
{
|
||||
(void) part;
|
||||
(void) contenttype;
|
||||
(void) disposition;
|
||||
(void) strategy;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
curl_off_t Curl_mime_size(curl_mimepart *part)
|
||||
{
|
||||
(void) part;
|
||||
return (curl_off_t) -1;
|
||||
}
|
||||
|
||||
size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
|
||||
{
|
||||
(void) buffer;
|
||||
(void) size;
|
||||
(void) nitems;
|
||||
(void) instream;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CURLcode Curl_mime_rewind(curl_mimepart *part)
|
||||
{
|
||||
(void) part;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
/* VARARGS2 */
|
||||
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
|
||||
{
|
||||
(void) slp;
|
||||
(void) fmt;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
|
||||
#endif /* if disabled */
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,6 +22,8 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#define MIME_RAND_BOUNDARY_CHARS 16 /* Nb. of random boundary chars. */
|
||||
#define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */
|
||||
#define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */
|
||||
@@ -69,7 +71,7 @@ enum mimestrategy {
|
||||
typedef struct {
|
||||
const char * name; /* Encoding name. */
|
||||
size_t (*encodefunc)(char *buffer, size_t size, bool ateof,
|
||||
curl_mimepart *part); /* Encoded read. */
|
||||
curl_mimepart *part); /* Encoded read. */
|
||||
curl_off_t (*sizefunc)(curl_mimepart *part); /* Encoded size. */
|
||||
} mime_encoder;
|
||||
|
||||
@@ -88,13 +90,16 @@ typedef struct {
|
||||
size_t offset; /* State-dependent offset. */
|
||||
} mime_state;
|
||||
|
||||
/* minimum buffer size for the boundary string */
|
||||
#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1)
|
||||
|
||||
/* A mime multipart. */
|
||||
struct curl_mime_s {
|
||||
struct Curl_easy *easy; /* The associated easy handle. */
|
||||
curl_mimepart *parent; /* Parent part. */
|
||||
curl_mimepart *firstpart; /* First part. */
|
||||
curl_mimepart *lastpart; /* Last part. */
|
||||
char *boundary; /* The part boundary. */
|
||||
char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
|
||||
mime_state state; /* Current readback state. */
|
||||
};
|
||||
|
||||
@@ -122,6 +127,8 @@ struct curl_mimepart_s {
|
||||
mime_encoder_state encstate; /* Data encoder state. */
|
||||
};
|
||||
|
||||
#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \
|
||||
!defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP)
|
||||
|
||||
/* Prototypes. */
|
||||
void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
|
||||
@@ -140,4 +147,18 @@ CURLcode Curl_mime_rewind(curl_mimepart *part);
|
||||
CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
|
||||
const char *Curl_mime_contenttype(const char *filename);
|
||||
|
||||
#else
|
||||
/* if disabled */
|
||||
#define Curl_mime_initpart(x,y)
|
||||
#define Curl_mime_cleanpart(x)
|
||||
#define Curl_mime_duppart(x,y) CURLE_OK /* Nothing to duplicate. Succeed */
|
||||
#define Curl_mime_set_subparts(a,b,c) CURLE_NOT_BUILT_IN
|
||||
#define Curl_mime_prepare_headers(a,b,c,d) CURLE_NOT_BUILT_IN
|
||||
#define Curl_mime_size(x) (curl_off_t) -1
|
||||
#define Curl_mime_read NULL
|
||||
#define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN)
|
||||
#define Curl_mime_add_header(x,y,...) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_MIME_H */
|
||||
|
||||
@@ -835,7 +835,7 @@ static int dprintf_formatf(
|
||||
while(width-- > 0)
|
||||
OUTCHAR(' ');
|
||||
|
||||
while((len-- > 0) && *str)
|
||||
for(; len && *str; len--)
|
||||
OUTCHAR(*str++);
|
||||
if(p->flags&FLAGS_LEFT)
|
||||
while(width-- > 0)
|
||||
|
||||
+406
-522
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -46,18 +46,16 @@ typedef enum {
|
||||
CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
|
||||
CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
|
||||
phase */
|
||||
CURLM_STATE_WAITDO, /* 8 - wait for our turn to send the request */
|
||||
CURLM_STATE_DO, /* 9 - start send off the request (part 1) */
|
||||
CURLM_STATE_DOING, /* 10 - sending off the request (part 1) */
|
||||
CURLM_STATE_DO_MORE, /* 11 - send off the request (part 2) */
|
||||
CURLM_STATE_DO_DONE, /* 12 - done sending off request */
|
||||
CURLM_STATE_WAITPERFORM, /* 13 - wait for our turn to read the response */
|
||||
CURLM_STATE_PERFORM, /* 14 - transfer data */
|
||||
CURLM_STATE_TOOFAST, /* 15 - wait because limit-rate exceeded */
|
||||
CURLM_STATE_DONE, /* 16 - post data transfer operation */
|
||||
CURLM_STATE_COMPLETED, /* 17 - operation complete */
|
||||
CURLM_STATE_MSGSENT, /* 18 - the operation complete message is sent */
|
||||
CURLM_STATE_LAST /* 19 - not a true state, never use this */
|
||||
CURLM_STATE_DO, /* 8 - start send off the request (part 1) */
|
||||
CURLM_STATE_DOING, /* 9 - sending off the request (part 1) */
|
||||
CURLM_STATE_DO_MORE, /* 10 - send off the request (part 2) */
|
||||
CURLM_STATE_DO_DONE, /* 11 - done sending off request */
|
||||
CURLM_STATE_PERFORM, /* 12 - transfer data */
|
||||
CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */
|
||||
CURLM_STATE_DONE, /* 14 - post data transfer operation */
|
||||
CURLM_STATE_COMPLETED, /* 15 - operation complete */
|
||||
CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */
|
||||
CURLM_STATE_LAST /* 17 - not a true state, never use this */
|
||||
} CURLMstate;
|
||||
|
||||
/* we support N sockets per easy handle. Set the corresponding bit to what
|
||||
@@ -66,7 +64,7 @@ typedef enum {
|
||||
#define GETSOCK_READABLE (0x00ff)
|
||||
#define GETSOCK_WRITABLE (0xff00)
|
||||
|
||||
#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
|
||||
#define CURLPIPE_ANY (CURLPIPE_MULTIPLEX)
|
||||
|
||||
/* This is the struct known as CURLM on the outside */
|
||||
struct Curl_multi {
|
||||
@@ -112,8 +110,8 @@ struct Curl_multi {
|
||||
same actual socket) */
|
||||
struct curl_hash sockhash;
|
||||
|
||||
/* pipelining wanted bits (CURLPIPE*) */
|
||||
long pipelining;
|
||||
/* multiplexing wanted */
|
||||
bool multiplexing;
|
||||
|
||||
bool recheckstate; /* see Curl_multi_connchanged */
|
||||
|
||||
@@ -129,24 +127,6 @@ struct Curl_multi {
|
||||
long max_total_connections; /* if >0, a fixed limit of the maximum number
|
||||
of connections in total */
|
||||
|
||||
long max_pipeline_length; /* if >0, maximum number of requests in a
|
||||
pipeline */
|
||||
|
||||
long content_length_penalty_size; /* a connection with a
|
||||
content-length bigger than
|
||||
this is not considered
|
||||
for pipelining */
|
||||
|
||||
long chunk_length_penalty_size; /* a connection with a chunk length
|
||||
bigger than this is not
|
||||
considered for pipelining */
|
||||
|
||||
struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted
|
||||
from pipelining */
|
||||
|
||||
struct curl_llist pipelining_server_bl; /* List of server types that are
|
||||
blacklisted from pipelining */
|
||||
|
||||
/* timer callback and user data pointer for the *socket() API */
|
||||
curl_multi_timer_callback timer_cb;
|
||||
void *timer_userp;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -30,8 +30,10 @@ void Curl_updatesocket(struct Curl_easy *data);
|
||||
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
|
||||
void Curl_expire_clear(struct Curl_easy *data);
|
||||
void Curl_expire_done(struct Curl_easy *data, expire_id id);
|
||||
bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
|
||||
void Curl_multi_handlePipeBreak(struct Curl_easy *data);
|
||||
void Curl_detach_connnection(struct Curl_easy *data);
|
||||
void Curl_attach_connnection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
bool Curl_multiplex_wanted(const struct Curl_multi *multi);
|
||||
void Curl_set_in_callback(struct Curl_easy *data, bool value);
|
||||
bool Curl_is_in_callback(struct Curl_easy *easy);
|
||||
|
||||
@@ -62,22 +64,11 @@ void Curl_multi_dump(struct Curl_multi *multi);
|
||||
/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
|
||||
size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
|
||||
curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */
|
||||
curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */
|
||||
struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */
|
||||
struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
|
||||
|
||||
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
|
||||
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
|
||||
|
||||
void Curl_multi_connchanged(struct Curl_multi *multi);
|
||||
void Curl_multiuse_state(struct connectdata *conn,
|
||||
int bundlestate); /* use BUNDLE_* defines */
|
||||
|
||||
/*
|
||||
* Curl_multi_closed()
|
||||
@@ -89,7 +80,7 @@ void Curl_multi_connchanged(struct Curl_multi *multi);
|
||||
* socket again and it gets the same file descriptor number.
|
||||
*/
|
||||
|
||||
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
|
||||
void Curl_multi_closed(struct Curl_easy *data, curl_socket_t s);
|
||||
|
||||
/*
|
||||
* Add a handle and move it into PERFORM state at once. For pushed streams.
|
||||
@@ -97,4 +88,12 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
|
||||
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
||||
CURLMcode Curl_multi_wait(struct Curl_multi *multi,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret,
|
||||
bool *gotsocket); /* if any socket was checked */
|
||||
|
||||
#endif /* HEADER_CURL_MULTIIF_H */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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
|
||||
@@ -21,6 +21,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
@@ -53,6 +54,8 @@ enum host_lookup_state {
|
||||
int Curl_parsenetrc(const char *host,
|
||||
char **loginp,
|
||||
char **passwordp,
|
||||
bool *login_changed,
|
||||
bool *password_changed,
|
||||
char *netrcfile)
|
||||
{
|
||||
FILE *file;
|
||||
@@ -164,7 +167,7 @@ int Curl_parsenetrc(const char *host,
|
||||
if(specific_login) {
|
||||
state_our_login = strcasecompare(login, tok);
|
||||
}
|
||||
else {
|
||||
else if(!login || strcmp(login, tok)) {
|
||||
if(login_alloc) {
|
||||
free(login);
|
||||
login_alloc = FALSE;
|
||||
@@ -179,7 +182,8 @@ int Curl_parsenetrc(const char *host,
|
||||
state_login = 0;
|
||||
}
|
||||
else if(state_password) {
|
||||
if(state_our_login || !specific_login) {
|
||||
if((state_our_login || !specific_login)
|
||||
&& (!password || strcmp(password, tok))) {
|
||||
if(password_alloc) {
|
||||
free(password);
|
||||
password_alloc = FALSE;
|
||||
@@ -211,15 +215,19 @@ int Curl_parsenetrc(const char *host,
|
||||
|
||||
out:
|
||||
if(!retcode) {
|
||||
*login_changed = FALSE;
|
||||
*password_changed = FALSE;
|
||||
if(login_alloc) {
|
||||
if(*loginp)
|
||||
free(*loginp);
|
||||
*loginp = login;
|
||||
*login_changed = TRUE;
|
||||
}
|
||||
if(password_alloc) {
|
||||
if(*passwordp)
|
||||
free(*passwordp);
|
||||
*passwordp = password;
|
||||
*password_changed = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -233,3 +241,5 @@ int Curl_parsenetrc(const char *host,
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,15 +22,24 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
#ifndef CURL_DISABLE_NETRC
|
||||
|
||||
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
|
||||
int Curl_parsenetrc(const char *host,
|
||||
char **loginp,
|
||||
char **passwordp,
|
||||
bool *login_changed,
|
||||
bool *password_changed,
|
||||
char *filename);
|
||||
/* Assume: (*passwordp)[0]=0, host[0] != 0.
|
||||
* If (*loginp)[0] = 0, search for login and password within a machine
|
||||
* section in the netrc.
|
||||
* If (*loginp)[0] != 0, search for password within machine and login.
|
||||
*/
|
||||
#else
|
||||
/* disabled */
|
||||
#define Curl_parsenetrc(a,b,c,d,e,f) 1
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_NETRC_H */
|
||||
|
||||
@@ -78,7 +78,7 @@ CURLcode Curl_convert_clone(struct Curl_easy *data,
|
||||
|
||||
/*
|
||||
* Curl_convert_to_network() is an internal function for performing ASCII
|
||||
* conversions on non-ASCII platforms. It convers the buffer _in place_.
|
||||
* conversions on non-ASCII platforms. It converts the buffer _in place_.
|
||||
*/
|
||||
CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
@@ -144,7 +144,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data,
|
||||
|
||||
/*
|
||||
* Curl_convert_from_network() is an internal function for performing ASCII
|
||||
* conversions on non-ASCII platforms. It convers the buffer _in place_.
|
||||
* conversions on non-ASCII platforms. It converts the buffer _in place_.
|
||||
*/
|
||||
CURLcode Curl_convert_from_network(struct Curl_easy *data,
|
||||
char *buffer, size_t length)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
|
||||
* Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2019, 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
|
||||
@@ -196,9 +196,6 @@ static CURLcode ldap_setup_connection(struct connectdata *conn)
|
||||
li->proto = proto;
|
||||
conn->proto.generic = li;
|
||||
connkeep(conn, "OpenLDAP default");
|
||||
/* TODO:
|
||||
* - provide option to choose SASL Binds instead of Simple
|
||||
*/
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -220,8 +217,8 @@ static CURLcode ldap_connect(struct connectdata *conn, bool *done)
|
||||
ptr = hosturl + 4;
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
*ptr++ = 's';
|
||||
snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
|
||||
conn->host.name, conn->remote_port);
|
||||
msnprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
|
||||
conn->host.name, conn->remote_port);
|
||||
|
||||
#ifdef CURL_OPENLDAP_DEBUG
|
||||
static int do_trace = 0;
|
||||
@@ -414,7 +411,7 @@ static CURLcode ldap_do(struct connectdata *conn, bool *done)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
lr->msgid = msgid;
|
||||
data->req.protop = lr;
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
|
||||
Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1);
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -510,8 +507,6 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
lr->nument++;
|
||||
rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
|
||||
if(rc < 0) {
|
||||
/* TODO: verify that this is really how this return code should be
|
||||
handled */
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, 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,20 +82,6 @@
|
||||
#include "warnless.h"
|
||||
#include "parsedate.h"
|
||||
|
||||
const char * const Curl_wkday[] =
|
||||
{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||
static const char * const weekday[] =
|
||||
{ "Monday", "Tuesday", "Wednesday", "Thursday",
|
||||
"Friday", "Saturday", "Sunday" };
|
||||
const char * const Curl_month[]=
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
struct tzinfo {
|
||||
char name[5];
|
||||
int offset; /* +/- in minutes */
|
||||
};
|
||||
|
||||
/*
|
||||
* parsedate()
|
||||
*
|
||||
@@ -114,6 +100,22 @@ static int parsedate(const char *date, time_t *output);
|
||||
#define PARSEDATE_LATER 1
|
||||
#define PARSEDATE_SOONER 2
|
||||
|
||||
#ifndef CURL_DISABLE_PARSEDATE
|
||||
|
||||
const char * const Curl_wkday[] =
|
||||
{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||
static const char * const weekday[] =
|
||||
{ "Monday", "Tuesday", "Wednesday", "Thursday",
|
||||
"Friday", "Saturday", "Sunday" };
|
||||
const char * const Curl_month[]=
|
||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
struct tzinfo {
|
||||
char name[5];
|
||||
int offset; /* +/- in minutes */
|
||||
};
|
||||
|
||||
/* Here's a bunch of frequently used time zone names. These were supported
|
||||
by the old getdate parser. */
|
||||
#define tDAYZONE -60 /* offset for daylight savings time */
|
||||
@@ -555,6 +557,15 @@ static int parsedate(const char *date, time_t *output)
|
||||
|
||||
return PARSEDATE_OK;
|
||||
}
|
||||
#else
|
||||
/* disabled */
|
||||
static int parsedate(const char *date, time_t *output)
|
||||
{
|
||||
(void)date;
|
||||
*output = 0;
|
||||
return PARSEDATE_OK; /* a lie */
|
||||
}
|
||||
#endif
|
||||
|
||||
time_t curl_getdate(const char *p, const time_t *now)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user