Merge branch 'upstream-curl' into update-curl

* upstream-curl:
  curl 2019-05-22 (885ce314)
This commit is contained in:
Brad King
2019-05-22 14:15:06 -04:00
171 changed files with 6559 additions and 5987 deletions
+50 -2
View File
@@ -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
+2 -2
View File
@@ -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.*")
+50 -17
View File
@@ -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()
+39 -27
View File
@@ -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 -1
View File
@@ -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.
+58 -8
View File
@@ -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()
+6 -6
View File
@@ -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) \
+5 -2
View File
@@ -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 */
+10 -9
View File
@@ -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
+569
View File
@@ -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 */
+77
View File
@@ -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 */
+25 -7
View File
@@ -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__ */
+8 -2
View File
@@ -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 */
+140 -17
View File
@@ -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);
}
}
}
+50 -20
View File
@@ -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
View File
@@ -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
+20 -13
View File
@@ -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 */
+22 -16
View File
@@ -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) {
+4 -4
View File
@@ -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,
+67 -47
View File
@@ -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
+1 -8
View File
@@ -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
View File
@@ -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);
+11 -2
View File
@@ -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);
+16 -16
View File
@@ -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) */
+5 -8
View File
@@ -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
+8 -2
View File
@@ -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 -5
View File
@@ -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 */
+4 -11
View File
@@ -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 */
+55
View File
@@ -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 */
+3 -3
View File
@@ -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);
+1 -15
View File
@@ -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 */
+3 -1
View File
@@ -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 */
+5 -5
View File
@@ -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
+2 -2
View File
@@ -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,
+6 -6
View File
@@ -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;
}
+32 -37
View File
@@ -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;
+1 -3
View File
@@ -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
+67 -19
View File
@@ -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 -4
View File
@@ -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 -1
View File
@@ -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 */
+4 -12
View File
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -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 -4
View File
@@ -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;
}
+20 -20
View File
@@ -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 */
+20 -9
View File
@@ -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 */
+5 -6
View File
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -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 */
+4 -7
View File
@@ -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
View File
@@ -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 */
+9 -1
View File
@@ -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
View File
@@ -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 */
+1 -1
View File
@@ -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
View File
@@ -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;
+3 -2
View File
@@ -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
+7 -7
View File
@@ -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 */
+10 -1
View File
@@ -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
View File
@@ -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;
+1 -2
View File
@@ -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 */
+2 -5
View File
@@ -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;
+4 -4
View File
@@ -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;
+21 -7
View File
@@ -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*/
+4 -4
View File
@@ -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;
+4 -7
View File
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -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 */
+56 -97
View File
@@ -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 */
+6 -13
View File
@@ -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.
*
+2 -2
View File
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -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;
}
+8 -6
View File
@@ -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
View File
@@ -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)
+5 -4
View File
@@ -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;
+60 -16
View File
@@ -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. */
+5 -2
View File
@@ -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 */
+3 -2
View File
@@ -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);
+6 -6
View File
@@ -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 */
+108 -26
View File
@@ -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 */
+4 -4
View File
@@ -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 */
+24 -16
View File
@@ -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
}
+5 -5
View File
@@ -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 */
+2 -2
View File
@@ -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);
+14 -45
View File
@@ -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;
+2 -4
View File
@@ -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
View File
@@ -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 == '\\')
+6 -6
View File
@@ -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?
+2 -1
View File
@@ -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);
+13 -9
View File
@@ -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);
+6 -6
View File
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -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
View File
@@ -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
View File
@@ -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 */
+69 -85
View File
@@ -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);
}
+59 -64
View File
@@ -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 */
+9 -85
View File
@@ -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 */
+24 -3
View File
@@ -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 */
+1 -1
View File
@@ -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)
File diff suppressed because it is too large Load Diff
+14 -34
View File
@@ -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;
+16 -17
View File
@@ -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 */
+13 -3
View File
@@ -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
+10 -1
View File
@@ -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 */
+2 -2
View File
@@ -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)
+4 -9
View File
@@ -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;
}
+26 -15
View File
@@ -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