Merge branch 'master' into nuget-fixes
This commit is contained in:
commit
88d37b17c6
@ -45,6 +45,9 @@ none:
|
||||
@echo " osx linux"
|
||||
|
||||
mingw: $(SRC)
|
||||
$(SILENT) rm -rf ./bin
|
||||
$(SILENT) rm -rf ./build
|
||||
$(SILENT) rm -rf ./obj
|
||||
mkdir -p build/bootstrap
|
||||
$(CC) -o build/bootstrap/premake_bootstrap -DPREMAKE_NO_BUILTIN_SCRIPTS -I"$(LUA_DIR)" $? -lole32
|
||||
./build/bootstrap/premake_bootstrap embed
|
||||
@ -52,6 +55,9 @@ mingw: $(SRC)
|
||||
$(MAKE) -C build/bootstrap
|
||||
|
||||
osx: $(SRC)
|
||||
$(SILENT) rm -rf ./bin
|
||||
$(SILENT) rm -rf ./build
|
||||
$(SILENT) rm -rf ./obj
|
||||
mkdir -p build/bootstrap
|
||||
$(CC) -o build/bootstrap/premake_bootstrap -DPREMAKE_NO_BUILTIN_SCRIPTS -DLUA_USE_MACOSX -I"$(LUA_DIR)" -framework CoreServices -framework Foundation -framework Security $?
|
||||
./build/bootstrap/premake_bootstrap embed
|
||||
@ -59,13 +65,29 @@ osx: $(SRC)
|
||||
$(MAKE) -C build/bootstrap -j`getconf _NPROCESSORS_ONLN`
|
||||
|
||||
linux: $(SRC)
|
||||
$(SILENT) rm -rf ./bin
|
||||
$(SILENT) rm -rf ./build
|
||||
$(SILENT) rm -rf ./obj
|
||||
mkdir -p build/bootstrap
|
||||
$(CC) -o build/bootstrap/premake_bootstrap -DPREMAKE_NO_BUILTIN_SCRIPTS -DLUA_USE_POSIX -DLUA_USE_DLOPEN -I"$(LUA_DIR)" $? -lm -ldl -lrt
|
||||
./build/bootstrap/premake_bootstrap embed
|
||||
./build/bootstrap/premake_bootstrap --to=build/bootstrap gmake
|
||||
$(MAKE) -C build/bootstrap -j`getconf _NPROCESSORS_ONLN`
|
||||
|
||||
bsd: $(SRC)
|
||||
$(SILENT) rm -rf ./bin
|
||||
$(SILENT) rm -rf ./build
|
||||
$(SILENT) rm -rf ./obj
|
||||
mkdir -p build/bootstrap
|
||||
$(CC) -o build/bootstrap/premake_bootstrap -DPREMAKE_NO_BUILTIN_SCRIPTS -DLUA_USE_POSIX -DLUA_USE_DLOPEN -I"$(LUA_DIR)" $? -lm
|
||||
./build/bootstrap/premake_bootstrap embed
|
||||
./build/bootstrap/premake_bootstrap --to=build/bootstrap gmake
|
||||
$(MAKE) -C build/bootstrap -j`getconf _NPROCESSORS_ONLN`
|
||||
|
||||
windows-base: $(SRC)
|
||||
$(SILENT) if exist .\bin rmdir /s /q .\bin
|
||||
$(SILENT) if exist .\build rmdir /s /q .\build
|
||||
$(SILENT) if exist .\obj rmdir /s /q .\obj
|
||||
if not exist build\bootstrap (mkdir build\bootstrap)
|
||||
cl /Fo.\build\bootstrap\ /Fe.\build\bootstrap\premake_bootstrap.exe /DPREMAKE_NO_BUILTIN_SCRIPTS /I"$(LUA_DIR)" user32.lib ole32.lib advapi32.lib $**
|
||||
.\build\bootstrap\premake_bootstrap.exe embed
|
||||
|
@ -37,7 +37,7 @@ The following notes apply to libcurl version 7.19.0 and later.
|
||||
also distribute along with it the generated curl/curlbuild.h which has been
|
||||
used to compile it. Otherwise the library will be of no use for the users of
|
||||
the library that you have built. It is _your_ responsibility to provide this
|
||||
file. No one at the cURL project can know how you have built the library.
|
||||
file. No one at the curl project can know how you have built the library.
|
||||
|
||||
* File curl/curlbuild.h includes platform and configuration dependent info,
|
||||
and must not be modified by anyone. Configure script generates it for you.
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -30,6 +30,10 @@
|
||||
* https://cool.haxx.se/mailman/listinfo/curl-library/
|
||||
*/
|
||||
|
||||
#ifdef CURL_NO_OLDIES
|
||||
#define CURL_STRICTER
|
||||
#endif
|
||||
|
||||
#include "curlver.h" /* libcurl version defines */
|
||||
#include "curlbuild.h" /* libcurl build definitions */
|
||||
#include "curlrules.h" /* libcurl rules enforcement */
|
||||
@ -91,7 +95,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
||||
typedef struct Curl_easy CURL;
|
||||
typedef struct Curl_share CURLSH;
|
||||
#else
|
||||
typedef void CURL;
|
||||
typedef void CURLSH;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* libcurl external API function linkage decorations.
|
||||
@ -183,6 +193,11 @@ typedef int (*curl_xferinfo_callback)(void *clientp,
|
||||
curl_off_t ultotal,
|
||||
curl_off_t ulnow);
|
||||
|
||||
#ifndef CURL_MAX_READ_SIZE
|
||||
/* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
|
||||
#define CURL_MAX_READ_SIZE 524288
|
||||
#endif
|
||||
|
||||
#ifndef CURL_MAX_WRITE_SIZE
|
||||
/* Tests have proven that 20K is a very bad buffer size for uploads on
|
||||
Windows, while 16K for some odd reason performed a lot better.
|
||||
@ -425,7 +440,7 @@ typedef enum {
|
||||
CURLE_COULDNT_RESOLVE_PROXY, /* 5 */
|
||||
CURLE_COULDNT_RESOLVE_HOST, /* 6 */
|
||||
CURLE_COULDNT_CONNECT, /* 7 */
|
||||
CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */
|
||||
CURLE_WEIRD_SERVER_REPLY, /* 8 */
|
||||
CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
|
||||
due to lack of access - when login fails
|
||||
this is not returned. */
|
||||
@ -469,7 +484,7 @@ typedef enum {
|
||||
CURLE_LDAP_CANNOT_BIND, /* 38 */
|
||||
CURLE_LDAP_SEARCH_FAILED, /* 39 */
|
||||
CURLE_OBSOLETE40, /* 40 - NOT USED */
|
||||
CURLE_FUNCTION_NOT_FOUND, /* 41 */
|
||||
CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */
|
||||
CURLE_ABORTED_BY_CALLBACK, /* 42 */
|
||||
CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */
|
||||
CURLE_OBSOLETE44, /* 44 - NOT USED */
|
||||
@ -556,6 +571,7 @@ typedef enum {
|
||||
|
||||
/* compatibility with older names */
|
||||
#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
|
||||
#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
|
||||
|
||||
/* The following were added in 7.21.5, April 2011 */
|
||||
#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
|
||||
@ -629,6 +645,7 @@ typedef enum {
|
||||
CONNECT HTTP/1.1 */
|
||||
CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
|
||||
HTTP/1.0 */
|
||||
CURLPROXY_HTTPS = 2, /* added in 7.52.0 */
|
||||
CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
|
||||
in 7.10 */
|
||||
CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
|
||||
@ -1195,7 +1212,8 @@ typedef enum {
|
||||
CINIT(SHARE, OBJECTPOINT, 100),
|
||||
|
||||
/* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
|
||||
CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
|
||||
CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
|
||||
CURLPROXY_SOCKS5. */
|
||||
CINIT(PROXYTYPE, LONG, 101),
|
||||
|
||||
/* Set the Accept-Encoding string. Use this to tell a server you would like
|
||||
@ -1689,6 +1707,77 @@ typedef enum {
|
||||
/* Set TCP Fast Open */
|
||||
CINIT(TCP_FASTOPEN, LONG, 244),
|
||||
|
||||
/* Continue to send data if the server responds early with an
|
||||
* HTTP status code >= 300 */
|
||||
CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
|
||||
|
||||
/* The CApath or CAfile used to validate the proxy certificate
|
||||
this option is used only if PROXY_SSL_VERIFYPEER is true */
|
||||
CINIT(PROXY_CAINFO, STRINGPOINT, 246),
|
||||
|
||||
/* The CApath directory used to validate the proxy certificate
|
||||
this option is used only if PROXY_SSL_VERIFYPEER is true */
|
||||
CINIT(PROXY_CAPATH, STRINGPOINT, 247),
|
||||
|
||||
/* Set if we should verify the proxy in ssl handshake,
|
||||
set 1 to verify. */
|
||||
CINIT(PROXY_SSL_VERIFYPEER, LONG, 248),
|
||||
|
||||
/* Set if we should verify the Common name from the proxy certificate in ssl
|
||||
* handshake, set 1 to check existence, 2 to ensure that it matches
|
||||
* the provided hostname. */
|
||||
CINIT(PROXY_SSL_VERIFYHOST, LONG, 249),
|
||||
|
||||
/* What version to specifically try to use for proxy.
|
||||
See CURL_SSLVERSION defines below. */
|
||||
CINIT(PROXY_SSLVERSION, LONG, 250),
|
||||
|
||||
/* Set a username for authenticated TLS for proxy */
|
||||
CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251),
|
||||
|
||||
/* Set a password for authenticated TLS for proxy */
|
||||
CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252),
|
||||
|
||||
/* Set authentication type for authenticated TLS for proxy */
|
||||
CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253),
|
||||
|
||||
/* name of the file keeping your private SSL-certificate for proxy */
|
||||
CINIT(PROXY_SSLCERT, STRINGPOINT, 254),
|
||||
|
||||
/* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
|
||||
proxy */
|
||||
CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255),
|
||||
|
||||
/* name of the file keeping your private SSL-key for proxy */
|
||||
CINIT(PROXY_SSLKEY, STRINGPOINT, 256),
|
||||
|
||||
/* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
|
||||
proxy */
|
||||
CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257),
|
||||
|
||||
/* password for the SSL private key for proxy */
|
||||
CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258),
|
||||
|
||||
/* Specify which SSL ciphers to use for proxy */
|
||||
CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259),
|
||||
|
||||
/* CRL file for proxy */
|
||||
CINIT(PROXY_CRLFILE, STRINGPOINT, 260),
|
||||
|
||||
/* Enable/disable specific SSL features with a bitmask for proxy, see
|
||||
CURLSSLOPT_* */
|
||||
CINIT(PROXY_SSL_OPTIONS, LONG, 261),
|
||||
|
||||
/* Name of pre proxy to use. */
|
||||
CINIT(PRE_PROXY, STRINGPOINT, 262),
|
||||
|
||||
/* The public key in DER form used to validate the proxy public key
|
||||
this option is used only if PROXY_SSL_VERIFYPEER is true */
|
||||
CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
|
||||
|
||||
/* Path to an abstract Unix domain socket */
|
||||
CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@ -1790,6 +1879,7 @@ enum {
|
||||
CURL_SSLVERSION_TLSv1_0,
|
||||
CURL_SSLVERSION_TLSv1_1,
|
||||
CURL_SSLVERSION_TLSv1_2,
|
||||
CURL_SSLVERSION_TLSv1_3,
|
||||
|
||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||
};
|
||||
@ -1824,7 +1914,10 @@ typedef enum {
|
||||
|
||||
|
||||
/* curl_strequal() and curl_strnequal() are subject for removal in a future
|
||||
libcurl, see lib/README.curlx for details */
|
||||
libcurl, see lib/README.curlx for details
|
||||
|
||||
!checksrc! disable SPACEBEFOREPAREN 2
|
||||
*/
|
||||
CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2);
|
||||
CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n);
|
||||
|
||||
@ -2193,9 +2286,13 @@ typedef enum {
|
||||
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
|
||||
CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44,
|
||||
CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45,
|
||||
CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46,
|
||||
CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
|
||||
CURLINFO_PROTOCOL = CURLINFO_LONG + 48,
|
||||
CURLINFO_SCHEME = CURLINFO_STRING + 49,
|
||||
/* Fill in new entries below here! */
|
||||
|
||||
CURLINFO_LASTONE = 45
|
||||
CURLINFO_LASTONE = 49
|
||||
} CURLINFO;
|
||||
|
||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||
@ -2257,7 +2354,6 @@ typedef void (*curl_unlock_function)(CURL *handle,
|
||||
curl_lock_data data,
|
||||
void *userptr);
|
||||
|
||||
typedef void CURLSH;
|
||||
|
||||
typedef enum {
|
||||
CURLSHE_OK, /* all is fine */
|
||||
@ -2357,6 +2453,7 @@ typedef struct {
|
||||
#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
|
||||
#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used
|
||||
for cookie domain verification */
|
||||
#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,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 - 2016 Daniel Stenberg, <daniel@haxx.se>."
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.49.1-DEV"
|
||||
#define LIBCURL_VERSION "7.53.1-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 49
|
||||
#define LIBCURL_VERSION_MINOR 53
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
/* 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 0x073101
|
||||
#define LIBCURL_VERSION_NUM 0x073501
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -52,7 +52,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
||||
typedef struct Curl_multi CURLM;
|
||||
#else
|
||||
typedef void CURLM;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -151,7 +151,7 @@ _CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
|
||||
"curl_easy_setopt expects a curl_off_t argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_string,
|
||||
"curl_easy_setopt expects a "
|
||||
"string (char* or char[]) argument for this option"
|
||||
"string ('char *' or char[]) argument for this option"
|
||||
)
|
||||
_CURL_WARNING(_curl_easy_setopt_err_write_callback,
|
||||
"curl_easy_setopt expects a curl_write_callback argument for this option")
|
||||
@ -182,24 +182,25 @@ _CURL_WARNING(_curl_easy_setopt_err_error_buffer,
|
||||
"curl_easy_setopt expects a "
|
||||
"char buffer of CURL_ERROR_SIZE as argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_FILE,
|
||||
"curl_easy_setopt expects a FILE* argument for this option")
|
||||
"curl_easy_setopt expects a 'FILE *' argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_postfields,
|
||||
"curl_easy_setopt expects a void* or char* argument for this option")
|
||||
"curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
|
||||
"curl_easy_setopt expects a struct curl_httppost* argument for this option")
|
||||
"curl_easy_setopt expects a 'struct curl_httppost *' "
|
||||
"argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
|
||||
"curl_easy_setopt expects a struct curl_slist* argument for this option")
|
||||
"curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
|
||||
_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
|
||||
"curl_easy_setopt expects a CURLSH* argument for this option")
|
||||
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_string,
|
||||
"curl_easy_getinfo expects a pointer to char * for this info")
|
||||
"curl_easy_getinfo expects a pointer to 'char *' for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_long,
|
||||
"curl_easy_getinfo expects a pointer to long for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_double,
|
||||
"curl_easy_getinfo expects a pointer to double for this info")
|
||||
_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
"curl_easy_getinfo expects a pointer to struct curl_slist * for this info")
|
||||
"curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
|
||||
|
||||
/* groups of curl_easy_setops options that take the same type of argument */
|
||||
|
||||
@ -218,7 +219,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
|
||||
/* evaluates to true if option takes a char* argument */
|
||||
#define _curl_is_string_option(option) \
|
||||
((option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \
|
||||
(option) == CURLOPT_ACCEPT_ENCODING || \
|
||||
(option) == CURLOPT_CAINFO || \
|
||||
(option) == CURLOPT_CAPATH || \
|
||||
(option) == CURLOPT_COOKIE || \
|
||||
|
1
contrib/curl/lib/.gitignore
vendored
1
contrib/curl/lib/.gitignore
vendored
@ -4,7 +4,6 @@
|
||||
*.orig
|
||||
*.rej
|
||||
*.res
|
||||
Makefile.vc*.dist
|
||||
TAGS
|
||||
curl_config.h
|
||||
curl_config.h.in
|
||||
|
@ -87,6 +87,11 @@ endif()
|
||||
|
||||
set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
|
||||
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
|
||||
endif()
|
||||
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
|
||||
|
@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@ -23,7 +23,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
|
||||
|
||||
EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 config-win32.h \
|
||||
EXTRA_DIST = Makefile.b32 Makefile.m32 config-win32.h \
|
||||
config-win32ce.h config-riscos.h config-mac.h curl_config.h.in \
|
||||
makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \
|
||||
makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h \
|
||||
|
@ -40,31 +40,31 @@ LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||
ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
|
||||
getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c \
|
||||
getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \
|
||||
fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
|
||||
strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
|
||||
http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
|
||||
strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
|
||||
inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
|
||||
ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
|
||||
openldap.c curl_gethostname.c gopher.c idn_win32.c \
|
||||
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 \
|
||||
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
|
||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c
|
||||
|
||||
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
|
||||
speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
|
||||
strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
|
||||
hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
|
||||
http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
|
||||
inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
|
||||
easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
|
||||
socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h \
|
||||
socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \
|
||||
slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
|
||||
rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
|
||||
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
|
||||
@ -72,7 +72,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
|
||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
||||
curl_printf.h system_win32.h
|
||||
curl_printf.h system_win32.h rand.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
|
@ -258,6 +258,10 @@ ifdef SSL
|
||||
CFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifdef WINSSL
|
||||
DLL_LIBS += -lcrypt32
|
||||
endif
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
|
@ -87,7 +87,7 @@ endif
|
||||
TARGET = libcurl
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
|
||||
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
|
||||
DESCR = curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
SCREEN = none
|
||||
|
@ -1,689 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# 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.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC6
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC6 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\rawstr.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strequal.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
@ -57,7 +57,7 @@ bool Curl_amiga_init()
|
||||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
|
||||
TAG_DONE)) {
|
||||
__request("SocketBaseTags ERROR");
|
||||
return FALSE;
|
||||
|
@ -249,7 +249,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
|
||||
static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
int nfds;
|
||||
int bitmask;
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
@ -309,7 +309,7 @@ static int waitperform(struct connectdata *conn, int timeout_ms)
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **dns)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ResolverResults *res = (struct ResolverResults *)
|
||||
conn->async.os_specific;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -353,7 +353,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
long timeout;
|
||||
struct timeval now = Curl_tvnow();
|
||||
struct Curl_dns_entry *temp_entry;
|
||||
@ -492,7 +492,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
int *waitp)
|
||||
{
|
||||
char *bufp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct in_addr in;
|
||||
int family = PF_INET;
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
@ -583,7 +583,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
return NULL; /* no struct yet */
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
char *servers)
|
||||
{
|
||||
CURLcode result = CURLE_NOT_BUILT_IN;
|
||||
@ -621,7 +621,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
@ -638,7 +638,7 @@ CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
@ -663,7 +663,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
|
||||
|
@ -169,7 +169,7 @@ struct thread_sync_data {
|
||||
struct thread_data {
|
||||
curl_thread_t thread_hnd;
|
||||
unsigned int poll_interval;
|
||||
long interval_end;
|
||||
time_t interval_end;
|
||||
struct thread_sync_data tsd;
|
||||
};
|
||||
|
||||
@ -279,6 +279,9 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
if(tsd->sock_error == 0)
|
||||
tsd->sock_error = RESOLVER_ENOMEM;
|
||||
}
|
||||
else {
|
||||
Curl_addrinfo_set_port(tsd->res, tsd->port);
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
@ -494,7 +497,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
int done = 0;
|
||||
|
||||
@ -522,7 +525,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
/* poll for name lookup done with exponential backoff up to 250ms */
|
||||
long elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||
time_t elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
|
||||
if(elapsed < 0)
|
||||
elapsed = 0;
|
||||
|
||||
@ -602,6 +605,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
/* First check if this is an IPv4 address string */
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
@ -612,7 +616,10 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
|
||||
/* This is an IPv6 address literal */
|
||||
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||
#endif /* CURLRES_IPV6 */
|
||||
#endif /* !USE_RESOLVE_ON_IPS */
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
/*
|
||||
* Check if a limited name resolve has been requested.
|
||||
*/
|
||||
@ -631,7 +638,6 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
if((pf != PF_INET) && !Curl_ipv6works())
|
||||
/* The stack seems to be a non-IPv6 one */
|
||||
pf = PF_INET;
|
||||
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
@ -656,12 +662,16 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
hostname, port, Curl_strerror(conn, SOCKERRNO));
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
Curl_addrinfo_set_port(res, port);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
char *servers)
|
||||
{
|
||||
(void)data;
|
||||
@ -670,7 +680,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
(void)data;
|
||||
@ -678,7 +688,7 @@ CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
(void)data;
|
||||
@ -686,7 +696,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
(void)data;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
struct Curl_dns_entry;
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
/* Base64 encoding/decoding */
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "urldata.h" /* for the SessionHandle definition */
|
||||
#include "urldata.h" /* for the Curl_easy definition */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "non-ascii.h"
|
||||
@ -169,7 +169,7 @@ CURLcode Curl_base64_decode(const char *src,
|
||||
}
|
||||
|
||||
static CURLcode base64_encode(const char *table64,
|
||||
struct SessionHandle *data,
|
||||
struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
@ -190,6 +190,11 @@ static CURLcode base64_encode(const char *table64,
|
||||
if(!insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
if(insize > UINT_MAX/4)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
base64data = output = malloc(insize * 4 / 3 + 4);
|
||||
if(!output)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -283,7 +288,7 @@ static CURLcode base64_encode(const char *table64,
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
@ -307,7 +312,7 @@ CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64url_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
|
@ -55,7 +55,10 @@ my %warnings = (
|
||||
'COPYRIGHT' => 'file missing a copyright statement',
|
||||
'BADCOMMAND' => 'bad !checksrc! instruction',
|
||||
'UNUSEDIGNORE' => 'a warning ignore was not used',
|
||||
'OPENCOMMENT' => 'file ended with a /* comment still "open"'
|
||||
'OPENCOMMENT' => 'file ended with a /* comment still "open"',
|
||||
'ASTERISKSPACE' => 'pointer declared with space after asterisk',
|
||||
'ASTERISKNOSPACE' => 'pointer declared without space before asterisk',
|
||||
'ASSIGNWITHINCONDITION' => 'assignment within conditional expression'
|
||||
);
|
||||
|
||||
sub readwhitelist {
|
||||
@ -241,6 +244,12 @@ sub checksrc {
|
||||
}
|
||||
}
|
||||
|
||||
sub nostrings {
|
||||
my ($str) = @_;
|
||||
$str =~ s/\".*\"//g;
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub scanfile {
|
||||
my ($file) = @_;
|
||||
|
||||
@ -327,17 +336,35 @@ sub scanfile {
|
||||
$line, length($1), $file, $l, "\/\/ comment");
|
||||
}
|
||||
|
||||
# check spaces after for/if/while
|
||||
if($l =~ /^(.*)(for|if|while) \(/) {
|
||||
my $nostr = nostrings($l);
|
||||
# check spaces after for/if/while/function call
|
||||
if($nostr =~ /^(.*)(for|if|while| ([a-zA-Z0-9_]+)) \((.)/) {
|
||||
if($1 =~ / *\#/) {
|
||||
# this is a #if, treat it differently
|
||||
}
|
||||
elsif($3 eq "return") {
|
||||
# return must have a space
|
||||
}
|
||||
elsif($4 eq "*") {
|
||||
# (* beginning makes the space OK!
|
||||
}
|
||||
elsif($1 =~ / *typedef/) {
|
||||
# typedefs can use space-paren
|
||||
}
|
||||
else {
|
||||
checkwarn("SPACEBEFOREPAREN", $line, length($1)+length($2), $file, $l,
|
||||
"$2 with space");
|
||||
}
|
||||
}
|
||||
|
||||
if($nostr =~ /^((.*)(if) *\()(.*)\)/) {
|
||||
my $pos = length($1);
|
||||
if($4 =~ / = /) {
|
||||
checkwarn("ASSIGNWITHINCONDITION",
|
||||
$line, $pos+1, $file, $l,
|
||||
"assignment within conditional expression");
|
||||
}
|
||||
}
|
||||
# check spaces after open parentheses
|
||||
if($l =~ /^(.*[a-z])\( /i) {
|
||||
checkwarn("SPACEAFTERPAREN",
|
||||
@ -421,7 +448,14 @@ sub scanfile {
|
||||
}
|
||||
|
||||
# scan for use of banned functions
|
||||
if($l =~ /^(.*\W)(sprintf|vsprintf|strcat|strncat|_mbscat|_mbsncat|_tcscat|_tcsncat|wcscat|wcsncat|gets)\s*\(/) {
|
||||
if($l =~ /^(.*\W)
|
||||
(gets|
|
||||
strtok|
|
||||
v?sprintf|
|
||||
(str|_mbs|_tcs|_wcs)n?cat|
|
||||
LoadLibrary(Ex)?(A|W)?)
|
||||
\s*\(
|
||||
/x) {
|
||||
checkwarn("BANNEDFUNC",
|
||||
$line, length($1), $file, $ol,
|
||||
"use of $2 is banned");
|
||||
@ -464,6 +498,31 @@ sub scanfile {
|
||||
}
|
||||
}
|
||||
|
||||
# check for 'char * name'
|
||||
if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) {
|
||||
checkwarn("ASTERISKNOSPACE",
|
||||
$line, length($1), $file, $ol,
|
||||
"no space after declarative asterisk");
|
||||
}
|
||||
# check for 'char*'
|
||||
if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) {
|
||||
checkwarn("ASTERISKNOSPACE",
|
||||
$line, length($1)-1, $file, $ol,
|
||||
"no space before asterisk");
|
||||
}
|
||||
|
||||
# check for 'void func() {', but avoid false positives by requiring
|
||||
# both an open and closed parentheses before the open brace
|
||||
if($l =~ /^((\w).*){\z/) {
|
||||
my $k = $1;
|
||||
$k =~ s/const *//;
|
||||
$k =~ s/static *//;
|
||||
if($k =~ /\(.*\)/) {
|
||||
checkwarn("BRACEPOS",
|
||||
$line, length($l)-1, $file, $ol,
|
||||
"wrongly placed open brace");
|
||||
}
|
||||
}
|
||||
$line++;
|
||||
$prevl = $ol;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -98,7 +98,7 @@
|
||||
#define OS "AmigaOS"
|
||||
|
||||
#define PACKAGE "curl"
|
||||
#define PACKAGE_BUGREPORT "curl-bug@haxx.se"
|
||||
#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.haxx.se/mail/"
|
||||
#define PACKAGE_NAME "curl"
|
||||
#define PACKAGE_STRING "curl -"
|
||||
#define PACKAGE_TARNAME "curl"
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "conncache.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -45,7 +44,7 @@ static void conn_llist_dtor(void *user, void *element)
|
||||
data->bundle = NULL;
|
||||
}
|
||||
|
||||
static CURLcode bundle_create(struct SessionHandle *data,
|
||||
static CURLcode bundle_create(struct Curl_easy *data,
|
||||
struct connectbundle **cb_ptr)
|
||||
{
|
||||
(void)data;
|
||||
@ -133,14 +132,16 @@ static char *hashkey(struct connectdata *conn)
|
||||
{
|
||||
const char *hostname;
|
||||
|
||||
if(conn->bits.proxy)
|
||||
hostname = conn->proxy.name;
|
||||
if(conn->bits.socksproxy)
|
||||
hostname = conn->socks_proxy.host.name;
|
||||
else if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
return aprintf("%s:%d", hostname, conn->port);
|
||||
return aprintf("%s:%ld", hostname, conn->port);
|
||||
}
|
||||
|
||||
/* Look up the bundle with all the connections to the same host this
|
||||
@ -199,7 +200,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
CURLcode result;
|
||||
struct connectbundle *bundle;
|
||||
struct connectbundle *new_bundle = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
|
||||
if(!bundle) {
|
||||
|
@ -72,6 +72,7 @@
|
||||
#include "warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "system_win32.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -103,7 +104,7 @@ struct tcp_keepalive {
|
||||
#endif
|
||||
|
||||
static void
|
||||
tcpkeepalive(struct SessionHandle *data,
|
||||
tcpkeepalive(struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
int optval = data->set.tcp_keepalive?1:0;
|
||||
@ -178,12 +179,12 @@ singleipconnect(struct connectdata *conn,
|
||||
*
|
||||
* @unittest: 1303
|
||||
*/
|
||||
long Curl_timeleft(struct SessionHandle *data,
|
||||
time_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct timeval *nowp,
|
||||
bool duringconnect)
|
||||
{
|
||||
int timeout_set = 0;
|
||||
long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
|
||||
time_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
|
||||
struct timeval now;
|
||||
|
||||
/* if a timeout is set, use the most restrictive one */
|
||||
@ -238,7 +239,7 @@ long Curl_timeleft(struct SessionHandle *data,
|
||||
static CURLcode bindlocal(struct connectdata *conn,
|
||||
curl_socket_t sockfd, int af, unsigned int scope)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
struct Curl_sockaddr_storage sa;
|
||||
struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */
|
||||
@ -600,6 +601,8 @@ void Curl_persistconninfo(struct connectdata *conn)
|
||||
{
|
||||
memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
|
||||
memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
|
||||
conn->data->info.conn_scheme = conn->handler->scheme;
|
||||
conn->data->info.conn_protocol = conn->handler->protocol;
|
||||
conn->data->info.conn_primary_port = conn->primary_port;
|
||||
conn->data->info.conn_local_port = conn->local_port;
|
||||
}
|
||||
@ -662,7 +665,7 @@ 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 SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(conn->socktype == SOCK_DGRAM)
|
||||
/* there's no connection! */
|
||||
@ -719,9 +722,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *connected)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
long allow;
|
||||
time_t allow;
|
||||
int error = 0;
|
||||
struct timeval now;
|
||||
int rc;
|
||||
@ -761,7 +764,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
/* check socket for connect */
|
||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
|
||||
rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
|
||||
|
||||
if(rc == 0) { /* no connection yet */
|
||||
error = 0;
|
||||
@ -852,8 +855,10 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->bits.proxy)
|
||||
hostname = conn->proxy.name;
|
||||
if(conn->bits.socksproxy)
|
||||
hostname = conn->socks_proxy.host.name;
|
||||
else if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
@ -870,7 +875,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
#if defined(TCP_NODELAY)
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif
|
||||
curl_socklen_t onoff = (curl_socklen_t) 1;
|
||||
int level = IPPROTO_TCP;
|
||||
@ -912,7 +917,7 @@ void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
static void nosigpipe(struct connectdata *conn,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
struct SessionHandle *data= conn->data;
|
||||
struct Curl_easy *data= conn->data;
|
||||
int onoff = 1;
|
||||
if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
|
||||
sizeof(onoff)) < 0)
|
||||
@ -945,43 +950,15 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
int val = CURL_MAX_WRITE_SIZE + 32;
|
||||
int curval = 0;
|
||||
int curlen = sizeof(curval);
|
||||
DWORD majorVersion = 6;
|
||||
|
||||
static int detectOsState = DETECT_OS_NONE;
|
||||
|
||||
if(detectOsState == DETECT_OS_NONE) {
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
|
||||
detectOsState = DETECT_OS_PREVISTA;
|
||||
if(GetVersionEx(&osver)) {
|
||||
if(osver.dwMajorVersion >= majorVersion)
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
}
|
||||
#else
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
|
||||
VERSION_GREATER_THAN_EQUAL))
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
else
|
||||
detectOsState = DETECT_OS_PREVISTA;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(detectOsState == DETECT_OS_VISTA_OR_LATER)
|
||||
@ -1012,7 +989,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
int rc = -1;
|
||||
int error = 0;
|
||||
bool isconnected = FALSE;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t sockfd;
|
||||
CURLcode result;
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
@ -1111,6 +1088,9 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
|
||||
NULL, 0, NULL, NULL);
|
||||
#elif defined(MSG_FASTOPEN) /* Linux */
|
||||
if(conn->given->flags & PROTOPT_SSL)
|
||||
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
|
||||
else
|
||||
rc = 0; /* Do nothing */
|
||||
#endif
|
||||
}
|
||||
@ -1173,11 +1153,11 @@ static CURLcode singleipconnect(struct connectdata *conn,
|
||||
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
const struct Curl_dns_entry *remotehost)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct timeval before = Curl_tvnow();
|
||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||
|
||||
long timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||
time_t timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
@ -1232,11 +1212,11 @@ static int conn_is_conn(struct connectdata *conn, void *param)
|
||||
|
||||
/*
|
||||
* Used to extract socket and connectdata struct for the most recent
|
||||
* transfer on the given SessionHandle.
|
||||
* transfer on the given Curl_easy.
|
||||
*
|
||||
* The returned socket will be CURL_SOCKET_BAD in case of failure!
|
||||
*/
|
||||
curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
||||
struct connectdata **connp)
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
@ -1267,24 +1247,6 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
/* only store this if the caller cares for it */
|
||||
*connp = c;
|
||||
sockfd = c->sock[FIRSTSOCKET];
|
||||
/* we have a socket connected, let's determine if the server shut down */
|
||||
/* determine if ssl */
|
||||
if(c->ssl[FIRSTSOCKET].use) {
|
||||
/* use the SSL context */
|
||||
if(!Curl_ssl_check_cxn(c))
|
||||
return CURL_SOCKET_BAD; /* FIN received */
|
||||
}
|
||||
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
|
||||
#ifdef MSG_PEEK
|
||||
else if(sockfd != CURL_SOCKET_BAD) {
|
||||
/* use the socket */
|
||||
char buf;
|
||||
if(recv((RECV_TYPE_ARG1)sockfd, (RECV_TYPE_ARG2)&buf,
|
||||
(RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
|
||||
return CURL_SOCKET_BAD; /* FIN received */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return CURL_SOCKET_BAD;
|
||||
@ -1292,6 +1254,33 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if a connection seems to be alive.
|
||||
*/
|
||||
bool Curl_connalive(struct connectdata *conn)
|
||||
{
|
||||
/* First determine if ssl */
|
||||
if(conn->ssl[FIRSTSOCKET].use) {
|
||||
/* use the SSL context */
|
||||
if(!Curl_ssl_check_cxn(conn))
|
||||
return false; /* FIN received */
|
||||
}
|
||||
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
|
||||
#ifdef MSG_PEEK
|
||||
else if(conn->sock[FIRSTSOCKET] == CURL_SOCKET_BAD)
|
||||
return false;
|
||||
else {
|
||||
/* use the socket */
|
||||
char buf;
|
||||
if(recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
|
||||
(RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
|
||||
return false; /* FIN received */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a socket.
|
||||
*
|
||||
@ -1336,7 +1325,7 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct Curl_sockaddr_ex dummy;
|
||||
|
||||
if(!addr)
|
||||
@ -1392,25 +1381,39 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
|
||||
* MUST be called with the connclose() or connkeep() macros with a stated
|
||||
* reason. The reason is only shown in debug builds but helps to figure out
|
||||
* decision paths when connections are or aren't re-used as expected.
|
||||
* Curl_conncontrol() marks streams or connection for closure.
|
||||
*/
|
||||
void Curl_conncontrol(struct connectdata *conn, bool closeit,
|
||||
const char *reason)
|
||||
{
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) reason;
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
int ctrl /* see defines in header */
|
||||
#ifdef DEBUGBUILD
|
||||
, const char *reason
|
||||
#endif
|
||||
if(closeit != conn->bits.close) {
|
||||
infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
|
||||
reason);
|
||||
|
||||
)
|
||||
{
|
||||
/* close if a connection, or a stream that isn't multiplexed */
|
||||
bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
|
||||
((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
|
||||
if((ctrl == CONNCTRL_STREAM) &&
|
||||
(conn->handler->flags & PROTOPT_STREAM))
|
||||
DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
|
||||
else if(closeit != conn->bits.close) {
|
||||
DEBUGF(infof(conn->data, "Marked for [%s]: %s\n",
|
||||
closeit?"closure":"keep alive", reason));
|
||||
conn->bits.close = closeit; /* the only place in the source code that
|
||||
should assign this bit */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Data received can be cached at various levels, so check them all here. */
|
||||
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
int readable;
|
||||
|
||||
if(Curl_ssl_data_pending(conn, sockindex) ||
|
||||
Curl_recv_has_postponed_data(conn, sockindex))
|
||||
return true;
|
||||
|
||||
readable = SOCKET_READABLE(conn->sock[sockindex], 0);
|
||||
return (readable > 0 && (readable & CURL_CSELECT_IN));
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -35,7 +35,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,
|
||||
|
||||
/* generic function that returns how much time there's left to run, according
|
||||
to the timeouts set */
|
||||
long Curl_timeleft(struct SessionHandle *data,
|
||||
time_t Curl_timeleft(struct Curl_easy *data,
|
||||
struct timeval *nowp,
|
||||
bool duringconnect);
|
||||
|
||||
@ -45,13 +45,18 @@ long Curl_timeleft(struct SessionHandle *data,
|
||||
|
||||
/*
|
||||
* Used to extract socket and connectdata struct for the most recent
|
||||
* transfer on the given SessionHandle.
|
||||
* transfer on the given Curl_easy.
|
||||
*
|
||||
* The returned socket will be CURL_SOCKET_BAD in case of failure!
|
||||
*/
|
||||
curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
|
||||
struct connectdata **connp);
|
||||
|
||||
/*
|
||||
* Check if a connection seems to be alive.
|
||||
*/
|
||||
bool Curl_connalive(struct connectdata *conn);
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* When you run a program that uses the Windows Sockets API, you may
|
||||
experience slow performance when you copy data to a TCP server.
|
||||
@ -104,21 +109,39 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
|
||||
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Curl_connclose() sets the bit.close bit to TRUE with an explanation.
|
||||
* Nothing else.
|
||||
* Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
|
||||
* argument specifies if it is the end of a connection or a stream.
|
||||
*
|
||||
* For stream-based protocols (such as HTTP/2), a stream close will not cause
|
||||
* a connection close. Other protocols will close the connection for both
|
||||
* cases.
|
||||
*
|
||||
* It sets the bit.close bit to TRUE (with an explanation for debug builds),
|
||||
* when the connection will close.
|
||||
*/
|
||||
|
||||
#define CONNCTRL_KEEP 0 /* undo a marked closure */
|
||||
#define CONNCTRL_CONNECTION 1
|
||||
#define CONNCTRL_STREAM 2
|
||||
|
||||
void Curl_conncontrol(struct connectdata *conn,
|
||||
bool closeit,
|
||||
const char *reason);
|
||||
#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
|
||||
int closeit
|
||||
#ifdef DEBUGBUILD
|
||||
, const char *reason
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
|
||||
#else /* if !CURLDEBUG */
|
||||
|
||||
#define connclose(x,y) (x)->bits.close = TRUE
|
||||
#define connkeep(x,y) (x)->bits.close = FALSE
|
||||
|
||||
#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
|
||||
#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
|
||||
#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
|
||||
#endif
|
||||
|
||||
bool Curl_conn_data_pending(struct connectdata *conn, int sockindex);
|
||||
|
||||
#endif /* HEADER_CURL_CONNECT_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -28,8 +28,8 @@
|
||||
#include <curl/curl.h>
|
||||
#include "sendf.h"
|
||||
#include "content_encoding.h"
|
||||
#include "strdup.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
|
||||
@ -67,7 +67,7 @@ zfree_cb(voidpf opaque, voidpf ptr)
|
||||
static CURLcode
|
||||
process_zlib_error(struct connectdata *conn, z_stream *z)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
if(z->msg)
|
||||
failf(data, "Error while processing content unencoding: %s",
|
||||
z->msg);
|
||||
@ -314,7 +314,7 @@ Curl_unencode_gzip_write(struct connectdata *conn,
|
||||
#ifndef OLD_ZLIB_SUPPORT
|
||||
/* Support for old zlib versions is compiled away and we are running with
|
||||
an old version, so return an error. */
|
||||
return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
|
||||
return exit_zlib(z, &k->zlib_init, CURLE_WRITE_ERROR);
|
||||
|
||||
#else
|
||||
/* This next mess is to get around the potential case where there isn't
|
||||
@ -371,12 +371,9 @@ Curl_unencode_gzip_write(struct connectdata *conn,
|
||||
{
|
||||
/* Need more gzip header data state */
|
||||
ssize_t hlen;
|
||||
unsigned char *oldblock = z->next_in;
|
||||
|
||||
z->avail_in += (uInt)nread;
|
||||
z->next_in = realloc(z->next_in, z->avail_in);
|
||||
z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
|
||||
if(z->next_in == NULL) {
|
||||
free(oldblock);
|
||||
return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
|
||||
}
|
||||
/* Append the new block of data to the previous one */
|
||||
@ -425,7 +422,7 @@ Curl_unencode_gzip_write(struct connectdata *conn,
|
||||
|
||||
void Curl_unencode_cleanup(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
z_stream *z = &k->z;
|
||||
if(k->zlib_init != ZLIB_UNINIT)
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,13 +26,13 @@
|
||||
RECEIVING COOKIE INFORMATION
|
||||
============================
|
||||
|
||||
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *file, struct CookieInfo *inc, bool newsession);
|
||||
|
||||
Inits a cookie struct to store data in a local file. This is always
|
||||
called before any cookies are set.
|
||||
|
||||
struct Cookie *Curl_cookie_add(struct SessionHandle *data,
|
||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *c, bool httpheader, char *lineptr,
|
||||
const char *domain, const char *path);
|
||||
|
||||
@ -90,13 +90,12 @@ Example set of cookies:
|
||||
|
||||
#include "urldata.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "slist.h"
|
||||
#include "share.h"
|
||||
#include "strtoofft.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
@ -126,7 +125,7 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
||||
if(hostname_len < cookie_domain_len)
|
||||
return FALSE;
|
||||
|
||||
if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
|
||||
if(!strcasecompare(cooke_domain, hostname+hostname_len-cookie_domain_len))
|
||||
return FALSE;
|
||||
|
||||
/* A lead char of cookie_domain is not '.'.
|
||||
@ -260,7 +259,7 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
||||
*
|
||||
* NOTE: OOM or cookie parsing failures are ignored.
|
||||
*/
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data)
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data)
|
||||
{
|
||||
struct curl_slist *list = data->change.cookielist;
|
||||
if(list) {
|
||||
@ -362,7 +361,7 @@ static bool isip(const char *domain)
|
||||
***************************************************************************/
|
||||
|
||||
struct Cookie *
|
||||
Curl_cookie_add(struct SessionHandle *data,
|
||||
Curl_cookie_add(struct Curl_easy *data,
|
||||
/* The 'data' pointer here may be NULL at times, and thus
|
||||
must only be used very carefully for things that can deal
|
||||
with data being NULL. Such as infof() and similar */
|
||||
@ -469,9 +468,9 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
/* this was a "<name>=" with no content, and we must allow
|
||||
'secure' and 'httponly' specified this weirdly */
|
||||
done = TRUE;
|
||||
if(Curl_raw_equal("secure", name))
|
||||
if(strcasecompare("secure", name))
|
||||
co->secure = TRUE;
|
||||
else if(Curl_raw_equal("httponly", name))
|
||||
else if(strcasecompare("httponly", name))
|
||||
co->httponly = TRUE;
|
||||
else if(sep)
|
||||
/* there was a '=' so we're not done parsing this field */
|
||||
@ -479,7 +478,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
}
|
||||
if(done)
|
||||
;
|
||||
else if(Curl_raw_equal("path", name)) {
|
||||
else if(strcasecompare("path", name)) {
|
||||
strstore(&co->path, whatptr);
|
||||
if(!co->path) {
|
||||
badcookie = TRUE; /* out of memory bad */
|
||||
@ -491,9 +490,8 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("domain", name)) {
|
||||
else if(strcasecompare("domain", name)) {
|
||||
bool is_ip;
|
||||
const char *dotp;
|
||||
|
||||
/* Now, we make sure that our host is within the given domain,
|
||||
or the given domain is not valid and thus cannot be set. */
|
||||
@ -501,12 +499,22 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
if('.' == whatptr[0])
|
||||
whatptr++; /* ignore preceding dot */
|
||||
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
|
||||
#ifndef USE_LIBPSL
|
||||
/*
|
||||
* Without PSL we don't know when the incoming cookie is set on a
|
||||
* TLD or otherwise "protected" suffix. To reduce risk, we require a
|
||||
* dot OR the exact host name being "localhost".
|
||||
*/
|
||||
{
|
||||
const char *dotp;
|
||||
/* check for more dots */
|
||||
dotp = strchr(whatptr, '.');
|
||||
if(!dotp)
|
||||
if(!dotp && !strcasecompare("localhost", whatptr))
|
||||
domain=":";
|
||||
}
|
||||
#endif
|
||||
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
|
||||
if(!domain
|
||||
|| (is_ip && !strcmp(whatptr, domain))
|
||||
@ -529,14 +537,14 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
whatptr);
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("version", name)) {
|
||||
else if(strcasecompare("version", name)) {
|
||||
strstore(&co->version, whatptr);
|
||||
if(!co->version) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("max-age", name)) {
|
||||
else if(strcasecompare("max-age", name)) {
|
||||
/* Defined in RFC2109:
|
||||
|
||||
Optional. The Max-Age attribute defines the lifetime of the
|
||||
@ -552,7 +560,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("expires", name)) {
|
||||
else if(strcasecompare("expires", name)) {
|
||||
strstore(&co->expirestr, whatptr);
|
||||
if(!co->expirestr) {
|
||||
badcookie = TRUE;
|
||||
@ -713,7 +721,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
As far as I can see, it is set to true when the cookie says
|
||||
.domain.com and to false when the domain is complete www.domain.com
|
||||
*/
|
||||
co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
|
||||
co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
|
||||
break;
|
||||
case 2:
|
||||
/* It turns out, that sometimes the file format allows the path
|
||||
@ -742,7 +750,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
fields++; /* add a field and fall down to secure */
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
|
||||
co->secure = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
|
||||
break;
|
||||
case 4:
|
||||
co->expires = curlx_strtoofft(ptr, NULL, 10);
|
||||
@ -799,8 +807,8 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
/* Check if the domain is a Public Suffix and if yes, ignore the cookie.
|
||||
This needs a libpsl compiled with builtin data. */
|
||||
if(domain && co->domain && !isip(co->domain)) {
|
||||
if(((psl = psl_builtin()) != NULL)
|
||||
&& !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
|
||||
psl = psl_builtin();
|
||||
if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
|
||||
infof(data,
|
||||
"cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n",
|
||||
co->name, domain, co->domain);
|
||||
@ -813,11 +821,12 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
clist = c->cookies;
|
||||
replace_old = FALSE;
|
||||
while(clist) {
|
||||
if(Curl_raw_equal(clist->name, co->name)) {
|
||||
if(strcasecompare(clist->name, co->name)) {
|
||||
/* the names are identical */
|
||||
|
||||
if(clist->domain && co->domain) {
|
||||
if(Curl_raw_equal(clist->domain, co->domain))
|
||||
if(strcasecompare(clist->domain, co->domain) &&
|
||||
(clist->tailmatch == co->tailmatch))
|
||||
/* The domains are identical */
|
||||
replace_old=TRUE;
|
||||
}
|
||||
@ -828,7 +837,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
/* the domains were identical */
|
||||
|
||||
if(clist->spath && co->spath) {
|
||||
if(Curl_raw_equal(clist->spath, co->spath)) {
|
||||
if(strcasecompare(clist->spath, co->spath)) {
|
||||
replace_old = TRUE;
|
||||
}
|
||||
else
|
||||
@ -902,6 +911,35 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
return co;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_line() makes sure to only return complete whole lines that fit in 'len'
|
||||
* bytes and end with a newline.
|
||||
*/
|
||||
static char *get_line(char *buf, int len, FILE *input)
|
||||
{
|
||||
bool partial = FALSE;
|
||||
while(1) {
|
||||
char *b = fgets(buf, len, input);
|
||||
if(b) {
|
||||
size_t rlen = strlen(b);
|
||||
if(rlen && (b[rlen-1] == '\n')) {
|
||||
if(partial) {
|
||||
partial = FALSE;
|
||||
continue;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
else
|
||||
/* read a partial, discard the next piece that ends with newline */
|
||||
partial = TRUE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Curl_cookie_init()
|
||||
@ -913,7 +951,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
*
|
||||
* Returns NULL on out of memory. Invalid cookies are ignored.
|
||||
****************************************************************************/
|
||||
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *file,
|
||||
struct CookieInfo *inc,
|
||||
bool newsession)
|
||||
@ -938,7 +976,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
}
|
||||
c->running = FALSE; /* this is not running, this is init */
|
||||
|
||||
if(file && strequal(file, "-")) {
|
||||
if(file && !strcmp(file, "-")) {
|
||||
fp = stdin;
|
||||
fromfile=FALSE;
|
||||
}
|
||||
@ -958,7 +996,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
line = malloc(MAX_COOKIE_LINE);
|
||||
if(!line)
|
||||
goto fail;
|
||||
while(fgets(line, MAX_COOKIE_LINE, fp)) {
|
||||
while(get_line(line, MAX_COOKIE_LINE, fp)) {
|
||||
if(checkprefix("Set-Cookie:", line)) {
|
||||
/* This is a cookie line, get it! */
|
||||
lineptr=&line[11];
|
||||
@ -1023,6 +1061,40 @@ static int cookie_sort(const void *p1, const void *p2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CLONE(field) \
|
||||
do { \
|
||||
if(src->field) { \
|
||||
d->field = strdup(src->field); \
|
||||
if(!d->field) \
|
||||
goto fail; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
static struct Cookie *dup_cookie(struct Cookie *src)
|
||||
{
|
||||
struct Cookie *d = calloc(sizeof(struct Cookie), 1);
|
||||
if(d) {
|
||||
CLONE(expirestr);
|
||||
CLONE(domain);
|
||||
CLONE(path);
|
||||
CLONE(spath);
|
||||
CLONE(name);
|
||||
CLONE(value);
|
||||
CLONE(maxage);
|
||||
CLONE(version);
|
||||
d->expires = src->expires;
|
||||
d->tailmatch = src->tailmatch;
|
||||
d->secure = src->secure;
|
||||
d->livecookie = src->livecookie;
|
||||
d->httponly = src->httponly;
|
||||
}
|
||||
return d;
|
||||
|
||||
fail:
|
||||
freecookie(d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Curl_cookie_getlist()
|
||||
@ -1067,7 +1139,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* now check if the domain is correct */
|
||||
if(!co->domain ||
|
||||
(co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
|
||||
((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
|
||||
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
|
||||
/* the right part of the host matches the domain stuff in the
|
||||
cookie data */
|
||||
|
||||
@ -1078,11 +1150,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* and now, we know this is a match and we should create an
|
||||
entry for the return-linked-list */
|
||||
|
||||
newco = malloc(sizeof(struct Cookie));
|
||||
newco = dup_cookie(co);
|
||||
if(newco) {
|
||||
/* first, copy the whole source cookie: */
|
||||
memcpy(newco, co, sizeof(struct Cookie));
|
||||
|
||||
/* then modify our next */
|
||||
newco->next = mainco;
|
||||
|
||||
@ -1094,12 +1163,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
else {
|
||||
fail:
|
||||
/* failure, clear up the allocated chain and return NULL */
|
||||
while(mainco) {
|
||||
co = mainco->next;
|
||||
free(mainco);
|
||||
mainco = co;
|
||||
}
|
||||
|
||||
Curl_cookie_freelist(mainco);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1151,7 +1215,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||
{
|
||||
if(cookies) {
|
||||
Curl_cookie_freelist(cookies->cookies, TRUE);
|
||||
Curl_cookie_freelist(cookies->cookies);
|
||||
cookies->cookies = NULL;
|
||||
cookies->numcookies = 0;
|
||||
}
|
||||
@ -1163,21 +1227,14 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||
*
|
||||
* Free a list of cookies previously returned by Curl_cookie_getlist();
|
||||
*
|
||||
* The 'cookiestoo' argument tells this function whether to just free the
|
||||
* list or actually also free all cookies within the list as well.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
|
||||
void Curl_cookie_freelist(struct Cookie *co)
|
||||
{
|
||||
struct Cookie *next;
|
||||
while(co) {
|
||||
next = co->next;
|
||||
if(cookiestoo)
|
||||
freecookie(co);
|
||||
else
|
||||
free(co); /* we only free the struct since the "members" are all just
|
||||
pointed out in the main cookie list! */
|
||||
co = next;
|
||||
}
|
||||
}
|
||||
@ -1232,7 +1289,7 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||
{
|
||||
if(c) {
|
||||
free(c->filename);
|
||||
Curl_cookie_freelist(c->cookies, TRUE);
|
||||
Curl_cookie_freelist(c->cookies);
|
||||
free(c); /* free the base struct as well */
|
||||
}
|
||||
}
|
||||
@ -1290,7 +1347,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
/* at first, remove expired cookies */
|
||||
remove_expired(c);
|
||||
|
||||
if(strequal("-", dumphere)) {
|
||||
if(!strcmp("-", dumphere)) {
|
||||
/* use stdout */
|
||||
out = stdout;
|
||||
use_stdout=TRUE;
|
||||
@ -1326,7 +1383,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data)
|
||||
{
|
||||
struct curl_slist *list = NULL;
|
||||
struct curl_slist *beg;
|
||||
@ -1357,7 +1414,7 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
||||
return list;
|
||||
}
|
||||
|
||||
void Curl_flush_cookies(struct SessionHandle *data, int cleanup)
|
||||
void Curl_flush_cookies(struct Curl_easy *data, int cleanup)
|
||||
{
|
||||
if(data->set.str[STRING_COOKIEJAR]) {
|
||||
if(data->change.cookielist) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -70,19 +70,19 @@ struct CookieInfo {
|
||||
#define MAX_NAME 1024
|
||||
#define MAX_NAME_TXT "1023"
|
||||
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
/*
|
||||
* Add a cookie to the internal list of cookies. The domain and path arguments
|
||||
* are only used if the header boolean is TRUE.
|
||||
*/
|
||||
|
||||
struct Cookie *Curl_cookie_add(struct SessionHandle *data,
|
||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *, bool header, char *lineptr,
|
||||
const char *domain, const char *path);
|
||||
|
||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
|
||||
const char *, bool);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies);
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
|
||||
@ -93,12 +93,12 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x,y) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
|
||||
void Curl_flush_cookies(struct Curl_easy *data, int cleanup);
|
||||
void Curl_cookie_cleanup(struct CookieInfo *);
|
||||
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *, struct CookieInfo *, bool);
|
||||
struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data);
|
||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_COOKIE_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -47,6 +47,8 @@
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "inet_pton.h"
|
||||
#include "warnless.h"
|
||||
@ -146,7 +148,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
|
||||
ca = malloc(sizeof(Curl_addrinfo));
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
}
|
||||
@ -163,7 +166,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
if((ca->ai_addr = malloc(ss_size)) == NULL) {
|
||||
ca->ai_addr = malloc(ss_size);
|
||||
if(!ca->ai_addr) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca);
|
||||
break;
|
||||
@ -171,7 +175,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||
|
||||
if(ai->ai_canonname != NULL) {
|
||||
if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
|
||||
ca->ai_canonname = strdup(ai->ai_canonname);
|
||||
if(!ca->ai_canonname) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca->ai_addr);
|
||||
free(ca);
|
||||
@ -291,16 +296,19 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
#endif
|
||||
ss_size = sizeof(struct sockaddr_in);
|
||||
|
||||
if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) {
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
if(!ai) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
if((ai->ai_canonname = strdup(he->h_name)) == NULL) {
|
||||
ai->ai_canonname = strdup(he->h_name);
|
||||
if(!ai->ai_canonname) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai);
|
||||
break;
|
||||
}
|
||||
if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
|
||||
ai->ai_addr = calloc(1, ss_size);
|
||||
if(!ai->ai_addr) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
@ -475,34 +483,48 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
/**
|
||||
* Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
|
||||
* struct initialized with this path.
|
||||
* Set '*longpath' to TRUE if the error is a too long path.
|
||||
*/
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path)
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
struct sockaddr_un *sa_un;
|
||||
size_t path_len;
|
||||
|
||||
*longpath = FALSE;
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
|
||||
ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
|
||||
if(!ai->ai_addr) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
|
||||
/* sun_path must be able to store the NUL-terminated path */
|
||||
path_len = strlen(path);
|
||||
if(path_len >= sizeof(sa_un->sun_path)) {
|
||||
path_len = strlen(path) + 1;
|
||||
if(path_len > sizeof(sa_un->sun_path)) {
|
||||
free(ai->ai_addr);
|
||||
free(ai);
|
||||
*longpath = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ai->ai_family = AF_UNIX;
|
||||
ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
|
||||
ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
|
||||
ai->ai_addrlen = (curl_socklen_t)
|
||||
((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF);
|
||||
|
||||
/* Abstract Unix domain socket have NULL prefix instead of suffix */
|
||||
if(abstract)
|
||||
memcpy(sa_un->sun_path + 1, path, path_len - 1);
|
||||
else
|
||||
memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */
|
||||
|
||||
return ai;
|
||||
}
|
||||
#endif
|
||||
@ -563,3 +585,32 @@ curl_dogetaddrinfo(const char *hostname,
|
||||
}
|
||||
#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
|
||||
|
||||
#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS)
|
||||
/*
|
||||
* Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
|
||||
* 10.11.5.
|
||||
*/
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
|
||||
{
|
||||
Curl_addrinfo *ca;
|
||||
struct sockaddr_in *addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *addr6;
|
||||
#endif
|
||||
for(ca = addrinfo; ca != NULL; ca = ca->ai_next) {
|
||||
switch(ca->ai_family) {
|
||||
case AF_INET:
|
||||
addr = (void *)ca->ai_addr; /* storage area for this info */
|
||||
addr->sin_port = htons((unsigned short)port);
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
addr6 = (void *)ca->ai_addr; /* storage area for this info */
|
||||
addr6->sin6_port = htons((unsigned short)port);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -80,7 +80,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path);
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
@ -99,4 +99,12 @@ curl_dogetaddrinfo(const char *hostname,
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#ifdef USE_RESOLVE_ON_IPS
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
|
||||
#else
|
||||
#define Curl_addrinfo_set_port(x,y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_ADDRINFO_H */
|
||||
|
@ -22,10 +22,10 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode Curl_base64url_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
||||
|
||||
/* to make a symbol visible */
|
||||
#cmakedefine CURL_EXTERN_SYMBOL 1
|
||||
#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
|
||||
/* Ensure using CURL_EXTERN_SYMBOL is possible */
|
||||
#ifndef CURL_EXTERN_SYMBOL
|
||||
#define CURL_EXTERN_SYMBOL
|
||||
@ -518,6 +518,15 @@
|
||||
/* Define to 1 if you have the send function. */
|
||||
#cmakedefine HAVE_SEND 1
|
||||
|
||||
/* Define to 1 if you have the 'fsetxattr' function. */
|
||||
#cmakedefine HAVE_FSETXATTR 1
|
||||
|
||||
/* fsetxattr() takes 5 args */
|
||||
#cmakedefine HAVE_FSETXATTR_5 1
|
||||
|
||||
/* fsetxattr() takes 6 args */
|
||||
#cmakedefine HAVE_FSETXATTR_6 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#cmakedefine HAVE_SETJMP_H 1
|
||||
|
||||
@ -906,6 +915,9 @@
|
||||
/* Define if you want to enable POSIX threaded DNS lookup */
|
||||
#cmakedefine USE_THREADS_POSIX 1
|
||||
|
||||
/* Define if you want to enable WIN32 threaded DNS lookup */
|
||||
#cmakedefine USE_THREADS_WIN32 1
|
||||
|
||||
/* Define to disable non-blocking sockets. */
|
||||
#cmakedefine USE_BLOCKING_SOCKETS 1
|
||||
|
||||
@ -915,6 +927,9 @@
|
||||
/* if PolarSSL is enabled */
|
||||
#cmakedefine USE_POLARSSL 1
|
||||
|
||||
/* if mbedTLS is enabled */
|
||||
#cmakedefine USE_MBEDTLS 1
|
||||
|
||||
/* if libSSH2 is in use */
|
||||
#cmakedefine USE_LIBSSH2 1
|
||||
|
||||
@ -930,11 +945,13 @@
|
||||
/* if OpenSSL is in use */
|
||||
#cmakedefine USE_OPENSSL 1
|
||||
|
||||
/* to enable NGHTTP2 */
|
||||
#cmakedefine USE_NGHTTP2 1
|
||||
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS
|
||||
|
||||
/* Define to 1 if you are building a Windows target without large file
|
||||
support. */
|
||||
/* Define to 1 if you are building a Windows target with large file support. */
|
||||
#cmakedefine USE_WIN32_LARGE_FILES 1
|
||||
|
||||
/* to enable SSPI support */
|
||||
|
@ -34,7 +34,7 @@
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -37,7 +37,7 @@
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_le(unsigned char *buf)
|
||||
unsigned short Curl_read16_le(const unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0]) |
|
||||
((unsigned short)buf[1] << 8));
|
||||
@ -56,7 +56,7 @@ unsigned short Curl_read16_le(unsigned char *buf)
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_le(unsigned char *buf)
|
||||
unsigned int Curl_read32_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||
@ -77,7 +77,7 @@ unsigned int Curl_read32_le(unsigned char *buf)
|
||||
* Returns the integer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_le(unsigned char *buf)
|
||||
unsigned long long Curl_read64_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned long long)buf[0]) |
|
||||
((unsigned long long)buf[1] << 8) |
|
||||
@ -89,7 +89,7 @@ unsigned long long Curl_read64_le(unsigned char *buf)
|
||||
((unsigned long long)buf[7] << 56);
|
||||
}
|
||||
#else
|
||||
unsigned __int64 Curl_read64_le(unsigned char *buf)
|
||||
unsigned __int64 Curl_read64_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
|
||||
((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
|
||||
@ -113,7 +113,7 @@ unsigned __int64 Curl_read64_le(unsigned char *buf)
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_be(unsigned char *buf)
|
||||
unsigned short Curl_read16_be(const unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0] << 8) |
|
||||
((unsigned short)buf[1]));
|
||||
@ -132,7 +132,7 @@ unsigned short Curl_read16_be(unsigned char *buf)
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_be(unsigned char *buf)
|
||||
unsigned int Curl_read32_be(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
|
||||
((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
|
||||
@ -153,7 +153,7 @@ unsigned int Curl_read32_be(unsigned char *buf)
|
||||
* Returns the integer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_be(unsigned char *buf)
|
||||
unsigned long long Curl_read64_be(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned long long)buf[0] << 56) |
|
||||
((unsigned long long)buf[1] << 48) |
|
||||
@ -165,7 +165,7 @@ unsigned long long Curl_read64_be(unsigned char *buf)
|
||||
((unsigned long long)buf[7]);
|
||||
}
|
||||
#else
|
||||
unsigned __int64 Curl_read64_be(unsigned char *buf)
|
||||
unsigned __int64 Curl_read64_be(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
|
||||
((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,32 +23,32 @@
|
||||
***************************************************************************/
|
||||
|
||||
/* Converts a 16-bit integer from little endian */
|
||||
unsigned short Curl_read16_le(unsigned char *buf);
|
||||
unsigned short Curl_read16_le(const unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from little endian */
|
||||
unsigned int Curl_read32_le(unsigned char *buf);
|
||||
unsigned int Curl_read32_le(const unsigned char *buf);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer from little endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_le(unsigned char *buf);
|
||||
unsigned long long Curl_read64_le(const unsigned char *buf);
|
||||
#else
|
||||
unsigned __int64 Curl_read64_le(unsigned char *buf);
|
||||
unsigned __int64 Curl_read64_le(const unsigned char *buf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Converts a 16-bit integer from big endian */
|
||||
unsigned short Curl_read16_be(unsigned char *buf);
|
||||
unsigned short Curl_read16_be(const unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from big endian */
|
||||
unsigned int Curl_read32_be(unsigned char *buf);
|
||||
unsigned int Curl_read32_be(const unsigned char *buf);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer from big endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_be(unsigned char *buf);
|
||||
unsigned long long Curl_read64_be(const unsigned char *buf);
|
||||
#else
|
||||
unsigned __int64 Curl_read64_be(unsigned char *buf);
|
||||
unsigned __int64 Curl_read64_be(const unsigned char *buf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -48,8 +48,8 @@
|
||||
* For libcurl static library release builds no overriding takes place.
|
||||
*/
|
||||
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
|
||||
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
{
|
||||
#ifndef HAVE_GETHOSTNAME
|
||||
|
||||
/* Allow compilation and return failure when unavailable */
|
||||
|
@ -33,7 +33,7 @@ static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
@ -114,7 +114,7 @@ static size_t display_gss_error(OM_uint32 status, int type,
|
||||
* major [in] - The major status code.
|
||||
* minor [in] - The minor status code.
|
||||
*/
|
||||
void Curl_gss_log_error(struct SessionHandle *data, const char *prefix,
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor)
|
||||
{
|
||||
char buf[GSS_LOG_BUFFER_LEN];
|
||||
|
@ -44,7 +44,7 @@ extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
/* Common method for using GSS-API */
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
@ -56,7 +56,7 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
OM_uint32 *ret_flags);
|
||||
|
||||
/* Helper to log a GSS-API error status */
|
||||
void Curl_gss_log_error(struct SessionHandle *data, const char *prefix,
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor);
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@ -76,6 +76,11 @@
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
# define MD4_DIGEST_LENGTH 16
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
# include <mbedtls/des.h>
|
||||
# include <mbedtls/md4.h>
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
# include <nss.h>
|
||||
@ -100,7 +105,7 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
@ -188,6 +193,26 @@ static void setup_des_key(const unsigned char *key_56,
|
||||
gcry_cipher_setkey(*des, key, sizeof(key));
|
||||
}
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
mbedtls_des_context ctx;
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
mbedtls_des_key_set_parity((unsigned char *) key);
|
||||
|
||||
/* Perform the encryption */
|
||||
mbedtls_des_init(&ctx);
|
||||
mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
|
||||
return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
|
||||
}
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
/*
|
||||
@ -400,8 +425,8 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
setup_des_key(keys + 14, &des);
|
||||
gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
||||
|| defined(USE_WIN32_CRYPTO)
|
||||
#elif defined(USE_MBEDTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
encrypt_des(plaintext, results + 16, keys + 14);
|
||||
@ -411,7 +436,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
/*
|
||||
* Set up lanmanager hashed password
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
@ -464,8 +489,8 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
setup_des_key(pw + 7, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
||||
|| defined(USE_WIN32_CRYPTO)
|
||||
#elif defined(USE_MBEDTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) \
|
||||
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
#endif
|
||||
@ -505,7 +530,7 @@ static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
* Set up nt hashed passwords
|
||||
* @unittest: 1600
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */)
|
||||
{
|
||||
@ -543,6 +568,8 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
gcry_md_write(MD4pw, pw, 2 * len);
|
||||
memcpy(ntbuffer, gcry_md_read(MD4pw, 0), MD4_DIGEST_LENGTH);
|
||||
gcry_md_close(MD4pw);
|
||||
#elif defined(USE_MBEDTLS)
|
||||
mbedtls_md4(pw, 2 * len, ntbuffer);
|
||||
#elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#elif defined(USE_DARWINSSL)
|
||||
@ -688,8 +715,10 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
|
||||
/* Create the BLOB structure */
|
||||
snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
|
||||
NTLMv2_BLOB_SIGNATURE
|
||||
"%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
|
||||
"%c%c%c%c", /* Reserved = 0 */
|
||||
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
|
||||
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
|
||||
0, 0, 0, 0);
|
||||
|
||||
Curl_write64_le(tw, ptr + 24);
|
||||
|
@ -64,12 +64,12 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "url.h"
|
||||
#include "strerror.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -156,7 +157,8 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
}
|
||||
slash = strpbrk(username, "\\/");
|
||||
if(slash) {
|
||||
if((domain = strdup(username)) == NULL)
|
||||
domain = strdup(username);
|
||||
if(!domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
slash = domain + (slash - username);
|
||||
*slash = '\0';
|
||||
@ -293,11 +295,10 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
buf[len_out - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf) {
|
||||
free(buf);
|
||||
newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
buf = newbuf;
|
||||
}
|
||||
|
||||
@ -349,7 +350,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
userp = conn->http_proxy.user;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
|
@ -42,8 +42,6 @@
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "strequal.h"
|
||||
#include "rawstr.h"
|
||||
#include "sendf.h"
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
/* The last 3 #include files should be in this order */
|
||||
@ -159,7 +157,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
sasl->prefmech = SASL_AUTH_NONE;
|
||||
}
|
||||
|
||||
if(strnequal(value, "*", len))
|
||||
if(!strncmp(value, "*", len))
|
||||
sasl->prefmech = SASL_AUTH_DEFAULT;
|
||||
else {
|
||||
mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
|
||||
@ -257,13 +255,16 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
bool force_ir, saslprogress *progress)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
unsigned int enabledmechs;
|
||||
const char *mech = NULL;
|
||||
char *resp = NULL;
|
||||
size_t len = 0;
|
||||
saslstate state1 = SASL_STOP;
|
||||
saslstate state2 = SASL_FINAL;
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
#if defined(USE_KERBEROS5)
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
@ -288,7 +289,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
}
|
||||
else if(conn->bits.user_passwd) {
|
||||
#if defined(USE_KERBEROS5)
|
||||
if(enabledmechs & SASL_MECH_GSSAPI) {
|
||||
if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
|
||||
Curl_auth_user_contains_domain(conn->user)) {
|
||||
sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
|
||||
mech = SASL_MECH_STRING_GSSAPI;
|
||||
state1 = SASL_GSSAPI;
|
||||
@ -308,7 +310,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(enabledmechs & SASL_MECH_DIGEST_MD5) {
|
||||
if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
Curl_auth_is_digest_supported()) {
|
||||
mech = SASL_MECH_STRING_DIGEST_MD5;
|
||||
state1 = SASL_DIGESTMD5;
|
||||
sasl->authused = SASL_MECH_DIGEST_MD5;
|
||||
@ -321,7 +324,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_NTLM
|
||||
if(enabledmechs & SASL_MECH_NTLM) {
|
||||
if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
|
||||
mech = SASL_MECH_STRING_NTLM;
|
||||
state1 = SASL_NTLM;
|
||||
state2 = SASL_NTLM_TYPE2MSG;
|
||||
@ -341,8 +344,8 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
|
||||
if(force_ir || data->set.sasl_ir)
|
||||
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
||||
conn->host.name,
|
||||
conn->port,
|
||||
hostname,
|
||||
port,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
}
|
||||
@ -405,9 +408,12 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
int code, saslprogress *progress)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
saslstate newstate = SASL_FINAL;
|
||||
char *resp = NULL;
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
char *serverdata;
|
||||
char *chlg = NULL;
|
||||
@ -542,8 +548,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
/* Create the authorisation message */
|
||||
if(sasl->authused == SASL_MECH_OAUTHBEARER) {
|
||||
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
||||
conn->host.name,
|
||||
conn->port,
|
||||
hostname,
|
||||
port,
|
||||
conn->oauth_bearer,
|
||||
&resp, &len);
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
|
||||
/* Authentication mechanism flags */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@ -82,6 +82,10 @@
|
||||
# include "config-linux.h"
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
# include "config-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__ && __MACH__
|
||||
# include "config-osx.h"
|
||||
#endif
|
||||
@ -229,6 +233,15 @@
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
|
||||
* interface doesn’t support IPv4, but supports IPv6, NAT64, and DNS64,
|
||||
* performing this task will result in a synthesized IPv6 address.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#define USE_RESOLVE_ON_IPS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include header files for windows builds before redefining anything.
|
||||
* Use this preprocessor block only to include or exclude windows.h,
|
||||
@ -598,10 +611,9 @@ int netware_init(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
|
||||
/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
|
||||
but we only work with libidn 0.4.1 or later) */
|
||||
#define USE_LIBIDN
|
||||
#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H)
|
||||
/* The lib and header are present */
|
||||
#define USE_LIBIDN2
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_TIME_T
|
||||
@ -637,6 +649,13 @@ int netware_init(void);
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#define USE_NTLM
|
||||
|
||||
#elif defined(USE_MBEDTLS)
|
||||
# include <mbedtls/md4.h>
|
||||
# if defined(MBEDTLS_MD4_C)
|
||||
#define USE_NTLM
|
||||
# endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -745,4 +764,14 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
# endif
|
||||
#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */
|
||||
|
||||
/* Detect Windows App environment which has a restricted access
|
||||
* to the Win32 APIs. */
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)
|
||||
# include <winapifamily.h>
|
||||
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
|
||||
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
# define CURL_WINDOWS_APP
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
@ -64,10 +64,15 @@ PSecurityFunctionTable s_pSecFn = NULL;
|
||||
*
|
||||
* Once this function has been executed, Windows SSPI functions can be
|
||||
* called through the Security Service Provider Interface dispatch table.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sspi_global_init(void)
|
||||
{
|
||||
bool securityDll = FALSE;
|
||||
INITSECURITYINTERFACE_FN pInitSecurityInterface;
|
||||
|
||||
/* If security interface is not yet initialized try to do this */
|
||||
@ -75,49 +80,9 @@ CURLcode Curl_sspi_global_init(void)
|
||||
/* Security Service Provider Interface (SSPI) functions are located in
|
||||
* security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
|
||||
* have both these DLLs (security.dll forwards calls to secur32.dll) */
|
||||
DWORD majorVersion = 4;
|
||||
DWORD platformId = VER_PLATFORM_WIN32_NT;
|
||||
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
|
||||
/* Find out Windows version */
|
||||
if(!GetVersionEx(&osver))
|
||||
return CURLE_FAILED_INIT;
|
||||
|
||||
/* Verify the major version number == 4 and platform id == WIN_NT */
|
||||
if(osver.dwMajorVersion == majorVersion &&
|
||||
osver.dwPlatformId == platformId)
|
||||
securityDll = TRUE;
|
||||
#else
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
osver.dwPlatformId = platformId;
|
||||
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
/* Verify the major version number == 4 and platform id == WIN_NT */
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
|
||||
VER_PLATFORMID),
|
||||
cm))
|
||||
securityDll = TRUE;
|
||||
#endif
|
||||
|
||||
/* Load SSPI dll into the address space of the calling process */
|
||||
if(securityDll)
|
||||
if(Curl_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL))
|
||||
s_hSecDll = Curl_load_library(TEXT("security.dll"));
|
||||
else
|
||||
s_hSecDll = Curl_load_library(TEXT("secur32.dll"));
|
||||
@ -143,8 +108,11 @@ CURLcode Curl_sspi_global_init(void)
|
||||
* Curl_sspi_global_cleanup()
|
||||
*
|
||||
* This deinitializes the Security Service Provider Interface from libcurl.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* None.
|
||||
*/
|
||||
|
||||
void Curl_sspi_global_cleanup(void)
|
||||
{
|
||||
if(s_hSecDll) {
|
||||
@ -246,6 +214,15 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sspi_free_identity()
|
||||
*
|
||||
* This is used to free the contents of a SSPI identifier structure.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* identity [in/out] - The identity structure.
|
||||
*/
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
{
|
||||
if(identity) {
|
||||
|
@ -100,6 +100,7 @@ int Curl_thread_join(curl_thread_t *hnd)
|
||||
|
||||
#elif defined(USE_THREADS_WIN32)
|
||||
|
||||
/* !checksrc! disable SPACEBEFOREPAREN 1 */
|
||||
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
|
||||
void *arg)
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -50,6 +50,7 @@
|
||||
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
|
||||
/* !checksrc! disable SPACEBEFOREPAREN 1 */
|
||||
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
|
||||
void *arg);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -34,8 +34,8 @@
|
||||
functions while they still are offered publicly. They will be made library-
|
||||
private one day */
|
||||
|
||||
#include "strequal.h"
|
||||
/* "strequal.h" provides the strequal protos */
|
||||
#include "strcase.h"
|
||||
/* "strcase.h" provides the strcasecompare protos */
|
||||
|
||||
#include "strtoofft.h"
|
||||
/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
|
||||
@ -67,15 +67,12 @@
|
||||
be removed from a future libcurl official API:
|
||||
curlx_getenv
|
||||
curlx_mprintf (and its variations)
|
||||
curlx_strequal
|
||||
curlx_strnequal
|
||||
curlx_strcasecompare
|
||||
curlx_strncasecompare
|
||||
|
||||
*/
|
||||
|
||||
#define curlx_getenv curl_getenv
|
||||
#define curlx_strequal curl_strequal
|
||||
#define curlx_strnequal curl_strnequal
|
||||
#define curlx_raw_equal Curl_raw_equal
|
||||
#define curlx_mvsnprintf curl_mvsnprintf
|
||||
#define curlx_msnprintf curl_msnprintf
|
||||
#define curlx_maprintf curl_maprintf
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -52,11 +52,10 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "escape.h"
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
#include "dict.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@ -91,17 +90,17 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
|
||||
};
|
||||
|
||||
static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
|
||||
static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
|
||||
{
|
||||
char *newp;
|
||||
char *dictp;
|
||||
char *ptr;
|
||||
int len;
|
||||
size_t len;
|
||||
char ch;
|
||||
int olen=0;
|
||||
|
||||
newp = curl_easy_unescape(data, inputbuff, 0, &len);
|
||||
if(!newp)
|
||||
CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
|
||||
if(!newp || result)
|
||||
return NULL;
|
||||
|
||||
dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
|
||||
@ -133,7 +132,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
char *nthdef = NULL; /* This is not part of the protocol, but required
|
||||
by RFC 2229 */
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
char *path = data->state.path;
|
||||
@ -145,9 +144,9 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
/* AUTH is missing */
|
||||
}
|
||||
|
||||
if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
|
||||
word = strchr(path, ':');
|
||||
if(word) {
|
||||
@ -203,9 +202,9 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
}
|
||||
else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
|
||||
else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
|
||||
|
||||
word = strchr(path, ':');
|
||||
if(word) {
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include "strequal.h"
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
@ -144,28 +143,6 @@ static CURLcode win32_init(void)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
/*
|
||||
* Initialise use of IDNA library.
|
||||
* It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
|
||||
* idna_to_ascii_lz().
|
||||
*/
|
||||
static void idna_init (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char buf[60];
|
||||
UINT cp = GetACP();
|
||||
|
||||
if(!getenv("CHARSET") && cp > 0) {
|
||||
snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
|
||||
putenv(buf);
|
||||
}
|
||||
#else
|
||||
/* to do? */
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_LIBIDN */
|
||||
|
||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||
static unsigned int initialized;
|
||||
static long init_flags;
|
||||
@ -217,7 +194,7 @@ curl_calloc_callback Curl_ccalloc;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* curl_global_init() globally initializes curl given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
@ -262,15 +239,13 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
idna_init();
|
||||
#endif
|
||||
|
||||
if(Curl_resolver_global_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
(void)Curl_ipv6works();
|
||||
|
||||
#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
|
||||
if(libssh2_init(0)) {
|
||||
DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
|
||||
@ -290,7 +265,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
|
||||
|
||||
/**
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* curl_global_init() globally initializes curl given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
CURLcode curl_global_init(long flags)
|
||||
@ -299,7 +274,7 @@ CURLcode curl_global_init(long flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_global_init_mem() globally initializes cURL and also registers the
|
||||
* curl_global_init_mem() globally initializes curl and also registers the
|
||||
* user provided callback routines.
|
||||
*/
|
||||
CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
@ -331,7 +306,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
}
|
||||
|
||||
/**
|
||||
* curl_global_cleanup() globally cleanups cURL, uses the value of
|
||||
* curl_global_cleanup() globally cleanups curl, uses the value of
|
||||
* "init_flags" to determine what needs to be cleaned up and what doesn't.
|
||||
*/
|
||||
void curl_global_cleanup(void)
|
||||
@ -365,10 +340,10 @@ void curl_global_cleanup(void)
|
||||
* curl_easy_init() is the external interface to alloc, setup and init an
|
||||
* easy handle that is returned. If anything goes wrong, NULL is returned.
|
||||
*/
|
||||
CURL *curl_easy_init(void)
|
||||
struct Curl_easy *curl_easy_init(void)
|
||||
{
|
||||
CURLcode result;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
|
||||
/* Make sure we inited the global SSL stuff */
|
||||
if(!initialized) {
|
||||
@ -396,13 +371,12 @@ CURL *curl_easy_init(void)
|
||||
*/
|
||||
|
||||
#undef curl_easy_setopt
|
||||
CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
|
||||
{
|
||||
va_list arg;
|
||||
struct SessionHandle *data = curl;
|
||||
CURLcode result;
|
||||
|
||||
if(!curl)
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
va_start(arg, tag);
|
||||
@ -434,7 +408,7 @@ struct events {
|
||||
* updated.
|
||||
*/
|
||||
|
||||
static int events_timer(CURLM *multi, /* multi handle */
|
||||
static int events_timer(struct Curl_multi *multi, /* multi handle */
|
||||
long timeout_ms, /* see above */
|
||||
void *userp) /* private callback pointer */
|
||||
{
|
||||
@ -489,7 +463,7 @@ static short socketcb2poll(int pollmask)
|
||||
* Callback that gets called with information about socket activity to
|
||||
* monitor.
|
||||
*/
|
||||
static int events_socket(CURL *easy, /* easy handle */
|
||||
static int events_socket(struct Curl_easy *easy, /* easy handle */
|
||||
curl_socket_t s, /* socket */
|
||||
int what, /* see above */
|
||||
void *userp, /* private callback
|
||||
@ -567,7 +541,7 @@ static int events_socket(CURL *easy, /* easy handle */
|
||||
*
|
||||
* Do the multi handle setups that only event-based transfers need.
|
||||
*/
|
||||
static void events_setup(CURLM *multi, struct events *ev)
|
||||
static void events_setup(struct Curl_multi *multi, struct events *ev)
|
||||
{
|
||||
/* timer callback */
|
||||
curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
|
||||
@ -671,7 +645,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
*
|
||||
* Runs a transfer in a blocking manner using the events-based API
|
||||
*/
|
||||
static CURLcode easy_events(CURLM *multi)
|
||||
static CURLcode easy_events(struct Curl_multi *multi)
|
||||
{
|
||||
struct events evs= {2, FALSE, 0, NULL, 0};
|
||||
|
||||
@ -685,7 +659,7 @@ static CURLcode easy_events(CURLM *multi)
|
||||
#define easy_events(x) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
|
||||
static CURLcode easy_transfer(CURLM *multi)
|
||||
static CURLcode easy_transfer(struct Curl_multi *multi)
|
||||
{
|
||||
bool done = FALSE;
|
||||
CURLMcode mcode = CURLM_OK;
|
||||
@ -765,9 +739,9 @@ static CURLcode easy_transfer(CURLM *multi)
|
||||
* DEBUG: if 'events' is set TRUE, this function will use a replacement engine
|
||||
* instead of curl_multi_perform() and use curl_multi_socket_action().
|
||||
*/
|
||||
static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
static CURLcode easy_perform(struct Curl_easy *data, bool events)
|
||||
{
|
||||
CURLM *multi;
|
||||
struct Curl_multi *multi;
|
||||
CURLMcode mcode;
|
||||
CURLcode result = CURLE_OK;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
@ -827,9 +801,9 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
* curl_easy_perform() is the external interface that performs a blocking
|
||||
* transfer as previously setup.
|
||||
*/
|
||||
CURLcode curl_easy_perform(CURL *easy)
|
||||
CURLcode curl_easy_perform(struct Curl_easy *data)
|
||||
{
|
||||
return easy_perform(easy, FALSE);
|
||||
return easy_perform(data, FALSE);
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
@ -837,9 +811,9 @@ CURLcode curl_easy_perform(CURL *easy)
|
||||
* curl_easy_perform_ev() is the external interface that performs a blocking
|
||||
* transfer using the event-based API internally.
|
||||
*/
|
||||
CURLcode curl_easy_perform_ev(CURL *easy)
|
||||
CURLcode curl_easy_perform_ev(struct Curl_easy *data)
|
||||
{
|
||||
return easy_perform(easy, TRUE);
|
||||
return easy_perform(data, TRUE);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -848,9 +822,8 @@ CURLcode curl_easy_perform_ev(CURL *easy)
|
||||
* curl_easy_cleanup() is the external interface to cleaning/freeing the given
|
||||
* easy handle.
|
||||
*/
|
||||
void curl_easy_cleanup(CURL *curl)
|
||||
void curl_easy_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(!data)
|
||||
@ -866,12 +839,11 @@ void curl_easy_cleanup(CURL *curl)
|
||||
* information from a performed transfer and similar.
|
||||
*/
|
||||
#undef curl_easy_getinfo
|
||||
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
void *paramp;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
va_start(arg, info);
|
||||
paramp = va_arg(arg, void *);
|
||||
@ -887,11 +859,9 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
* given input easy handle. The returned handle will be a new working handle
|
||||
* with all options set exactly as the input source handle.
|
||||
*/
|
||||
CURL *curl_easy_duphandle(CURL *incurl)
|
||||
struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *data=(struct SessionHandle *)incurl;
|
||||
|
||||
struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
|
||||
struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
|
||||
if(NULL == outcurl)
|
||||
goto fail;
|
||||
|
||||
@ -900,6 +870,11 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
* get setup on-demand in the code, as that would probably decrease
|
||||
* the likeliness of us forgetting to init a buffer here in the future.
|
||||
*/
|
||||
outcurl->set.buffer_size = data->set.buffer_size;
|
||||
outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
|
||||
if(!outcurl->state.buffer)
|
||||
goto fail;
|
||||
|
||||
outcurl->state.headerbuff = malloc(HEADERSIZE);
|
||||
if(!outcurl->state.headerbuff)
|
||||
goto fail;
|
||||
@ -957,6 +932,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
|
||||
Curl_convert_setup(outcurl);
|
||||
|
||||
Curl_initinfo(outcurl);
|
||||
|
||||
outcurl->magic = CURLEASY_MAGIC_NUMBER;
|
||||
|
||||
/* we reach this point and thus we are OK */
|
||||
@ -968,6 +945,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
if(outcurl) {
|
||||
curl_slist_free_all(outcurl->change.cookielist);
|
||||
outcurl->change.cookielist = NULL;
|
||||
Curl_safefree(outcurl->state.buffer);
|
||||
Curl_safefree(outcurl->state.headerbuff);
|
||||
Curl_safefree(outcurl->change.url);
|
||||
Curl_safefree(outcurl->change.referer);
|
||||
@ -982,10 +960,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
* curl_easy_reset() is an external interface that allows an app to re-
|
||||
* initialize a session handle to the default values.
|
||||
*/
|
||||
void curl_easy_reset(CURL *curl)
|
||||
void curl_easy_reset(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
|
||||
data->state.path = NULL;
|
||||
@ -1000,6 +976,9 @@ void curl_easy_reset(CURL *curl)
|
||||
/* zero out Progress data: */
|
||||
memset(&data->progress, 0, sizeof(struct Progress));
|
||||
|
||||
/* zero out PureInfo data: */
|
||||
Curl_initinfo(data);
|
||||
|
||||
data->progress.flags |= PGRS_HIDE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
}
|
||||
@ -1014,9 +993,8 @@ void curl_easy_reset(CURL *curl)
|
||||
*
|
||||
* Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
|
||||
*/
|
||||
CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@ -1050,13 +1028,13 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
if(!result &&
|
||||
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
||||
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
|
||||
Curl_expire(data, 1); /* get this handle going again */
|
||||
Curl_expire(data, 0); /* get this handle going again */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode easy_connection(struct SessionHandle *data,
|
||||
static CURLcode easy_connection(struct Curl_easy *data,
|
||||
curl_socket_t *sfd,
|
||||
struct connectdata **connp)
|
||||
{
|
||||
@ -1084,13 +1062,13 @@ static CURLcode easy_connection(struct SessionHandle *data,
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
* Returns CURLE_OK on success, error code on error.
|
||||
*/
|
||||
CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
|
||||
CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
|
||||
size_t *n)
|
||||
{
|
||||
curl_socket_t sfd;
|
||||
CURLcode result;
|
||||
ssize_t n1;
|
||||
struct connectdata *c;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
result = easy_connection(data, &sfd, &c);
|
||||
if(result)
|
||||
@ -1111,14 +1089,13 @@ CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
|
||||
* Sends data over the connected socket. Use after successful
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
*/
|
||||
CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
|
||||
size_t *n)
|
||||
CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
|
||||
size_t buflen, size_t *n)
|
||||
{
|
||||
curl_socket_t sfd;
|
||||
CURLcode result;
|
||||
ssize_t n1;
|
||||
struct connectdata *c = NULL;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
result = easy_connection(data, &sfd, &c);
|
||||
if(result)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,7 +26,7 @@
|
||||
* Prototypes for library-wide functions provided by easy.c
|
||||
*/
|
||||
#ifdef CURLDEBUG
|
||||
CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy);
|
||||
CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_EASYIF_H */
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "escape.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -75,17 +76,24 @@ char *curl_unescape(const char *string, int length)
|
||||
return curl_easy_unescape(NULL, string, length, NULL);
|
||||
}
|
||||
|
||||
char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
int inlength)
|
||||
{
|
||||
size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
|
||||
size_t alloc;
|
||||
char *ns;
|
||||
char *testing_ptr = NULL;
|
||||
unsigned char in; /* we need to treat the characters unsigned */
|
||||
size_t newlen = alloc;
|
||||
size_t newlen;
|
||||
size_t strindex=0;
|
||||
size_t length;
|
||||
CURLcode result;
|
||||
|
||||
if(inlength < 0)
|
||||
return NULL;
|
||||
|
||||
alloc = (inlength?(size_t)inlength:strlen(string))+1;
|
||||
newlen = alloc;
|
||||
|
||||
ns = malloc(alloc);
|
||||
if(!ns)
|
||||
return NULL;
|
||||
@ -102,17 +110,15 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
newlen += 2; /* the size grows with two, since this'll become a %XX */
|
||||
if(newlen > alloc) {
|
||||
alloc *= 2;
|
||||
testing_ptr = realloc(ns, alloc);
|
||||
if(!testing_ptr) {
|
||||
free(ns);
|
||||
testing_ptr = Curl_saferealloc(ns, alloc);
|
||||
if(!testing_ptr)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
ns = testing_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
result = Curl_convert_to_network(handle, &in, 1);
|
||||
result = Curl_convert_to_network(data, &in, 1);
|
||||
if(result) {
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
@ -139,7 +145,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
* *olen. If length == 0, the length is assumed to be strlen(string).
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_urldecode(struct SessionHandle *data,
|
||||
CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
const char *string, size_t length,
|
||||
char **ostring, size_t *olen,
|
||||
bool reject_ctrl)
|
||||
@ -206,18 +212,26 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
|
||||
* If length == 0, the length is assumed to be strlen(string).
|
||||
* If olen == NULL, no output length is stored.
|
||||
*/
|
||||
char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||
int *olen)
|
||||
char *curl_easy_unescape(struct Curl_easy *data, const char *string,
|
||||
int length, int *olen)
|
||||
{
|
||||
char *str = NULL;
|
||||
if(length >= 0) {
|
||||
size_t inputlen = length;
|
||||
size_t outputlen;
|
||||
CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
|
||||
CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
|
||||
FALSE);
|
||||
if(res)
|
||||
return NULL;
|
||||
if(olen)
|
||||
|
||||
if(olen) {
|
||||
if(outputlen <= (size_t) INT_MAX)
|
||||
*olen = curlx_uztosi(outputlen);
|
||||
else
|
||||
/* too large to return in an int, fail! */
|
||||
Curl_safefree(str);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
/* Escape and unescape URL encoding in strings. The functions return a new
|
||||
* allocated string or NULL if an error occurred. */
|
||||
|
||||
CURLcode Curl_urldecode(struct SessionHandle *data,
|
||||
CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
const char *string, size_t length,
|
||||
char **ostring, size_t *olen,
|
||||
bool reject_crlf);
|
||||
|
@ -135,7 +135,7 @@ static CURLcode file_range(struct connectdata *conn)
|
||||
curl_off_t totalsize=-1;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(data->state.use_range && data->state.range) {
|
||||
from=curlx_strtoofft(data->state.range, &ptr, 0);
|
||||
@ -185,19 +185,20 @@ static CURLcode file_range(struct connectdata *conn)
|
||||
*/
|
||||
static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *real_path;
|
||||
struct FILEPROTO *file = data->req.protop;
|
||||
int fd;
|
||||
#ifdef DOS_FILESYSTEM
|
||||
int i;
|
||||
size_t i;
|
||||
char *actual_path;
|
||||
#endif
|
||||
int real_path_len;
|
||||
size_t real_path_len;
|
||||
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path,
|
||||
&real_path_len, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#ifdef DOS_FILESYSTEM
|
||||
/* If the first character is a slash, and there's
|
||||
@ -227,15 +228,19 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
for(i=0; i < real_path_len; ++i)
|
||||
if(actual_path[i] == '/')
|
||||
actual_path[i] = '\\';
|
||||
else if(!actual_path[i]) /* binary zero */
|
||||
else if(!actual_path[i]) { /* binary zero */
|
||||
Curl_safefree(real_path);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
if(memchr(real_path, 0, real_path_len))
|
||||
if(memchr(real_path, 0, real_path_len)) {
|
||||
/* binary zeroes indicate foul play */
|
||||
Curl_safefree(real_path);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
fd = open_readonly(real_path, O_RDONLY);
|
||||
file->path = real_path;
|
||||
@ -301,7 +306,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
int fd;
|
||||
int mode;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
size_t nread;
|
||||
size_t nwrite;
|
||||
@ -428,7 +433,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
bool size_known;
|
||||
bool fstated=FALSE;
|
||||
ssize_t nread;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
curl_off_t bytecount = 0;
|
||||
int fd;
|
||||
@ -471,7 +476,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
time_t filetime;
|
||||
struct tm buffer;
|
||||
const struct tm *tm = &buffer;
|
||||
snprintf(buf, sizeof(data->state.buffer),
|
||||
snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||||
if(result)
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -30,12 +30,13 @@
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h" /* for struct SessionHandle */
|
||||
#include "urldata.h" /* for struct Curl_easy */
|
||||
#include "formdata.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
#include "rand.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -47,7 +48,7 @@ static char *Curl_basename(char *path);
|
||||
#endif
|
||||
|
||||
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
|
||||
static char *formboundary(struct SessionHandle *data);
|
||||
static char *formboundary(struct Curl_easy *data);
|
||||
|
||||
/* What kind of Content-Type to use on un-specified files with unrecognized
|
||||
extensions. */
|
||||
@ -201,7 +202,7 @@ static const char *ContentTypeForFilename(const char *filename,
|
||||
if(filename) { /* in case a NULL was passed in */
|
||||
for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
|
||||
if(strlen(filename) >= strlen(ctts[i].extension)) {
|
||||
if(strequal(filename +
|
||||
if(strcasecompare(filename +
|
||||
strlen(filename) - strlen(ctts[i].extension),
|
||||
ctts[i].extension)) {
|
||||
contenttype = ctts[i].type;
|
||||
@ -845,7 +846,7 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(type != FORM_DATAMEM) {
|
||||
newform->line = malloc((size_t)length+1);
|
||||
if(!newform->line) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@ -853,8 +854,15 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
}
|
||||
alloc2 = newform->line;
|
||||
memcpy(newform->line, line, (size_t)length);
|
||||
|
||||
/* zero terminate for easier debugging */
|
||||
newform->line[(size_t)length]=0;
|
||||
}
|
||||
else {
|
||||
newform->line = (char *)line;
|
||||
type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
|
||||
}
|
||||
newform->length = (size_t)length;
|
||||
newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
|
||||
}
|
||||
else
|
||||
/* For callbacks and files we don't have any actual data so we just keep a
|
||||
@ -863,13 +871,6 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
|
||||
newform->type = type;
|
||||
|
||||
if(*formp) {
|
||||
(*formp)->next = newform;
|
||||
*formp = newform;
|
||||
}
|
||||
else
|
||||
*formp = newform;
|
||||
|
||||
if(size) {
|
||||
if(type != FORM_FILE)
|
||||
/* for static content as well as callback data we add the size given
|
||||
@ -878,7 +879,7 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
else {
|
||||
/* Since this is a file to be uploaded here, add the size of the actual
|
||||
file */
|
||||
if(!strequal("-", newform->line)) {
|
||||
if(strcmp("-", newform->line)) {
|
||||
struct_stat file;
|
||||
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
|
||||
*size += filesize(newform->line, file);
|
||||
@ -889,6 +890,14 @@ static CURLcode AddFormData(struct FormData **formp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*formp) {
|
||||
(*formp)->next = newform;
|
||||
*formp = newform;
|
||||
}
|
||||
else
|
||||
*formp = newform;
|
||||
|
||||
return CURLE_OK;
|
||||
error:
|
||||
if(newform)
|
||||
@ -906,13 +915,21 @@ static CURLcode AddFormDataf(struct FormData **formp,
|
||||
curl_off_t *size,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
char s[4096];
|
||||
char *s;
|
||||
CURLcode result;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(s, sizeof(s), fmt, ap);
|
||||
s = curl_mvaprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return AddFormData(formp, FORM_DATA, s, 0, size);
|
||||
if(!s)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
result = AddFormData(formp, FORM_DATAMEM, s, 0, size);
|
||||
if(result)
|
||||
free(s);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -932,8 +949,8 @@ void Curl_formclean(struct FormData **form_ptr)
|
||||
if(form->type <= FORM_CONTENT)
|
||||
free(form->line); /* free the line */
|
||||
free(form); /* free the struct */
|
||||
|
||||
} while((form = next) != NULL); /* continue */
|
||||
form = next;
|
||||
} while(form); /* continue */
|
||||
|
||||
*form_ptr = NULL;
|
||||
}
|
||||
@ -1014,8 +1031,8 @@ void curl_formfree(struct curl_httppost *form)
|
||||
free(form->contenttype); /* free the content type */
|
||||
free(form->showfilename); /* free the faked file name */
|
||||
free(form); /* free the struct */
|
||||
|
||||
} while((form = next) != NULL); /* continue */
|
||||
form = next;
|
||||
} while(form); /* continue */
|
||||
}
|
||||
|
||||
#ifndef HAVE_BASENAME
|
||||
@ -1136,7 +1153,7 @@ static CURLcode formdata_add_filename(const struct curl_httppost *file,
|
||||
* a NULL pointer in the 'data' argument.
|
||||
*/
|
||||
|
||||
CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
struct FormData **finalform,
|
||||
struct curl_httppost *post,
|
||||
const char *custom_content_type,
|
||||
@ -1289,7 +1306,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
/* we should include the contents from the specified file */
|
||||
FILE *fileread;
|
||||
|
||||
fileread = strequal("-", file->contents)?
|
||||
fileread = !strcmp("-", file->contents)?
|
||||
stdin:fopen(file->contents, "rb"); /* binary read for win32 */
|
||||
|
||||
/*
|
||||
@ -1315,7 +1332,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
char buffer[512];
|
||||
while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) {
|
||||
result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size);
|
||||
if(result)
|
||||
if(result || feof(fileread) || ferror(fileread))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1357,8 +1374,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
|
||||
} while((post = post->next) != NULL); /* for each field */
|
||||
post = post->next;
|
||||
} while(post); /* for each field */
|
||||
|
||||
/* end-boundary for everything */
|
||||
if(!result)
|
||||
@ -1410,7 +1427,8 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata)
|
||||
*
|
||||
*/
|
||||
# define fopen_read vmsfopenread
|
||||
static FILE * vmsfopenread(const char *file, const char *mode) {
|
||||
static FILE * vmsfopenread(const char *file, const char *mode)
|
||||
{
|
||||
struct_stat statbuf;
|
||||
int result;
|
||||
|
||||
@ -1535,7 +1553,7 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
||||
struct Form *form=(struct Form *)formp;
|
||||
|
||||
if(!form->data)
|
||||
return 0; /* nothing, ERROR! */
|
||||
return NULL; /* nothing, ERROR! */
|
||||
|
||||
header = form->data->line;
|
||||
*len = form->data->length;
|
||||
@ -1549,12 +1567,16 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
||||
* formboundary() creates a suitable boundary string and returns an allocated
|
||||
* one.
|
||||
*/
|
||||
static char *formboundary(struct SessionHandle *data)
|
||||
static char *formboundary(struct Curl_easy *data)
|
||||
{
|
||||
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
|
||||
combinations */
|
||||
return aprintf("------------------------%08x%08x",
|
||||
Curl_rand(data), Curl_rand(data));
|
||||
unsigned int rnd[2];
|
||||
CURLcode result = Curl_rand(data, &rnd[0], 2);
|
||||
if(result)
|
||||
return NULL;
|
||||
|
||||
return aprintf("------------------------%08x%08x", rnd[0], rnd[1]);
|
||||
}
|
||||
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
|
@ -23,6 +23,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
enum formtype {
|
||||
FORM_DATAMEM, /* already allocated FORM_DATA memory */
|
||||
FORM_DATA, /* form metadata (convert to network encoding if necessary) */
|
||||
FORM_CONTENT, /* form content (never convert) */
|
||||
FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback
|
||||
@ -70,7 +71,7 @@ typedef struct FormInfo {
|
||||
|
||||
int Curl_FormInit(struct Form *form, struct FormData *formdata);
|
||||
|
||||
CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
struct FormData **,
|
||||
struct curl_httppost *post,
|
||||
const char *custom_contenttype,
|
||||
@ -93,6 +94,6 @@ char *Curl_FormBoundary(void);
|
||||
|
||||
void Curl_formclean(struct FormData **);
|
||||
|
||||
CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *);
|
||||
CURLcode Curl_formconvert(struct Curl_easy *, struct FormData *);
|
||||
|
||||
#endif /* HEADER_CURL_FORMDATA_H */
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_sec.h"
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
@ -72,7 +72,7 @@
|
||||
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "speedcheck.h"
|
||||
#include "warnless.h"
|
||||
#include "http_proxy.h"
|
||||
@ -327,7 +327,7 @@ static bool isBadFtpString(const char *string)
|
||||
*/
|
||||
static CURLcode AcceptServerConnect(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t sock = conn->sock[SECONDARYSOCKET];
|
||||
curl_socket_t s = CURL_SOCKET_BAD;
|
||||
#ifdef ENABLE_IPV6
|
||||
@ -384,10 +384,10 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
|
||||
* Curl_pgrsTime(..., TIMER_STARTACCEPT);
|
||||
*
|
||||
*/
|
||||
static long ftp_timeleft_accept(struct SessionHandle *data)
|
||||
static time_t ftp_timeleft_accept(struct Curl_easy *data)
|
||||
{
|
||||
long timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
|
||||
long other;
|
||||
time_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
|
||||
time_t other;
|
||||
struct timeval now;
|
||||
|
||||
if(data->set.accepttimeout > 0)
|
||||
@ -424,13 +424,13 @@ static long ftp_timeleft_accept(struct SessionHandle *data)
|
||||
*/
|
||||
static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
|
||||
curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
struct pingpong *pp = &ftpc->pp;
|
||||
int result;
|
||||
long timeout_ms;
|
||||
time_t timeout_ms;
|
||||
ssize_t nread;
|
||||
int ftpcode;
|
||||
|
||||
@ -475,7 +475,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
if(ftpcode/100 > 3)
|
||||
return CURLE_FTP_ACCEPT_FAILED;
|
||||
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -495,11 +495,11 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
|
||||
*/
|
||||
static CURLcode InitiateTransfer(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
if(conn->bits.ftp_use_data_ssl) {
|
||||
/* since we only have a plaintext TCP connection here, we must now
|
||||
* do the TLS stuff */
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
@ -546,8 +546,8 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
|
||||
*/
|
||||
static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout_ms;
|
||||
struct Curl_easy *data = conn->data;
|
||||
time_t timeout_ms;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*connected = FALSE;
|
||||
@ -617,7 +617,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
size_t *size) /* size of the response */
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
#ifdef HAVE_GSSAPI
|
||||
char * const buf = data->state.buffer;
|
||||
#endif
|
||||
@ -687,9 +687,9 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
* line in a response or continue reading. */
|
||||
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
long timeout; /* timeout in milliseconds */
|
||||
long interval_ms;
|
||||
struct SessionHandle *data = conn->data;
|
||||
time_t timeout; /* timeout in milliseconds */
|
||||
time_t interval_ms;
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
struct pingpong *pp = &ftpc->pp;
|
||||
@ -740,8 +740,8 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
* wait for more data anyway.
|
||||
*/
|
||||
}
|
||||
else {
|
||||
switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
|
||||
else if(!Curl_conn_data_pending(conn, FIRSTSOCKET)) {
|
||||
switch(SOCKET_READABLE(sockfd, interval_ms)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
failf(data, "FTP response aborted due to select/poll error: %d",
|
||||
SOCKERRNO);
|
||||
@ -911,7 +911,7 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||
}
|
||||
else {
|
||||
socks[1] = conn->sock[SECONDARYSOCKET];
|
||||
bits |= GETSOCK_WRITESOCK(1);
|
||||
bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
|
||||
}
|
||||
|
||||
return bits;
|
||||
@ -980,7 +980,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
curl_socket_t portsock= CURL_SOCKET_BAD;
|
||||
char myhost[256] = "";
|
||||
|
||||
@ -1035,7 +1035,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(*string_ftpport == '[') {
|
||||
/* [ipv6]:port(-range) */
|
||||
ip_start = string_ftpport + 1;
|
||||
if((ip_end = strchr(string_ftpport, ']')) != NULL)
|
||||
ip_end = strchr(string_ftpport, ']');
|
||||
if(ip_end)
|
||||
strncpy(addr, ip_start, ip_end - ip_start);
|
||||
}
|
||||
else
|
||||
@ -1044,7 +1045,9 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
/* :port */
|
||||
ip_end = string_ftpport;
|
||||
}
|
||||
else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
|
||||
else {
|
||||
ip_end = strchr(string_ftpport, ':');
|
||||
if(ip_end) {
|
||||
/* either ipv6 or (ipv4|domain|interface):port(-range) */
|
||||
#ifdef ENABLE_IPV6
|
||||
if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
|
||||
@ -1061,12 +1064,15 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
else
|
||||
/* ipv4|interface */
|
||||
strcpy(addr, string_ftpport);
|
||||
}
|
||||
|
||||
/* parse the port */
|
||||
if(ip_end != NULL) {
|
||||
if((port_start = strchr(ip_end, ':')) != NULL) {
|
||||
port_start = strchr(ip_end, ':');
|
||||
if(port_start) {
|
||||
port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
|
||||
if((port_sep = strchr(port_start, '-')) != NULL) {
|
||||
port_sep = strchr(port_start, '-');
|
||||
if(port_sep) {
|
||||
port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
|
||||
}
|
||||
else
|
||||
@ -1403,7 +1409,7 @@ static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct FTP *ftp = conn->data->req.protop;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(ftp->transfer != FTPTRANSFER_BODY) {
|
||||
/* doesn't transfer any data */
|
||||
@ -1486,7 +1492,7 @@ static CURLcode ftp_state_size(struct connectdata *conn)
|
||||
static CURLcode ftp_state_list(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* If this output is to be machine-parsed, the NLST command might be better
|
||||
to use, since the LIST command output is not specified or standard in any
|
||||
@ -1575,7 +1581,7 @@ static CURLcode ftp_state_type(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct FTP *ftp = conn->data->req.protop;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
||||
@ -1607,7 +1613,7 @@ static CURLcode ftp_state_type(struct connectdata *conn)
|
||||
static CURLcode ftp_state_mdtm(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
/* Requested time of file or time-depended transfer? */
|
||||
@ -1632,7 +1638,7 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct FTP *ftp = conn->data->req.protop;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
int seekerr = CURL_SEEKFUNC_OK;
|
||||
|
||||
@ -1728,7 +1734,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
|
||||
ftpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
bool quote=FALSE;
|
||||
@ -1835,7 +1841,7 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
if(conn->bits.ipv6) {
|
||||
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
|
||||
failf(conn->data, "Failed EPSV attempt, exiting\n");
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
|
||||
@ -1850,84 +1856,6 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the necessary magic that needs to be done once the TCP connection
|
||||
* to the proxy has completed.
|
||||
*/
|
||||
static CURLcode proxy_magic(struct connectdata *conn,
|
||||
char *newhost, unsigned short newport,
|
||||
bool *magicdone)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if defined(CURL_DISABLE_PROXY)
|
||||
(void) newhost;
|
||||
(void) newport;
|
||||
#endif
|
||||
|
||||
*magicdone = FALSE;
|
||||
|
||||
switch(conn->proxytype) {
|
||||
case CURLPROXY_SOCKS5:
|
||||
case CURLPROXY_SOCKS5_HOSTNAME:
|
||||
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
|
||||
newport, SECONDARYSOCKET, conn);
|
||||
*magicdone = TRUE;
|
||||
break;
|
||||
case CURLPROXY_SOCKS4:
|
||||
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
||||
SECONDARYSOCKET, conn, FALSE);
|
||||
*magicdone = TRUE;
|
||||
break;
|
||||
case CURLPROXY_SOCKS4A:
|
||||
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
||||
SECONDARYSOCKET, conn, TRUE);
|
||||
*magicdone = TRUE;
|
||||
break;
|
||||
case CURLPROXY_HTTP:
|
||||
case CURLPROXY_HTTP_1_0:
|
||||
/* do nothing here. handled later. */
|
||||
break;
|
||||
default:
|
||||
failf(data, "unknown proxytype option given");
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
break;
|
||||
}
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
/* BLOCKING */
|
||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||
|
||||
/* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
|
||||
* member conn->proto.http; we want FTP through HTTP and we have to
|
||||
* change the member temporarily for connecting to the HTTP proxy. After
|
||||
* Curl_proxyCONNECT we have to set back the member to the original
|
||||
* struct FTP pointer
|
||||
*/
|
||||
struct HTTP http_proxy;
|
||||
struct FTP *ftp_save = data->req.protop;
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
data->req.protop = &http_proxy;
|
||||
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
|
||||
|
||||
data->req.protop = ftp_save;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
|
||||
/* the CONNECT procedure is not complete, the tunnel is not yet up */
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
return result;
|
||||
}
|
||||
else
|
||||
*magicdone = TRUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *control_address(struct connectdata *conn)
|
||||
{
|
||||
@ -1935,11 +1863,7 @@ static char *control_address(struct connectdata *conn)
|
||||
If a proxy tunnel is used, returns the original host name instead, because
|
||||
the effective control connection address is the proxy address,
|
||||
not the ftp host. */
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
|
||||
return conn->host.name;
|
||||
|
||||
return conn->ip_addr_str;
|
||||
@ -1950,7 +1874,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
{
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
struct Curl_dns_entry *addr=NULL;
|
||||
int rc;
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
@ -2063,7 +1987,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
* here. We don't want to rely on a former host lookup that might've
|
||||
* expired now, instead we remake the lookup here and now!
|
||||
*/
|
||||
rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
|
||||
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);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
||||
case of failure */
|
||||
@ -2073,9 +1999,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||
|
||||
if(!addr) {
|
||||
failf(data, "Can't resolve proxy host %s:%hu",
|
||||
conn->proxy.name, connectport);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -2115,6 +2040,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
|
||||
|
||||
Curl_safefree(conn->secondaryhostname);
|
||||
conn->secondaryhostname = strdup(ftpc->newhost);
|
||||
conn->secondary_port = ftpc->newport;
|
||||
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
conn->bits.do_more = TRUE;
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
@ -2125,7 +2054,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
static CURLcode ftp_state_port_resp(struct connectdata *conn,
|
||||
int ftpcode)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
ftpport fcmd = (ftpport)ftpc->count1;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -2162,7 +2091,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
int ftpcode)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
@ -2178,7 +2107,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
/* we have a time, reformat it */
|
||||
time_t secs=time(NULL);
|
||||
/* using the good old yacc/bison yuck */
|
||||
snprintf(buf, sizeof(conn->data->state.buffer),
|
||||
snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
|
||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||
year, month, day, hour, minute, second);
|
||||
/* now, convert this into a time() value: */
|
||||
@ -2267,7 +2196,7 @@ static CURLcode ftp_state_type_resp(struct connectdata *conn,
|
||||
ftpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
|
||||
if(ftpcode/100 != 2) {
|
||||
/* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
|
||||
@ -2296,7 +2225,7 @@ static CURLcode ftp_state_retr(struct connectdata *conn,
|
||||
curl_off_t filesize)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
@ -2379,7 +2308,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||||
ftpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
curl_off_t filesize;
|
||||
char *buf = data->state.buffer;
|
||||
|
||||
@ -2389,7 +2318,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||||
if(instate == FTP_SIZE) {
|
||||
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||||
if(-1 != filesize) {
|
||||
snprintf(buf, sizeof(data->state.buffer),
|
||||
snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||||
if(result)
|
||||
@ -2451,7 +2380,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
||||
int ftpcode, ftpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(ftpcode>=400) {
|
||||
failf(data, "Failed FTP upload: %0d", ftpcode);
|
||||
@ -2490,7 +2419,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||||
ftpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
char *buf = data->state.buffer;
|
||||
|
||||
@ -2647,7 +2576,7 @@ static CURLcode ftp_state_user_resp(struct connectdata *conn,
|
||||
ftpstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
(void)instate; /* no use for this yet */
|
||||
@ -2702,7 +2631,7 @@ static CURLcode ftp_state_acct_resp(struct connectdata *conn,
|
||||
int ftpcode)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
if(ftpcode != 230) {
|
||||
failf(data, "ACCT rejected by server: %03d", ftpcode);
|
||||
result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
|
||||
@ -2718,7 +2647,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
int ftpcode;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
struct pingpong *pp = &ftpc->pp;
|
||||
@ -2742,7 +2671,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
else if(ftpcode != 220) {
|
||||
failf(data, "Got a %03d ftp-server response when 220 was expected",
|
||||
ftpcode);
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* We have received a 220 response fine, now we proceed. */
|
||||
@ -2763,7 +2692,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
if(data->set.use_ssl &&
|
||||
(!conn->ssl[FIRSTSOCKET].use ||
|
||||
(conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
|
||||
!conn->proxy_ssl[FIRSTSOCKET].use))) {
|
||||
/* We don't have a SSL/TLS connection yet, but FTPS is
|
||||
requested. Try a FTPS connection now */
|
||||
|
||||
@ -2808,7 +2740,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
/* Curl_ssl_connect is BLOCKING */
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(!result) {
|
||||
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
|
||||
conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
|
||||
result = ftp_state_user(conn);
|
||||
}
|
||||
}
|
||||
@ -2850,7 +2782,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
case FTP_PROT:
|
||||
if(ftpcode/100 == 2)
|
||||
/* We have enabled SSL for the data connection! */
|
||||
conn->ssl[SECONDARYSOCKET].use =
|
||||
conn->bits.ftp_use_data_ssl =
|
||||
(data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
|
||||
/* FTP servers typically responds with 500 if they decide to reject
|
||||
our 'P' request */
|
||||
@ -2891,6 +2823,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
case FTP_PWD:
|
||||
if(ftpcode == 257) {
|
||||
char *ptr=&data->state.buffer[4]; /* start on the first letter */
|
||||
const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
|
||||
char *dir;
|
||||
char *store;
|
||||
|
||||
@ -2908,7 +2841,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
*/
|
||||
|
||||
/* scan for the first double-quote for non-standard responses */
|
||||
while(ptr < &data->state.buffer[sizeof(data->state.buffer)]
|
||||
while(ptr < &data->state.buffer[buf_size]
|
||||
&& *ptr != '\n' && *ptr != '\0' && *ptr != '"')
|
||||
ptr++;
|
||||
|
||||
@ -2999,7 +2932,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
|
||||
/* Check for special servers here. */
|
||||
|
||||
if(strequal(os, "OS/400")) {
|
||||
if(strcasecompare(os, "OS/400")) {
|
||||
/* Force OS400 name format 1. */
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
|
||||
if(result) {
|
||||
@ -3165,7 +3098,7 @@ static CURLcode ftp_multi_statemach(struct connectdata *conn,
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
|
||||
|
||||
/* Check for the state outside of the Curl_socket_ready() return code checks
|
||||
/* Check for the state outside of the Curl_socket_check() return code checks
|
||||
since at times we are in fact already in this state when this function
|
||||
gets called. */
|
||||
*done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
|
||||
@ -3243,15 +3176,14 @@ static CURLcode ftp_connect(struct connectdata *conn,
|
||||
static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct FTP *ftp = data->req.protop;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
struct pingpong *pp = &ftpc->pp;
|
||||
ssize_t nread;
|
||||
int ftpcode;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool was_ctl_valid = ftpc->ctl_valid;
|
||||
char *path;
|
||||
char *path = NULL;
|
||||
const char *path_to_use = data->state.path;
|
||||
|
||||
if(!ftp)
|
||||
@ -3274,10 +3206,9 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
/* the connection stays alive fine even though this happened */
|
||||
/* fall-through */
|
||||
case CURLE_OK: /* doesn't affect the control connection's status */
|
||||
if(!premature) {
|
||||
ftpc->ctl_valid = was_ctl_valid;
|
||||
if(!premature)
|
||||
break;
|
||||
}
|
||||
|
||||
/* until we cope better with prematurely ended requests, let them
|
||||
* fallback as if in complete failure */
|
||||
default: /* by default, an error means the control connection is
|
||||
@ -3300,13 +3231,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
ftpc->known_filesize = -1;
|
||||
}
|
||||
|
||||
/* get the "raw" path */
|
||||
path = curl_easy_unescape(data, path_to_use, 0, NULL);
|
||||
if(!path) {
|
||||
/* out of memory, but we can limp along anyway (and should try to
|
||||
* since we may already be in the out of memory cleanup path) */
|
||||
if(!result)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
/* get the "raw" path */
|
||||
result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
|
||||
if(result) {
|
||||
/* We can limp along anyway (and should try to since we may already be in
|
||||
* the error path) */
|
||||
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
|
||||
connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
|
||||
ftpc->prevpath = NULL; /* no path remembering */
|
||||
@ -3587,7 +3517,7 @@ static CURLcode ftp_range(struct connectdata *conn)
|
||||
curl_off_t from, to;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
if(data->state.use_range && data->state.range) {
|
||||
@ -3645,7 +3575,7 @@ static CURLcode ftp_range(struct connectdata *conn)
|
||||
|
||||
static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
{
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
CURLcode result = CURLE_OK;
|
||||
bool connected = FALSE;
|
||||
@ -3669,10 +3599,6 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
/* Ready to do more? */
|
||||
if(connected) {
|
||||
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
|
||||
if(conn->bits.proxy) {
|
||||
infof(data, "Connection to proxy confirmed\n");
|
||||
result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(result && (ftpc->count1 == 0)) {
|
||||
@ -3684,6 +3610,18 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
}
|
||||
}
|
||||
|
||||
result = Curl_proxy_connect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(CONNECT_SECONDARYSOCKET_PROXY_SSL())
|
||||
return result;
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
|
||||
conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE)
|
||||
return result;
|
||||
|
||||
|
||||
if(ftpc->state) {
|
||||
/* already in a state so skip the intial commands.
|
||||
They are only done to kickstart the do_more state */
|
||||
@ -4093,8 +4031,7 @@ static CURLcode ftp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
const char *fmt, ...)
|
||||
CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
#define SBUF_SIZE 1024
|
||||
@ -4106,10 +4043,9 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
enum protection_level data_sec = conn->data_prot;
|
||||
#endif
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
write_len = vsnprintf(s, SBUF_SIZE-3, fmt, ap);
|
||||
va_end(ap);
|
||||
write_len = strlen(cmd);
|
||||
if(write_len > (sizeof(s) -3))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
|
||||
write_len +=2;
|
||||
@ -4209,7 +4145,7 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
(void)ftp_quit(conn); /* ignore errors on the QUIT */
|
||||
|
||||
if(ftpc->entrypath) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
|
||||
data->state.most_recent_ftp_entrypath = NULL;
|
||||
}
|
||||
@ -4242,7 +4178,7 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
static
|
||||
CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
/* the ftp struct is already inited in ftp_connect() */
|
||||
struct FTP *ftp = data->req.protop;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
@ -4251,8 +4187,8 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
const char *cur_pos;
|
||||
const char *filename = NULL;
|
||||
|
||||
cur_pos = path_to_use; /* current position in path. point at the begin
|
||||
of next path component */
|
||||
cur_pos = path_to_use; /* current position in path. point at the begin of
|
||||
next path component */
|
||||
|
||||
ftpc->ctl_valid = FALSE;
|
||||
ftpc->cwdfail = FALSE;
|
||||
@ -4291,6 +4227,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
slash_pos=strrchr(cur_pos, '/');
|
||||
if(slash_pos || !*cur_pos) {
|
||||
size_t dirlen = slash_pos-cur_pos;
|
||||
CURLcode result;
|
||||
|
||||
ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
|
||||
if(!ftpc->dirs)
|
||||
@ -4299,12 +4236,13 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
if(!dirlen)
|
||||
dirlen++;
|
||||
|
||||
ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
|
||||
slash_pos ? curlx_uztosi(dirlen) : 1,
|
||||
NULL);
|
||||
if(!ftpc->dirs[0]) {
|
||||
result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
|
||||
slash_pos ? dirlen : 1,
|
||||
&ftpc->dirs[0], NULL,
|
||||
FALSE);
|
||||
if(result) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return result;
|
||||
}
|
||||
ftpc->dirdepth = 1; /* we consider it to be a single dir */
|
||||
filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
|
||||
@ -4322,7 +4260,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* we have a special case for listing the root dir only */
|
||||
if(strequal(path_to_use, "/")) {
|
||||
if(!strcmp(path_to_use, "/")) {
|
||||
cur_pos++; /* make it point to the zero byte */
|
||||
ftpc->dirs[0] = strdup("/");
|
||||
ftpc->dirdepth++;
|
||||
@ -4339,18 +4277,15 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
/* we skip empty path components, like "x//y" since the FTP command
|
||||
CWD requires a parameter and a non-existent parameter a) doesn't
|
||||
work on many servers and b) has no effect on the others. */
|
||||
int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir);
|
||||
ftpc->dirs[ftpc->dirdepth] =
|
||||
curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
|
||||
if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
|
||||
failf(data, "no memory");
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
|
||||
size_t len = slash_pos - cur_pos + absolute_dir;
|
||||
CURLcode result =
|
||||
Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
|
||||
&ftpc->dirs[ftpc->dirdepth], NULL,
|
||||
TRUE);
|
||||
if(result) {
|
||||
free(ftpc->dirs[ftpc->dirdepth]);
|
||||
freedirs(ftpc);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -4386,15 +4321,12 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
} /* switch */
|
||||
|
||||
if(filename && *filename) {
|
||||
ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL);
|
||||
if(NULL == ftpc->file) {
|
||||
CURLcode result =
|
||||
Curl_urldecode(conn->data, filename, 0, &ftpc->file, NULL, TRUE);
|
||||
|
||||
if(result) {
|
||||
freedirs(ftpc);
|
||||
failf(data, "no memory");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(isBadFtpString(ftpc->file)) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -4412,16 +4344,18 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
if(ftpc->prevpath) {
|
||||
/* prevpath is "raw" so we convert the input path before we compare the
|
||||
strings */
|
||||
int dlen;
|
||||
char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen);
|
||||
if(!path) {
|
||||
size_t dlen;
|
||||
char *path;
|
||||
CURLcode result =
|
||||
Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
|
||||
if(result) {
|
||||
freedirs(ftpc);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return result;
|
||||
}
|
||||
|
||||
dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0;
|
||||
if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) &&
|
||||
strnequal(path, ftpc->prevpath, dlen)) {
|
||||
dlen -= ftpc->file?strlen(ftpc->file):0;
|
||||
if((dlen == strlen(ftpc->prevpath)) &&
|
||||
!strncmp(path, ftpc->prevpath, dlen)) {
|
||||
infof(data, "Request has same path as previous transfer\n");
|
||||
ftpc->cwddone = TRUE;
|
||||
}
|
||||
@ -4494,7 +4428,7 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
bool connected=FALSE;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
data->req.size = -1; /* make sure this is unknown at this point */
|
||||
|
||||
@ -4528,7 +4462,7 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
|
||||
static CURLcode ftp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *type;
|
||||
char command;
|
||||
struct FTP *ftp;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -31,7 +31,7 @@ extern const struct Curl_handler Curl_handler_ftp;
|
||||
extern const struct Curl_handler Curl_handler_ftps;
|
||||
#endif
|
||||
|
||||
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
CURLcode Curl_ftpsend(struct connectdata *, const char *cmd);
|
||||
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
||||
int *ftpcode);
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
@ -97,9 +97,9 @@ typedef enum {
|
||||
file */
|
||||
} curl_ftpfile;
|
||||
|
||||
/* This FTP struct is used in the SessionHandle. All FTP data that is
|
||||
/* This FTP struct is used in the Curl_easy. All FTP data that is
|
||||
connection-oriented must be in FTP_conn to properly deal with the fact that
|
||||
perhaps the SessionHandle is changed between the times the connection is
|
||||
perhaps the Curl_easy is changed between the times the connection is
|
||||
used. */
|
||||
struct FTP {
|
||||
curl_off_t *bytecountp;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -45,7 +45,6 @@
|
||||
#include "fileinfo.h"
|
||||
#include "llist.h"
|
||||
#include "strtoofft.h"
|
||||
#include "rawstr.h"
|
||||
#include "ftp.h"
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_fnmatch.h"
|
||||
|
@ -30,7 +30,8 @@
|
||||
static
|
||||
char *GetEnv(const char *variable)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
|
||||
(void)variable;
|
||||
return NULL;
|
||||
#else
|
||||
#ifdef WIN32
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -36,10 +36,13 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* This is supposed to be called in the beginning of a perform() session
|
||||
* and should reset all session-info variables
|
||||
* Initialize statistical and informational data.
|
||||
*
|
||||
* This function is called in curl_easy_reset, curl_easy_duphandle and at the
|
||||
* beginning of a perform session. It must reset the session-info variables,
|
||||
* in particular all variables in struct PureInfo.
|
||||
*/
|
||||
CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
CURLcode Curl_initinfo(struct Curl_easy *data)
|
||||
{
|
||||
struct Progress *pro = &data->progress;
|
||||
struct PureInfo *info = &data->info;
|
||||
@ -58,23 +61,35 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
|
||||
info->timecond = FALSE;
|
||||
|
||||
info->header_size = 0;
|
||||
info->request_size = 0;
|
||||
info->proxyauthavail = 0;
|
||||
info->httpauthavail = 0;
|
||||
info->numconnects = 0;
|
||||
|
||||
free(info->contenttype);
|
||||
info->contenttype = NULL;
|
||||
|
||||
info->header_size = 0;
|
||||
info->request_size = 0;
|
||||
info->numconnects = 0;
|
||||
free(info->wouldredirect);
|
||||
info->wouldredirect = NULL;
|
||||
|
||||
info->conn_primary_ip[0] = '\0';
|
||||
info->conn_local_ip[0] = '\0';
|
||||
info->conn_primary_port = 0;
|
||||
info->conn_local_port = 0;
|
||||
|
||||
info->conn_scheme = 0;
|
||||
info->conn_protocol = 0;
|
||||
|
||||
#ifdef USE_SSL
|
||||
Curl_ssl_free_certinfo(data);
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
char **param_charp)
|
||||
static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
|
||||
const char **param_charp)
|
||||
{
|
||||
switch(info) {
|
||||
case CURLINFO_EFFECTIVE_URL:
|
||||
@ -111,6 +126,9 @@ static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_RTSP_SESSION_ID:
|
||||
*param_charp = data->set.str[STRING_RTSP_SESSION_ID];
|
||||
break;
|
||||
case CURLINFO_SCHEME:
|
||||
*param_charp = data->info.conn_scheme;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
@ -119,7 +137,7 @@ static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
long *param_longp)
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
@ -148,6 +166,9 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_PROXY_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.proxy_ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_REDIRECT_COUNT:
|
||||
*param_longp = data->set.followlocation;
|
||||
break;
|
||||
@ -198,6 +219,25 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_RTSP_CSEQ_RECV:
|
||||
*param_longp = data->state.rtsp_CSeq_recv;
|
||||
break;
|
||||
case CURLINFO_HTTP_VERSION:
|
||||
switch(data->info.httpversion) {
|
||||
case 10:
|
||||
*param_longp = CURL_HTTP_VERSION_1_0;
|
||||
break;
|
||||
case 11:
|
||||
*param_longp = CURL_HTTP_VERSION_1_1;
|
||||
break;
|
||||
case 20:
|
||||
*param_longp = CURL_HTTP_VERSION_2_0;
|
||||
break;
|
||||
default:
|
||||
*param_longp = CURL_HTTP_VERSION_NONE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CURLINFO_PROTOCOL:
|
||||
*param_longp = data->info.conn_protocol;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
@ -206,7 +246,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
|
||||
double *param_doublep)
|
||||
{
|
||||
switch(info) {
|
||||
@ -259,7 +299,7 @@ static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
|
||||
struct curl_slist **param_slistp)
|
||||
{
|
||||
union {
|
||||
@ -335,7 +375,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info,
|
||||
curl_socket_t *param_socketp)
|
||||
{
|
||||
switch(info) {
|
||||
@ -349,12 +389,12 @@ static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
long *param_longp = NULL;
|
||||
double *param_doublep = NULL;
|
||||
char **param_charp = NULL;
|
||||
const char **param_charp = NULL;
|
||||
struct curl_slist **param_slistp = NULL;
|
||||
curl_socket_t *param_socketp = NULL;
|
||||
int type;
|
||||
@ -368,7 +408,7 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
type = CURLINFO_TYPEMASK & (int)info;
|
||||
switch(type) {
|
||||
case CURLINFO_STRING:
|
||||
param_charp = va_arg(arg, char **);
|
||||
param_charp = va_arg(arg, const char **);
|
||||
if(param_charp)
|
||||
result = getinfo_char(data, info, param_charp);
|
||||
break;
|
||||
|
@ -21,7 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
|
||||
CURLcode Curl_initinfo(struct SessionHandle *data);
|
||||
CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...);
|
||||
CURLcode Curl_initinfo(struct Curl_easy *data);
|
||||
|
||||
#endif /* HEADER_CURL_GETINFO_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -28,13 +28,11 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
#include "gopher.h"
|
||||
#include "rawstr.h"
|
||||
#include "select.h"
|
||||
#include "url.h"
|
||||
#include "escape.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@ -75,7 +73,7 @@ const struct Curl_handler Curl_handler_gopher = {
|
||||
static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
curl_off_t *bytecount = &data->req.bytecount;
|
||||
@ -83,7 +81,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
char *sel;
|
||||
char *sel_org = NULL;
|
||||
ssize_t amount, k;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@ -107,7 +105,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
newp[i] = '\x09';
|
||||
|
||||
/* ... and finally unescape */
|
||||
sel = curl_easy_unescape(data, newp, 0, &len);
|
||||
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
|
||||
if(!sel)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
sel_org = sel;
|
||||
@ -121,20 +119,17 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||
if(!result) { /* Which may not have written it all! */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||
if(result) {
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
if(result)
|
||||
break;
|
||||
|
||||
k -= amount;
|
||||
sel += amount;
|
||||
if(k < 1)
|
||||
break; /* but it did write it all */
|
||||
}
|
||||
else {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
/* Don't busyloop. The entire loop thing is a work-around as it causes a
|
||||
BLOCKING behavior which is a NO-NO. This function should rather be
|
||||
split up in a do and a doing piece where the pieces that aren't
|
||||
@ -144,11 +139,15 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
Wait a while for the socket to be writable. Note that this doesn't
|
||||
acknowledge the timeout.
|
||||
*/
|
||||
Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
|
||||
if(SOCKET_WRITABLE(sockfd, 100) < 0) {
|
||||
result = CURLE_SEND_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(sel_org);
|
||||
|
||||
if(!result)
|
||||
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||
save allocing another string/doing another _write loop. */
|
||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -87,7 +87,6 @@ void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num);
|
||||
size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2,
|
||||
size_t key2_len);
|
||||
|
||||
void Curl_hash_start_iterate(struct curl_hash *hash,
|
||||
struct curl_hash_iterator *iter);
|
||||
struct curl_hash_element *
|
||||
|
@ -77,7 +77,7 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
|
||||
if(CURL_ASYNC_SUCCESS == status) {
|
||||
if(ai) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,7 +22,10 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
|
||||
#if defined(USE_OPENSSL) \
|
||||
|| defined(USE_AXTLS) \
|
||||
|| defined(USE_GSKIT) \
|
||||
|| (defined(USE_SCHANNEL) && defined(_WIN32_WCE))
|
||||
/* these backends use functions from this file */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
@ -30,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include "hostcheck.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
@ -77,7 +80,7 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
pattern_wildcard = strchr(pattern, '*');
|
||||
if(pattern_wildcard == NULL)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
return strcasecompare(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
/* detect IP address as hostname and fail the match if so */
|
||||
@ -94,16 +97,16 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
pattern_label_end = strchr(pattern, '.');
|
||||
if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
|
||||
pattern_wildcard > pattern_label_end ||
|
||||
Curl_raw_nequal(pattern, "xn--", 4)) {
|
||||
strncasecompare(pattern, "xn--", 4)) {
|
||||
wildcard_enabled = 0;
|
||||
}
|
||||
if(!wildcard_enabled)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
return strcasecompare(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
hostname_label_end = strchr(hostname, '.');
|
||||
if(hostname_label_end == NULL ||
|
||||
!Curl_raw_equal(pattern_label_end, hostname_label_end))
|
||||
!strcasecompare(pattern_label_end, hostname_label_end))
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
/* The wildcard must match at least one character, so the left-most
|
||||
@ -114,8 +117,8 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
prefixlen = pattern_wildcard - pattern;
|
||||
suffixlen = pattern_label_end - (pattern_wildcard+1);
|
||||
return Curl_raw_nequal(pattern, hostname, prefixlen) &&
|
||||
Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
return strncasecompare(pattern, hostname, prefixlen) &&
|
||||
strncasecompare(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
suffixlen) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
}
|
||||
@ -144,4 +147,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL or AXTLS or GSKIT */
|
||||
#endif /* OPENSSL, AXTLS, GSKIT or schannel+wince */
|
||||
|
@ -254,7 +254,7 @@ hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now)
|
||||
* Library-wide function for pruning the DNS cache. This function takes and
|
||||
* returns the appropriate locks.
|
||||
*/
|
||||
void Curl_hostcache_prune(struct SessionHandle *data)
|
||||
void Curl_hostcache_prune(struct Curl_easy *data)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
@ -293,7 +293,7 @@ fetch_addr(struct connectdata *conn,
|
||||
char *entry_id = NULL;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
size_t entry_len;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
@ -345,7 +345,7 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
|
||||
if(data->share)
|
||||
@ -372,7 +372,7 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_cache_addr(struct SessionHandle *data,
|
||||
Curl_cache_addr(struct Curl_easy *data,
|
||||
Curl_addrinfo *addr,
|
||||
const char *hostname,
|
||||
int port)
|
||||
@ -447,7 +447,7 @@ int Curl_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result;
|
||||
int rc = CURLRESOLV_ERROR; /* default to failure */
|
||||
|
||||
@ -568,7 +568,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
struct Curl_dns_entry **entry,
|
||||
long timeoutms)
|
||||
time_t timeoutms)
|
||||
{
|
||||
#ifdef USE_ALARM_TIMEOUT
|
||||
#ifdef HAVE_SIGACTION
|
||||
@ -582,7 +582,7 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
#endif /* HAVE_SIGACTION */
|
||||
volatile long timeout;
|
||||
volatile unsigned int prev_alarm = 0;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif /* USE_ALARM_TIMEOUT */
|
||||
int rc;
|
||||
|
||||
@ -603,11 +603,14 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
|
||||
return Curl_resolv(conn, hostname, port, entry);
|
||||
|
||||
if(timeout < 1000)
|
||||
if(timeout < 1000) {
|
||||
/* The alarm() function only provides integer second resolution, so if
|
||||
we want to wait less than one second we must bail out already now. */
|
||||
failf(data,
|
||||
"remaining timeout of %ld too small to resolve via SIGALRM method",
|
||||
timeout);
|
||||
return CURLRESOLV_TIMEDOUT;
|
||||
|
||||
}
|
||||
/* This allows us to time-out from the name resolver, as the timeout
|
||||
will generate a signal and we will siglongjmp() from that here.
|
||||
This technique has problems (see alarmfunc).
|
||||
@ -716,7 +719,7 @@ clean_up:
|
||||
*
|
||||
* May be called with 'data' == NULL for global cache.
|
||||
*/
|
||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns)
|
||||
{
|
||||
if(data && data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
@ -758,7 +761,7 @@ int Curl_mk_dnscache(struct curl_hash *hash)
|
||||
* can be done!
|
||||
*/
|
||||
|
||||
void Curl_hostcache_clean(struct SessionHandle *data,
|
||||
void Curl_hostcache_clean(struct Curl_easy *data,
|
||||
struct curl_hash *hash)
|
||||
{
|
||||
if(data && data->share)
|
||||
@ -771,7 +774,7 @@ void Curl_hostcache_clean(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_loadhostpairs(struct SessionHandle *data)
|
||||
CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||
{
|
||||
struct curl_slist *hostp;
|
||||
char hostname[256];
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
|
||||
/*
|
||||
@ -87,7 +87,7 @@ int Curl_resolv(struct connectdata *conn, const char *hostname,
|
||||
int port, struct Curl_dns_entry **dnsentry);
|
||||
int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
|
||||
int port, struct Curl_dns_entry **dnsentry,
|
||||
long timeoutms);
|
||||
time_t timeoutms);
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
/*
|
||||
@ -118,7 +118,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
|
||||
/* unlock a previously resolved dns entry */
|
||||
void Curl_resolv_unlock(struct SessionHandle *data,
|
||||
void Curl_resolv_unlock(struct Curl_easy *data,
|
||||
struct Curl_dns_entry *dns);
|
||||
|
||||
/* for debugging purposes only: */
|
||||
@ -128,7 +128,7 @@ void Curl_scan_cache_used(void *user, void *ptr);
|
||||
int Curl_mk_dnscache(struct curl_hash *hash);
|
||||
|
||||
/* prune old entries from the DNS cache */
|
||||
void Curl_hostcache_prune(struct SessionHandle *data);
|
||||
void Curl_hostcache_prune(struct Curl_easy *data);
|
||||
|
||||
/* Return # of adresses in a Curl_addrinfo struct */
|
||||
int Curl_num_addresses(const Curl_addrinfo *addr);
|
||||
@ -188,7 +188,7 @@ Curl_fetch_addr(struct connectdata *conn,
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
|
||||
Curl_cache_addr(struct Curl_easy *data, Curl_addrinfo *addr,
|
||||
const char *hostname, int port);
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
@ -209,42 +209,42 @@ extern sigjmp_buf curl_jmpenv;
|
||||
/*
|
||||
* Function provided by the resolver backend to set DNS servers to use.
|
||||
*/
|
||||
CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data, char *servers);
|
||||
|
||||
/*
|
||||
* Function provided by the resolver backend to set
|
||||
* outgoing interface to use for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf);
|
||||
|
||||
/*
|
||||
* Function provided by the resolver backend to set
|
||||
* local IPv4 address to use as source address for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4);
|
||||
|
||||
/*
|
||||
* Function provided by the resolver backend to set
|
||||
* local IPv6 address to use as source address for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6);
|
||||
|
||||
/*
|
||||
* Clean off entries from the cache
|
||||
*/
|
||||
void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
|
||||
void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash);
|
||||
|
||||
/*
|
||||
* Destroy the hostcache of this handle.
|
||||
*/
|
||||
void Curl_hostcache_destroy(struct SessionHandle *data);
|
||||
void Curl_hostcache_destroy(struct Curl_easy *data);
|
||||
|
||||
/*
|
||||
* Populate the cache with specified entries from CURLOPT_RESOLVE.
|
||||
*/
|
||||
CURLcode Curl_loadhostpairs(struct SessionHandle *data);
|
||||
CURLcode Curl_loadhostpairs(struct Curl_easy *data);
|
||||
|
||||
#endif /* HEADER_CURL_HOSTIP_H */
|
||||
|
@ -167,10 +167,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
int error;
|
||||
char sbuf[12];
|
||||
char *sbufptr = NULL;
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
char addrbuf[128];
|
||||
#endif
|
||||
int pf;
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif
|
||||
|
||||
*waitp = 0; /* synchronous response only */
|
||||
@ -196,11 +198,17 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = conn->socktype;
|
||||
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
/*
|
||||
* The AI_NUMERICHOST must not be set to get synthesized IPv6 address from
|
||||
* an IPv4 address on iOS and Mac OS X.
|
||||
*/
|
||||
if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
|
||||
(1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
|
||||
/* the given address is numerical only, prevent a reverse lookup */
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(port) {
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
@ -213,6 +221,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(port) {
|
||||
Curl_addrinfo_set_port(res, port);
|
||||
}
|
||||
|
||||
dump_addrinfo(conn, res);
|
||||
|
||||
return res;
|
||||
|
@ -59,7 +59,7 @@
|
||||
/*
|
||||
* Function provided by the resolver backend to set DNS servers to use.
|
||||
*/
|
||||
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
char *servers)
|
||||
{
|
||||
(void)data;
|
||||
@ -72,7 +72,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
* Function provided by the resolver backend to set
|
||||
* outgoing interface to use for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
(void)data;
|
||||
@ -84,7 +84,7 @@ CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
* Function provided by the resolver backend to set
|
||||
* local IPv4 address to use as source address for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
(void)data;
|
||||
@ -96,7 +96,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
* Function provided by the resolver backend to set
|
||||
* local IPv6 address to use as source address for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
(void)data;
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include "progress.h"
|
||||
#include "curl_base64.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "http_digest.h"
|
||||
@ -68,7 +67,7 @@
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "strtoofft.h"
|
||||
#include "multiif.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "content_encoding.h"
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
@ -77,6 +76,7 @@
|
||||
#include "pipeline.h"
|
||||
#include "http2.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -151,7 +151,7 @@ const struct Curl_handler Curl_handler_https = {
|
||||
|
||||
CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the SessionHandle, only to survive
|
||||
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
|
||||
during this request */
|
||||
struct HTTP *http;
|
||||
DEBUGASSERT(conn->data->req.protop == NULL);
|
||||
@ -179,10 +179,10 @@ char *Curl_checkheaders(const struct connectdata *conn,
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = data->set.headers;head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
if(strncasecompare(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ char *Curl_checkheaders(const struct connectdata *conn,
|
||||
* if proxy headers are not available, then it will lookup into http header
|
||||
* link list
|
||||
*
|
||||
* It takes a connectdata struct as input instead of the SessionHandle simply
|
||||
* It takes a connectdata struct as input instead of the Curl_easy simply
|
||||
* to know if this is a proxy request or not, as it then might check a
|
||||
* different header list.
|
||||
*/
|
||||
@ -203,12 +203,12 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = (conn->bits.proxy && data->set.sep_headers) ?
|
||||
data->set.proxyheaders : data->set.headers;
|
||||
head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
if(strncasecompare(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
|
||||
@ -280,7 +280,7 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
size_t size = 0;
|
||||
char *authorization = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char **userp;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
@ -288,8 +288,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
|
||||
if(proxy) {
|
||||
userp = &conn->allocptr.proxyuserpwd;
|
||||
user = conn->proxyuser;
|
||||
pwd = conn->proxypasswd;
|
||||
user = conn->http_proxy.user;
|
||||
pwd = conn->http_proxy.passwd;
|
||||
}
|
||||
else {
|
||||
userp = &conn->allocptr.userpwd;
|
||||
@ -297,7 +297,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
pwd = conn->passwd;
|
||||
}
|
||||
|
||||
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||||
snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"%s:%s", user, pwd);
|
||||
|
||||
result = Curl_base64_encode(data,
|
||||
data->state.buffer, strlen(data->state.buffer),
|
||||
@ -377,7 +378,7 @@ static bool pickoneauth(struct auth *pick)
|
||||
*/
|
||||
static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
curl_off_t bytessent;
|
||||
curl_off_t expectsend = -1; /* default is unknown */
|
||||
@ -462,7 +463,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
#endif
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
connclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
streamclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
/* There still is data left to send, but this connection is marked for
|
||||
@ -485,7 +486,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
bool pickhost = FALSE;
|
||||
bool pickproxy = FALSE;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -567,7 +568,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
const char *auth = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy ?
|
||||
@ -642,7 +643,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
if(auth) {
|
||||
infof(data, "%s auth using %s with user '%s'\n",
|
||||
proxy ? "Proxy" : "Server", auth,
|
||||
proxy ? (conn->proxyuser ? conn->proxyuser : "") :
|
||||
proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
|
||||
(conn->user ? conn->user : ""));
|
||||
authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
|
||||
}
|
||||
@ -674,7 +675,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
up the proxy tunnel */
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct auth *authhost;
|
||||
struct auth *authproxy;
|
||||
|
||||
@ -726,7 +727,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
conn->bits.netrc ||
|
||||
!data->state.first_host ||
|
||||
data->set.http_disable_hostname_check_before_authentication ||
|
||||
Curl_raw_equal(data->state.first_host, conn->host.name)) {
|
||||
strcasecompare(data->state.first_host, conn->host.name)) {
|
||||
result = output_auth_headers(conn, authhost, request, path, FALSE);
|
||||
}
|
||||
else
|
||||
@ -747,7 +748,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
/*
|
||||
* This resource requires authentication
|
||||
*/
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy?
|
||||
@ -784,11 +785,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
while(*auth) {
|
||||
#ifdef USE_SPNEGO
|
||||
if(checkprefix("Negotiate", auth)) {
|
||||
if((authp->avail & CURLAUTH_NEGOTIATE) ||
|
||||
Curl_auth_is_spnego_supported()) {
|
||||
*availp |= CURLAUTH_NEGOTIATE;
|
||||
authp->avail |= CURLAUTH_NEGOTIATE;
|
||||
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
|
||||
if(negdata->state == GSS_AUTHSENT ||
|
||||
negdata->state == GSS_AUTHNONE) {
|
||||
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(!result) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
@ -804,13 +808,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_NTLM
|
||||
/* NTLM support requires the SSL crypto libs */
|
||||
if(checkprefix("NTLM", auth)) {
|
||||
if((authp->avail & CURLAUTH_NTLM) ||
|
||||
(authp->avail & CURLAUTH_NTLM_WB) ||
|
||||
Curl_auth_is_ntlm_supported()) {
|
||||
*availp |= CURLAUTH_NTLM;
|
||||
authp->avail |= CURLAUTH_NTLM;
|
||||
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
@ -832,11 +841,13 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
auth += strlen("NTLM");
|
||||
while(*auth && ISSPACE(*auth))
|
||||
auth++;
|
||||
if(*auth)
|
||||
if((conn->challenge_header = strdup(auth)) == NULL)
|
||||
if(*auth) {
|
||||
conn->challenge_header = strdup(auth);
|
||||
if(!conn->challenge_header)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@ -845,22 +856,23 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(checkprefix("Digest", auth)) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0) {
|
||||
if((authp->avail & CURLAUTH_DIGEST) != 0)
|
||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||
}
|
||||
else {
|
||||
else if(Curl_auth_is_digest_supported()) {
|
||||
CURLcode result;
|
||||
|
||||
*availp |= CURLAUTH_DIGEST;
|
||||
authp->avail |= CURLAUTH_DIGEST;
|
||||
|
||||
/* We call this function on input Digest headers even if Digest
|
||||
* authentication isn't activated yet, as we need to store the
|
||||
* incoming data from this header in case we are gonna use
|
||||
* Digest. */
|
||||
* incoming data from this header in case we are going to use
|
||||
* Digest */
|
||||
result = Curl_input_digest(conn, proxy, auth);
|
||||
if(result) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
@ -907,7 +919,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
*/
|
||||
static int http_should_fail(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
int httpcode;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
@ -1090,7 +1102,9 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
return result;
|
||||
}
|
||||
|
||||
if((conn->handler->flags & PROTOPT_SSL) && conn->httpversion != 20) {
|
||||
if((conn->handler->flags & PROTOPT_SSL ||
|
||||
conn->http_proxy.proxytype == CURLPROXY_HTTPS)
|
||||
&& conn->httpversion != 20) {
|
||||
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
|
||||
when we speak HTTPS, as if only a fraction of it is sent now, this data
|
||||
needs to fit into the normal read-callback buffer later on and that
|
||||
@ -1247,14 +1261,13 @@ CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
|
||||
|
||||
if(in->buffer)
|
||||
/* we have a buffer, enlarge the existing one */
|
||||
new_rb = realloc(in->buffer, new_size);
|
||||
new_rb = Curl_saferealloc(in->buffer, new_size);
|
||||
else
|
||||
/* create a new buffer */
|
||||
new_rb = malloc(new_size);
|
||||
|
||||
if(!new_rb) {
|
||||
/* If we failed, we cleanup the whole buffer and return error */
|
||||
Curl_safefree(in->buffer);
|
||||
free(in);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -1296,7 +1309,7 @@ Curl_compareheader(const char *headerline, /* line to check */
|
||||
const char *start;
|
||||
const char *end;
|
||||
|
||||
if(!Curl_raw_nequal(headerline, header, hlen))
|
||||
if(!strncasecompare(headerline, header, hlen))
|
||||
return FALSE; /* doesn't start with header */
|
||||
|
||||
/* pass the header */
|
||||
@ -1322,7 +1335,7 @@ Curl_compareheader(const char *headerline, /* line to check */
|
||||
|
||||
/* find the content string in the rest of the line */
|
||||
for(;len>=clen;len--, start++) {
|
||||
if(Curl_raw_nequal(start, content, clen))
|
||||
if(strncasecompare(start, content, clen))
|
||||
return TRUE; /* match! */
|
||||
}
|
||||
|
||||
@ -1342,10 +1355,13 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
connkeep(conn, "HTTP default");
|
||||
|
||||
/* the CONNECT procedure might not have been completed */
|
||||
result = Curl_proxy_connect(conn);
|
||||
result = Curl_proxy_connect(conn, FIRSTSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
|
||||
return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
|
||||
|
||||
if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
|
||||
/* nothing else to do except wait right now - we're not done here. */
|
||||
return CURLE_OK;
|
||||
@ -1388,50 +1404,16 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
|
||||
defined(USE_MBEDTLS)
|
||||
/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
|
||||
It should be made to query the generic SSL layer instead. */
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
if(connssl->connecting_state == ssl_connect_2_writing) {
|
||||
/* write mode */
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
else if(connssl->connecting_state == ssl_connect_2_reading) {
|
||||
/* read mode */
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(0);
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
#else
|
||||
#ifdef USE_SSL
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
(void)conn;
|
||||
(void)socks;
|
||||
(void)numsocks;
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
return Curl_ssl_getsock(conn, socks, numsocks);
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
#endif /* USE_SSL */
|
||||
#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
|
||||
|
||||
/*
|
||||
* Curl_http_done() gets called after a single HTTP request has been
|
||||
@ -1441,11 +1423,8 @@ static int https_getsock(struct connectdata *conn,
|
||||
CURLcode Curl_http_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
#ifdef USE_NGHTTP2
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
#endif
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
@ -1458,7 +1437,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
* Do not close CONNECT_ONLY connections. */
|
||||
if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
|
||||
!data->set.connect_only)
|
||||
connclose(conn, "Negotiate transfer completed");
|
||||
streamclose(conn, "Negotiate transfer completed");
|
||||
Curl_cleanup_negotiate(data);
|
||||
}
|
||||
#endif
|
||||
@ -1475,27 +1454,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
http->send_buffer = NULL; /* clear the pointer */
|
||||
}
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(http->header_recvbuf) {
|
||||
DEBUGF(infof(data, "free header_recvbuf!!\n"));
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
Curl_add_buffer_free(http->trailer_recvbuf);
|
||||
http->trailer_recvbuf = NULL; /* clear the pointer */
|
||||
if(http->push_headers) {
|
||||
/* if they weren't used and then freed before */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
}
|
||||
if(http->stream_id) {
|
||||
nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
|
||||
http->stream_id = 0;
|
||||
}
|
||||
#endif
|
||||
Curl_http2_done(conn, premature);
|
||||
|
||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||
data->req.bytecount = http->readbytecount + http->writebytecount;
|
||||
@ -1539,7 +1498,7 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
* - if any server previously contacted to handle this request only supports
|
||||
* 1.0.
|
||||
*/
|
||||
static bool use_http_1_1plus(const struct SessionHandle *data,
|
||||
static bool use_http_1_1plus(const struct Curl_easy *data,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
if((data->state.httpversion == 10) || (conn->httpversion == 10))
|
||||
@ -1551,8 +1510,22 @@ static bool use_http_1_1plus(const struct SessionHandle *data,
|
||||
(data->set.httpversion >= CURL_HTTP_VERSION_1_1));
|
||||
}
|
||||
|
||||
static const char *get_http_string(const struct Curl_easy *data,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
#ifdef USE_NGHTTP2
|
||||
if(conn->proto.httpc.h2)
|
||||
return "2";
|
||||
#endif
|
||||
|
||||
if(use_http_1_1plus(data, conn))
|
||||
return "1.1";
|
||||
|
||||
return "1.0";
|
||||
}
|
||||
|
||||
/* check and possibly add an Expect: header */
|
||||
static CURLcode expect100(struct SessionHandle *data,
|
||||
static CURLcode expect100(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
Curl_send_buffer *req_buffer)
|
||||
{
|
||||
@ -1595,7 +1568,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
struct curl_slist *h[2];
|
||||
struct curl_slist *headers;
|
||||
int numlists=1; /* by default */
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
int i;
|
||||
|
||||
enum proxy_use proxy;
|
||||
@ -1660,6 +1633,10 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
Connection: */
|
||||
checkprefix("Connection", headers->data))
|
||||
;
|
||||
else if((conn->httpversion == 20) &&
|
||||
checkprefix("Transfer-Encoding:", headers->data))
|
||||
/* HTTP/2 doesn't support chunked requests */
|
||||
;
|
||||
else {
|
||||
CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
|
||||
headers->data);
|
||||
@ -1700,7 +1677,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
Curl_send_buffer *req_buffer)
|
||||
{
|
||||
const struct tm *tm;
|
||||
@ -1758,13 +1735,13 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_http() gets called from the generic Curl_do() function when a HTTP
|
||||
* Curl_http() gets called from the generic multi_do() function when a HTTP
|
||||
* request is to be performed. This creates and sends a properly constructed
|
||||
* HTTP request.
|
||||
*/
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct HTTP *http;
|
||||
const char *ppath = data->state.path;
|
||||
@ -1946,10 +1923,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(conn->httpversion == 20)
|
||||
/* In HTTP2 forbids Transfer-Encoding: chunked */
|
||||
ptr = NULL;
|
||||
else {
|
||||
ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
@ -1980,13 +1953,12 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(data->req.upload_chunky)
|
||||
te = "Transfer-Encoding: chunked\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(conn->allocptr.host);
|
||||
|
||||
ptr = Curl_checkheaders(conn, "Host:");
|
||||
if(ptr && (!data->state.this_is_a_follow ||
|
||||
Curl_raw_equal(data->state.first_host, conn->host.name))) {
|
||||
strcasecompare(data->state.first_host, conn->host.name))) {
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
/* If we have a given custom Host: header, we extract the host name in
|
||||
order to possibly use it for cookie reasons later on. We only allow the
|
||||
@ -2266,9 +2238,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
}
|
||||
|
||||
/* Use 1.1 unless the user specifically asked for 1.0 or the server only
|
||||
supports 1.0 */
|
||||
httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
|
||||
httpstring = get_http_string(data, conn);
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
req_buffer = Curl_add_buffer_init();
|
||||
@ -2305,6 +2275,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
"%s" /* TE: */
|
||||
"%s" /* accept-encoding */
|
||||
"%s" /* referer */
|
||||
"%s" /* Proxy-Connection */
|
||||
"%s",/* transfer-encoding */
|
||||
|
||||
ftp_typecode,
|
||||
@ -2327,6 +2298,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
conn->allocptr.accept_encoding:"",
|
||||
(data->change.referer && conn->allocptr.ref)?
|
||||
conn->allocptr.ref:"" /* Referer: <data> */,
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
te
|
||||
);
|
||||
|
||||
@ -2392,7 +2367,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
co = co->next; /* next cookie please */
|
||||
}
|
||||
Curl_cookie_freelist(store, FALSE); /* free the cookie list */
|
||||
Curl_cookie_freelist(store);
|
||||
}
|
||||
if(addcookies && !result) {
|
||||
if(!count)
|
||||
@ -2537,7 +2512,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
postsize = data->state.infilesize;
|
||||
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
@ -2589,7 +2564,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
(conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
@ -2768,6 +2743,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
}
|
||||
|
||||
if((conn->httpversion == 20) && data->req.upload_chunky)
|
||||
/* upload_chunky was set above to set up the request in a chunky fashion,
|
||||
but is disabled here again to avoid that the chunked encoded version is
|
||||
actually used when sending the request body over h2 */
|
||||
data->req.upload_chunky = FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2777,7 +2757,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
* Returns TRUE if member of the list matches prefix of string
|
||||
*/
|
||||
static bool
|
||||
checkhttpprefix(struct SessionHandle *data,
|
||||
checkhttpprefix(struct Curl_easy *data,
|
||||
const char *s)
|
||||
{
|
||||
struct curl_slist *head = data->set.http200aliases;
|
||||
@ -2816,7 +2796,7 @@ checkhttpprefix(struct SessionHandle *data,
|
||||
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
static bool
|
||||
checkrtspprefix(struct SessionHandle *data,
|
||||
checkrtspprefix(struct Curl_easy *data,
|
||||
const char *s)
|
||||
{
|
||||
|
||||
@ -2844,7 +2824,7 @@ checkrtspprefix(struct SessionHandle *data,
|
||||
#endif /* CURL_DISABLE_RTSP */
|
||||
|
||||
static bool
|
||||
checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
|
||||
checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
|
||||
const char *s)
|
||||
{
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
@ -2862,7 +2842,7 @@ checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
|
||||
* header. We make sure that the full string fit in the allocated header
|
||||
* buffer, or else we enlarge it.
|
||||
*/
|
||||
static CURLcode header_append(struct SessionHandle *data,
|
||||
static CURLcode header_append(struct Curl_easy *data,
|
||||
struct SingleRequest *k,
|
||||
size_t length)
|
||||
{
|
||||
@ -2900,7 +2880,7 @@ static CURLcode header_append(struct SessionHandle *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void print_http_error(struct SessionHandle *data)
|
||||
static void print_http_error(struct Curl_easy *data)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
char *beg = k->p;
|
||||
@ -2940,7 +2920,7 @@ static void print_http_error(struct SessionHandle *data)
|
||||
/*
|
||||
* Read any HTTP header lines from the server and pass them to the client app.
|
||||
*/
|
||||
CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
ssize_t *nread,
|
||||
bool *stop_reading)
|
||||
@ -3040,6 +3020,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(100 <= k->httpcode && 199 >= k->httpcode) {
|
||||
/* "A user agent MAY ignore unexpected 1xx status responses." */
|
||||
switch(k->httpcode) {
|
||||
case 100:
|
||||
/*
|
||||
* We have made a HTTP PUT or POST and this is 1.1-lingo
|
||||
* that tells us that the server is OK with this and ready
|
||||
@ -3050,11 +3033,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
|
||||
/* "A user agent MAY ignore unexpected 1xx status responses." */
|
||||
switch(k->httpcode) {
|
||||
case 100:
|
||||
/* if we did wait for this do enable write now! */
|
||||
if(k->exp100) {
|
||||
if(k->exp100 > EXP100_SEND_DATA) {
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
k->keepon |= KEEP_SEND;
|
||||
}
|
||||
@ -3062,9 +3042,14 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
case 101:
|
||||
/* Switching Protocols */
|
||||
if(k->upgr101 == UPGR101_REQUESTED) {
|
||||
/* Switching to HTTP/2 */
|
||||
infof(data, "Received 101\n");
|
||||
k->upgr101 = UPGR101_RECEIVED;
|
||||
|
||||
/* we'll get more headers (HTTP/2 response) */
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
|
||||
/* switch to http2 now. The bytes after response headers
|
||||
are also processed here, otherwise they are lost. */
|
||||
result = Curl_http2_switched(conn, k->str, *nread);
|
||||
@ -3072,8 +3057,16 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
return result;
|
||||
*nread = 0;
|
||||
}
|
||||
else {
|
||||
/* Switching to another protocol (e.g. WebSocket) */
|
||||
k->header = FALSE; /* no more header to parse! */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* the status code 1xx indicates a provisional response, so
|
||||
we'll get another set of headers */
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3091,7 +3084,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
signal the end of the document. */
|
||||
infof(data, "no chunk, no close, no size. Assume close to "
|
||||
"signal end\n");
|
||||
connclose(conn, "HTTP: No end-of-message indicator");
|
||||
streamclose(conn, "HTTP: No end-of-message indicator");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3138,7 +3131,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
data->req.deductheadercount =
|
||||
(100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
|
||||
|
||||
if(!*stop_reading) {
|
||||
/* Curl_http_auth_act() checks what authentication methods
|
||||
* that are available and decides which one (if any) to
|
||||
* use. It will set 'newurl' if an auth method was picked. */
|
||||
@ -3172,20 +3164,28 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
* connection for closure after we've read the entire response.
|
||||
*/
|
||||
if(!k->upload_done) {
|
||||
if(data->set.http_keep_sending_on_error) {
|
||||
infof(data, "HTTP error before end of send, keep sending\n");
|
||||
if(k->exp100 > EXP100_SEND_DATA) {
|
||||
k->exp100 = EXP100_SEND_DATA;
|
||||
k->keepon |= KEEP_SEND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
infof(data, "HTTP error before end of send, stop sending\n");
|
||||
connclose(conn, "Stop sending data before everything sent");
|
||||
streamclose(conn, "Stop sending data before everything sent");
|
||||
k->upload_done = TRUE;
|
||||
k->keepon &= ~KEEP_SEND; /* don't send */
|
||||
if(data->state.expect100header)
|
||||
k->exp100 = EXP100_FAILED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* default label present to avoid compiler warnings */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(conn->bits.rewindaftersend) {
|
||||
/* We rewind after a complete send, so thus we continue
|
||||
@ -3210,7 +3210,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
(k->size <= -1))
|
||||
/* Respect section 4.4 of rfc2326: If the Content-Length header is
|
||||
absent, a length 0 must be assumed. It will prevent libcurl from
|
||||
hanging on DECRIBE request that got refused for whatever
|
||||
hanging on DESCRIBE request that got refused for whatever
|
||||
reason */
|
||||
*stop_reading = TRUE;
|
||||
#endif
|
||||
@ -3308,6 +3308,13 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
&httpversion_major,
|
||||
&conn->httpversion,
|
||||
&k->httpcode);
|
||||
|
||||
if(nc == 1 && httpversion_major == 2 &&
|
||||
1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
|
||||
conn->httpversion = 0;
|
||||
nc = 3;
|
||||
}
|
||||
|
||||
if(nc==3) {
|
||||
conn->httpversion += 10 * httpversion_major;
|
||||
|
||||
@ -3471,7 +3478,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
/* Negative Content-Length is really odd, and we know it
|
||||
happens for example when older Apache servers send large
|
||||
files */
|
||||
connclose(conn, "negative content-length");
|
||||
streamclose(conn, "negative content-length");
|
||||
infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
|
||||
", closing after transfer\n", contentlength);
|
||||
}
|
||||
@ -3544,7 +3551,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
* the connection will close when this request has been
|
||||
* served.
|
||||
*/
|
||||
connclose(conn, "Connection: close used");
|
||||
streamclose(conn, "Connection: close used");
|
||||
}
|
||||
else if(checkprefix("Transfer-Encoding:", k->p)) {
|
||||
/* One or more encodings. We check for chunked and/or a compression
|
||||
@ -3754,7 +3761,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
k->hbufp = data->state.headerbuff;
|
||||
k->hbuflen = 0;
|
||||
}
|
||||
while(!*stop_reading && *k->str); /* header line within buffer */
|
||||
while(*k->str); /* header line within buffer */
|
||||
|
||||
/* We might have reached the end of the header part here, but
|
||||
there might be a non-header part left in the end of the read
|
||||
|
@ -69,7 +69,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
size_t included_body_bytes,
|
||||
int socketindex);
|
||||
|
||||
CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
Curl_send_buffer *buf);
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_connect,
|
||||
@ -87,7 +87,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
||||
ssize_t length, ssize_t *wrote);
|
||||
|
||||
/* These functions are in http.c */
|
||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||
void Curl_http_auth_stage(struct Curl_easy *data, int stage);
|
||||
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
const char *auth);
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||
@ -168,6 +168,7 @@ struct HTTP {
|
||||
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
|
||||
size_t pauselen; /* the number of bytes left in data */
|
||||
bool closed; /* TRUE on HTTP2 stream close */
|
||||
bool close_handled; /* TRUE if stream closure is handled by libcurl */
|
||||
uint32_t error_code; /* HTTP/2 error code */
|
||||
|
||||
char *mem; /* points to a buffer in memory to store received data */
|
||||
@ -216,14 +217,18 @@ struct http_conn {
|
||||
nghttp2_session_mem_recv */
|
||||
size_t drain_total; /* sum of all stream's UrlState.drain */
|
||||
|
||||
/* this is a hash of all individual streams (SessionHandle structs) */
|
||||
/* this is a hash of all individual streams (Curl_easy structs) */
|
||||
struct h2settings settings;
|
||||
|
||||
/* list of settings that will be sent */
|
||||
nghttp2_settings_entry local_settings[3];
|
||||
size_t local_settings_num;
|
||||
#else
|
||||
int unused; /* prevent a compiler warning */
|
||||
#endif
|
||||
};
|
||||
|
||||
CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
ssize_t *nread,
|
||||
bool *stop_reading);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -29,13 +29,13 @@
|
||||
#include "http.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_base64.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "multiif.h"
|
||||
#include "conncache.h"
|
||||
#include "url.h"
|
||||
#include "connect.h"
|
||||
#include "strtoofft.h"
|
||||
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -59,6 +59,12 @@
|
||||
#define nghttp2_session_callbacks_set_error_callback(x,y)
|
||||
#endif
|
||||
|
||||
#if (NGHTTP2_VERSION_NUM >= 0x010c00)
|
||||
#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
|
||||
#endif
|
||||
|
||||
#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
|
||||
|
||||
/*
|
||||
* Curl_http2_init_state() is called when the easy handle is created and
|
||||
* allows for HTTP/2 specific init of state.
|
||||
@ -92,7 +98,8 @@ static int http2_perform_getsock(const struct connectdata *conn,
|
||||
because of renegotiation. */
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(nghttp2_session_want_read(c->h2))
|
||||
/* in a HTTP/2 connection we can basically always get a frame so we should
|
||||
always be ready for one */
|
||||
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
|
||||
|
||||
if(nghttp2_session_want_write(c->h2))
|
||||
@ -109,18 +116,11 @@ static int http2_getsock(struct connectdata *conn,
|
||||
return http2_perform_getsock(conn, sock, numsocks);
|
||||
}
|
||||
|
||||
static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
/*
|
||||
* http2_stream_free() free HTTP2 stream related data
|
||||
*/
|
||||
static void http2_stream_free(struct HTTP *http)
|
||||
{
|
||||
struct HTTP *http = conn->data->req.protop;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
(void)dead_connection;
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
|
||||
if(http) {
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
@ -132,6 +132,19 @@ static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
bool dead_connection)
|
||||
{
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
(void)dead_connection;
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
|
||||
|
||||
nghttp2_session_del(c->h2);
|
||||
Curl_safefree(c->inbuf);
|
||||
http2_stream_free(conn->data->req.protop);
|
||||
|
||||
DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
|
||||
|
||||
@ -139,7 +152,7 @@ static CURLcode http2_disconnect(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_req(struct SessionHandle *data)
|
||||
void Curl_http2_setup_req(struct Curl_easy *data)
|
||||
{
|
||||
struct HTTP *http = data->req.protop;
|
||||
|
||||
@ -150,6 +163,7 @@ void Curl_http2_setup_req(struct SessionHandle *data)
|
||||
http->pauselen = 0;
|
||||
http->error_code = NGHTTP2_NO_ERROR;
|
||||
http->closed = FALSE;
|
||||
http->close_handled = FALSE;
|
||||
http->mem = data->state.buffer;
|
||||
http->len = BUFSIZE;
|
||||
http->memlen = 0;
|
||||
@ -184,7 +198,7 @@ const struct Curl_handler Curl_handler_http2 = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTP, /* defport */
|
||||
CURLPROTO_HTTP, /* protocol */
|
||||
PROTOPT_NONE /* flags */
|
||||
PROTOPT_STREAM /* flags */
|
||||
};
|
||||
|
||||
const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
@ -204,7 +218,7 @@ const struct Curl_handler Curl_handler_http2_ssl = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_HTTP, /* defport */
|
||||
CURLPROTO_HTTPS, /* protocol */
|
||||
PROTOPT_SSL /* flags */
|
||||
PROTOPT_SSL | PROTOPT_STREAM /* flags */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -221,7 +235,8 @@ int Curl_http2_ver(char *p, size_t len)
|
||||
https://tools.ietf.org/html/rfc7540#page-77
|
||||
nghttp2_error_code enums are identical.
|
||||
*/
|
||||
const char *Curl_http2_strerror(uint32_t err) {
|
||||
const char *Curl_http2_strerror(uint32_t err)
|
||||
{
|
||||
#ifndef NGHTTP2_HAS_HTTP2_STRERROR
|
||||
const char *str[] = {
|
||||
"NO_ERROR", /* 0x0 */
|
||||
@ -284,7 +299,7 @@ static ssize_t send_callback(nghttp2_session *h2,
|
||||
/* We pass a pointer to this struct in the push callback, but the contents of
|
||||
the struct are hidden from the user. */
|
||||
struct curl_pushheaders {
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
const nghttp2_push_promise *frame;
|
||||
};
|
||||
|
||||
@ -317,7 +332,7 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
|
||||
the middle of header, it could be matched in middle of the value,
|
||||
this is because we do prefix match.*/
|
||||
if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
|
||||
Curl_raw_equal(header, ":") || strchr(header + 1, ':'))
|
||||
!strcmp(header, ":") || strchr(header + 1, ':'))
|
||||
return NULL;
|
||||
else {
|
||||
struct HTTP *stream = h->data->req.protop;
|
||||
@ -335,9 +350,9 @@ char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CURL *duphandle(struct SessionHandle *data)
|
||||
static struct Curl_easy *duphandle(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *second = curl_easy_duphandle(data);
|
||||
struct Curl_easy *second = curl_easy_duphandle(data);
|
||||
if(second) {
|
||||
/* setup the request struct */
|
||||
struct HTTP *http = calloc(1, sizeof(struct HTTP));
|
||||
@ -363,7 +378,7 @@ static CURL *duphandle(struct SessionHandle *data)
|
||||
}
|
||||
|
||||
|
||||
static int push_promise(struct SessionHandle *data,
|
||||
static int push_promise(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
const nghttp2_push_promise *frame)
|
||||
{
|
||||
@ -378,7 +393,7 @@ static int push_promise(struct SessionHandle *data,
|
||||
struct http_conn *httpc;
|
||||
size_t i;
|
||||
/* clone the parent */
|
||||
struct SessionHandle *newhandle = duphandle(data);
|
||||
struct Curl_easy *newhandle = duphandle(data);
|
||||
if(!newhandle) {
|
||||
infof(data, "failed to duplicate handle\n");
|
||||
rv = 1; /* FAIL HARD */
|
||||
@ -406,9 +421,11 @@ static int push_promise(struct SessionHandle *data,
|
||||
free(stream->push_headers[i]);
|
||||
free(stream->push_headers);
|
||||
stream->push_headers = NULL;
|
||||
stream->push_headers_used = 0;
|
||||
|
||||
if(rv) {
|
||||
/* denied, kill off the new handle again */
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
(void)Curl_close(newhandle);
|
||||
goto fail;
|
||||
}
|
||||
@ -423,6 +440,7 @@ static int push_promise(struct SessionHandle *data,
|
||||
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
|
||||
if(rc) {
|
||||
infof(data, "failed to add handle to multi\n");
|
||||
http2_stream_free(newhandle->req.protop);
|
||||
Curl_close(newhandle);
|
||||
rv = 1;
|
||||
goto fail;
|
||||
@ -445,7 +463,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct SessionHandle *data_s = NULL;
|
||||
struct Curl_easy *data_s = NULL;
|
||||
struct HTTP *stream = NULL;
|
||||
static int lastStream = -1;
|
||||
int rv;
|
||||
@ -482,14 +500,17 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
}
|
||||
if(!data_s) {
|
||||
DEBUGF(infof(conn->data,
|
||||
"No SessionHandle associated with stream: %x\n",
|
||||
"No Curl_easy associated with stream: %x\n",
|
||||
stream_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream = data_s->req.protop;
|
||||
if(!stream)
|
||||
if(!stream) {
|
||||
DEBUGF(infof(conn->data, "No proto pointer for stream: %x\n",
|
||||
stream_id));
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
|
||||
frame->hd.type, stream_id));
|
||||
@ -547,7 +568,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn_s->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 0);
|
||||
}
|
||||
break;
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
@ -573,7 +594,7 @@ static int on_invalid_frame_recv(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
int lib_error_code, void *userp)
|
||||
{
|
||||
struct SessionHandle *data_s = NULL;
|
||||
struct Curl_easy *data_s = NULL;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
@ -590,7 +611,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
const uint8_t *data, size_t len, void *userp)
|
||||
{
|
||||
struct HTTP *stream;
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
size_t nread;
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
@ -621,8 +642,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
|
||||
immediately? */
|
||||
Curl_expire(data_s, 0);
|
||||
|
||||
DEBUGF(infof(data_s, "%zu data received for stream %u "
|
||||
"(%zu left in buffer %p, total %zu)\n",
|
||||
@ -656,7 +676,7 @@ static int before_frame_send(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
@ -670,7 +690,7 @@ static int on_frame_send(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
@ -684,7 +704,7 @@ static int on_frame_not_send(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
int lib_error_code, void *userp)
|
||||
{
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
@ -698,7 +718,7 @@ static int on_frame_not_send(nghttp2_session *session,
|
||||
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
uint32_t error_code, void *userp)
|
||||
{
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
struct HTTP *stream;
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
@ -735,7 +755,7 @@ static int on_begin_headers(nghttp2_session *session,
|
||||
const nghttp2_frame *frame, void *userp)
|
||||
{
|
||||
struct HTTP *stream;
|
||||
struct SessionHandle *data_s = NULL;
|
||||
struct Curl_easy *data_s = NULL;
|
||||
(void)userp;
|
||||
|
||||
data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
|
||||
@ -802,7 +822,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
void *userp)
|
||||
{
|
||||
struct HTTP *stream;
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
int32_t stream_id = frame->hd.stream_id;
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)flags;
|
||||
@ -837,10 +857,9 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
stream->push_headers_alloc) {
|
||||
char **headp;
|
||||
stream->push_headers_alloc *= 2;
|
||||
headp = realloc(stream->push_headers,
|
||||
headp = Curl_saferealloc(stream->push_headers,
|
||||
stream->push_headers_alloc * sizeof(char *));
|
||||
if(!headp) {
|
||||
free(stream->push_headers);
|
||||
stream->push_headers = NULL;
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
@ -883,7 +902,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 0);
|
||||
|
||||
DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
||||
stream->status_code, data_s));
|
||||
@ -899,7 +918,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 0);
|
||||
|
||||
DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
|
||||
value));
|
||||
@ -914,7 +933,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
nghttp2_data_source *source,
|
||||
void *userp)
|
||||
{
|
||||
struct SessionHandle *data_s;
|
||||
struct Curl_easy *data_s;
|
||||
struct HTTP *stream = NULL;
|
||||
size_t nread;
|
||||
(void)source;
|
||||
@ -941,11 +960,12 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
memcpy(buf, stream->upload_mem, nread);
|
||||
stream->upload_mem += nread;
|
||||
stream->upload_len -= nread;
|
||||
if(data_s->state.infilesize != -1)
|
||||
stream->upload_left -= nread;
|
||||
}
|
||||
|
||||
if(stream->upload_left == 0)
|
||||
*data_flags = 1;
|
||||
*data_flags = NGHTTP2_DATA_FLAG_EOF;
|
||||
else if(nread == 0)
|
||||
return NGHTTP2_ERR_DEFERRED;
|
||||
|
||||
@ -956,14 +976,6 @@ static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
return nread;
|
||||
}
|
||||
|
||||
/*
|
||||
* The HTTP2 settings we send in the Upgrade request
|
||||
*/
|
||||
static nghttp2_settings_entry settings[] = {
|
||||
{ NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 },
|
||||
{ NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE },
|
||||
};
|
||||
|
||||
#define H2_BUFSIZE 32768
|
||||
|
||||
#ifdef NGHTTP2_HAS_ERROR_CALLBACK
|
||||
@ -979,6 +991,60 @@ static int error_callback(nghttp2_session *session,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void populate_settings(struct connectdata *conn,
|
||||
struct http_conn *httpc)
|
||||
{
|
||||
nghttp2_settings_entry *iv = httpc->local_settings;
|
||||
|
||||
iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||
iv[0].value = 100;
|
||||
|
||||
iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
|
||||
iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
|
||||
|
||||
iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
|
||||
iv[2].value = conn->data->multi->push_cb != NULL;
|
||||
|
||||
httpc->local_settings_num = 3;
|
||||
}
|
||||
|
||||
void Curl_http2_done(struct connectdata *conn, bool premature)
|
||||
{
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
|
||||
if(http->header_recvbuf) {
|
||||
DEBUGF(infof(data, "free header_recvbuf!!\n"));
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
Curl_add_buffer_free(http->trailer_recvbuf);
|
||||
http->trailer_recvbuf = NULL; /* clear the pointer */
|
||||
if(http->push_headers) {
|
||||
/* if they weren't used and then freed before */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(premature) {
|
||||
/* RST_STREAM */
|
||||
nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
|
||||
NGHTTP2_STREAM_CLOSED);
|
||||
if(http->stream_id == httpc->pause_stream_id) {
|
||||
infof(data, "stopped the pause stream!\n");
|
||||
httpc->pause_stream_id = 0;
|
||||
}
|
||||
}
|
||||
if(http->stream_id) {
|
||||
nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
|
||||
http->stream_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize nghttp2 for a Curl connection
|
||||
*/
|
||||
@ -1055,16 +1121,14 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
size_t blen;
|
||||
struct SingleRequest *k = &conn->data->req;
|
||||
uint8_t *binsettings = conn->proto.httpc.binsettings;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
|
||||
/* As long as we have a fixed set of settings, we don't have to dynamically
|
||||
* figure out the base64 strings since it'll always be the same. However,
|
||||
* the settings will likely not be fixed every time in the future.
|
||||
*/
|
||||
populate_settings(conn, httpc);
|
||||
|
||||
/* this returns number of bytes it wrote */
|
||||
binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
|
||||
settings,
|
||||
sizeof(settings)/sizeof(settings[0]));
|
||||
httpc->local_settings,
|
||||
httpc->local_settings_num);
|
||||
if(!binlen) {
|
||||
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
|
||||
return CURLE_FAILED_INIT;
|
||||
@ -1091,12 +1155,13 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
/*
|
||||
* Returns nonzero if current HTTP/2 session should be closed.
|
||||
*/
|
||||
static int should_close_session(struct http_conn *httpc) {
|
||||
static int should_close_session(struct http_conn *httpc)
|
||||
{
|
||||
return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) &&
|
||||
!nghttp2_session_want_write(httpc->h2);
|
||||
}
|
||||
|
||||
static int h2_session_send(struct SessionHandle *data,
|
||||
static int h2_session_send(struct Curl_easy *data,
|
||||
nghttp2_session *h2);
|
||||
|
||||
/*
|
||||
@ -1105,9 +1170,10 @@ static int h2_session_send(struct SessionHandle *data,
|
||||
* This function returns 0 if it succeeds, or -1 and error code will
|
||||
* be assigned to *err.
|
||||
*/
|
||||
static int h2_process_pending_input(struct SessionHandle *data,
|
||||
static int h2_process_pending_input(struct Curl_easy *data,
|
||||
struct http_conn *httpc,
|
||||
CURLcode *err) {
|
||||
CURLcode *err)
|
||||
{
|
||||
ssize_t nread;
|
||||
char *inbuf;
|
||||
ssize_t rv;
|
||||
@ -1155,9 +1221,41 @@ static int h2_process_pending_input(struct SessionHandle *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from transfer.c:done_sending when we stop uploading.
|
||||
*/
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if((conn->handler == &Curl_handler_http2_ssl) ||
|
||||
(conn->handler == &Curl_handler_http2)) {
|
||||
/* make sure this is only attempted for HTTP/2 transfers */
|
||||
|
||||
struct HTTP *stream = conn->data->req.protop;
|
||||
|
||||
if(stream->upload_left) {
|
||||
/* If the stream still thinks there's data left to upload. */
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
nghttp2_session *h2 = httpc->h2;
|
||||
|
||||
stream->upload_left = 0; /* DONE! */
|
||||
|
||||
/* resume sending here to trigger the callback to get called again so
|
||||
that it can signal EOF to nghttp2 */
|
||||
(void)nghttp2_session_resume_data(h2, stream->stream_id);
|
||||
|
||||
(void)h2_process_pending_input(conn->data, httpc, &result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
struct SessionHandle *data,
|
||||
struct HTTP *stream, CURLcode *err) {
|
||||
struct Curl_easy *data,
|
||||
struct HTTP *stream, CURLcode *err)
|
||||
{
|
||||
char *trailer_pos, *trailer_end;
|
||||
CURLcode result;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
@ -1178,8 +1276,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(data->state.drain == 0);
|
||||
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data
|
||||
function. */
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
|
||||
stream->closed = FALSE;
|
||||
if(stream->error_code != NGHTTP2_NO_ERROR) {
|
||||
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
|
||||
@ -1216,6 +1313,8 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
stream->close_handled = TRUE;
|
||||
|
||||
DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
|
||||
return 0;
|
||||
}
|
||||
@ -1226,7 +1325,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
|
||||
* struct.
|
||||
*/
|
||||
|
||||
static void h2_pri_spec(struct SessionHandle *data,
|
||||
static void h2_pri_spec(struct Curl_easy *data,
|
||||
nghttp2_priority_spec *pri_spec)
|
||||
{
|
||||
struct HTTP *depstream = (data->set.stream_depends_on?
|
||||
@ -1244,7 +1343,7 @@ static void h2_pri_spec(struct SessionHandle *data,
|
||||
* dependency settings and if so it submits a PRIORITY frame with the updated
|
||||
* info.
|
||||
*/
|
||||
static int h2_session_send(struct SessionHandle *data,
|
||||
static int h2_session_send(struct Curl_easy *data,
|
||||
nghttp2_session *h2)
|
||||
{
|
||||
struct HTTP *stream = data->req.protop;
|
||||
@ -1268,10 +1367,6 @@ static int h2_session_send(struct SessionHandle *data,
|
||||
return nghttp2_session_send(h2);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
|
||||
* a regular CURLcode value.
|
||||
*/
|
||||
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
char *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
@ -1279,7 +1374,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
ssize_t rv;
|
||||
ssize_t nread;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *stream = data->req.protop;
|
||||
|
||||
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
|
||||
@ -1297,7 +1392,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
stream->upload_len = 0;
|
||||
|
||||
/*
|
||||
* At this point 'stream' is just in the SessionHandle the connection
|
||||
* At this point 'stream' is just in the Curl_easy the connection
|
||||
* identifies as its owner at this time.
|
||||
*/
|
||||
|
||||
@ -1382,6 +1477,8 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
socket is not read. But it seems that usually streams are
|
||||
notified with its drain property, and socket is read again
|
||||
quickly. */
|
||||
DEBUGF(infof(data, "stream %x is paused, pause id: %x\n",
|
||||
stream->stream_id, httpc->pause_stream_id));
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
@ -1497,7 +1594,72 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
#define HEADER_OVERFLOW(x) \
|
||||
(x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen)
|
||||
|
||||
/* return number of received (decrypted) bytes */
|
||||
/*
|
||||
* Check header memory for the token "trailers".
|
||||
* Parse the tokens as separated by comma and surrounded by whitespace.
|
||||
* Returns TRUE if found or FALSE if not.
|
||||
*/
|
||||
static bool contains_trailers(const char *p, size_t len)
|
||||
{
|
||||
const char *end = p + len;
|
||||
for(;;) {
|
||||
for(; p != end && (*p == ' ' || *p == '\t'); ++p)
|
||||
;
|
||||
if(p == end || (size_t)(end - p) < sizeof("trailers") - 1)
|
||||
return FALSE;
|
||||
if(strncasecompare("trailers", p, sizeof("trailers") - 1)) {
|
||||
p += sizeof("trailers") - 1;
|
||||
for(; p != end && (*p == ' ' || *p == '\t'); ++p)
|
||||
;
|
||||
if(p == end || *p == ',')
|
||||
return TRUE;
|
||||
}
|
||||
/* skip to next token */
|
||||
for(; p != end && *p != ','; ++p)
|
||||
;
|
||||
if(p == end)
|
||||
return FALSE;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
/* Send header to server */
|
||||
HEADERINST_FORWARD,
|
||||
/* Don't send header to server */
|
||||
HEADERINST_IGNORE,
|
||||
/* Discard header, and replace it with "te: trailers" */
|
||||
HEADERINST_TE_TRAILERS
|
||||
} header_instruction;
|
||||
|
||||
/* Decides how to treat given header field. */
|
||||
static header_instruction inspect_header(const char *name, size_t namelen,
|
||||
const char *value, size_t valuelen) {
|
||||
switch(namelen) {
|
||||
case 2:
|
||||
if(!strncasecompare("te", name, namelen))
|
||||
return HEADERINST_FORWARD;
|
||||
|
||||
return contains_trailers(value, valuelen) ?
|
||||
HEADERINST_TE_TRAILERS : HEADERINST_IGNORE;
|
||||
case 7:
|
||||
return strncasecompare("upgrade", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 10:
|
||||
return (strncasecompare("connection", name, namelen) ||
|
||||
strncasecompare("keep-alive", name, namelen)) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 16:
|
||||
return strncasecompare("proxy-connection", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
case 17:
|
||||
return strncasecompare("transfer-encoding", name, namelen) ?
|
||||
HEADERINST_IGNORE : HEADERINST_FORWARD;
|
||||
default:
|
||||
return HEADERINST_FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
{
|
||||
@ -1525,6 +1687,14 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
|
||||
|
||||
if(stream->stream_id != -1) {
|
||||
if(stream->close_handled) {
|
||||
infof(conn->data, "stream %d closed\n", stream->stream_id);
|
||||
*err = CURLE_HTTP2_STREAM;
|
||||
return -1;
|
||||
}
|
||||
else if(stream->closed) {
|
||||
return http2_handle_stream_close(conn, conn->data, stream, err);
|
||||
}
|
||||
/* If stream_id != -1, we have dispatched request HEADERS, and now
|
||||
are going to send or sending request body in DATA frame */
|
||||
stream->upload_mem = mem;
|
||||
@ -1643,7 +1813,6 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
i = 3;
|
||||
while(i < nheader) {
|
||||
size_t hlen;
|
||||
int skip = 0;
|
||||
|
||||
hdbuf = line_end + 2;
|
||||
|
||||
@ -1661,12 +1830,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
goto fail;
|
||||
hlen = end - hdbuf;
|
||||
|
||||
if(hlen == 10 && Curl_raw_nequal("connection", hdbuf, 10)) {
|
||||
/* skip Connection: headers! */
|
||||
skip = 1;
|
||||
--nheader;
|
||||
}
|
||||
else if(hlen == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
|
||||
if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
|
||||
authority_idx = i;
|
||||
nva[i].name = (unsigned char *)":authority";
|
||||
nva[i].namelen = strlen((char *)nva[i].name);
|
||||
@ -1679,39 +1843,29 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
while(*hdbuf == ' ' || *hdbuf == '\t')
|
||||
++hdbuf;
|
||||
end = line_end;
|
||||
if(!skip) {
|
||||
|
||||
switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
|
||||
end - hdbuf)) {
|
||||
case HEADERINST_IGNORE:
|
||||
/* skip header fields prohibited by HTTP/2 specification. */
|
||||
--nheader;
|
||||
continue;
|
||||
case HEADERINST_TE_TRAILERS:
|
||||
nva[i].value = (uint8_t*)"trailers";
|
||||
nva[i].valuelen = sizeof("trailers") - 1;
|
||||
break;
|
||||
default:
|
||||
nva[i].value = (unsigned char *)hdbuf;
|
||||
nva[i].valuelen = (size_t)(end - hdbuf);
|
||||
}
|
||||
|
||||
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||
if(HEADER_OVERFLOW(nva[i])) {
|
||||
failf(conn->data, "Failed sending HTTP request: Header overflow");
|
||||
goto fail;
|
||||
}
|
||||
/* Inspect Content-Length header field and retrieve the request
|
||||
entity length so that we can set END_STREAM to the last DATA
|
||||
frame. */
|
||||
if(nva[i].namelen == 14 &&
|
||||
Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) {
|
||||
size_t j;
|
||||
stream->upload_left = 0;
|
||||
if(!nva[i].valuelen)
|
||||
goto fail;
|
||||
for(j = 0; j < nva[i].valuelen; ++j) {
|
||||
if(nva[i].value[j] < '0' || nva[i].value[j] > '9')
|
||||
goto fail;
|
||||
if(stream->upload_left >= CURL_OFF_T_MAX / 10)
|
||||
goto fail;
|
||||
stream->upload_left *= 10;
|
||||
stream->upload_left += nva[i].value[j] - '0';
|
||||
}
|
||||
DEBUGF(infof(conn->data,
|
||||
"request content-length=%"
|
||||
CURL_FORMAT_CURL_OFF_T
|
||||
"\n", stream->upload_left));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* :authority must come before non-pseudo header fields */
|
||||
if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
|
||||
@ -1724,24 +1878,22 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* Warn stream may be rejected if cumulative length of headers is too large.
|
||||
It appears nghttp2 will not send a header frame larger than 64KB. */
|
||||
#define MAX_ACC 60000 /* <64KB to account for some overhead */
|
||||
{
|
||||
size_t acc = 0;
|
||||
const size_t max_acc = 60000; /* <64KB to account for some overhead */
|
||||
|
||||
for(i = 0; i < nheader; ++i) {
|
||||
if(nva[i].namelen > max_acc - acc)
|
||||
break;
|
||||
acc += nva[i].namelen;
|
||||
acc += nva[i].namelen + nva[i].valuelen;
|
||||
|
||||
if(nva[i].valuelen > max_acc - acc)
|
||||
break;
|
||||
acc += nva[i].valuelen;
|
||||
DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
|
||||
nva[i].namelen, nva[i].name,
|
||||
nva[i].valuelen, nva[i].value));
|
||||
}
|
||||
|
||||
if(i != nheader) {
|
||||
if(acc > MAX_ACC) {
|
||||
infof(conn->data, "http2_send: Warning: The cumulative length of all "
|
||||
"headers exceeds %zu bytes and that could cause the "
|
||||
"stream to be rejected.\n", max_acc);
|
||||
"stream to be rejected.\n", MAX_ACC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1751,6 +1903,12 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
case HTTPREQ_PUT:
|
||||
if(conn->data->state.infilesize != -1)
|
||||
stream->upload_left = conn->data->state.infilesize;
|
||||
else
|
||||
/* data sending without specifying the data amount up front */
|
||||
stream->upload_left = -1; /* unknown, but not zero */
|
||||
|
||||
data_prd.read_callback = data_source_read_callback;
|
||||
data_prd.source.ptr = NULL;
|
||||
stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
|
||||
@ -1850,10 +2008,6 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
|
||||
Curl_multi_connchanged(conn->data->multi);
|
||||
|
||||
/* switch on TCP_NODELAY as we need to send off packets without delay for
|
||||
maximum throughput */
|
||||
Curl_tcpnodelay(conn, conn->sock[FIRSTSOCKET]);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -1864,7 +2018,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
int rv;
|
||||
ssize_t nproc;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *stream = conn->data->req.protop;
|
||||
|
||||
result = Curl_http2_setup(conn);
|
||||
@ -1893,9 +2047,13 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
conn->data);
|
||||
}
|
||||
else {
|
||||
populate_settings(conn, httpc);
|
||||
|
||||
/* stream ID is unknown at this point */
|
||||
stream->stream_id = -1;
|
||||
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
|
||||
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE,
|
||||
httpc->local_settings,
|
||||
httpc->local_settings_num);
|
||||
if(rv != 0) {
|
||||
failf(data, "nghttp2_submit_settings() failed: %s(%d)",
|
||||
nghttp2_strerror(rv), rv);
|
||||
@ -1903,6 +2061,16 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
|
||||
rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
|
||||
HTTP2_HUGE_WINDOW_SIZE);
|
||||
if(rv != 0) {
|
||||
failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
|
||||
nghttp2_strerror(rv), rv);
|
||||
return CURLE_HTTP2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we are going to copy mem to httpc->inbuf. This is required since
|
||||
mem is part of buffer pointed by stream->mem, and callbacks
|
||||
called by nghttp2_session_mem_recv() will write stream specific
|
||||
@ -1918,6 +2086,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
" after upgrade: len=%zu\n",
|
||||
nread);
|
||||
|
||||
if(nread)
|
||||
memcpy(httpc->inbuf, mem, nread);
|
||||
httpc->inbuflen = nread;
|
||||
|
||||
@ -1958,6 +2127,82 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child,
|
||||
bool exclusive)
|
||||
{
|
||||
struct Curl_http2_dep **tail;
|
||||
struct Curl_http2_dep *dep = calloc(1, sizeof(struct Curl_http2_dep));
|
||||
dep->data = child;
|
||||
|
||||
if(parent->set.stream_dependents && exclusive) {
|
||||
struct Curl_http2_dep *node = parent->set.stream_dependents;
|
||||
while(node) {
|
||||
node->data->set.stream_depends_on = child;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
tail = &child->set.stream_dependents;
|
||||
while(*tail)
|
||||
tail = &(*tail)->next;
|
||||
|
||||
DEBUGASSERT(!*tail);
|
||||
*tail = parent->set.stream_dependents;
|
||||
parent->set.stream_dependents = 0;
|
||||
}
|
||||
|
||||
tail = &parent->set.stream_dependents;
|
||||
while(*tail) {
|
||||
(*tail)->data->set.stream_depends_e = FALSE;
|
||||
tail = &(*tail)->next;
|
||||
}
|
||||
|
||||
DEBUGASSERT(!*tail);
|
||||
*tail = dep;
|
||||
|
||||
child->set.stream_depends_on = parent;
|
||||
child->set.stream_depends_e = exclusive;
|
||||
}
|
||||
|
||||
void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child)
|
||||
{
|
||||
struct Curl_http2_dep *last = 0;
|
||||
struct Curl_http2_dep *data = parent->set.stream_dependents;
|
||||
DEBUGASSERT(child->set.stream_depends_on == parent);
|
||||
|
||||
while(data && data->data != child) {
|
||||
last = data;
|
||||
data = data->next;
|
||||
}
|
||||
|
||||
DEBUGASSERT(data);
|
||||
|
||||
if(data) {
|
||||
if(last) {
|
||||
last->next = data->next;
|
||||
}
|
||||
else {
|
||||
parent->set.stream_dependents = data->next;
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
child->set.stream_depends_on = 0;
|
||||
child->set.stream_depends_e = FALSE;
|
||||
}
|
||||
|
||||
void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
|
||||
{
|
||||
while(data->set.stream_dependents) {
|
||||
struct Curl_easy *tmp = data->set.stream_dependents->data;
|
||||
Curl_http2_remove_child(data, tmp);
|
||||
if(data->set.stream_depends_on)
|
||||
Curl_http2_add_child(data->set.stream_depends_on, tmp, FALSE);
|
||||
}
|
||||
|
||||
if(data->set.stream_depends_on)
|
||||
Curl_http2_remove_child(data->set.stream_depends_on, data);
|
||||
}
|
||||
|
||||
#else /* !USE_NGHTTP2 */
|
||||
|
||||
/* Satisfy external references even if http2 is not compiled in. */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -50,7 +50,14 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
const char *data, size_t nread);
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
void Curl_http2_setup_req(struct SessionHandle *data);
|
||||
void Curl_http2_setup_req(struct Curl_easy *data);
|
||||
void Curl_http2_done(struct connectdata *conn, bool premature);
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn);
|
||||
void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child,
|
||||
bool exclusive);
|
||||
void Curl_http2_remove_child(struct Curl_easy *parent,
|
||||
struct Curl_easy *child);
|
||||
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
@ -61,6 +68,11 @@ void Curl_http2_setup_req(struct SessionHandle *data);
|
||||
#define Curl_http2_setup_req(x)
|
||||
#define Curl_http2_init_state(x)
|
||||
#define Curl_http2_init_userset(x)
|
||||
#define Curl_http2_done(x,y)
|
||||
#define Curl_http2_done_sending(x)
|
||||
#define Curl_http2_add_child(x, y, z)
|
||||
#define Curl_http2_remove_child(x, y)
|
||||
#define Curl_http2_cleanup_dependencies(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
@ -108,7 +108,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
ssize_t *wrotep)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct Curl_chunker *ch = &conn->chunk;
|
||||
struct SingleRequest *k = &data->req;
|
||||
size_t piece;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "http_digest.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
@ -45,7 +45,7 @@ CURLcode Curl_input_digest(struct connectdata *conn,
|
||||
const char *header) /* rest of the *-authenticate:
|
||||
header */
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* Point to the correct struct with this */
|
||||
struct digestdata *digest;
|
||||
@ -73,9 +73,9 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
const unsigned char *uripath)
|
||||
{
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = conn->data;
|
||||
unsigned char *path;
|
||||
char *tmp;
|
||||
struct Curl_easy *data = conn->data;
|
||||
unsigned char *path = NULL;
|
||||
char *tmp = NULL;
|
||||
char *response;
|
||||
size_t len;
|
||||
bool have_chlg;
|
||||
@ -95,8 +95,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
if(proxy) {
|
||||
digest = &data->state.proxydigest;
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
authp = &data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
@ -140,12 +140,14 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
http://www.fngtps.com/2006/09/http-authentication
|
||||
*/
|
||||
|
||||
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
|
||||
if(authp->iestyle) {
|
||||
tmp = strchr((char *)uripath, '?');
|
||||
if(tmp) {
|
||||
size_t urilen = tmp - (char *)uripath;
|
||||
|
||||
path = (unsigned char *) aprintf("%.*s", urilen, uripath);
|
||||
}
|
||||
else
|
||||
}
|
||||
if(!tmp)
|
||||
path = (unsigned char *) strdup((char *) uripath);
|
||||
|
||||
if(!path)
|
||||
@ -169,7 +171,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
void Curl_digest_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
Curl_auth_digest_cleanup(&data->state.digest);
|
||||
Curl_auth_digest_cleanup(&data->state.proxydigest);
|
||||
|
@ -34,7 +34,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
const unsigned char *uripath);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||
void Curl_digest_cleanup(struct Curl_easy *data);
|
||||
#else
|
||||
#define Curl_digest_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "vauth/vauth.h"
|
||||
|
||||
@ -38,7 +37,8 @@
|
||||
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result;
|
||||
struct Curl_easy *data = conn->data;
|
||||
size_t len;
|
||||
|
||||
/* Point to the username, password, service and host */
|
||||
@ -51,11 +51,11 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
struct negotiatedata *neg_ctx;
|
||||
|
||||
if(proxy) {
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||
host = conn->proxy.name;
|
||||
host = conn->http_proxy.host.name;
|
||||
neg_ctx = &data->state.proxyneg;
|
||||
}
|
||||
else {
|
||||
@ -90,8 +90,13 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
|
||||
/* Initilise the security context and decode our challenge */
|
||||
return Curl_auth_decode_spnego_message(data, userp, passwdp, service, host,
|
||||
header, neg_ctx);
|
||||
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
|
||||
host, header, neg_ctx);
|
||||
|
||||
if(result)
|
||||
Curl_auth_spnego_cleanup(neg_ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
@ -124,7 +129,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data)
|
||||
{
|
||||
Curl_auth_spnego_cleanup(&data->state.negotiate);
|
||||
Curl_auth_spnego_cleanup(&data->state.proxyneg);
|
||||
|
@ -31,7 +31,7 @@ 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 SessionHandle *data);
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data);
|
||||
|
||||
#endif /* USE_SPNEGO */
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "vauth/vauth.h"
|
||||
@ -136,8 +136,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -31,19 +31,54 @@
|
||||
#include "http.h"
|
||||
#include "url.h"
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "progress.h"
|
||||
#include "non-ascii.h"
|
||||
#include "connect.h"
|
||||
#include "curlx.h"
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
/*
|
||||
* Perform SSL initialization for HTTPS proxy. Sets
|
||||
* proxy_ssl_connected connection bit when complete. Can be
|
||||
* called multiple times.
|
||||
*/
|
||||
static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
CURLcode result = CURLE_OK;
|
||||
DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS);
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex]) {
|
||||
/* perform SSL initialization for this socket */
|
||||
result =
|
||||
Curl_ssl_connect_nonblocking(conn, sockindex,
|
||||
&conn->bits.proxy_ssl_connected[sockindex]);
|
||||
if(result)
|
||||
conn->bits.close = TRUE; /* a failed connection is marked for closure to
|
||||
prevent (bad) re-use or similar */
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void) conn;
|
||||
(void) sockindex;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
|
||||
const CURLcode result = https_proxy_connect(conn, sockindex);
|
||||
if(result)
|
||||
return result;
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex])
|
||||
return result; /* wait for HTTPS proxy SSL initialization to complete */
|
||||
}
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/* for [protocol] tunneled through HTTP proxy */
|
||||
@ -63,21 +98,31 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
* original pointer
|
||||
*
|
||||
* This function might be called several times in the multi interface case
|
||||
* if the proxy's CONNTECT response is not instant.
|
||||
* if the proxy's CONNECT response is not instant.
|
||||
*/
|
||||
prot_save = conn->data->req.protop;
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
conn->data->req.protop = &http_proxy;
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
*/
|
||||
|
||||
if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else if(sockindex == SECONDARYSOCKET)
|
||||
hostname = conn->secondaryhostname;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
if(conn->bits.conn_to_port)
|
||||
|
||||
if(sockindex == SECONDARYSOCKET)
|
||||
remote_port = conn->secondary_port;
|
||||
else if(conn->bits.conn_to_port)
|
||||
remote_port = conn->conn_to_port;
|
||||
else
|
||||
remote_port = conn->remote_port;
|
||||
result = Curl_proxyCONNECT(conn, FIRSTSOCKET, hostname,
|
||||
result = Curl_proxyCONNECT(conn, sockindex, hostname,
|
||||
remote_port, FALSE);
|
||||
conn->data->req.protop = prot_save;
|
||||
if(CURLE_OK != result)
|
||||
@ -107,14 +152,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
bool blocking)
|
||||
{
|
||||
int subversion=0;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result;
|
||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||
curl_off_t cl=0;
|
||||
bool closeConnection = FALSE;
|
||||
bool chunked_encoding = FALSE;
|
||||
long check;
|
||||
time_t check;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
@ -159,9 +204,10 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(host_port);
|
||||
|
||||
if(!result) {
|
||||
char *host=(char *)"";
|
||||
char *host = NULL;
|
||||
const char *proxyconn="";
|
||||
const char *useragent="";
|
||||
const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
"1.0" : "1.1";
|
||||
bool ipv6_ip = conn->bits.ipv6_ip;
|
||||
char *hostheader;
|
||||
@ -185,6 +231,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
|
||||
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = conn->allocptr.uagent;
|
||||
@ -194,15 +243,17 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
"CONNECT %s HTTP/%s\r\n"
|
||||
"%s" /* Host: */
|
||||
"%s" /* Proxy-Authorization */
|
||||
"%s", /* User-Agent */
|
||||
"%s" /* User-Agent */
|
||||
"%s", /* Proxy-Connection */
|
||||
hostheader,
|
||||
http,
|
||||
host,
|
||||
host?host:"",
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
useragent);
|
||||
useragent,
|
||||
proxyconn);
|
||||
|
||||
if(host && *host)
|
||||
if(host)
|
||||
free(host);
|
||||
free(hostheader);
|
||||
|
||||
@ -239,7 +290,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(!blocking) {
|
||||
if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
|
||||
if(!Curl_conn_data_pending(conn, sockindex))
|
||||
/* return so we'll be called again polling-style */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
@ -264,7 +315,16 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
nread = 0;
|
||||
perline = 0;
|
||||
|
||||
while((nread<BUFSIZE) && (keepon && !error)) {
|
||||
while(nread < BUFSIZE && keepon && !error) {
|
||||
int writetype;
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
if(ptr >= &data->state.buffer[BUFSIZE]) {
|
||||
failf(data, "CONNECT response too large!");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
@ -273,25 +333,22 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
/* loop every second at least, less if the timeout is near */
|
||||
switch (Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD,
|
||||
check<1000L?check:1000)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
/* Read one byte at a time to avoid a race condition. Wait at most one
|
||||
second before looping to ensure continuous pgrsUpdates. */
|
||||
result = Curl_read(conn, tunnelsocket, ptr, 1, &gotbytes);
|
||||
if(result == CURLE_AGAIN) {
|
||||
if(SOCKET_READABLE(tunnelsocket, check<1000L?check:1000) == -1) {
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Proxy CONNECT aborted due to select/poll error");
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if(result) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
default:
|
||||
DEBUGASSERT(ptr+BUFSIZE-nread <= data->state.buffer+BUFSIZE+1);
|
||||
result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread,
|
||||
&gotbytes);
|
||||
if(result==CURLE_AGAIN)
|
||||
continue; /* go loop yourself */
|
||||
else if(result)
|
||||
keepon = FALSE;
|
||||
}
|
||||
else if(gotbytes <= 0) {
|
||||
keepon = FALSE;
|
||||
if(data->set.proxyauth && data->state.authproxy.avail) {
|
||||
/* proxy auth was requested and there was proxy auth available,
|
||||
then deem this as "mere" proxy disconnect */
|
||||
@ -302,16 +359,12 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
error = SELECT_ERROR;
|
||||
failf(data, "Proxy CONNECT aborted");
|
||||
}
|
||||
keepon = FALSE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* We got a whole chunk of data, which can be anything from one
|
||||
* byte to a set of lines and possibly just a piece of the last
|
||||
* line.
|
||||
*/
|
||||
int i;
|
||||
|
||||
nread += gotbytes;
|
||||
/* We got a byte of data */
|
||||
nread++;
|
||||
|
||||
if(keepon > TRUE) {
|
||||
/* This means we are currently ignoring a response-body */
|
||||
@ -321,7 +374,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
if(cl) {
|
||||
/* A Content-Length based body: simply count down the counter
|
||||
and make sure to break out of the loop when we're done! */
|
||||
cl -= gotbytes;
|
||||
cl--;
|
||||
if(cl <= 0) {
|
||||
keepon = FALSE;
|
||||
break;
|
||||
@ -335,7 +388,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
/* now parse the chunked piece of data so that we can
|
||||
properly tell when the stream ends */
|
||||
r = Curl_httpchunk_read(conn, ptr, gotbytes, &tookcareof);
|
||||
r = Curl_httpchunk_read(conn, ptr, 1, &tookcareof);
|
||||
if(r == CHUNKE_STOP) {
|
||||
/* we're done reading chunks! */
|
||||
infof(data, "chunk reading DONE\n");
|
||||
@ -343,21 +396,20 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* we did the full CONNECT treatment, go COMPLETE */
|
||||
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
|
||||
}
|
||||
else
|
||||
infof(data, "Read %zd bytes of chunk, continue\n",
|
||||
tookcareof);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||
|
||||
perline++; /* amount of bytes in this line so far */
|
||||
if(*ptr == 0x0a) {
|
||||
char letter;
|
||||
int writetype;
|
||||
|
||||
/* if this is not the end of a header line then continue */
|
||||
if(*ptr != 0x0a) {
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* convert from the network encoding */
|
||||
result = Curl_convert_from_network(data, line_start,
|
||||
perline);
|
||||
result = Curl_convert_from_network(data, line_start, perline);
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
if(result)
|
||||
return result;
|
||||
@ -372,8 +424,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
if(data->set.include_header)
|
||||
writetype |= CLIENTWRITE_BODY;
|
||||
|
||||
result = Curl_client_write(conn, writetype, line_start,
|
||||
perline);
|
||||
result = Curl_client_write(conn, writetype, line_start, perline);
|
||||
|
||||
data->info.header_size += (long)perline;
|
||||
data->req.headerbytecount += (long)perline;
|
||||
@ -400,36 +451,27 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
if(cl) {
|
||||
infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
|
||||
" bytes of response-body\n", cl);
|
||||
|
||||
/* remove the remaining chunk of what we already
|
||||
read */
|
||||
cl -= (gotbytes - i);
|
||||
|
||||
if(cl<=0)
|
||||
/* if the whole thing was already read, we are done!
|
||||
*/
|
||||
keepon=FALSE;
|
||||
}
|
||||
else if(chunked_encoding) {
|
||||
CHUNKcode r;
|
||||
|
||||
infof(data, "Ignore chunked response-body\n");
|
||||
|
||||
/* We set ignorebody true here since the chunked
|
||||
decoder function will acknowledge that. Pay
|
||||
attention so that this is cleared again when this
|
||||
function returns! */
|
||||
k->ignorebody = TRUE;
|
||||
infof(data, "%zd bytes of chunk left\n", gotbytes-i);
|
||||
|
||||
if(line_start[1] == '\n') {
|
||||
/* this can only be a LF if the letter at index 0
|
||||
was a CR */
|
||||
line_start++;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* now parse the chunked piece of data so that we can
|
||||
properly tell when the stream ends */
|
||||
r = Curl_httpchunk_read(conn, line_start+1,
|
||||
gotbytes -i, &gotbytes);
|
||||
r = Curl_httpchunk_read(conn, line_start + 1, 1, &gotbytes);
|
||||
if(r == CHUNKE_STOP) {
|
||||
/* we're done reading chunks! */
|
||||
infof(data, "chunk reading DONE\n");
|
||||
@ -438,9 +480,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
COMPLETE */
|
||||
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
|
||||
}
|
||||
else
|
||||
infof(data, "Read %zd bytes of chunk, continue\n",
|
||||
gotbytes);
|
||||
}
|
||||
else {
|
||||
/* without content-length or chunked encoding, we
|
||||
@ -449,22 +488,13 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
keepon = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
keepon = FALSE;
|
||||
if(200 == data->info.httpproxycode) {
|
||||
if(gotbytes - (i+1))
|
||||
failf(data, "Proxy CONNECT followed by %zd bytes "
|
||||
"of opaque data. Data ignored (known bug #39)",
|
||||
gotbytes - (i+1));
|
||||
}
|
||||
}
|
||||
/* we did the full CONNECT treatment, go to COMPLETE */
|
||||
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
|
||||
break; /* breaks out of for-loop, not switch() */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* keep a backup of the position we are about to blank */
|
||||
letter = line_start[perline];
|
||||
line_start[perline] = 0; /* zero terminate the buffer */
|
||||
if((checkprefix("WWW-Authenticate:", line_start) &&
|
||||
(401 == k->httpcode)) ||
|
||||
@ -484,22 +514,36 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
else if(checkprefix("Content-Length:", line_start)) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
/* A server MUST NOT send any Transfer-Encoding or
|
||||
Content-Length header fields in a 2xx (Successful)
|
||||
response to CONNECT. (RFC 7231 section 4.3.6) */
|
||||
failf(data, "Content-Length: in %03d response",
|
||||
k->httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
cl = curlx_strtoofft(line_start +
|
||||
strlen("Content-Length:"), NULL, 10);
|
||||
}
|
||||
else if(Curl_compareheader(line_start,
|
||||
"Connection:", "close"))
|
||||
else if(Curl_compareheader(line_start, "Connection:", "close"))
|
||||
closeConnection = TRUE;
|
||||
else if(Curl_compareheader(line_start,
|
||||
"Transfer-Encoding:",
|
||||
"chunked")) {
|
||||
if(k->httpcode/100 == 2) {
|
||||
/* A server MUST NOT send any Transfer-Encoding or
|
||||
Content-Length header fields in a 2xx (Successful)
|
||||
response to CONNECT. (RFC 7231 section 4.3.6) */
|
||||
failf(data, "Transfer-Encoding: in %03d response", k->httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
infof(data, "CONNECT responded chunked\n");
|
||||
chunked_encoding = TRUE;
|
||||
/* init our chunky engine */
|
||||
Curl_httpchunk_init(conn);
|
||||
}
|
||||
else if(Curl_compareheader(line_start,
|
||||
"Proxy-Connection:", "close"))
|
||||
else if(Curl_compareheader(line_start, "Proxy-Connection:", "close"))
|
||||
closeConnection = TRUE;
|
||||
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
@ -507,19 +551,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* store the HTTP code from the proxy */
|
||||
data->info.httpproxycode = k->httpcode;
|
||||
}
|
||||
/* put back the letter we blanked out before */
|
||||
line_start[perline]= letter;
|
||||
|
||||
perline = 0; /* line starts over here */
|
||||
line_start = ptr+1; /* this skips the zero byte we wrote */
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
ptr = data->state.buffer;
|
||||
line_start = ptr;
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
} /* while there's buffer left and loop is requested */
|
||||
|
||||
if(error)
|
||||
return CURLE_RECV_ERROR;
|
||||
@ -534,8 +573,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
if(conn->bits.close)
|
||||
/* the connection has been marked for closure, most likely in the
|
||||
Curl_http_auth_act() function and thus we can kill it at once
|
||||
below
|
||||
*/
|
||||
below */
|
||||
closeConnection = TRUE;
|
||||
}
|
||||
|
||||
@ -568,7 +606,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
/* failure, close this connection to avoid re-use */
|
||||
connclose(conn, "proxy CONNECT failure");
|
||||
streamclose(conn, "proxy CONNECT failure");
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* Default proxy timeout in milliseconds */
|
||||
#define PROXY_TIMEOUT (3600*1000)
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn);
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex);
|
||||
|
||||
#else
|
||||
#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
|
||||
#define Curl_proxy_connect(x) CURLE_OK
|
||||
#define Curl_proxy_connect(x,y) CURLE_OK
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_PROXY_H */
|
||||
|
@ -51,7 +51,7 @@
|
||||
#endif
|
||||
|
||||
#include "inet_ntop.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "if2ip.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -102,7 +102,7 @@ bool Curl_if_is_interface_name(const char *interf)
|
||||
|
||||
if(getifaddrs(&head) >= 0) {
|
||||
for(iface=head; iface != NULL; iface=iface->ifa_next) {
|
||||
if(curl_strequal(iface->ifa_name, interf)) {
|
||||
if(strcasecompare(iface->ifa_name, interf)) {
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
@ -132,7 +132,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
for(iface = head; iface != NULL; iface=iface->ifa_next) {
|
||||
if(iface->ifa_addr != NULL) {
|
||||
if(iface->ifa_addr->sa_family == af) {
|
||||
if(curl_strequal(iface->ifa_name, interf)) {
|
||||
if(strcasecompare(iface->ifa_name, interf)) {
|
||||
void *addr;
|
||||
char *ip;
|
||||
char scope[12] = "";
|
||||
@ -180,7 +180,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
}
|
||||
}
|
||||
else if((res == IF2IP_NOT_FOUND) &&
|
||||
curl_strequal(iface->ifa_name, interf)) {
|
||||
strcasecompare(iface->ifa_name, interf)) {
|
||||
res = IF2IP_AF_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -68,16 +68,15 @@
|
||||
#include "http.h" /* for HTTP proxy tunnel stuff */
|
||||
#include "socks.h"
|
||||
#include "imap.h"
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
#include "strerror.h"
|
||||
#include "select.h"
|
||||
#include "multiif.h"
|
||||
#include "url.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
|
||||
@ -131,7 +130,8 @@ const struct Curl_handler Curl_handler_imap = {
|
||||
ZERO_NULL, /* readwrite */
|
||||
PORT_IMAP, /* defport */
|
||||
CURLPROTO_IMAP, /* protocol */
|
||||
PROTOPT_CLOSEACTION /* flags */
|
||||
PROTOPT_CLOSEACTION| /* flags */
|
||||
PROTOPT_URLOPTIONS
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
@ -271,7 +271,7 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd)
|
||||
|
||||
/* Does the command name match and is it followed by a space character or at
|
||||
the end of line? */
|
||||
if(line + cmd_len <= end && Curl_raw_nequal(line, cmd, cmd_len) &&
|
||||
if(line + cmd_len <= end && strncasecompare(line, cmd, cmd_len) &&
|
||||
(line[cmd_len] == ' ' || line + cmd_len + 2 == end))
|
||||
return TRUE;
|
||||
|
||||
@ -648,7 +648,7 @@ static CURLcode imap_perform_authentication(struct connectdata *conn)
|
||||
static CURLcode imap_perform_list(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = data->req.protop;
|
||||
char *mailbox;
|
||||
|
||||
@ -683,7 +683,7 @@ static CURLcode imap_perform_list(struct connectdata *conn)
|
||||
static CURLcode imap_perform_select(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = data->req.protop;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
char *mailbox;
|
||||
@ -840,13 +840,13 @@ static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(imapcode != 'O') {
|
||||
failf(data, "Got unexpected imap-server response");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
else
|
||||
result = imap_perform_capability(conn);
|
||||
@ -860,7 +860,7 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
const char *line = data->state.buffer;
|
||||
size_t wordlen;
|
||||
@ -947,13 +947,13 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(imapcode != 'O') {
|
||||
if(data->set.use_ssl != CURLUSESSL_TRY) {
|
||||
failf(data, "STARTTLS denied. %c", imapcode);
|
||||
failf(data, "STARTTLS denied");
|
||||
result = CURLE_USE_SSL_FAILED;
|
||||
}
|
||||
else
|
||||
@ -971,7 +971,7 @@ static CURLcode imap_state_auth_resp(struct connectdata *conn,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
saslprogress progress;
|
||||
|
||||
@ -1005,7 +1005,7 @@ static CURLcode imap_state_login_resp(struct connectdata *conn,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
@ -1051,7 +1051,7 @@ static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = conn->data->req.protop;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
const char *line = data->state.buffer;
|
||||
@ -1098,7 +1098,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
struct pingpong *pp = &imapc->pp;
|
||||
const char *ptr = data->state.buffer;
|
||||
@ -1179,7 +1179,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
else {
|
||||
/* We don't know how to parse this line */
|
||||
failf(pp->conn->data, "Failed to parse FETCH response.");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
/* End of DO phase */
|
||||
@ -1198,7 +1198,7 @@ static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
|
||||
(void)instate; /* No use for this yet */
|
||||
|
||||
if(imapcode != 'O')
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */
|
||||
result = CURLE_WEIRD_SERVER_REPLY;
|
||||
else
|
||||
/* End of DONE phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@ -1211,7 +1211,7 @@ static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
(void)instate; /* No use for this yet */
|
||||
|
||||
@ -1275,7 +1275,7 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
|
||||
|
||||
/* Was there an error parsing the response line? */
|
||||
if(imapcode == -1)
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
return CURLE_WEIRD_SERVER_REPLY;
|
||||
|
||||
if(!imapcode)
|
||||
break;
|
||||
@ -1371,12 +1371,12 @@ static CURLcode imap_block_statemach(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Allocate and initialize the struct IMAP for the current SessionHandle if
|
||||
/* Allocate and initialize the struct IMAP for the current Curl_easy if
|
||||
required */
|
||||
static CURLcode imap_init(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap;
|
||||
|
||||
imap = data->req.protop = calloc(sizeof(struct IMAP), 1);
|
||||
@ -1456,7 +1456,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = data->req.protop;
|
||||
|
||||
(void)premature;
|
||||
@ -1518,7 +1518,7 @@ static CURLcode imap_perform(struct connectdata *conn, bool *connected,
|
||||
{
|
||||
/* This is IMAP and no proxy */
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = data->req.protop;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
bool selected = FALSE;
|
||||
@ -1683,7 +1683,7 @@ static CURLcode imap_regular_transfer(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
bool connected = FALSE;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* Make sure size is unknown at this point */
|
||||
data->req.size = -1;
|
||||
@ -1706,7 +1706,7 @@ static CURLcode imap_regular_transfer(struct connectdata *conn,
|
||||
|
||||
static CURLcode imap_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* Initialise the IMAP layer */
|
||||
CURLcode result = imap_init(conn);
|
||||
@ -1935,7 +1935,7 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
|
||||
while(*ptr && *ptr != ';')
|
||||
ptr++;
|
||||
|
||||
if(strnequal(key, "AUTH=", 5))
|
||||
if(strncasecompare(key, "AUTH=", 5))
|
||||
result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
|
||||
value, ptr - value);
|
||||
else
|
||||
@ -1971,7 +1971,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
|
||||
{
|
||||
/* The imap struct is already initialised in imap_connect() */
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = data->req.protop;
|
||||
const char *begin = data->state.path;
|
||||
const char *ptr = begin;
|
||||
@ -2031,28 +2031,28 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
|
||||
PARTIAL) stripping of the trailing slash character if it is present.
|
||||
|
||||
Note: Unknown parameters trigger a URL_MALFORMAT error. */
|
||||
if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) {
|
||||
if(strcasecompare(name, "UIDVALIDITY") && !imap->uidvalidity) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
imap->uidvalidity = value;
|
||||
value = NULL;
|
||||
}
|
||||
else if(Curl_raw_equal(name, "UID") && !imap->uid) {
|
||||
else if(strcasecompare(name, "UID") && !imap->uid) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
imap->uid = value;
|
||||
value = NULL;
|
||||
}
|
||||
else if(Curl_raw_equal(name, "SECTION") && !imap->section) {
|
||||
else if(strcasecompare(name, "SECTION") && !imap->section) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
imap->section = value;
|
||||
value = NULL;
|
||||
}
|
||||
else if(Curl_raw_equal(name, "PARTIAL") && !imap->partial) {
|
||||
else if(strcasecompare(name, "PARTIAL") && !imap->partial) {
|
||||
if(valuelen > 0 && value[valuelen - 1] == '/')
|
||||
value[valuelen - 1] = '\0';
|
||||
|
||||
@ -2101,7 +2101,7 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
|
||||
static CURLcode imap_parse_custom_request(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct IMAP *imap = data->req.protop;
|
||||
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
|
||||
|
||||
|
@ -49,9 +49,9 @@ typedef enum {
|
||||
IMAP_LAST /* never used */
|
||||
} imapstate;
|
||||
|
||||
/* This IMAP struct is used in the SessionHandle. All IMAP data that is
|
||||
/* This IMAP struct is used in the Curl_easy. All IMAP data that is
|
||||
connection-oriented must be in imap_conn to properly deal with the fact that
|
||||
perhaps the SessionHandle is changed between the times the connection is
|
||||
perhaps the Curl_easy is changed between the times the connection is
|
||||
used. */
|
||||
struct IMAP {
|
||||
curl_pp_transfer transfer;
|
||||
|
@ -103,7 +103,8 @@ inet_pton4(const char *src, unsigned char *dst)
|
||||
while((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if((pch = strchr(digits, ch)) != NULL) {
|
||||
pch = strchr(digits, ch);
|
||||
if(pch) {
|
||||
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
|
||||
|
||||
if(saw_digit && *tp == 0)
|
||||
@ -169,7 +170,8 @@ inet_pton6(const char *src, unsigned char *dst)
|
||||
while((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_l), ch);
|
||||
if(!pch)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if(pch != NULL) {
|
||||
val <<= 4;
|
||||
|
@ -150,7 +150,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
const char *host = conn->host.name;
|
||||
ssize_t nread;
|
||||
curl_socklen_t l = sizeof(conn->local_addr);
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
CURLcode result;
|
||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] :
|
||||
@ -182,7 +182,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
for(;;) {
|
||||
/* this really shouldn't be repeated here, but can't help it */
|
||||
if(service == srv_host) {
|
||||
result = Curl_ftpsendf(conn, "AUTH GSSAPI");
|
||||
result = Curl_ftpsend(conn, "AUTH GSSAPI");
|
||||
if(result)
|
||||
return -2;
|
||||
|
||||
@ -243,16 +243,22 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
}
|
||||
|
||||
if(output_buffer.length != 0) {
|
||||
char *cmd;
|
||||
|
||||
result = Curl_base64_encode(data, (char *)output_buffer.value,
|
||||
output_buffer.length, &p, &base64_sz);
|
||||
if(result) {
|
||||
Curl_infof(data, "base64-encoding: %s\n",
|
||||
curl_easy_strerror(result));
|
||||
ret = AUTH_CONTINUE;
|
||||
ret = AUTH_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
result = Curl_ftpsendf(conn, "ADAT %s", p);
|
||||
cmd = aprintf("ADAT %s", p);
|
||||
if(cmd)
|
||||
result = Curl_ftpsend(conn, cmd);
|
||||
else
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
||||
free(p);
|
||||
|
||||
|
@ -69,12 +69,11 @@
|
||||
#include "escape.h"
|
||||
#include "progress.h"
|
||||
#include "transfer.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "strtok.h"
|
||||
#include "curl_ldap.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_base64.h"
|
||||
#include "rawstr.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -192,7 +191,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
LDAPMessage *ldapmsg = NULL;
|
||||
LDAPMessage *entryIterator;
|
||||
int num = 0;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
int ldap_proto = LDAP_VERSION3;
|
||||
int ldap_ssl = 0;
|
||||
char *val_b64 = NULL;
|
||||
@ -272,7 +271,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
|
||||
#else
|
||||
int ldap_option;
|
||||
char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
|
||||
char *ldap_ca = conn->ssl_config.CAfile;
|
||||
#if defined(CURL_HAS_NOVELL_LDAPSDK)
|
||||
rc = ldapssl_client_init(NULL, NULL);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
@ -280,11 +279,11 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
if(data->set.ssl.verifypeer) {
|
||||
if(conn->ssl_config.verifypeer) {
|
||||
/* Novell SDK supports DER or BASE64 files. */
|
||||
int cert_type = LDAPSSL_CERT_FILETYPE_B64;
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
|
||||
if((data->set.ssl.cert_type) &&
|
||||
(strcasecompare(data->set.ssl.cert_type, "DER")))
|
||||
cert_type = LDAPSSL_CERT_FILETYPE_DER;
|
||||
if(!ldap_ca) {
|
||||
failf(data, "LDAP local: ERROR %s CA cert not set!",
|
||||
@ -322,10 +321,10 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
#elif defined(LDAP_OPT_X_TLS)
|
||||
if(data->set.ssl.verifypeer) {
|
||||
if(conn->ssl_config.verifypeer) {
|
||||
/* OpenLDAP SDK supports BASE64 files. */
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
|
||||
if((data->set.ssl.cert_type) &&
|
||||
(!strcasecompare(data->set.ssl.cert_type, "PEM"))) {
|
||||
failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
@ -708,15 +707,15 @@ static void _ldap_trace (const char *fmt, ...)
|
||||
*/
|
||||
static int str2scope(const char *p)
|
||||
{
|
||||
if(strequal(p, "one"))
|
||||
if(strcasecompare(p, "one"))
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
if(strequal(p, "onetree"))
|
||||
if(strcasecompare(p, "onetree"))
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
if(strequal(p, "base"))
|
||||
if(strcasecompare(p, "base"))
|
||||
return LDAP_SCOPE_BASE;
|
||||
if(strequal(p, "sub"))
|
||||
if(strcasecompare(p, "sub"))
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
if(strequal(p, "subtree"))
|
||||
if(strcasecompare(p, "subtree"))
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
return (-1);
|
||||
}
|
||||
@ -798,12 +797,13 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(*p) {
|
||||
char *dn = p;
|
||||
char *unescaped;
|
||||
CURLcode result;
|
||||
|
||||
LDAP_TRACE(("DN '%s'\n", dn));
|
||||
|
||||
/* Unescape the DN */
|
||||
unescaped = curl_easy_unescape(conn->data, dn, 0, NULL);
|
||||
if(!unescaped) {
|
||||
result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, FALSE);
|
||||
if(result) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
goto quit;
|
||||
@ -862,12 +862,14 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
char *unescaped;
|
||||
CURLcode result;
|
||||
|
||||
LDAP_TRACE(("attr[%d] '%s'\n", i, attributes[i]));
|
||||
|
||||
/* Unescape the attribute */
|
||||
unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
|
||||
if(!unescaped) {
|
||||
result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
|
||||
FALSE);
|
||||
if(result) {
|
||||
free(attributes);
|
||||
|
||||
rc = LDAP_NO_MEMORY;
|
||||
@ -930,12 +932,13 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
|
||||
if(*p) {
|
||||
char *filter = p;
|
||||
char *unescaped;
|
||||
CURLcode result;
|
||||
|
||||
LDAP_TRACE(("filter '%s'\n", filter));
|
||||
|
||||
/* Unescape the filter */
|
||||
unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
|
||||
if(!unescaped) {
|
||||
result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE);
|
||||
if(result) {
|
||||
rc = LDAP_NO_MEMORY;
|
||||
|
||||
goto quit;
|
||||
|
@ -1,53 +0,0 @@
|
||||
;
|
||||
; Definition file for the DLL version of the LIBCURL library from curl
|
||||
;
|
||||
|
||||
LIBRARY LIBCURL
|
||||
|
||||
;DESCRIPTION 'curl libcurl - https://curl.haxx.se'
|
||||
|
||||
EXPORTS
|
||||
curl_easy_cleanup @ 1 ;
|
||||
curl_easy_getinfo @ 2 ;
|
||||
curl_easy_init @ 3 ;
|
||||
curl_easy_perform @ 4 ;
|
||||
curl_easy_setopt @ 5 ;
|
||||
curl_escape @ 6 ;
|
||||
curl_unescape @ 7;
|
||||
curl_formfree @ 9 ;
|
||||
curl_getdate @ 10 ;
|
||||
curl_getenv @ 11 ;
|
||||
curl_global_cleanup @ 12 ;
|
||||
curl_global_init @ 13 ;
|
||||
curl_slist_append @ 14 ;
|
||||
curl_slist_free_all @ 15 ;
|
||||
curl_version @ 16 ;
|
||||
curl_maprintf @ 17 ;
|
||||
curl_mfprintf @ 18 ;
|
||||
curl_mprintf @ 19 ;
|
||||
curl_msprintf @ 20 ;
|
||||
curl_msnprintf @ 21 ;
|
||||
curl_mvfprintf @ 22 ;
|
||||
curl_strequal @ 23 ;
|
||||
curl_strnequal @ 24 ;
|
||||
curl_easy_duphandle @ 25 ;
|
||||
curl_formadd @ 26 ;
|
||||
curl_multi_init @ 27;
|
||||
curl_multi_add_handle @ 28;
|
||||
curl_multi_remove_handle @ 29;
|
||||
curl_multi_fdset @ 30;
|
||||
curl_multi_perform @ 31;
|
||||
curl_multi_cleanup @ 32;
|
||||
curl_multi_info_read @ 33;
|
||||
curl_free @ 34;
|
||||
curl_version_info @ 35;
|
||||
curl_share_init @ 36;
|
||||
curl_share_setopt @ 37;
|
||||
curl_share_cleanup @ 38;
|
||||
curl_global_init_mem @ 39;
|
||||
curl_easy_strerror @ 40;
|
||||
curl_multi_strerror @ 41;
|
||||
curl_share_strerror @ 42;
|
||||
curl_easy_reset @ 43;
|
||||
curl_mvsnprintf @ 44 ;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -44,14 +44,14 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "The cURL library, https://curl.haxx.se/\0"
|
||||
VALUE "CompanyName", "The curl library, https://curl.haxx.se/\0"
|
||||
VALUE "FileDescription", "libcurl Shared Library\0"
|
||||
VALUE "FileVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "InternalName", "libcurl\0"
|
||||
VALUE "OriginalFilename", "libcurl.dll\0"
|
||||
VALUE "ProductName", "The cURL library\0"
|
||||
VALUE "ProductName", "The curl library\0"
|
||||
VALUE "ProductVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "LegalCopyright", "© " LIBCURL_COPYRIGHT "\0"
|
||||
VALUE "LegalCopyright", "\xa9 " LIBCURL_COPYRIGHT "\0" /* a9: Copyright symbol */
|
||||
VALUE "License", "https://curl.haxx.se/docs/copyright.html\0"
|
||||
END
|
||||
END
|
||||
|
@ -213,7 +213,8 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
if(ctx->lo < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += (MD4_u32plus)size >> 29;
|
||||
|
||||
|
@ -124,7 +124,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
CC_MD5_Final(digest, ctx);
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
|
||||
|
||||
#include <wincrypt.h>
|
||||
#include "curl_memory.h"
|
||||
@ -402,7 +402,8 @@ static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
if(ctx->lo < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += (MD5_u32plus)size >> 29;
|
||||
|
||||
|
@ -119,7 +119,7 @@ void curl_memdebug(const char *logname)
|
||||
logfile = stderr;
|
||||
#ifdef MEMDEBUG_LOG_SYNC
|
||||
/* Flush the log file after every line so the log isn't lost in a crash */
|
||||
setvbuf(logfile, (char *)NULL, _IOLBF, 0);
|
||||
setbuf(logfile, (char *)NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
# * | (__| |_| | _ <| |___
|
||||
# * \___|\___/|_| \_\_____|
|
||||
# *
|
||||
# * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# *
|
||||
# * This software is licensed as described in the file COPYING, which
|
||||
# * you should have received as part of this distribution. The terms
|
||||
@ -30,11 +30,11 @@
|
||||
# dependency is the OpenSSL commandline tool for optional text listing.
|
||||
# Hacked by Guenter Knauf.
|
||||
#
|
||||
use Encode;
|
||||
use Getopt::Std;
|
||||
use MIME::Base64;
|
||||
use LWP::UserAgent;
|
||||
use strict;
|
||||
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
|
||||
use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w);
|
||||
use List::Util;
|
||||
use Text::Wrap;
|
||||
my $MOD_SHA = "Digest::SHA";
|
||||
@ -43,18 +43,19 @@ if ($@) {
|
||||
$MOD_SHA = "Digest::SHA::PurePerl";
|
||||
eval "require $MOD_SHA";
|
||||
}
|
||||
eval "require LWP::UserAgent";
|
||||
|
||||
my %urls = (
|
||||
'nss' =>
|
||||
'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
|
||||
'https://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
|
||||
'central' =>
|
||||
'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'aurora' =>
|
||||
'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'https://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'beta' =>
|
||||
'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'release' =>
|
||||
'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
);
|
||||
|
||||
$opt_d = 'release';
|
||||
@ -62,7 +63,7 @@ $opt_d = 'release';
|
||||
# If the OpenSSL commandline is not in search path you can configure it here!
|
||||
my $openssl = 'openssl';
|
||||
|
||||
my $version = '1.25';
|
||||
my $version = '1.27';
|
||||
|
||||
$opt_w = 76; # default base64 encoded lines length
|
||||
|
||||
@ -109,7 +110,7 @@ my @valid_signature_algorithms = (
|
||||
|
||||
$0 =~ s@.*(/|\\)@@;
|
||||
$Getopt::Std::STANDARD_HELP_VERSION = 1;
|
||||
getopts('bd:fhilnp:qs:tuvw:');
|
||||
getopts('bd:fhiklmnp:qs:tuvw:');
|
||||
|
||||
if(!defined($opt_d)) {
|
||||
# to make plain "-d" use not cause warnings, and actually still work
|
||||
@ -117,7 +118,16 @@ if(!defined($opt_d)) {
|
||||
}
|
||||
|
||||
# Use predefined URL or else custom URL specified on command line.
|
||||
my $url = ( defined( $urls{$opt_d} ) ) ? $urls{$opt_d} : $opt_d;
|
||||
my $url;
|
||||
if(defined($urls{$opt_d})) {
|
||||
$url = $urls{$opt_d};
|
||||
if(!$opt_k && $url !~ /^https:\/\//i) {
|
||||
die "The URL for '$opt_d' is not HTTPS. Use -k to override (insecure).\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$url = $opt_d;
|
||||
}
|
||||
|
||||
my $curl = `curl -V`;
|
||||
|
||||
@ -128,8 +138,8 @@ if ($opt_i) {
|
||||
print "Operating System Name : $^O\n";
|
||||
print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n";
|
||||
print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n";
|
||||
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n";
|
||||
print "LWP.pm Version : ${LWP::VERSION}\n";
|
||||
print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n" if($LWP::UserAgent::VERSION);
|
||||
print "LWP.pm Version : ${LWP::VERSION}\n" if($LWP::VERSION);
|
||||
print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION);
|
||||
print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION);
|
||||
print ("=" x 78 . "\n");
|
||||
@ -139,7 +149,7 @@ sub warning_message() {
|
||||
if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit
|
||||
print "Warning: Use of this script may pose some risk:\n";
|
||||
print "\n";
|
||||
print " 1) Using http is subject to man in the middle attack of certdata content\n";
|
||||
print " 1) If you use HTTP URLs they are subject to a man in the middle attack\n";
|
||||
print " 2) Default to 'release', but more recent updates may be found in other trees\n";
|
||||
print " 3) certdata.txt file format may change, lag time to update this script\n";
|
||||
print " 4) Generally unwise to blindly trust CAs without manual review & verification\n";
|
||||
@ -153,14 +163,16 @@ sub warning_message() {
|
||||
}
|
||||
|
||||
sub HELP_MESSAGE() {
|
||||
print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
|
||||
print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-k] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n";
|
||||
print "\t-b\tbackup an existing version of ca-bundle.crt\n";
|
||||
print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n";
|
||||
print "\t\t Valid names are:\n";
|
||||
print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n";
|
||||
print "\t-f\tforce rebuild even if certdata.txt is current\n";
|
||||
print "\t-i\tprint version info about used modules\n";
|
||||
print "\t-k\tallow URLs other than HTTPS, enable HTTP fallback (insecure)\n";
|
||||
print "\t-l\tprint license info about certdata.txt\n";
|
||||
print "\t-m\tinclude meta data in output\n";
|
||||
print "\t-n\tno download of certdata.txt (to use existing)\n";
|
||||
print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n";
|
||||
print "\t\t Valid purposes are:\n";
|
||||
@ -224,33 +236,34 @@ sub parse_csv_param($$@) {
|
||||
return @values;
|
||||
}
|
||||
|
||||
sub sha1 {
|
||||
sub sha256 {
|
||||
my $result;
|
||||
if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) {
|
||||
open(FILE, $_[0]) or die "Can't open '$_[0]': $!";
|
||||
binmode(FILE);
|
||||
$result = $MOD_SHA->new(1)->addfile(*FILE)->hexdigest;
|
||||
$result = $MOD_SHA->new(256)->addfile(*FILE)->hexdigest;
|
||||
close(FILE);
|
||||
} else {
|
||||
# Use OpenSSL command if Perl Digest::SHA modules not available
|
||||
$result = (split(/ |\r|\n/,`$openssl dgst -sha1 $_[0]`))[1];
|
||||
$result = `"$openssl" dgst -r -sha256 "$_[0]"`;
|
||||
$result =~ s/^([0-9a-f]{64}) .+/$1/is;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
sub oldsha1 {
|
||||
my $sha1 = "";
|
||||
sub oldhash {
|
||||
my $hash = "";
|
||||
open(C, "<$_[0]") || return 0;
|
||||
while(<C>) {
|
||||
chomp;
|
||||
if($_ =~ /^\#\# SHA1: (.*)/) {
|
||||
$sha1 = $1;
|
||||
if($_ =~ /^\#\# SHA256: (.*)/) {
|
||||
$hash = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(C);
|
||||
return $sha1;
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if ( $opt_p !~ m/:/ ) {
|
||||
@ -282,34 +295,66 @@ my $stdout = $crt eq '-';
|
||||
my $resp;
|
||||
my $fetched;
|
||||
|
||||
my $oldsha1 = oldsha1($crt);
|
||||
my $oldhash = oldhash($crt);
|
||||
|
||||
report "SHA1 of old file: $oldsha1";
|
||||
report "SHA256 of old file: $oldhash";
|
||||
|
||||
report "Downloading '$txt' ...";
|
||||
if(!$opt_n) {
|
||||
report "Downloading $txt ...";
|
||||
|
||||
if($curl && !$opt_n) {
|
||||
my $https = $url;
|
||||
$https =~ s/^http:/https:/;
|
||||
report "Get certdata over HTTPS with curl!";
|
||||
# If we have an HTTPS URL then use curl
|
||||
if($url =~ /^https:\/\//i) {
|
||||
if($curl) {
|
||||
if($curl =~ /^Protocols:.* https( |$)/m) {
|
||||
report "Get certdata with curl!";
|
||||
my $proto = !$opt_k ? "--proto =https" : "";
|
||||
my $quiet = $opt_q ? "-s" : "";
|
||||
my @out = `curl -w %{response_code} $quiet -O $https`;
|
||||
my @out = `curl -w %{response_code} $proto $quiet -o "$txt" "$url"`;
|
||||
if(@out && $out[0] == 200) {
|
||||
$fetched = 1;
|
||||
} else {
|
||||
report "Failed downloading HTTPS with curl, trying HTTP with LWP";
|
||||
report "Downloaded $txt";
|
||||
}
|
||||
else {
|
||||
report "Failed downloading via HTTPS with curl";
|
||||
if(-e $txt && !unlink($txt)) {
|
||||
report "Failed to remove '$txt': $!";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
report "curl lacks https support";
|
||||
}
|
||||
}
|
||||
else {
|
||||
report "curl not found";
|
||||
}
|
||||
}
|
||||
|
||||
unless ($fetched || ($opt_n and -e $txt)) {
|
||||
# If nothing was fetched then use LWP
|
||||
if(!$fetched) {
|
||||
if($url =~ /^https:\/\//i) {
|
||||
report "Falling back to HTTP";
|
||||
$url =~ s/^https:\/\//http:\/\//i;
|
||||
}
|
||||
if(!$opt_k) {
|
||||
report "URLs other than HTTPS are disabled by default, to enable use -k";
|
||||
exit 1;
|
||||
}
|
||||
report "Get certdata with LWP!";
|
||||
if(!defined(${LWP::UserAgent::VERSION})) {
|
||||
report "LWP is not available (LWP::UserAgent not found)";
|
||||
exit 1;
|
||||
}
|
||||
my $ua = new LWP::UserAgent(agent => "$0/$version");
|
||||
$ua->env_proxy();
|
||||
$resp = $ua->mirror($url, $txt);
|
||||
if($resp && $resp->code eq '304') {
|
||||
report "Not modified";
|
||||
exit 0 if -e $crt && !$opt_f;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$fetched = 1;
|
||||
report "Downloaded $txt";
|
||||
}
|
||||
if(!$resp || $resp->code !~ /^(?:200|304)$/) {
|
||||
report "Unable to download latest data: "
|
||||
@ -317,6 +362,7 @@ unless ($fetched || ($opt_n and -e $txt)) {
|
||||
exit 1 if -e $crt || ! -r $txt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $filedate = $resp ? $resp->last_modified : (stat($txt))[9];
|
||||
my $datesrc = "as of";
|
||||
@ -327,14 +373,14 @@ if(!$filedate) {
|
||||
}
|
||||
|
||||
# get the hash from the download file
|
||||
my $newsha1= sha1($txt);
|
||||
my $newhash= sha256($txt);
|
||||
|
||||
if(!$opt_f && $oldsha1 eq $newsha1) {
|
||||
if(!$opt_f && $oldhash eq $newhash) {
|
||||
report "Downloaded file identical to previous run\'s source file. Exiting";
|
||||
exit;
|
||||
}
|
||||
|
||||
report "SHA1 of new file: $newsha1";
|
||||
report "SHA256 of new file: $newhash";
|
||||
|
||||
my $currentdate = scalar gmtime($filedate);
|
||||
|
||||
@ -348,7 +394,7 @@ print CRT <<EOT;
|
||||
##
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla ${datesrc}: ${currentdate}
|
||||
## Certificate data from Mozilla ${datesrc}: ${currentdate} GMT
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
@ -361,7 +407,7 @@ print CRT <<EOT;
|
||||
## Just configure this file as the SSLCACertificateFile.
|
||||
##
|
||||
## Conversion done with mk-ca-bundle.pl version $version.
|
||||
## SHA1: $newsha1
|
||||
## SHA256: $newhash
|
||||
##
|
||||
|
||||
EOT
|
||||
@ -371,6 +417,7 @@ my $caname;
|
||||
my $certnum = 0;
|
||||
my $skipnum = 0;
|
||||
my $start_of_cert = 0;
|
||||
my @precert;
|
||||
|
||||
open(TXT,"$txt") or die "Couldn't open $txt: $!\n";
|
||||
while (<TXT>) {
|
||||
@ -383,11 +430,15 @@ while (<TXT>) {
|
||||
last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/);
|
||||
}
|
||||
}
|
||||
next if /^#|^\s*$/;
|
||||
chomp;
|
||||
if (/^CVS_ID\s+\"(.*)\"/) {
|
||||
print CRT "# $1\n";
|
||||
elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) {
|
||||
push @precert, $_;
|
||||
next;
|
||||
}
|
||||
elsif(/^#|^\s*$/) {
|
||||
undef @precert;
|
||||
next;
|
||||
}
|
||||
chomp;
|
||||
|
||||
# this is a match for the start of a certificate
|
||||
if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
|
||||
@ -436,8 +487,8 @@ while (<TXT>) {
|
||||
. $encoded
|
||||
. "-----END CERTIFICATE-----\n";
|
||||
print CRT "\n$caname\n";
|
||||
|
||||
my $maxStringLength = length($caname);
|
||||
print CRT @precert if($opt_m);
|
||||
my $maxStringLength = length(decode('UTF-8', $caname, Encode::FB_CROAK));
|
||||
if ($opt_t) {
|
||||
foreach my $key (keys %trust_purposes_by_level) {
|
||||
my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}});
|
||||
@ -479,7 +530,9 @@ while (<TXT>) {
|
||||
$certnum ++;
|
||||
$start_of_cert = 0;
|
||||
}
|
||||
undef @precert;
|
||||
}
|
||||
|
||||
}
|
||||
close(TXT) or die "Couldn't close $txt: $!\n";
|
||||
close(CRT) or die "Couldn't close $crt.~: $!\n";
|
||||
@ -495,5 +548,7 @@ unless( $stdout ) {
|
||||
}
|
||||
rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n";
|
||||
}
|
||||
unlink $txt if ($opt_u);
|
||||
if($opt_u && -e $txt && !unlink($txt)) {
|
||||
report "Failed to remove $txt: $!\n";
|
||||
}
|
||||
report "Done ($certnum CA certs processed, $skipnum skipped).";
|
||||
|
@ -26,20 +26,36 @@
|
||||
'* Hacked by Guenter Knauf
|
||||
'***************************************************************************
|
||||
Option Explicit
|
||||
Const myVersion = "0.3.9"
|
||||
Const myVersion = "0.4.0"
|
||||
|
||||
Const myUrl = "http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt"
|
||||
Const myOpenssl = "openssl.exe"
|
||||
Const myUrl = "https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt"
|
||||
|
||||
Const myCdSavF = FALSE ' Flag: save downloaded data to file certdata.txt
|
||||
Const myOpenSSL = "openssl.exe"
|
||||
Dim myUseOpenSSL
|
||||
myUseOpenSSL = TRUE ' Flag: TRUE to use OpenSSL. If TRUE and is not
|
||||
' found then a warning is shown before continuing.
|
||||
|
||||
Const myCdSavF = TRUE ' Flag: save downloaded data to file certdata.txt
|
||||
Const myCaBakF = TRUE ' Flag: backup existing ca-bundle certificate
|
||||
Const myAskLiF = TRUE ' Flag: display certdata.txt license agreement
|
||||
Const myAskTiF = TRUE ' Flag: ask to include certificate text info
|
||||
Const myWrapLe = 76 ' Default length of base64 output lines
|
||||
|
||||
' cert info code doesn't work properly with any recent openssl, leave disabled.
|
||||
' Also: we want our certificate output by default to be as similar as possible
|
||||
' to mk-ca-bundle.pl and setting this TRUE changes the base64 width to
|
||||
' OpenSSL's built-in default width, which is not the same as mk-ca-bundle.pl.
|
||||
Const myAskTiF = FALSE ' Flag: ask to include certificate text info
|
||||
|
||||
'
|
||||
'******************* Nothing to configure below! *******************
|
||||
'
|
||||
Const adTypeBinary = 1
|
||||
Const adTypeText = 2
|
||||
Const adSaveCreateNotExist = 1
|
||||
Const adSaveCreateOverWrite = 2
|
||||
Dim objShell, objNetwork, objFSO, objHttp
|
||||
Dim myBase, mySelf, myFh, myTmpFh, myCdData, myCdFile, myCaFile, myTmpName, myBakNum, myOptTxt, i
|
||||
Dim myBase, mySelf, myStream, myTmpFh, myCdData, myCdFile
|
||||
Dim myCaFile, myTmpName, myBakNum, myOptTxt, i
|
||||
Set objNetwork = WScript.CreateObject("WScript.Network")
|
||||
Set objShell = WScript.CreateObject("WScript.Shell")
|
||||
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
|
||||
@ -47,14 +63,60 @@ Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest.5.1")
|
||||
If objHttp Is Nothing Then Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest")
|
||||
myBase = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\"))
|
||||
mySelf = Left(WScript.ScriptName, InstrRev(WScript.ScriptName, ".") - 1) & " " & myVersion
|
||||
|
||||
myCdFile = Mid(myUrl, InstrRev(myUrl, "/") + 1)
|
||||
myCaFile = "ca-bundle.crt"
|
||||
myTmpName = InputBox("Enter output filename:", mySelf, myCaFile)
|
||||
If Not (myTmpName = "") Then
|
||||
myCaFile = myTmpName
|
||||
myTmpName = InputBox("It will take a minute to download and parse the " & _
|
||||
"certificate data." & _
|
||||
vbLf & vbLf & _
|
||||
"Please enter the output filename:", mySelf, myCaFile)
|
||||
If (myTmpName = "") Then
|
||||
WScript.Quit 1
|
||||
End If
|
||||
' Lets ignore SSL invalid cert errors
|
||||
objHttp.Option(4) = 256 + 512 + 4096 + 8192
|
||||
myCaFile = myTmpName
|
||||
If (myCdFile = "") Then
|
||||
MsgBox("URL does not contain filename!"), vbCritical, mySelf
|
||||
WScript.Quit 1
|
||||
End If
|
||||
|
||||
' Don't use OpenSSL if it's not present.
|
||||
If (myUseOpenSSL = TRUE) Then
|
||||
Dim errnum
|
||||
|
||||
On Error Resume Next
|
||||
Call objShell.Run("""" & myOpenSSL & """ version", 0, TRUE)
|
||||
errnum = Err.Number
|
||||
On Error GoTo 0
|
||||
|
||||
If Not (errnum = 0) Then
|
||||
myUseOpenSSL = FALSE
|
||||
MsgBox("OpenSSL was not found so the certificate bundle will not " & _
|
||||
"include the SHA256 hash of the raw certificate data file " & _
|
||||
"that was used to generate the certificates in the bundle. " & _
|
||||
vbLf & vbLf & _
|
||||
"This does not have any effect on the certificate output, " & _
|
||||
"so this script will continue." & _
|
||||
vbLf & vbLf & _
|
||||
"If you want to set a custom location for OpenSSL or disable " & _
|
||||
"this message then edit the variables at the start of the " & _
|
||||
"script."), vbInformation, mySelf
|
||||
End If
|
||||
End If
|
||||
|
||||
If (myAskTiF = TRUE) And (myUseOpenSSL = TRUE) Then
|
||||
If (6 = objShell.PopUp("Do you want to include text information about " & _
|
||||
"each certificate?" & vbLf & _
|
||||
"(Requires OpenSSL.exe in the current directory " & _
|
||||
"or search path)",, _
|
||||
mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then
|
||||
myOptTxt = TRUE
|
||||
Else
|
||||
myOptTxt = FALSE
|
||||
End If
|
||||
End If
|
||||
|
||||
' Uncomment the line below to ignore SSL invalid cert errors
|
||||
' objHttp.Option(4) = 256 + 512 + 4096 + 8192
|
||||
objHttp.SetTimeouts 0, 5000, 10000, 10000
|
||||
objHttp.Open "GET", myUrl, FALSE
|
||||
objHttp.setRequestHeader "User-Agent", WScript.ScriptName & "/" & myVersion
|
||||
@ -63,15 +125,13 @@ If Not (objHttp.Status = 200) Then
|
||||
MsgBox("Failed to download '" & myCdFile & "': " & objHttp.Status & " - " & objHttp.StatusText), vbCritical, mySelf
|
||||
WScript.Quit 1
|
||||
End If
|
||||
' Convert data from ResponseBody instead of using ResponseText because of UTF-8
|
||||
myCdData = ConvertBinaryData(objHttp.ResponseBody)
|
||||
Set objHttp = Nothing
|
||||
' Write received data to file if enabled
|
||||
If (myCdSavF = TRUE) Then
|
||||
Set myFh = objFSO.OpenTextFile(myCdFile, 2, TRUE)
|
||||
myFh.Write myCdData
|
||||
myFh.Close
|
||||
Call SaveBinaryData(myCdFile, objHttp.ResponseBody)
|
||||
End If
|
||||
' Convert data from ResponseBody instead of using ResponseText because of UTF-8
|
||||
myCdData = ConvertBinaryToUTF8(objHttp.ResponseBody)
|
||||
Set objHttp = Nothing
|
||||
' Backup exitsing ca-bundle certificate file
|
||||
If (myCaBakF = TRUE) Then
|
||||
If objFSO.FileExists(myCaFile) Then
|
||||
@ -86,15 +146,7 @@ If (myCaBakF = TRUE) Then
|
||||
myTmpFh.Move myBakFile
|
||||
End If
|
||||
End If
|
||||
If (myAskTiF = TRUE) Then
|
||||
If (6 = objShell.PopUp("Do you want to include text information about each certificate?" & vbLf & _
|
||||
"(requires OpenSSL commandline in current directory or in search path)",, _
|
||||
mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then
|
||||
myOptTxt = TRUE
|
||||
Else
|
||||
myOptTxt = FALSE
|
||||
End If
|
||||
End If
|
||||
|
||||
' Process the received data
|
||||
Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts, myNumSkipped
|
||||
Dim myLabel, myOctets, myData, myPem, myRev, myUntrusted, j
|
||||
@ -102,23 +154,33 @@ myNumSkipped = 0
|
||||
myNumCerts = 0
|
||||
myData = ""
|
||||
myLines = Split(myCdData, vbLf, -1)
|
||||
Set myFh = objFSO.OpenTextFile(myCaFile, 2, TRUE)
|
||||
myFh.Write "##" & vbLf
|
||||
myFh.Write "## " & myCaFile & " -- Bundle of CA Root Certificates" & vbLf
|
||||
myFh.Write "##" & vbLf
|
||||
myFh.Write "## Converted at: " & Now & vbLf
|
||||
myFh.Write "##" & vbLf
|
||||
myFh.Write "## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf
|
||||
myFh.Write "## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf
|
||||
myFh.Write "## file (certdata.txt). This file can be found in the mozilla source tree:" & vbLf
|
||||
myFh.Write "## '/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt'" & vbLf
|
||||
myFh.Write "##" & vbLf
|
||||
myFh.Write "## It contains the certificates in PEM format and therefore" & vbLf
|
||||
myFh.Write "## can be directly used with curl / libcurl / php_curl, or with" & vbLf
|
||||
myFh.Write "## an Apache+mod_ssl webserver for SSL client authentication." & vbLf
|
||||
myFh.Write "## Just configure this file as the SSLCACertificateFile." & vbLf
|
||||
myFh.Write "##" & vbLf
|
||||
myFh.Write vbLf
|
||||
Set myStream = CreateObject("ADODB.Stream")
|
||||
myStream.Open
|
||||
myStream.Type = adTypeText
|
||||
myStream.Charset = "utf-8"
|
||||
myStream.WriteText "##" & vbLf & _
|
||||
"## Bundle of CA Root Certificates" & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## Certificate data from Mozilla as of: " & _
|
||||
ConvertDateToString(LocalDateToUTC(Now)) & " GMT" & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf & _
|
||||
"## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf & _
|
||||
"## file (certdata.txt). This file can be found in the mozilla source tree:" & vbLf & _
|
||||
"## " & myUrl & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## It contains the certificates in PEM format and therefore" & vbLf & _
|
||||
"## can be directly used with curl / libcurl / php_curl, or with" & vbLf & _
|
||||
"## an Apache+mod_ssl webserver for SSL client authentication." & vbLf & _
|
||||
"## Just configure this file as the SSLCACertificateFile." & vbLf & _
|
||||
"##" & vbLf & _
|
||||
"## Conversion done with mk-ca-bundle.vbs version " & myVersion & "." & vbLf
|
||||
If (myCdSavF = TRUE) And (myUseOpenSSL = TRUE) Then
|
||||
myStream.WriteText "## SHA256: " & FileSHA256(myCdFile) & vbLf
|
||||
End If
|
||||
myStream.WriteText "##" & vbLf & vbLf
|
||||
|
||||
myStream.WriteText vbLf
|
||||
For i = 0 To UBound(myLines)
|
||||
If InstrRev(myLines(i), "CKA_LABEL ") Then
|
||||
myPattern = "^CKA_LABEL\s+[A-Z0-9]+\s+""(.+?)"""
|
||||
@ -136,13 +198,13 @@ For i = 0 To UBound(myLines)
|
||||
If (myUntrusted = TRUE) Then
|
||||
myNumSkipped = myNumSkipped + 1
|
||||
Else
|
||||
myFh.Write myLabel & vbLf
|
||||
myFh.Write String(Len(myLabel), "=") & vbLf
|
||||
myStream.WriteText myLabel & vbLf
|
||||
myStream.WriteText String(Len(myLabel), "=") & vbLf
|
||||
myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _
|
||||
Base64Encode(myData) & vbLf & _
|
||||
"-----END CERTIFICATE-----" & vbLf
|
||||
If (myOptTxt = FALSE) Then
|
||||
myFh.Write myPem & vbLf
|
||||
myStream.WriteText myPem & vbLf
|
||||
Else
|
||||
Dim myCmd, myRval, myTmpIn, myTmpOut
|
||||
myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
@ -150,8 +212,8 @@ For i = 0 To UBound(myLines)
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE)
|
||||
myTmpFh.Write myPem
|
||||
myTmpFh.Close
|
||||
myCmd = myOpenssl & " x509 -md5 -fingerprint -text -inform PEM" & _
|
||||
" -in " & myTmpIn & " -out " & myTmpOut
|
||||
myCmd = """" & myOpenSSL & """ x509 -md5 -fingerprint -text " & _
|
||||
"-inform PEM -in " & myTmpIn & " -out " & myTmpOut
|
||||
myRval = objShell.Run (myCmd, 0, TRUE)
|
||||
objFSO.DeleteFile myTmpIn, TRUE
|
||||
If Not (myRval = 0) Then
|
||||
@ -160,7 +222,7 @@ For i = 0 To UBound(myLines)
|
||||
WScript.Quit 3
|
||||
End If
|
||||
Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1)
|
||||
myFh.Write myTmpFh.ReadAll & vbLf
|
||||
myStream.WriteText myTmpFh.ReadAll & vbLf
|
||||
myTmpFh.Close
|
||||
objFSO.DeleteFile myTmpOut, TRUE
|
||||
End If
|
||||
@ -176,7 +238,7 @@ For i = 0 To UBound(myLines)
|
||||
If InstrRev(myLines(i), "CVS_ID ") Then
|
||||
myPattern = "^CVS_ID\s+""(.+?)"""
|
||||
myRev = RegExprFirst(myPattern, myLines(i))
|
||||
myFh.Write "# " & myRev & vbLf & vbLf
|
||||
myStream.WriteText "# " & myRev & vbLf & vbLf
|
||||
End If
|
||||
If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then
|
||||
myInsideCert = TRUE
|
||||
@ -187,7 +249,7 @@ For i = 0 To UBound(myLines)
|
||||
myInsideLicense = TRUE
|
||||
End If
|
||||
If (myInsideLicense = TRUE) Then
|
||||
myFh.Write myLines(i) & vbLf
|
||||
myStream.WriteText myLines(i) & vbLf
|
||||
myLicenseText = myLicenseText & Mid(myLines(i), 2) & vbLf
|
||||
End If
|
||||
If InstrRev(myLines(i), "***** END LICENSE BLOCK *****") Then
|
||||
@ -196,28 +258,54 @@ For i = 0 To UBound(myLines)
|
||||
If Not (6 = objShell.PopUp(myLicenseText & vbLf & _
|
||||
"Do you agree to the license shown above (required to proceed) ?",, _
|
||||
mySelf, vbQuestion + vbYesNo + vbDefaultButton1)) Then
|
||||
myFh.Close
|
||||
myStream.Close
|
||||
objFSO.DeleteFile myCaFile, TRUE
|
||||
WScript.Quit 2
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
myFh.Close
|
||||
|
||||
' To stop the UTF-8 BOM from being written the stream has to be copied and
|
||||
' then saved as binary.
|
||||
Dim myCopy
|
||||
Set myCopy = CreateObject("ADODB.Stream")
|
||||
myCopy.Type = adTypeBinary
|
||||
myCopy.Open
|
||||
myStream.Position = 3 ' Skip UTF-8 BOM
|
||||
myStream.CopyTo myCopy
|
||||
myCopy.SaveToFile myCaFile, adSaveCreateOverWrite
|
||||
myCopy.Close
|
||||
myStream.Close
|
||||
Set myCopy = Nothing
|
||||
Set myStream = Nothing
|
||||
|
||||
' Done
|
||||
objShell.PopUp "Done (" & myNumCerts & " CA certs processed, " & myNumSkipped & _
|
||||
" untrusted skipped).", 20, mySelf, vbInformation
|
||||
WScript.Quit 0
|
||||
|
||||
Function ConvertBinaryData(arrBytes)
|
||||
Function ConvertBinaryToUTF8(arrBytes)
|
||||
Dim objStream
|
||||
Set objStream = CreateObject("ADODB.Stream")
|
||||
objStream.Open
|
||||
objStream.Type = 1
|
||||
objStream.Type = adTypeBinary
|
||||
objStream.Write arrBytes
|
||||
objStream.Position = 0
|
||||
objStream.Type = 2
|
||||
objStream.Charset = "ascii"
|
||||
ConvertBinaryData = objStream.ReadText
|
||||
objStream.Type = adTypeText
|
||||
objStream.Charset = "utf-8"
|
||||
ConvertBinaryToUTF8 = objStream.ReadText
|
||||
Set objStream = Nothing
|
||||
End Function
|
||||
|
||||
Function SaveBinaryData(filename, data)
|
||||
Dim objStream
|
||||
Set objStream = CreateObject("ADODB.Stream")
|
||||
objStream.Type = adTypeBinary
|
||||
objStream.Open
|
||||
objStream.Write data
|
||||
objStream.SaveToFile filename, adSaveCreateOverWrite
|
||||
objStream.Close
|
||||
Set objStream = Nothing
|
||||
End Function
|
||||
|
||||
@ -283,4 +371,61 @@ Function MyASC(OneChar)
|
||||
If OneChar = "" Then MyASC = 0 Else MyASC = Asc(OneChar)
|
||||
End Function
|
||||
|
||||
' Return the date in the same format as perl to match mk-ca-bundle.pl output:
|
||||
' Wed Sep 7 03:12:05 2016
|
||||
Function ConvertDateToString(input)
|
||||
Dim output
|
||||
output = WeekDayName(WeekDay(input), TRUE) & " " & _
|
||||
MonthName(Month(input), TRUE) & " "
|
||||
If (Len(Day(input)) = 1) Then
|
||||
output = output & " "
|
||||
End If
|
||||
output = output & _
|
||||
Day(input) & " " & _
|
||||
FormatDateTime(input, vbShortTime) & ":"
|
||||
If (Len(Second(input)) = 1) Then
|
||||
output = output & "0"
|
||||
End If
|
||||
output = output & _
|
||||
Second(input) & " " & _
|
||||
Year(input)
|
||||
ConvertDateToString = output
|
||||
End Function
|
||||
|
||||
' Convert local Date to UTC. Microsoft says:
|
||||
' Use Win32_ComputerSystem CurrentTimeZone property, because it automatically
|
||||
' adjusts the Time Zone bias for daylight saving time; Win32_Time Zone Bias
|
||||
' property does not.
|
||||
' https://msdn.microsoft.com/en-us/library/windows/desktop/ms696015.aspx
|
||||
Function LocalDateToUTC(localdate)
|
||||
Dim item, offset
|
||||
For Each item In GetObject("winmgmts:").InstancesOf("Win32_ComputerSystem")
|
||||
offset = item.CurrentTimeZone ' the offset in minutes
|
||||
Next
|
||||
If (offset < 0) Then
|
||||
LocalDateToUTC = DateAdd("n", ABS(offset), localdate)
|
||||
Else
|
||||
LocalDateToUTC = DateAdd("n", -ABS(offset), localdate)
|
||||
End If
|
||||
'objShell.PopUp LocalDateToUTC
|
||||
End Function
|
||||
|
||||
Function FileSHA256(filename)
|
||||
Dim cmd, rval, tmpOut, tmpFh
|
||||
if (myUseOpenSSL = TRUE) Then
|
||||
tmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName
|
||||
cmd = """" & myOpenSSL & """ dgst -r -sha256 -out """ & tmpOut & """ """ & filename & """"
|
||||
rval = objShell.Run(cmd, 0, TRUE)
|
||||
If Not (rval = 0) Then
|
||||
MsgBox("Failed to get sha256 of """ & filename & """ with OpenSSL commandline!"), vbCritical, mySelf
|
||||
objFSO.DeleteFile tmpOut, TRUE
|
||||
WScript.Quit 3
|
||||
End If
|
||||
Set tmpFh = objFSO.OpenTextFile(tmpOut, 1)
|
||||
FileSHA256 = RegExprFirst("^([0-9a-f]{64}) .+", tmpFh.ReadAll)
|
||||
tmpFh.Close
|
||||
objFSO.DeleteFile tmpOut, TRUE
|
||||
Else
|
||||
FileSHA256 = ""
|
||||
End If
|
||||
End Function
|
||||
|
@ -92,7 +92,8 @@
|
||||
# define mp_uintmax_t unsigned long
|
||||
#endif
|
||||
|
||||
#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
|
||||
#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should
|
||||
fit negative DBL_MAX (317 letters) */
|
||||
#define MAX_PARAMETERS 128 /* lame static limit */
|
||||
|
||||
#ifdef __AMIGA__
|
||||
@ -227,9 +228,11 @@ static bool dprintf_IsQualifierNoDollar(const char *fmt)
|
||||
* Create an index with the type of each parameter entry and its
|
||||
* value (may vary in size)
|
||||
*
|
||||
* Returns zero on success.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
va_list arglist)
|
||||
{
|
||||
char *fmt = (char *)format;
|
||||
@ -301,7 +304,6 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
flags |= FLAGS_ALT;
|
||||
break;
|
||||
case '.':
|
||||
flags |= FLAGS_PREC;
|
||||
if('*' == *fmt) {
|
||||
/* The precision is picked from a specified parameter */
|
||||
|
||||
@ -393,6 +395,10 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
|
||||
i = this_param - 1;
|
||||
|
||||
if((i < 0) || (i >= MAX_PARAMETERS))
|
||||
/* out of allowed range */
|
||||
return 1;
|
||||
|
||||
switch (*fmt) {
|
||||
case 'S':
|
||||
flags |= FLAGS_ALT;
|
||||
@ -549,7 +555,7 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
|
||||
}
|
||||
}
|
||||
|
||||
return max_param;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@ -587,7 +593,8 @@ static int dprintf_formatf(
|
||||
char *workend = &work[sizeof(work) - 2];
|
||||
|
||||
/* Do the actual %-code parsing */
|
||||
dprintf_Pass1(format, vto, endpos, ap_save);
|
||||
if(dprintf_Pass1(format, vto, endpos, ap_save))
|
||||
return -1;
|
||||
|
||||
end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
|
||||
created for us */
|
||||
@ -910,12 +917,25 @@ static int dprintf_formatf(
|
||||
*fptr = 0;
|
||||
|
||||
if(width >= 0) {
|
||||
if(width >= (long)sizeof(work))
|
||||
width = sizeof(work)-1;
|
||||
/* RECURSIVE USAGE */
|
||||
len = curl_msnprintf(fptr, left, "%ld", width);
|
||||
fptr += len;
|
||||
left -= len;
|
||||
}
|
||||
if(prec >= 0) {
|
||||
/* for each digit in the integer part, we can have one less
|
||||
precision */
|
||||
size_t maxprec = sizeof(work) - 2;
|
||||
double val = p->data.dnum;
|
||||
while(val >= 10.0) {
|
||||
val /= 10;
|
||||
maxprec--;
|
||||
}
|
||||
|
||||
if(prec > (long)maxprec)
|
||||
prec = (long)maxprec-1;
|
||||
/* RECURSIVE USAGE */
|
||||
len = curl_msnprintf(fptr, left, ".%ld", prec);
|
||||
fptr += len;
|
||||
@ -935,7 +955,9 @@ static int dprintf_formatf(
|
||||
/* NOTE NOTE NOTE!! Not all sprintf implementations return number of
|
||||
output characters */
|
||||
(sprintf)(work, formatbuf, p->data.dnum);
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
assert(strlen(work) <= sizeof(work));
|
||||
#endif
|
||||
for(fptr=work; *fptr; fptr++)
|
||||
OUTCHAR(*fptr);
|
||||
}
|
||||
@ -992,7 +1014,7 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
|
||||
info.max = maxlength;
|
||||
|
||||
retcode = dprintf_formatf(&info, addbyter, format, ap_save);
|
||||
if(info.max) {
|
||||
if((retcode != -1) && info.max) {
|
||||
/* we terminate this with a zero byte */
|
||||
if(info.max == info.length)
|
||||
/* we're at maximum, scrap the last letter */
|
||||
@ -1029,16 +1051,19 @@ static int alloc_addbyter(int output, FILE *data)
|
||||
infop->len =0;
|
||||
}
|
||||
else if(infop->len+1 >= infop->alloc) {
|
||||
char *newptr;
|
||||
char *newptr = NULL;
|
||||
size_t newsize = infop->alloc*2;
|
||||
|
||||
newptr = realloc(infop->buffer, infop->alloc*2);
|
||||
/* detect wrap-around or other overflow problems */
|
||||
if(newsize > infop->alloc)
|
||||
newptr = realloc(infop->buffer, newsize);
|
||||
|
||||
if(!newptr) {
|
||||
infop->fail = 1;
|
||||
return -1; /* fail */
|
||||
}
|
||||
infop->buffer = newptr;
|
||||
infop->alloc *= 2;
|
||||
infop->alloc = newsize;
|
||||
}
|
||||
|
||||
infop->buffer[ infop->len ] = outc;
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "multihandle.h"
|
||||
#include "pipeline.h"
|
||||
#include "sigpipe.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -61,15 +63,15 @@
|
||||
#define CURL_MULTI_HANDLE 0x000bab1e
|
||||
|
||||
#define GOOD_MULTI_HANDLE(x) \
|
||||
((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE))
|
||||
((x) && (x)->type == CURL_MULTI_HANDLE)
|
||||
|
||||
static void singlesocket(struct Curl_multi *multi,
|
||||
struct SessionHandle *data);
|
||||
struct Curl_easy *data);
|
||||
static int update_timer(struct Curl_multi *multi);
|
||||
|
||||
static CURLMcode add_next_timeout(struct timeval now,
|
||||
struct Curl_multi *multi,
|
||||
struct SessionHandle *d);
|
||||
struct Curl_easy *d);
|
||||
static CURLMcode multi_timeout(struct Curl_multi *multi,
|
||||
long *timeout_ms);
|
||||
|
||||
@ -100,10 +102,10 @@ static const char * const statename[]={
|
||||
static void multi_freetimeout(void *a, void *b);
|
||||
|
||||
/* function pointer called once when switching TO a state */
|
||||
typedef void (*init_multistate_func)(struct SessionHandle *data);
|
||||
typedef void (*init_multistate_func)(struct Curl_easy *data);
|
||||
|
||||
/* always use this function to change state, to make debugging easier */
|
||||
static void mstate(struct SessionHandle *data, CURLMstate state
|
||||
static void mstate(struct Curl_easy *data, CURLMstate state
|
||||
#ifdef DEBUGBUILD
|
||||
, int lineno
|
||||
#endif
|
||||
@ -162,7 +164,7 @@ static void mstate(struct SessionHandle *data, CURLMstate state
|
||||
*/
|
||||
|
||||
struct Curl_sh_entry {
|
||||
struct SessionHandle *easy;
|
||||
struct Curl_easy *easy;
|
||||
int action; /* what action READ/WRITE this socket waits for */
|
||||
curl_socket_t socket; /* mainly to ease debugging */
|
||||
void *socketp; /* settable by users with curl_multi_assign() */
|
||||
@ -185,7 +187,7 @@ static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
|
||||
/* make sure this socket is present in the hash for this handle */
|
||||
static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
|
||||
curl_socket_t s,
|
||||
struct SessionHandle *data)
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_sh_entry *there = sh_getentry(sh, s);
|
||||
struct Curl_sh_entry *check;
|
||||
@ -334,7 +336,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
||||
|
||||
/* -1 means it not set by user, use the default value */
|
||||
multi->maxconnects = -1;
|
||||
return (CURLM *) multi;
|
||||
return multi;
|
||||
|
||||
error:
|
||||
|
||||
@ -350,25 +352,23 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CURLM *curl_multi_init(void)
|
||||
struct Curl_multi *curl_multi_init(void)
|
||||
{
|
||||
return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
|
||||
CURL_CONNECTION_HASH_SIZE);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
CURL *easy_handle)
|
||||
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct curl_llist *timeoutlist;
|
||||
struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data = (struct SessionHandle *)easy_handle;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
/* Verify that we got a somewhat good easy handle too */
|
||||
if(!GOOD_EASY_HANDLE(easy_handle))
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
/* Prevent users from adding same easy handle more than once and prevent
|
||||
@ -417,14 +417,14 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
data->state.conn_cache = &multi->conn_cache;
|
||||
|
||||
/* This adds the new entry at the 'end' of the doubly-linked circular
|
||||
list of SessionHandle structs to try and maintain a FIFO queue so
|
||||
list of Curl_easy structs to try and maintain a FIFO queue so
|
||||
the pipelined requests are in order. */
|
||||
|
||||
/* We add this new entry last in the list. */
|
||||
|
||||
data->next = NULL; /* end of the line */
|
||||
if(multi->easyp) {
|
||||
struct SessionHandle *last = multi->easylp;
|
||||
struct Curl_easy *last = multi->easylp;
|
||||
last->next = data;
|
||||
data->prev = last;
|
||||
multi->easylp = data; /* the new last node */
|
||||
@ -435,8 +435,8 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
multi->easylp = multi->easyp = data; /* both first and last */
|
||||
}
|
||||
|
||||
/* make the SessionHandle refer back to this multi handle */
|
||||
data->multi = multi_handle;
|
||||
/* make the Curl_easy refer back to this multi handle */
|
||||
data->multi = multi;
|
||||
|
||||
/* Set the timeout for this handle to expire really soon so that it will
|
||||
be taken care of even when this handle is added in the midst of operation
|
||||
@ -444,7 +444,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
sockets that time-out or have actions will be dealt with. Since this
|
||||
handle has no action yet, we make sure it times out to get things to
|
||||
happen. */
|
||||
Curl_expire(data, 1);
|
||||
Curl_expire(data, 0);
|
||||
|
||||
/* increase the node-counter */
|
||||
multi->num_easy++;
|
||||
@ -464,6 +464,14 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
||||
handle is added */
|
||||
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
||||
|
||||
/* The closure handle only ever has default timeouts set. To improve the
|
||||
state somewhat we clone the timeouts from each added handle so that the
|
||||
closure handle always has the same timeouts as the most recently added
|
||||
easy handle. */
|
||||
multi->closure_handle->set.timeout = data->set.timeout;
|
||||
multi->closure_handle->set.server_response_timeout =
|
||||
data->set.server_response_timeout;
|
||||
|
||||
update_timer(multi);
|
||||
return CURLM_OK;
|
||||
}
|
||||
@ -487,7 +495,7 @@ static void debug_print_sock_hash(void *p)
|
||||
/* Mark the connection as 'idle', or close it if the cache is full.
|
||||
Returns TRUE if the connection is kept, or FALSE if it was closed. */
|
||||
static bool
|
||||
ConnectionDone(struct SessionHandle *data, struct connectdata *conn)
|
||||
ConnectionDone(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
/* data->multi->maxconnects can be negative, deal with it. */
|
||||
size_t maxconnects =
|
||||
@ -523,7 +531,7 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
{
|
||||
CURLcode result;
|
||||
struct connectdata *conn;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
|
||||
DEBUGASSERT(*connp);
|
||||
|
||||
@ -571,12 +579,12 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
if((!premature &&
|
||||
conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||
if(conn->send_pipe->size + conn->recv_pipe->size != 0 &&
|
||||
!data->set.reuse_forbid &&
|
||||
!conn->bits.close)) {
|
||||
!conn->bits.close) {
|
||||
/* Stop if pipeline is not empty and we do not have to close
|
||||
connection. */
|
||||
data->easy_conn = NULL;
|
||||
DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -630,7 +638,10 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
|
||||
infof(data, "Connection #%ld to host %s left intact\n",
|
||||
conn->connection_id,
|
||||
conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
|
||||
conn->bits.httpproxy ? conn->http_proxy.host.dispname :
|
||||
conn->bits.conn_to_host ? conn->conn_to_host.dispname :
|
||||
conn->host.dispname);
|
||||
}
|
||||
else
|
||||
data->state.lastconnect = NULL;
|
||||
@ -645,12 +656,10 @@ static CURLcode multi_done(struct connectdata **connp,
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
CURL *curl_handle)
|
||||
CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *easy = curl_handle;
|
||||
struct SessionHandle *data = easy;
|
||||
struct Curl_easy *easy = data;
|
||||
bool premature;
|
||||
bool easy_owns_conn;
|
||||
struct curl_llist_element *e;
|
||||
@ -660,7 +669,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
/* Verify that we got a somewhat good easy handle too */
|
||||
if(!GOOD_EASY_HANDLE(curl_handle))
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
/* Prevent users from trying to remove same easy handle more than once */
|
||||
@ -689,7 +698,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
/* If the handle is in a pipeline and has started sending off its
|
||||
request but not received its response yet, we need to close
|
||||
connection. */
|
||||
connclose(data->easy_conn, "Removed with partial response");
|
||||
streamclose(data->easy_conn, "Removed with partial response");
|
||||
/* Set connection owner so that the DONE function closes it. We can
|
||||
safely do this here since connection is killed. */
|
||||
data->easy_conn->data = easy;
|
||||
@ -699,7 +708,7 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||
/* The timer must be shut down before data->multi is set to NULL,
|
||||
else the timenode will remain in the splay tree after
|
||||
curl_easy_cleanup is called. */
|
||||
Curl_expire(data, 0);
|
||||
Curl_expire_clear(data);
|
||||
|
||||
if(data->dns.hostcachetype == HCACHE_MULTI) {
|
||||
/* stop using the multi handle's DNS cache */
|
||||
@ -791,7 +800,7 @@ bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
|
||||
return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void Curl_multi_handlePipeBreak(struct SessionHandle *data)
|
||||
void Curl_multi_handlePipeBreak(struct Curl_easy *data)
|
||||
{
|
||||
data->easy_conn = NULL;
|
||||
}
|
||||
@ -807,6 +816,11 @@ static int waitconnect_getsock(struct connectdata *conn,
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
#ifdef USE_SSL
|
||||
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
|
||||
return Curl_ssl_getsock(conn, sock, numsocks);
|
||||
#endif
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
if(conn->tempsock[i] != CURL_SOCKET_BAD) {
|
||||
sock[s] = conn->tempsock[i];
|
||||
@ -844,7 +858,7 @@ static int domore_getsock(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* returns bitmapped flags for this handle and its sockets */
|
||||
static int multi_getsock(struct SessionHandle *data,
|
||||
static int multi_getsock(struct Curl_easy *data,
|
||||
curl_socket_t *socks, /* points to numsocks number
|
||||
of sockets */
|
||||
int numsocks)
|
||||
@ -910,15 +924,14 @@ static int multi_getsock(struct SessionHandle *data,
|
||||
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
CURLMcode curl_multi_fdset(struct Curl_multi *multi,
|
||||
fd_set *read_fd_set, fd_set *write_fd_set,
|
||||
fd_set *exc_fd_set, int *max_fd)
|
||||
{
|
||||
/* Scan through all the easy handles to get the file descriptors set.
|
||||
Some easy handles may not have connected to the remote host yet,
|
||||
and then we must make sure that is done. */
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
int this_max_fd=-1;
|
||||
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
|
||||
int bitmap;
|
||||
@ -960,14 +973,13 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_wait(CURLM *multi_handle,
|
||||
CURLMcode curl_multi_wait(struct Curl_multi *multi,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
|
||||
int bitmap;
|
||||
unsigned int i;
|
||||
@ -1130,7 +1142,7 @@ static bool multi_ischanged(struct Curl_multi *multi, bool clear)
|
||||
}
|
||||
|
||||
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
||||
struct SessionHandle *data,
|
||||
struct Curl_easy *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
CURLMcode rc;
|
||||
@ -1155,7 +1167,7 @@ static CURLcode multi_reconnect_request(struct connectdata **connp)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = *connp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
/* This was a re-use of a connection and we got a write error in the
|
||||
* DO-phase. Then we DISCONNECT this connection and have another attempt to
|
||||
@ -1223,7 +1235,7 @@ static CURLcode multi_do(struct connectdata **connp, bool *done)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
struct connectdata *conn = *connp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(conn->handler->do_it) {
|
||||
/* generic protocol-specific function pointer set in curl_connect() */
|
||||
@ -1286,7 +1298,7 @@ static CURLcode multi_do_more(struct connectdata *conn, int *complete)
|
||||
|
||||
static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct timeval now,
|
||||
struct SessionHandle *data)
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_message *msg = NULL;
|
||||
bool connected;
|
||||
@ -1297,14 +1309,18 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
CURLMcode rc;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SingleRequest *k;
|
||||
long timeout_ms;
|
||||
time_t timeout_ms;
|
||||
time_t recv_timeout_ms;
|
||||
time_t send_timeout_ms;
|
||||
int control;
|
||||
|
||||
if(!GOOD_EASY_HANDLE(data))
|
||||
return CURLM_BAD_EASY_HANDLE;
|
||||
|
||||
do {
|
||||
bool disconnect_conn = FALSE;
|
||||
/* A "stream" here is a logical stream if the protocol can handle that
|
||||
(HTTP/2), or the full connection for older protocols */
|
||||
bool stream_error = FALSE;
|
||||
rc = CURLM_OK;
|
||||
|
||||
/* Handle the case when the pipe breaks, i.e., the connection
|
||||
@ -1382,8 +1398,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
/* Force connection closed if the connection has indeed been used */
|
||||
if(data->mstate > CURLM_STATE_DO) {
|
||||
connclose(data->easy_conn, "Disconnected with pending data");
|
||||
disconnect_conn = TRUE;
|
||||
streamclose(data->easy_conn, "Disconnected with pending data");
|
||||
stream_error = TRUE;
|
||||
}
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
(void)multi_done(&data->easy_conn, result, TRUE);
|
||||
@ -1432,7 +1448,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* Add this handle to the send or pend pipeline */
|
||||
result = Curl_add_handle_to_pipeline(data, data->easy_conn);
|
||||
if(result)
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
else {
|
||||
if(async)
|
||||
/* We're now waiting for an asynchronous name lookup */
|
||||
@ -1466,8 +1482,8 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
const char *hostname;
|
||||
|
||||
if(conn->bits.proxy)
|
||||
hostname = conn->proxy.name;
|
||||
if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
@ -1524,7 +1540,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
if(result) {
|
||||
/* failure detected */
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1543,7 +1559,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
multistate(data, CURLM_STATE_CONNECT);
|
||||
}
|
||||
else if(!result) {
|
||||
if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE) {
|
||||
if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
|
||||
data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
|
||||
(data->easy_conn->tunnel_state[FIRSTSOCKET] != TUNNEL_CONNECT)) {
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
/* initiate protocol connect phase */
|
||||
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
|
||||
@ -1556,6 +1574,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* awaiting a completion of an asynch TCP connect */
|
||||
result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
|
||||
if(connected && !result) {
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
|
||||
!data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
|
||||
(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)) {
|
||||
multistate(data, CURLM_STATE_WAITPROXYCONNECT);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
multistate(data, data->easy_conn->bits.tunnel_proxy?
|
||||
CURLM_STATE_WAITPROXYCONNECT:
|
||||
@ -1564,7 +1590,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
else if(result) {
|
||||
/* failure detected */
|
||||
/* Just break, the cleaning up is handled all in one place */
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1584,7 +1610,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, TRUE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1601,7 +1627,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, TRUE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1676,7 +1702,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
if(drc) {
|
||||
/* a failure here pretty much implies an out of memory */
|
||||
result = drc;
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
else
|
||||
retry = (newurl)?TRUE:FALSE;
|
||||
@ -1709,7 +1735,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
}
|
||||
else {
|
||||
/* Have error handler disconnect conn if we can't retry */
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
free(newurl);
|
||||
}
|
||||
}
|
||||
@ -1718,7 +1744,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
Curl_posttransfer(data);
|
||||
if(data->easy_conn)
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1740,7 +1766,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1769,7 +1795,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* failure detected */
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1805,52 +1831,67 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
else
|
||||
result = Curl_speedcheck(data, now);
|
||||
|
||||
if(( (data->set.max_send_speed == 0) ||
|
||||
(data->progress.ulspeed < data->set.max_send_speed)) &&
|
||||
( (data->set.max_recv_speed == 0) ||
|
||||
(data->progress.dlspeed < data->set.max_recv_speed)))
|
||||
if(!result) {
|
||||
send_timeout_ms = 0;
|
||||
if(data->set.max_send_speed > 0)
|
||||
send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now);
|
||||
|
||||
recv_timeout_ms = 0;
|
||||
if(data->set.max_recv_speed > 0)
|
||||
recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now);
|
||||
|
||||
if(send_timeout_ms <= 0 && recv_timeout_ms <= 0)
|
||||
multistate(data, CURLM_STATE_PERFORM);
|
||||
else if(send_timeout_ms >= recv_timeout_ms)
|
||||
Curl_expire_latest(data, send_timeout_ms);
|
||||
else
|
||||
Curl_expire_latest(data, recv_timeout_ms);
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLM_STATE_PERFORM:
|
||||
{
|
||||
char *newurl = NULL;
|
||||
bool retry = FALSE;
|
||||
bool comeback = FALSE;
|
||||
|
||||
/* check if over send speed */
|
||||
if((data->set.max_send_speed > 0) &&
|
||||
(data->progress.ulspeed > data->set.max_send_speed)) {
|
||||
int buffersize;
|
||||
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
|
||||
/* calculate upload rate-limitation timeout. */
|
||||
buffersize = (int)(data->set.buffer_size ?
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
timeout_ms = Curl_sleep_time(data->set.max_send_speed,
|
||||
data->progress.ulspeed, buffersize);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
send_timeout_ms = 0;
|
||||
if(data->set.max_send_speed > 0)
|
||||
send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
|
||||
data->progress.ul_limit_size,
|
||||
data->set.max_send_speed,
|
||||
data->progress.ul_limit_start,
|
||||
now);
|
||||
|
||||
/* check if over recv speed */
|
||||
if((data->set.max_recv_speed > 0) &&
|
||||
(data->progress.dlspeed > data->set.max_recv_speed)) {
|
||||
int buffersize;
|
||||
recv_timeout_ms = 0;
|
||||
if(data->set.max_recv_speed > 0)
|
||||
recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
|
||||
data->progress.dl_limit_size,
|
||||
data->set.max_recv_speed,
|
||||
data->progress.dl_limit_start,
|
||||
now);
|
||||
|
||||
if(send_timeout_ms > 0 || recv_timeout_ms > 0) {
|
||||
multistate(data, CURLM_STATE_TOOFAST);
|
||||
|
||||
/* Calculate download rate-limitation timeout. */
|
||||
buffersize = (int)(data->set.buffer_size ?
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
|
||||
data->progress.dlspeed, buffersize);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
if(send_timeout_ms >= recv_timeout_ms)
|
||||
Curl_expire_latest(data, send_timeout_ms);
|
||||
else
|
||||
Curl_expire_latest(data, recv_timeout_ms);
|
||||
break;
|
||||
}
|
||||
|
||||
/* read/write data if it is ready to do so */
|
||||
result = Curl_readwrite(data->easy_conn, data, &done);
|
||||
result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
|
||||
|
||||
k = &data->req;
|
||||
|
||||
@ -1890,10 +1931,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
|
||||
result != CURLE_HTTP2_STREAM)
|
||||
connclose(data->easy_conn, "Transfer returned error");
|
||||
streamclose(data->easy_conn, "Transfer returned error");
|
||||
|
||||
Curl_posttransfer(data);
|
||||
multi_done(&data->easy_conn, result, FALSE);
|
||||
multi_done(&data->easy_conn, result, TRUE);
|
||||
}
|
||||
else if(done) {
|
||||
followtype follow=FOLLOW_NONE;
|
||||
@ -1906,7 +1947,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
/* expire the new receiving pipeline head */
|
||||
if(data->easy_conn->recv_pipe->head)
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 0);
|
||||
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
@ -1949,13 +1990,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
if(!result)
|
||||
newurl = NULL; /* allocation was handed over Curl_follow() */
|
||||
else
|
||||
disconnect_conn = TRUE;
|
||||
stream_error = TRUE;
|
||||
}
|
||||
|
||||
multistate(data, CURLM_STATE_DONE);
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
}
|
||||
else if(comeback)
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
|
||||
free(newurl);
|
||||
break;
|
||||
@ -2014,7 +2057,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
that could be freed anytime */
|
||||
data->easy_conn = NULL;
|
||||
|
||||
Curl_expire(data, 0); /* stop all timers */
|
||||
Curl_expire_clear(data); /* stop all timers */
|
||||
break;
|
||||
|
||||
case CURLM_STATE_MSGSENT:
|
||||
@ -2048,7 +2091,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe);
|
||||
Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe);
|
||||
|
||||
if(disconnect_conn) {
|
||||
if(stream_error) {
|
||||
/* Don't attempt to send data over a connection that timed out */
|
||||
bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
|
||||
/* disconnect properly */
|
||||
@ -2072,7 +2115,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* aborted due to progress callback return code must close the
|
||||
connection */
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
connclose(data->easy_conn, "Aborted by callback");
|
||||
streamclose(data->easy_conn, "Aborted by callback");
|
||||
|
||||
/* if not yet in DONE state, go there, otherwise COMPLETED */
|
||||
multistate(data, (data->mstate < CURLM_STATE_DONE)?
|
||||
@ -2102,10 +2145,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
}
|
||||
|
||||
|
||||
CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||
CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
CURLMcode returncode=CURLM_OK;
|
||||
struct Curl_tree *t;
|
||||
struct timeval now = Curl_tvnow();
|
||||
@ -2164,7 +2206,10 @@ static void close_all_connections(struct Curl_multi *multi)
|
||||
conn->data = multi->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(conn, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
@ -2172,11 +2217,10 @@ static void close_all_connections(struct Curl_multi *multi)
|
||||
}
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data;
|
||||
struct SessionHandle *nextdata;
|
||||
struct Curl_easy *data;
|
||||
struct Curl_easy *nextdata;
|
||||
|
||||
if(GOOD_MULTI_HANDLE(multi)) {
|
||||
bool restore_pipe = FALSE;
|
||||
@ -2247,9 +2291,8 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
* beyond. The current design is fully O(1).
|
||||
*/
|
||||
|
||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
|
||||
CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_message *msg;
|
||||
|
||||
*msgs_in_queue = 0; /* default to none */
|
||||
@ -2280,7 +2323,7 @@ CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue)
|
||||
* call the callback accordingly.
|
||||
*/
|
||||
static void singlesocket(struct Curl_multi *multi,
|
||||
struct SessionHandle *data)
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
|
||||
int i;
|
||||
@ -2452,7 +2495,7 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
|
||||
/*
|
||||
* add_next_timeout()
|
||||
*
|
||||
* Each SessionHandle has a list of timeouts. The add_next_timeout() is called
|
||||
* Each Curl_easy has a list of timeouts. The add_next_timeout() is called
|
||||
* when it has just been removed from the splay tree because the timeout has
|
||||
* expired. This function is then to advance in the list to pick the next
|
||||
* timeout to use (skip the already expired ones) and add this node back to
|
||||
@ -2463,7 +2506,7 @@ void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
|
||||
*/
|
||||
static CURLMcode add_next_timeout(struct timeval now,
|
||||
struct Curl_multi *multi,
|
||||
struct SessionHandle *d)
|
||||
struct Curl_easy *d)
|
||||
{
|
||||
struct timeval *tv = &d->state.expiretime;
|
||||
struct curl_llist *list = d->state.timeoutlist;
|
||||
@ -2474,7 +2517,7 @@ static CURLMcode add_next_timeout(struct timeval now,
|
||||
timeout in *tv */
|
||||
for(e = list->head; e;) {
|
||||
struct curl_llist_element *n = e->next;
|
||||
long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
|
||||
time_t diff = curlx_tvdiff(*(struct timeval *)e->ptr, now);
|
||||
if(diff <= 0)
|
||||
/* remove outdated entry */
|
||||
Curl_llist_remove(list, e, NULL);
|
||||
@ -2511,7 +2554,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
int *running_handles)
|
||||
{
|
||||
CURLMcode result = CURLM_OK;
|
||||
struct SessionHandle *data = NULL;
|
||||
struct Curl_easy *data = NULL;
|
||||
struct Curl_tree *t;
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
@ -2639,10 +2682,9 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
}
|
||||
|
||||
#undef curl_multi_setopt
|
||||
CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
CURLMcode curl_multi_setopt(struct Curl_multi *multi,
|
||||
CURLMoption option, ...)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
CURLMcode res = CURLM_OK;
|
||||
va_list param;
|
||||
|
||||
@ -2710,33 +2752,32 @@ CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
/* we define curl_multi_socket() in the public multi.h header */
|
||||
#undef curl_multi_socket
|
||||
|
||||
CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
|
||||
CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
|
||||
int *running_handles)
|
||||
{
|
||||
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
|
||||
0, running_handles);
|
||||
CURLMcode result = multi_socket(multi, FALSE, s, 0, running_handles);
|
||||
if(CURLM_OK >= result)
|
||||
update_timer((struct Curl_multi *)multi_handle);
|
||||
update_timer(multi);
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s,
|
||||
CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
|
||||
int ev_bitmask, int *running_handles)
|
||||
{
|
||||
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s,
|
||||
CURLMcode result = multi_socket(multi, FALSE, s,
|
||||
ev_bitmask, running_handles);
|
||||
if(CURLM_OK >= result)
|
||||
update_timer((struct Curl_multi *)multi_handle);
|
||||
update_timer(multi);
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles)
|
||||
CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
|
||||
|
||||
{
|
||||
CURLMcode result = multi_socket((struct Curl_multi *)multi_handle,
|
||||
TRUE, CURL_SOCKET_BAD, 0, running_handles);
|
||||
CURLMcode result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0,
|
||||
running_handles);
|
||||
if(CURLM_OK >= result)
|
||||
update_timer((struct Curl_multi *)multi_handle);
|
||||
update_timer(multi);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2754,7 +2795,7 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
|
||||
|
||||
if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
|
||||
/* some time left before expiration */
|
||||
*timeout_ms = curlx_tvdiff(multi->timetree->key, now);
|
||||
*timeout_ms = (long)curlx_tvdiff(multi->timetree->key, now);
|
||||
if(!*timeout_ms)
|
||||
/*
|
||||
* Since we only provide millisecond resolution on the returned value
|
||||
@ -2775,11 +2816,9 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_timeout(CURLM *multi_handle,
|
||||
CURLMcode curl_multi_timeout(struct Curl_multi *multi,
|
||||
long *timeout_ms)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
|
||||
/* First, make some basic checks that the CURLM handle is a good handle */
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
@ -2806,7 +2845,7 @@ static int update_timer(struct Curl_multi *multi)
|
||||
multi->timer_lastcall = none;
|
||||
/* there's no timeout now but there was one previously, tell the app to
|
||||
disable it */
|
||||
return multi->timer_cb((CURLM*)multi, -1, multi->timer_userp);
|
||||
return multi->timer_cb(multi, -1, multi->timer_userp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2820,7 +2859,7 @@ static int update_timer(struct Curl_multi *multi)
|
||||
|
||||
multi->timer_lastcall = multi->timetree->key;
|
||||
|
||||
return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp);
|
||||
return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2863,7 +2902,7 @@ multi_addtimeout(struct curl_llist *timeoutlist,
|
||||
/* find the correct spot in the list */
|
||||
for(e = timeoutlist->head; e; e = e->next) {
|
||||
struct timeval *checktime = e->ptr;
|
||||
long diff = curlx_tvdiff(*checktime, *timedup);
|
||||
time_t diff = curlx_tvdiff(*checktime, *timedup);
|
||||
if(diff > 0)
|
||||
break;
|
||||
prev = e;
|
||||
@ -2887,51 +2926,23 @@ multi_addtimeout(struct curl_llist *timeoutlist,
|
||||
* given a number of milliseconds from now to use to set the 'act before
|
||||
* this'-time for the transfer, to be extracted by curl_multi_timeout()
|
||||
*
|
||||
* Note that the timeout will be added to a queue of timeouts if it defines a
|
||||
* moment in time that is later than the current head of queue.
|
||||
*
|
||||
* Pass zero to clear all timeout values for this handle.
|
||||
* The timeout will be added to a queue of timeouts if it defines a moment in
|
||||
* time that is later than the current head of queue.
|
||||
*/
|
||||
void Curl_expire(struct SessionHandle *data, long milli)
|
||||
void Curl_expire(struct Curl_easy *data, time_t milli)
|
||||
{
|
||||
struct Curl_multi *multi = data->multi;
|
||||
struct timeval *nowp = &data->state.expiretime;
|
||||
int rc;
|
||||
struct timeval set;
|
||||
|
||||
/* this is only interesting while there is still an associated multi struct
|
||||
remaining! */
|
||||
if(!multi)
|
||||
return;
|
||||
|
||||
if(!milli) {
|
||||
/* No timeout, clear the time data. */
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
the splay tree */
|
||||
struct curl_llist *list = data->state.timeoutlist;
|
||||
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error clearing splay node = %d\n", rc);
|
||||
|
||||
/* flush the timeout list too */
|
||||
while(list->size > 0)
|
||||
Curl_llist_remove(list, list->tail, NULL);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
infof(data, "Expire cleared\n");
|
||||
#endif
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct timeval set;
|
||||
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += milli/1000;
|
||||
set.tv_sec += (long)(milli/1000);
|
||||
set.tv_usec += (milli%1000)*1000;
|
||||
|
||||
if(set.tv_usec >= 1000000) {
|
||||
@ -2943,7 +2954,7 @@ void Curl_expire(struct SessionHandle *data, long milli)
|
||||
/* This means that the struct is added as a node in the splay tree.
|
||||
Compare if the new time is earlier, and only remove-old/add-new if it
|
||||
is. */
|
||||
long diff = curlx_tvdiff(set, *nowp);
|
||||
time_t diff = curlx_tvdiff(set, *nowp);
|
||||
if(diff > 0) {
|
||||
/* the new expire time was later so just add it to the queue
|
||||
and get out */
|
||||
@ -2966,14 +2977,9 @@ void Curl_expire(struct SessionHandle *data, long milli)
|
||||
|
||||
*nowp = set;
|
||||
data->state.timenode.payload = data;
|
||||
multi->timetree = Curl_splayinsert(*nowp,
|
||||
multi->timetree,
|
||||
multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
|
||||
&data->state.timenode);
|
||||
}
|
||||
#if 0
|
||||
Curl_splayprint(multi->timetree, 0, TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_expire_latest()
|
||||
@ -2986,14 +2992,14 @@ void Curl_expire(struct SessionHandle *data, long milli)
|
||||
* time-out period to expire.
|
||||
*
|
||||
*/
|
||||
void Curl_expire_latest(struct SessionHandle *data, long milli)
|
||||
void Curl_expire_latest(struct Curl_easy *data, time_t milli)
|
||||
{
|
||||
struct timeval *expire = &data->state.expiretime;
|
||||
|
||||
struct timeval set;
|
||||
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += milli / 1000;
|
||||
set.tv_sec += (long)(milli / 1000);
|
||||
set.tv_usec += (milli % 1000) * 1000;
|
||||
|
||||
if(set.tv_usec >= 1000000) {
|
||||
@ -3005,7 +3011,7 @@ void Curl_expire_latest(struct SessionHandle *data, long milli)
|
||||
/* This means that the struct is added as a node in the splay tree.
|
||||
Compare if the new time is earlier, and only remove-old/add-new if it
|
||||
is. */
|
||||
long diff = curlx_tvdiff(set, *expire);
|
||||
time_t diff = curlx_tvdiff(set, *expire);
|
||||
if(diff > 0)
|
||||
/* the new expire time was later than the top time, so just skip this */
|
||||
return;
|
||||
@ -3015,11 +3021,53 @@ void Curl_expire_latest(struct SessionHandle *data, long milli)
|
||||
Curl_expire(data, milli);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t s, void *hashp)
|
||||
|
||||
/*
|
||||
* Curl_expire_clear()
|
||||
*
|
||||
* Clear ALL timeout values for this handle.
|
||||
*/
|
||||
void Curl_expire_clear(struct Curl_easy *data)
|
||||
{
|
||||
struct Curl_multi *multi = data->multi;
|
||||
struct timeval *nowp = &data->state.expiretime;
|
||||
int rc;
|
||||
|
||||
/* this is only interesting while there is still an associated multi struct
|
||||
remaining! */
|
||||
if(!multi)
|
||||
return;
|
||||
|
||||
if(nowp->tv_sec || nowp->tv_usec) {
|
||||
/* Since this is an cleared time, we must remove the previous entry from
|
||||
the splay tree */
|
||||
struct curl_llist *list = data->state.timeoutlist;
|
||||
|
||||
rc = Curl_splayremovebyaddr(multi->timetree,
|
||||
&data->state.timenode,
|
||||
&multi->timetree);
|
||||
if(rc)
|
||||
infof(data, "Internal error clearing splay node = %d\n", rc);
|
||||
|
||||
/* flush the timeout list too */
|
||||
while(list->size > 0)
|
||||
Curl_llist_remove(list, list->tail, NULL);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
infof(data, "Expire cleared\n");
|
||||
#endif
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
|
||||
void *hashp)
|
||||
{
|
||||
struct Curl_sh_entry *there = NULL;
|
||||
struct Curl_multi *multi = (struct Curl_multi *)multi_handle;
|
||||
|
||||
there = sh_getentry(&multi->sockhash, s);
|
||||
|
||||
@ -3066,7 +3114,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
struct curl_llist_element *e = multi->pending->head;
|
||||
|
||||
while(e) {
|
||||
struct SessionHandle *data = e->ptr;
|
||||
struct Curl_easy *data = e->ptr;
|
||||
struct curl_llist_element *next = e->next;
|
||||
|
||||
if(data->mstate == CURLM_STATE_CONNECT_PEND) {
|
||||
@ -3076,7 +3124,7 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
Curl_llist_remove(multi->pending, e, NULL);
|
||||
|
||||
/* Make sure that the handle will be processed soonish. */
|
||||
Curl_expire_latest(data, 1);
|
||||
Curl_expire_latest(data, 0);
|
||||
}
|
||||
|
||||
e = next; /* operate on next handle */
|
||||
@ -3084,10 +3132,9 @@ void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
}
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
void Curl_multi_dump(const struct Curl_multi *multi_handle)
|
||||
void Curl_multi_dump(struct Curl_multi *multi)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
int i;
|
||||
fprintf(stderr, "* Multi status: %d handles, %d alive\n",
|
||||
multi->num_easy, multi->num_alive);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user